Hacker News new | ask | show | jobs
by danuker 1212 days ago
I code in assembly in my mind. I just translate it to Lisp so others can understand it.

(sarcasm over)

If Lisp is so amazing, why does it not get more followers?

2 comments

"If <FOO> is so amazing, why doesn't everyone use it?" has got to be one of my least favorite questions. Never mind that it's lazy (in a bad way), it presupposes that people automatically adopt the best available technology or whatever, which is obviously false. But I think the thing that bothers me the most is that, asked with a different attitude and intent, it's usually a good question.

E.g. Lisp is so much better than pretty much every other programming language (except maybe APL) that it truly is bizarre and therefore interesting that it doesn't get wider adoption. (I don't even use it, despite having such a near-worshipful attitude towards it.)

>Lisp is so much better than pretty much every other programming language

>I don't even use it, despite having such a near-worshipful attitude towards it.

How do you know that it is so much better then?

In a word, extrapolation. I hope I don't sound too ridiculous, here on Hacker News, but I've kinda devoted my life to computer programming (it's deeper than that, and there's a lot of other stuff going on, but to a first approximation, that's a true statement.) I used to joke that I was reserving a bank of brain cells for that day when it was time to learn Lisp. When that day finally came, I was well prepared and grokked it mildly, but enough to become angry when I saw all the time and energy that has been wasted due to non-use of Lisp. I literally stomped around the house for twenty minutes cussing!

Anyway, I know this is "argument from authority" by some rando on the Internet, so I don't expect you to take it seriously. :)

What about haskell and erlang how does lisp compare to these heavy weights?
Erlang is largely a different kind of niche than Haskell and lisp. Its more focused on distributed and reliable processing than more general purpose. In effect its the Actor model taken to the extreme. Where I'd categorize Haskell and lisp more general purpose but they take different approach. Lisp the more "keep it simple" approach and Haskell the high theory approach. I've yet to encounter someone that claims expertise in haskell that isn't obviously lying or delusional as it is probably the largest language feature wise. I've been learning it for years but still have yet to find the "target use case" that it is the best tool for the job. It certainly is worth learning about even if only for the new perspectives on problems it encourages.

At least in my opinion: Lisp is amazing for its simplicity and homoiconicness and the great powers that come with those. Erlang is amazing for its approach to distributed computation and reliability. Haskell is amazing for at least its theory, and probably more I'm not yet aware of.

That you think assembly is fundamental rather than an accident of architecture really shows how undereducsted you are in computer science. Lisp isn't great because it's weird, it's great because it lucked into homoiconicity in its birth. It's weird because no other language family can do that.

It's not popular because the majority of programmers are mediocre and will never understand the point of homoiconicity.

Show me homoiconicity used "for real". Sure, it's useful in compilers and interpreters, but how often do people need them in a business application? You will most likely use a library, and/or a syntax designed for serialization instead of programming, like JSON.

I personally vastly prefer Python's syntax over Lisp's, because the parentheses require two buttons pressed (shift + 9) instead of one (tab). That may sound trivial, but it's why I jump to Python instead of a Lisp.

That said, I do suffer from Python problems: the GIL, clunky immutable data structures like pyrsistent, poor support for shared memory for multithreading and so on.

Edit: I just realized in Lisp you could replace the built-in data structures if you wanted, so libraries like pyrsistent would require little change in client code syntax. I guess that's one example of homoiconicity in action.

Can you come up with another one? It is not very often that I find myself wanting to redefine the language I'm using (which comes with its risks: other coders and/or their tooling might find my code hard to follow).

The thing that makes lisp special, IMO, is how simple the syntax is. It makes thinking about certain kinds of problems much easier than in other languages, which can do the same things. As strange as it may sound, the book that most helped me understand Elixir's macros wasn't the book devoted to teaching them, but instead it was this Clojure book: https://pragprog.com/titles/cjclojure/mastering-clojure-macr...

In reality, they work pretty much the same way in the two languages, but due to the syntax, it was easier (at least for me) to grapple with the ideas in a lisp first.

I very rarely write macros, but I sure use them all the time via the web framework and db-wrapper libraries that dominate the Elixir ecosystem and they've been useful for all the "business applications" I've worked on in the past several years.

Running with the json example you don't need a json library in lisp because you'd just dump an s-expression holding the data you want directly. You don't need a library to parse it because it's already in a format that lisp can understand.

Hilariously enough the project that made me switch to lisp from python as my scripting language was writing a lightweight parser for ascii delimited files - https://en.wikipedia.org/wiki/Delimiter?useskin=vector#ASCII... - instead of csv files. After doing it in both I had the eureka moment of using nested s-expressions in the scheme version instead of special characters. All of a sudden I had access to a csv like file which could be arbitrarily nested and didn't require me to worry about escaping. The next mind blowing moment was when I realized I could embed the code of the parser as the header of the format as the type definition and use it to evaluate the format with the program that was used to create it.

You don't even need some deep insanity to do it just:

    (eval `(,(car ls) (cadr ls)) (interaction-environment))
It also shows why I wouldn't use lisp for everything: if I wanted to ingest a file of a known csv dialect that won't fit in memory I'd do it in C after doing the prototype/master version in lisp. I also wouldn't trust running unverified source code from the internet. But for internal projects it's better than sliced bread.
Well, I wrote a genetic programming library, and it was fun to parse a Lisp-like representation from Python. You still have recursion and everything (albeit no tail call optimization).

Here, `_from_source` goes from a plain array of tokens to a nested one (tree), depending on their arity:

https://github.com/danuker/symreg/blob/7c6593d3046f6c52dfb92...

S-Exps are almost valid Python. The exception is the single-element tuple which needs a comma: (x,)

But I still preferred to use Python as a programming language, and Lisp as a sort of AST. It's just easier. I am curious what roadblocks you faced in your ASCII delimited parsing.

Do you by any chance still have the two parsers? I'd love to see them. If you are worried about your anonymity, you can find my e-mail on my blog, and my website on my HN profile. I promise not to disclose your identity publicly.

>Here, `_from_source` goes from a plain array of tokens to a nested one (tree), depending on their arity:

You're 90% there. Lisp notation obviates the need for arity tracking, which is why in lisp + and sum are the same function:

    scheme@(guile-user)> (+)
    $416 = 0
    scheme@(guile-user)> (+ 1)
    $417 = 1
    scheme@(guile-user)> (+ 1 2)
    $418 = 3
    scheme@(guile-user)> (+ 1 2 3)
    $419 = 6

Add higher order functions, e.g. (λ (x) (x x)), and lisp notation is the simplest/only way to deal with the general case where you don't know ahead of time the arity of the function you'd be applying because of partial currying and data persistence.

As for the parsers this was 10 years ago at university. I've long since lost the source code. There weren't any problems with python, it's just that once I wrote the lisp version I realized just how useful the brackets actually are. There's a reason why every computer language is more or less context free. Lisp just takes that to its logical conclusion.

Well, thank you for your feedback. I don't know why I bothered with the flat list in the first place. I might rewrite this library in Clojure. And I might blog about my findings.

Cheers!

It also could be that autistic people such as yourself are such a small minority, that a programming language targetted for them won't ever have a large audience.
Greatness is indeed reserved for the few.

I guess the masses can muddle through with rust or typescript.