“Expressiveness”

Which language is more expressive, Lisp or Haskell?

I want to encourage you to forget the word “expressive,” or at least, strive to give it a particular sense in your language advocacy, because it means different things in different contexts, often nuanced and slightly contradictory things.

When Lisp is promoted as an expressive language, what is meant is that there is a complete macro system, and it is not difficult to write either abstract code or quite frankly machine-friendly, near-optimal code. But when Haskell is promoted as an expressive language, what is usually meant is that it has an extremely powerful type system that can express very abstract ideas. Few people seem to know it has a complete macro system inspired by Lisp—this does not seem to be a factor in its “expressiveness.”

In a certain sense, every strongly-typed language is less expressive than a weakly-typed language. Many classes of error that the strongly-typed language prevents the weakly-typed language would allow. There are literally more “expressions” in the weakly-typed language. This loss of “expressiveness” does not seem to keep advocates of Haskell from getting enough sleep, even though there are certainly programs that do not type check (or could not be made to within the confines of any particular regime) that are nonetheless correct, despite their unlikelihood.

Any program that my machine can execute can be written in assembly. Does that make assembly the most-expressive language? What if I want to say one thing and have it mean the same thing on different machines? Portability, in other words. If that constrains my options, does that also reduce expressiveness or improve it? Can you say more with haiku or with any random jumble of words?

A J program might be abstract over matrix dimensions for free. Can something be more expressive sometimes and less in others, depending on the context?

How does “high-level” vs. “low-level” fit into this? Prolog is more “high-level;” it has actual relations rather than just functions, and it will often figure out what you mean without you telling it how to do it. Yet, as Paul Graham once observed, it often actually requires more code to make a program in Prolog. And if it is more “high-level,” why did the Fifth Generation Project fail, and why does it sort of languish as an interesting class project but not widely used today?

More questions than answers, as usual.