Live data from Hacker News

A road to Lisp: Why Lisp

scotto.me

61–70 of 322 posts

Re: A road to Lisp: Why Lisp

#61

The website seems to have a bug with syntax highlighting. Pieces of code included in the post text are black, you can still see the actual text if you select it with your mouse. Same bug on Chrome desktop and on Safari on iPad

This is the classic example of why you should always set the foreground color when changing the background color. Otherwise you end up with blocks that are black-on-black. It probably works fine if your browser is in dark mode.

A workaround is to open one of the code elements in the browser's debugger and add color: white to the :not(pre) > code style.

Re: A road to Lisp: Why Lisp

#62

There are some truly powerful and unique things about Lisps, but I wish articles like this would stop including REPLs and hot-reloading. The former have been table stakes for interpreted languages (and some compiled ones!) for years, and the latter is neither unique nor particularly widely used (hot reloads have to tangle with state and patching, so resetting the world for ease of reasoning is considered a best pract…

Not all Lisp dialects have well-developed hot patching systems. The OOP system has to be carefully designed for it. What if a class definition is superseded by a reload, but there are existing instances? The Common Lisp dialect of Lisp has useful answers to questions like this, but not necessarily every Lisp you come across.

Even Bash supports hot-reloading. I've developed modules that are updated in place by sourcing:

   $ . /path/to/script.sh

Re: A road to Lisp: Why Lisp

#63
post #32

There are many articles extolling the virtues of Lisp. I would like to see some articles that have a level-headed criticisms or critique of Lisp, it's ideas and it's place in the ecosystem of languages. Articles like this, and the PG articles it references, amount to "if you know, you know". I understand the appeal and I understand the explicit and implicit arguments this article is making. Computer programming has m…

As a language Lisp is great (though the ecosystem is limited). It has two flaws-- it's very open-ended so unless you're talented and disciplined you can fall into a rabbit hole of hacking fun Lisp stuff and not actually getting any work done. Other languages have this problem, but Lisp I think more so.

The second flaw is that it eats perfectly capable minds for years and the results don't justify the time investment. Python or whatever is fine. I wish I took most (but not all) of the time I invested in Lisp and put it into something else instead.

Re: A road to Lisp: Why Lisp

#64

Programming is in tension between the Light Side and the Dark Side. The Light Side is about preventing the programmer from making mistakes: Get rid of go-tos! Add static types! Do not allow a bug to be expressible. The Dark Side is about giving power to the programmer: Macros? Obviously. Operator overloading? Self-modifying code? Multi-line reg-exps? Go to town! The Light Side knows programmers are flawed and imposes…

I think the big thing is that Lisp is (aside from mutable variable assignment) basically all declarative, rather than the imperative paradigm.

Even without static types, and even allowing macro craziness, there's just such a stronger baseline of declarative and functional thinking, you're off to such a good start in clearer thinking and reasoning about a program.

Re: A road to Lisp: Why Lisp

#65
post #4

I must admit - I still don't understand macros. I get that they're code that's generated at compile time. But I don't understand how that's different than a function which evaluates other functions. I guess the latter would actually be evaluated at runtime? I think I get it conceptually but I'm not sure I have the muscle memory to reach for them. Anybody here have an "ah hah!" Moment with macros?

You do not need macros for anything. They are not the tool to "extend the language", but instructions for the compiler. And if the system does not even have a compiler, macros are useless, often incredibly stupid.

If you have an interpreter only, no compiler, using macros for metaprogramming anwyay at least prepares you for the eventuality that one day there will be a compiler. The macros will Just Work as before, only the expanded code is now processed by compiling.

Suppose you reject the idea that there will ever be a compiler. Macros are still useful for doing "compiler-like things" in the context of interpretation, like transforming code into something that will interpret better.

We can regard the interpreter as a virtual machine acting on a representation of the code; the macro system lets you manipulate the representation in a pre-computed pass, which has no further cost at run time.

If you have a code expansion pass on top of an interpreter, for supporting macros, you can use that as an excuse to perform built-in code transformations that are not macros; those enable you to have more flexibility in how special forms are implemented.

In TXR Lisp case is a macro (family) which performs certain optimizations like recognizing values in a range and emitting a table switch. This works interpreted or compiled:

  1> (macroexpand '(case x (1 'a) (2 'b) (3 'c) (4 'd) (5 'e)
                           (6 'f) (7 'g) (8 'h) (9 'i) (10 'j)))
  (let ((#:test-0005
         x)
        (#:swres-0007
         '#:nohit))
    (and (integerp #:test-0005)
      (
It is faster to do some checks and interpret the sys:switch special form to dispatch by a numeric index than to do a large number of exhaustive comparisons.

Ultimately, the way we optimize interpretation is by compiling, but it can still be worth it to have better interpretation here and there.

You don't want to do this kind of optimization at run-time; you don't want the interpreter to be evaluating the condition "are these cases integers (or characters) in a tight range?". That's a property of the syntax in which the cases are constants; it wants to be pre-computed once.

Re: A road to Lisp: Why Lisp

#66
post #20

There are some truly powerful and unique things about Lisps, but I wish articles like this would stop including REPLs and hot-reloading. The former have been table stakes for interpreted languages (and some compiled ones!) for years, and the latter is neither unique nor particularly widely used (hot reloads have to tangle with state and patching, so resetting the world for ease of reasoning is considered a best pract…

But with Clojure and immutable by default, hot reload is a real thing, it sounds like not just on JVM but even among lisps.

Clojure barely let you import packages without restarting the JVM recently in its life.

Re: A road to Lisp: Why Lisp

#67

Earlier quoted context omitted.

No. There is real, palpable, practical, functional difference between working a Lisp REPL and a REPL in a non-homoiconic languages - Ruby, Python, Haskell, etc. Every single stage there in Read-Eval-Print-Loop differs. Man, it gets so exhausting trying to convince every PL critic who grabs a single (or a couple) of axis of any language and tries to dispute the value of a language without ever understanding the holist…

I wrote GGP as a Lisp user and enjoyer—not pretending to deep experience, but definitely am well acquainted. And neither the REPL nor live reloading are important differentiators. Neither is the ability to attach a REPL to a running program: plenty of languages have that built in (Erlang, Ruby), and many others support it through popular third party tooling (e.g. Pyrasite for Python, and—ironically—the class executor…

Homoiconicity is a "uniquely Lisp" feature and it doesn't seem like you've fully grokked the implications and differences between homoiconic and non-homoiconic. I'm not making this up - every step there in Read-Eval-Print-Loop does differ. That is easily verifiable info.

Re: A road to Lisp: Why Lisp

#69
post #25

I've been wondering - Is lisp (common lisp, clojure, scheme) easier for iterative work with LLMs?

I've found LLMs to be bad at balancing parenthesis. I've also found them to be less likely to hallucinate library types in dynamic languages, they tend to hallucinate arguments to library functions/methods instead.

> I've found LLMs to be bad at balancing parenthesis.

I think that was true last year. In my experience, it’s no longer the case with Claude Code or Codex.

Re: A road to Lisp: Why Lisp

#70

Programming is in tension between the Light Side and the Dark Side. The Light Side is about preventing the programmer from making mistakes: Get rid of go-tos! Add static types! Do not allow a bug to be expressible. The Dark Side is about giving power to the programmer: Macros? Obviously. Operator overloading? Self-modifying code? Multi-line reg-exps? Go to town! The Light Side knows programmers are flawed and imposes…

I like your metaphor but I'd argue that trusting programmers with power is the Light Side. Relevant PG: https://paulgraham.com/langdes.html

That's a great essay--thanks.

And you have a good point. Maybe it's a weakness in the metaphor if one can see it either way.

I fundamentally believe that there is no perfect language, instead one merely chooses a set of trade-offs. What's interesting about Lisp is that it is simultaneously well-respected and yet not widely used in productions (compared to C, C++, Python, JavaScript, and even Rust).

It's almost like Lisp chose a particularly extreme set of trade-offs that yield great power but also repel large swathes of programmers. I think PG might say that it repels dumb programmers, but maybe not.

Post reply on HN