sevensor 3 days ago

Every time I approach sbcl I run smack into the problem of installing dependencies. Quicklisp, clpm, roswell, ultralisp, qlot. Docker even. Each cool sounding project wants me to do something different. This one prefers ultralisp. Do CL users actually use libraries from multiple sources at the same time. Do all these tools play nicely with each other?

  • anonzzzies 2 days ago

    I mostly always use the same libraries and have them forked. And as little as possible. We have our own substantial tooling built on top of those libraries built up over the last 15 years. The only modern thing we use (now for everything) is CLOG.

    I wish someone would write something better, but on the other hand; we can quickly build anything we need with the tooling we have without the need for libraries. Basically; set up what you need and consider it 'your responsibility' now. I think that's the healthy way to handle libraries anyway, in any ecosystem; bad actors are everywhere and 'just updating/upgrading' stuff is such a bad idea usually.

    Don't get me wrong; I do feel your pain when you want to try out something; you have to have some understanding or how to work with CL and the tooling to get up projects that have rotted over time, but it's not hard. I recently added a library that is 12 years old to our project and it took a few minutes to fix some of the deps; now it's in our repos and works perfectly.

    For other work, I have to work in the nextjs / npm ecosystem and good lord am I happy CL doesn't have that; almost every library is terrible; I became a contributor to 100s of npms over the years because they almost all truly suck. Just 'quickly do this and that, npm publish, alright works for me kthnxbye'. Massively (over-invested some of them with millions of VC$) used projects in NPM contain seriously painful bugs that remain open for months or years (or wontfix... it's a bug mate, not a feature). Most major ones take me more time to debug and fix than I would write them from scratch in our CL tooling.

    Sorry for the rant.

  • koito17 3 days ago

    Ultralisp is Quicklisp but with frequently updating dists rather than monthly dist releases. Its popular is due to the fact Quicklisp, in comparison, takes lots of time for submitting and updating libraries.

    CLPM is an interesting project but not used very often since projects rarely version anything in the CL ecosystem (not even branch tags anymore). Personally, I have never seen a library that suggests CLPM for installation.

    Roswell is a CLI tool that manages Common Lisp installations, with Quicklisp set up automatically.

    Never heard of Qlot or Docker being used.

    My biggest gripe is the fact Quicklisp is widely used and no notion of version dependencies exist (not even lockfiles exist). So Common Lisp code with tons of Quicklisp dependencies tends to rot really fast. e.g. it's practically impossible today to build projects like https://github.com/akamai/cl-http2-protocol

    • anothername12 2 days ago

      > Never heard of Qlot

      > no notion of version dependencies exist (not even lockfiles exist

      I think that’s the point of Qlot

    • shawn_w 2 days ago

      Monthly? It's been over a year since the last quicklisp library update... Quick is not the word for it any more.

  • Onavo 3 days ago

    Lisp users generally treat libraries the same way C people do and vendor anything that's truly important. There's ocicl if you want something more scalable.

    https://github.com/ocicl/ocicl

    (Lisp users are generally very anachronistic people who don't understand dependency management nor know how to resolve diamond dependency issues, ocicl is one of the better approaches along with CLPM but they both get a lot of pushback from the community which "don't see a need".

    • sevensor 3 days ago

      Thanks! Actually vendoring it in sounds pretty reasonable for my purposes, which are basically “mess around with this thing somebody posted to HN.”

      • lukego 3 days ago

        I think the median user starts with quicklisp and then clones random stuff into the ~/quicklisp/local-projects/ dir where they are automatically visible.

        • lamuswawir 3 days ago

          Cloning into ~/common-lisp/ also works great.

        • pfdietz 3 days ago

          This is what I do.

  • anonzzzies 2 days ago

    Never heard about qlot, but looking at it now, doesn't that solve it?

    • sevensor 2 days ago

      I think you’re right? But as an outsider who wants to mess around with CL, I think I might be better off taking the sibling’s suggestion and just pulling in other people’s code, until that becomes unsustainable, and then figuring it out :)

      • anonzzzies 2 days ago

        Yes, that's what we do. It works well and you learn quite well how to fix/work with other ways over time.

  • BoingBoomTschak 3 days ago

    Well yeah, there's pain aplenty in the CL ecosystem but that's how it is. I'm still on quicklisp, but eyeing a better solution too (qlot or maybe ocicl, though I don't like the Entreprise^tm whiff and having to download a fat Go binary not packaged anywhere to do anything).

    • atgreen 11 hours ago

      The oras binary dependency could be replaced with lisp code. Doing this was a very low priority when I was getting started, mainly since oras works very well and is much better tested than anything I could put together myself. In truth, it's still a low priority for me, but I wouldn't be opposed to reviewing patches if somebody felt like doing this.

      For what it's worth, oras is packaged in homebrew for both mac and linux, and the homebrew ocicl package uses this instead of its own.

wk_end 2 days ago

My Lisp is rusty and was never that great to begin with, but:

Why is mcd a macro? And isn’t it missing a gensym?

  • tmtvl 2 days ago

    To answer in reverse order: it doesn't need a gensym because it isn't introducing a new variable. The only variable being used is `dir`, and that is passed in.

    As for why it's a macro rather than a function, I don't know, but it's possible that one of the features (probably variable substitution) is important.

      (frobnicate (mcd (foo bar)))
    
    Gets expanded to:

      (frobnicate (fg
                    (mkdir -p (foo bar))
                    (cd (foo bar))))
    
    At compile-time. I personally would have used a function declared inline, though.
    • wk_end 2 days ago

      But my intuition is that it needs to (well, should) introduce a new variable in order to store the evaluation of dir, otherwise it gets evaluated twice. If (foo bar) has no side-effects, that’s just a performance loss, but if it does it’s probably behaving in unexpected ways.

      • tmtvl 2 days ago

        Yeah, that is the strange thing, but binding it to a gensymmed variable would make it interchangeable with an inline function. That said, maybe `fg` is a macro which does some rewriting of its body, that could explain the decision.