5 ms·
> The language with the best chance of lasting a long time is the one with the simplest syntax. If you're going to make an argument for Lisp, I think focusing
by kerkeslager 4y ago
> The language with the best chance of lasting a long time is the one with the simplest syntax.
If you're going to make an argument for Lisp, I think focusing on syntax is the weakest argument you could make. Simplicity is good, sure, but syntactic simplicity is a very surface-level form of simplicity. Consider:
(def inc (n)
(+ n 1))
def inc(n):
return n + 1
fn inc(n) {
return n + 1;
}
inc(N) -> N + 1.
These are fictional example syntaxes, but you can see where my inspirations come from. The point is, these all express the same things. There's some argument about which syntax is clearest, but that's mostly going to be based on what languages people already know. It's a bit silly to argue what's clearest from some sort of ideal pure world where people coming into your language don't know any other languages, because that's not the world we live in.
Now consider:
(def void incAll (((list int) ns))
(decl int i)
(for (= i 0) (< i (length ns)) (++ i)
(++ ([] ns i))))
def incAll(ns) {
return map(ns, n => n + 1);
}
In the first example, we're doing C-ish things in Lisp-ish syntax, and in the second example we're doing Lisp-ish things in C-ish syntax. As you can see, doing Lisp-ish things in C-ish syntax works pretty well (and lots of modern languages do this). But doing C-ish things in Lisp-ish syntax is an abomination--in fact, the simpler syntax actually forces us to do more weird stuff to get around not having more complex syntax for more complex operations.
This gives us a clue that maybe simple syntax isn't inherently simpler to use. At least some of the simplicity of Lisp comes from the other ideas it brings to the table. And notably, nothing prevents us from using those ideas in other languages.
Discussion of Lisp syntax can't fail to mention that Lisp's simpler expressions enable its powerful macros. Lisp true believers will wax poetic about how Lisp macros allow you to create domain specific languages. But in practice, macros are are often just an opportunity to shoot yourself in the foot and create hard-to-debug bugs. If you're introducing macros, the simplicity argument starts to fall apart because you're adding a massive amount of complexity.
- dgb23 4y agoMacros are one thing that you easily get from that syntax. And I would argue that it's far less of a footgun than you make it out to be. But really there are many things that aren't mentioned such as Editor/IDE tooling, in-editor REPL, evaluating expressions, debugging, structural editing, code navigation, formatting... Your example is actually kind of misleading, because the second variation is much closer to how you write in a Lisp than the first. It would really be something like: ``` (def inc-all (partial map inc)) ``` It really makes no sense to use a Lisp in a non expression based manner. The syntax is inherently optimized for it.
- kerkeslager 4y ago> Your example is actually kind of misleading, because the second variation is much closer to how you write in a Lisp than the first. That's the point, yes. See how maybe the syntax isn't the important thing here?
- dgb23 4y agoIt's syntax that is optimized for expressions rather than statements. There are a lot of nice features falling out of that. In my opinion it makes little sense to misuse it in order to show its utility. It's a little bit like quoting someone out of context if that makes sense.
- kerkeslager 4y ago> It's syntax that is optimized for expressions rather than statements. I'm not sure how you think S-expressions are any more optimized for expressions than, for example, infix notation. That's exactly what I'm showing with the second example. I'm open to hearing why you think S-expressions are better for expressions, but I suspect any differences you might point out are pretty subjective. > There are a lot of nice features falling out of that. Really I can only identify one feature which falls out of S-expressions, which can't be obtained with other syntaxes: macros. And whether that's a good feature is pretty subjective: it's pretty arguably a misfeature in my experience. > In my opinion it makes little sense to misuse it in order to show its utility. Agreed: I'm not misusing S-expressions to show their utility. I'm misusing S-expressions to show that they don't inherently give you the benefits of Lisp. And I'm showing Lisp-y code without S-expressions to show how the benefits of Lisp can be obtained without S-expressions.
- lispm 4y ago> I'm not sure how you think S-expressions are any more optimized for expressions than, for example, infix notation. They aren't. But they are optimized to represent expressions as simple data: nested lists. One could write infix expressions as a data structure: (a + b * (c + d) * 3) READ converts it into a list. For that one could write a simple evaluator, a simplifier, or other tools based on simple list processing. > Really I can only identify one feature which falls out of S-expressions, which can't be obtained with other syntaxes: macros. Macros are one application of processing of s-expressions. The more general feature is representing any type of code as nested lists -> symbolic expressions. They are a compromise between a human-readable, textual & internal data format and machine processable code. Lisp code is just one application of that. It could be Prolog code, expressions of a theorem prover, or anything else which sports a custom processing engine and a lean way to input/process/output code as data. Actually macros can be obtained with other syntaxes. The Lisp way to represent code externally and internally as s-expressions is just one way. It's relatively simple and primitive. A simple interpreter for Lisp code can be written in a page of Lisp -> processing engines can also be very simple. The input and output of code then already provided by the reader and printer of s-expressions. Thus one can use s-expressions to design notations that are BOTH trivially a data structure with a textual representation AND processable with a simple predefined 'list processor' (aka Lisp) or any other custom "list processor". Looking at the textual representation in isolation is missing the bigger picture: it's the simple textual representation of lists AND a simple "list processor".
- psychoslave 4y agoTo my mind nothing can be as readable as: map some-function of some-parameter, other-parameter to some-parameter apply play-with other-parameter Which is a more casual way to express: def some_function ( some_parameter, other_parameter )= some_parameter . play_with other_parameter The latter is actually valid Ruby code, but the former is not valid in any programming language I’m aware of. Yet they are a simple token substitute version of each other. I purposefully placed spaces in the latter to better reflect that. Note that going a tiny bit further, you could easily get rid of the "apply" token in the former with some convention regarding precedence in denotation. And yet the whole industry prefer to clutter their communicated ideas with all kind of symbols that are impenetrable to the layman.