Hacker News new | past | comments | ask | show | jobs | submit login

There's a lot in this article that I really identify with: the preference for a functional style (even if I'm just not smart enough to do the whole ultra-abstract symbol soup Haskell thing); the comfort I feel leaning on the compiler; "it also always feels like I’m tricking Lisp into doing what I want, rather than simply expressing what I want" feels like it came right from my brain.

God, Lisp...the core language isn't exactly that interesting in this day-and-age. Dynamic typing, garbage collection, anonymous functions, this has been the bread-and-butter of Python, JS, Ruby, etc. developers for like 20 years now. It's got some really powerful features like conditions and CLOS. But then the bulk of the language and library built on top is such a mess: it's missing so much basic functionality, but also has so many niche functions that can be configured every which way with niche keyword arguments, and they all turned out to be evolutionary dead-ends and much worse than what the rest of the world settled on (actually CLOS probably falls into this category too). I think it's this, more than anything, that makes programming in Lisp feel like an act of trickery rather than clear thinking.

But I'll also say that I've been hobby programming in Lisp a bit recently and, despite that, I've been finding it immensely pleasurable, the first time I've really enjoyed working with a computer in years. The highly interactive, image-based workflow is just so much smoother than my day job, where I'm constantly jumping between VSCode and Chrome and a console and manually rebuilding and sitting around waiting...

Macros may be a double-edged sword - they encourage monstrosities like LOOP, rather than building more powerful/regular/comprehensible language features like iterators or comprehensions. BUT when paired with that interactive development experience, it really feels like you're in a dialogue with the computer, building out a little computational universe.




I learned Common Lisp during the life of this HN account, and there's an amusing trajectory in my comments, from "I hear Lisp is beautiful and I'd love to learn it", through "Wait, Common Lisp is kind of a horrendous mess", to "OK, I get this, this is very cool".

Common Lisp genuinely expanded my thinking about programming, so I find this article's poetry analogy very apt. But part of this growth was clarifying my own preferences about programming, and some of CL's greatest strengths - extremely clever runtime meta-programming, CLOS, etc - are not actually things I want to work with in a code base at scale.

I also think the UX for CL, outside the commercial Lisps, is pretty grim. CL would greatly benefit from a rustup-cargo-like system with good dep management and sane beginner defaults, like wrapping the SBCL REPL in rlwrap. Haskell is more beginner friendly than CL right now, and that's quite the indictment.


> good dep management

you can see https://github.com/ocicl/ocicl and https://github.com/fosskers/vend (newer)

> sane beginner defaults

agree. CLISP's REPL is beginner friendly, but we shall not advise it today. I'm doing this: https://github.com/ciel-lang/CIEL/ Common Lisp with batteries included. The terminal REPL has completion and syntax highlighting. You can run scripts easily. You get many common libraries. (beta)


I’m curious to know what would be your top reading suggestions for learning CL


Sorry for my late reply. Touretzky's Common Lisp: A Gentle Introduction to Symbolic Computation holds up well as a good introduction. Steve Losh's A Road to Common Lisp is a great roadmap for going further (https://stevelosh.com/blog/2018/08/a-road-to-common-lisp/).

For tooling, you can get started with just sbcl and rlwrap, both of which should be in any Linux repo. Get a REPL with `rlwrap sbcl`. Exit with `(exit)`.


>God, Lisp...the core language isn't exactly that interesting in this day-and-age. Dynamic typing, garbage collection, anonymous functions, this has been the bread-and-butter of Python, JS, Ruby, etc.

CL still got symbols, the reader (and its macros), gradual typing and user available runtime compilation (compile and compile-file).

I find the core language itself near perfect (mostly the historic stuff like threads/atomics/unicode missing, the whole divide between normal CL and CLOS and lack of recursive and parametric typing") but the standard library quite baroque and lacking; still infinitely more serviceable than C's, though.


(to be clear those historic stuff are present in today's implementations)


> CL still got symbols, the reader (and its macros), gradual typing and user available runtime compilation (compile and compile-file).

TypeScript has all of these, too.


JS Symbols are like CL gensym and CL symbols (interned strings) don't exist in JS.

Normal TS doesn't expose normal macros or reader macros to the user.

JS runtimes don't have the image introspection ability of CL.

TS types are removed before the JIT and don't actually impact performance (not to mention they encourage polymorphism which is actively BAD for JS performance). CL type hints are use by the compiler to actually speed up the output code (quite dramatically I'd add).


Really? You can `(compile nil my-lambda)` without having to write a JIT yourself?

I meant reader macros, by the way: can it do that?

  ; A comment
  (set-macro-character #\% (get-macro-character #\;))
  % Also a comment


Sure.

    new Function(“…”)
There’s no guarantee that it will be JITed, but then the CL standard is also pretty loose about the semantics of ‘compile’.


I must admit, I don't know what this is doing, and why.


The semi-colon symbol is the single-line comment symbol in Lisp, but the percent symbol means nothing special in Lisp.

SET-MACRO-CHARACTER is used to modify what happens when certain characters are found while reading code. In this case, SET-MACRO-CHARACTER is being used to instruct Lisp to start treating % as if it were a semi-colon (i.e. the third line is a comment), thus extending the syntax of Lisp on-the-fly.

The (GET-MACRO-CHARACTER #\;) portion could have been any code at all; GP could have defined % to do anything, such as "treat the remainder of this line as if it were a line of Python code", using calls to a Python implementation, such as cl-python [0].

[0] = <https://github.com/metawilm/cl-python>


who is using macros in ts ?


Yet, Python, JS, Ruby, etc, are still missing the JIT/AOT toolchains in the box like Lisp languages, even with V8, you need a debug build for something as basic as (disassemble ....), and then there are the IDE tooling, live coding experience, that for having something remotely close, means getting one of the JetBrains IDE, and still not the full stack experience like Lisp.

One would have expected that after all these years, dynamic languages would have learned a bit more from Lisp than only the type system, and having a GC.


Give Janet a try, it's a breath of fresh air with well-realized primitives and a solid standard library. For a decade now I've been immersed in the worlds of Clojure and Nim, where macros often get abused to no end. I've written 0 Nim macros, and a number of Lisp macros I could count on one hand.


I agree on macros: I have been using Common Lisp since 1982 and I almost never write macros. To be fair, I like my Common Lisp code to be readable (to me) and don't care as much about conciseness.

In any case, I think every developer should have a few languages that they really enjoy using.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: