I still Lisp (2021)
betterprogramming.pub
betterprogramming.pub
Edit: I’m wrong in the present case! Author has some cool projects on GitHub under themetaschemer. Still though I’m struck by the ratio of lisp project articles vs lisp praising articles hitting HN’s front page.
All those Rust posts you're talking about on HN? They're annoying.
With Racket?
Surely not true if you write it idiomatically using the standard “purely functional” collections.
I've seen Clojure sped up to within 20% of Java's speed, at the cost of very un-Clojure-y code.
File through the Elite source code. Do tut.txt in Arc.
Picture ten billion things and ChatGPT-X, Lisp interacting.
If you're looking to create a stand-alone executable and have C/C++ libraries you'd like to use then SBCL or Racket may be more useful to you.
I started with Common Lisp and PG's online book On Lisp. http://www.paulgraham.com/onlisp.html
https://docs.racket-lang.org/reference/index.html
I would think that it has roughly 4000 identifiers in the Racket language.
See the index: https://docs.racket-lang.org/reference/doc-index.html
Common Lisp has <1000 exported symbols in the "COMMON-LISP" package.
> when Common Lisp was being planned they needed to accomodate many features from many different Lisps before it
Common Lisp is mainly a slightly modernized & portable version of Lisp Machine Lisp, the feature influence of other Lisp dialects is not that big. The main difference is that Common Lisp provides lexical bindings and lacks a few features.
From the outside my code bases look 0% lisp, from the inside they are 100% lisp with build artifacts in other languages.
Is Rust brain dead language anyone can follow along? Did you mean python?
> From the outside my code bases look 0% lisp, from the inside they are 100% lisp with build artifacts in other languages.
Can you expand on that? You generate code of other language than lisp in lisp?
>Can you expand on that? You generate code of other language than lisp in lisp?
I write the real program in lisp in two weeks then translate it to a brain dead language over a few months so the average developer contribute to the code base.
It's rather impossible to get people used to algol descendants to think about complex programs. It's rather like explaining color to the bilnd.
(sarcasm over)
If Lisp is so amazing, why does it not get more followers?
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.)
>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?
Anyway, I know this is "argument from authority" by some rando on the Internet, so I don't expect you to take it seriously. :)
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.
It's not popular because the majority of programmers are mediocre and will never understand the point of homoiconicity.
I guess the masses can muddle through with rust or typescript.
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).
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.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.
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.
Cheers!
The fastest composite Python "framework" is uvicorn at 17.9% of the fastest run in Java (officefloor). The fastest Clojure run is Aleph at 36.4%.
https://www.techempower.com/benchmarks/#section=data-r21&l=z...
About SBCL, I get conflicting results. The Benchmarks Game shows it roughly as fast as Java for many problems:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
But here it's significantly worse than the Clojure runs, likely due to the slow DB bindings (the other test types show it roughly in line with Clojure; though it uses a "Stripped"/unrealistic HTTP implementation):
https://www.techempower.com/benchmarks/#section=data-r21&l=z...
I am not sure which Lisp implementation is used; is it SBCL? Does this file speak to you?
https://github.com/TechEmpower/FrameworkBenchmarks/blob/73eb...
[1] https://renato.athaydes.com/posts/revenge_of_lisp-part-2.htm...
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.
I never bothered checking it out before because I had always seen it described as unusable so I figured it would be a waste of time.
HN articles about exotic things, not just Lisp, do seem to get upvoted disproportionately.
Also, PG declared Lisp as something you're supposed to think is important or a superpower, and I've wondered whether that also contributes to some upvotes on HN.
But I'm not aware that a single one of the bajillion YC startups used Lisp.
Maybe it's like an admirable religious dogma that a congregation affirms each weekend, and then promptly forgets about for the rest of the week.
they switched to python for various reasons.
r2 (old reddit, the reddit API, some parts of new reddit, some of their ML stuff), their monolith, is still written in python.
some services they have in go include some real time services (like the reddit talk stuff seems to be primarily written in go)
reddit kinda seems to have a SOA (not microservices). while there are some codepaths that go through r2 (and indeed this seems to be the case in a lot of cases with regards to old reddit), a lot of newer code uses services.
(note: their engineering blog (/r/RedditEng) calls a lot of their stuff microservices and indeed they may be using that for some things but a lot of their stuff have been described as using more of a SOA vs a microservices.)
someone like /u/ketralnis may have more information as well?
I have received offers this year to join well-funded startups using Clojure.
Datomic is great for some usecases. Clojure often leads the Stack Overflow survey in terms of salary.
Clojure often leads the Stack Overflow survey in terms of salary.
wouldn't that also imply the classic demand and supply thingy ? the one that is alluded too in pg's articles...This actually meshes well with what you'd expect from a lisp being used well. Lisp's power and its downfall is that it lets you express abstraction at whatever skill level you're at with no built-in mechanisms to keep style consistent across large teams. This works really well for small teams of high powered developers.
this is exactly right. i guess, a large part of the puzzle is to build one, and then leave them be...
Taking a code base and expanding the macros to see whether that is more or less readable is a bit like expanding a C++ class hierarchy into assembly language and concluding that this program’s object oriented design is great because it is more readable than the resulting assembly language.
The real question is whether or not there are better alternatives than macros or metaprogramming in the first place. Functions, especially as found in modern languages[1], have proven to be very useful abstraction mechanisms and can often mitigate the lack of fancy macros.
I don’t want macros banned from Lisp, but I don’t miss them in other programming languages. Over exuberant use of fancy macros in Knuth’s brilliant TeX, in my opinion, contributes to the glacial pace of LaTeX development.
[1] By this I mean functions with circumscribed access to non local variables, provisions for choices of ownership of parameters, static scoping, first class functions, closures, and recursion.
You're stuck with the ill-designed crap that Python puts out. For instance, I don't agree with pattern matching that assigns to existing variables; from where I'm sitting, it looks like an incompetent clusterfuck. If someone did that in one Lisp program, the entire language would be blamed for allowing that sort of "curse".
The only relevant "better" in this debate is whether that would be more readable in those specific cases. People still make macros over functional solutions; e.g. the trick where a macro expands into just a function call to one or more generated lambdas which hold argument material. All macros expand to nothing but functions and special forms.
TeX macros are just preprocessor cruft that is more closely related to C macros than Lisp macros. TeX and LaTeX are fragile mainly because of the semantically impoverished target language which just has global variables and conditionals. LaTeX macros are leaky; use them in the wrong place and they misbehave.
After much searching for the perfect languages and perfect tools (while using emacs as a simple text editor), it finally dawned on me that Emacs itself is as close as I'd get to a lisp machine right here in my own back yard. A lisp machine that sits quite nicely on top of linux/unix and plays very nicely with it.
There's much that I love about the lisp world, and the author does a great job of articulating the reasons why. There's also much that I love about the unix philosophy. Emacs is a bridge between these two worlds that I love, and I'm old enough now not to give a shit (or need to give a shit) what the rest of the world is doing. This is home.
What's the lesson? That a text editor's extension language needs the strong concurrency and immutability models of a Clojure or sbcl? Getting emacs to sit and roll over doesn't exactly require an industrial grade language.
Do you mean since hitting rock bottom in June 2021?
https://pageviews.wmcloud.org/?project=en.wikipedia.org&plat...
Eg https://knowledge.autodesk.com/support/autocad/learn-explore...
I’d love to write more lisp, and like the article author I’m drawn to Racket, but I’ve just got very little bandwidth for exploring it further. Even so, lisp generally is something I advocate learning especially to mentees, because learning it (in author’s sense pretty much exactly as expressed, but with no strong feelings towards static typing at the time) was so transformative for me. I don’t need to write lisp to reap most of its benefits now… I write code in whatever language with the same attitude the author describes: mostly operate on values, abstract and isolate mutations with particularly high value, enjoy reasoning about code easily. And I’d add: recognize things which are like sexprs for what they are as things you can treat like sexprs because that’s more or less what they are.
Granted I’m not posting anything to HN, front page or otherwise besides comments. But I’m still inclined to praise lisp even a few years out from the last time I actually wrote any. Because it’s bound to be as foundational for others as it has been for me.
As such, it damn near was a superpower compared to everything else available at the time in about 1984--think Assembly, C, Pascal, etc. Garbage collection meant that all the effort everybody else spent on memory management could be spent on your problem. And the ecosystem meant that you had actual data structures to work with right in the language library instead of having to build those from scratch every time.
Emphasis on WAS. Right at about 1988, the new languages demonstrated that everybody got the message.
Perl, Tcl, Python, etc. all had garbage collection and worked very hard to create a general ecosystem. This roughly negated the advantages that Lisp had.
At that point, anybody really well versed in Perl, Tcl, Python, etc. was equally as productive as if they were writing in a Lisp.
I'm happy to hear more thoughts and notes like this from the silent majority.
Maybe I am missing something but I visited their GitHub but could not find any cool projects. Clearly there are better examples of people who write Lisp seriously instead of evangelizing it. You have given some good examples of them yourself.
The tricks my muscle memory does on its own accord with lisp syntax within Emacs makes programming more fun than any other context.
Type checking can remove an entire class of bugs from even being a consideration. Yes, it could be argued that type mismatches are a trivial class of bug, and yes, proper testing should catch any issues... but catching problems before you go to testing can save you precious seconds, especially when coding in the typical interactive style of Lisp. Lisp lets you code at amazingly high velocity, good support for type checking helps increase that velocity even further.
Isn't making sure the types flowing in and out of your functions match, at some point, something you will eventually need to do anyway? Or are we trying to say the type system doesn't allow for perfectly safe things that should be allowed?
I'm not sure I understand it.
Then again, I'm also the person who wonders if the restrictions Rust puts on "valid" code aren't also too restrictive, so maybe we all exist on a gradient?
While you are discovering the correct way to solve a problem, you may desire to make such changes.
Therefore types can make it harder to discover the correct solution.
For example, if our customer IDs used to simply be increasing integers but then we decide to change to a UUID variant it would be a pain if I had something like:
(declaim (ftype (function (integer) (option customer)) get-customer-by-id))
And then had a bunch of functions calling out to that which all require integers and I had to change all the declarations from integer to UUID. However, I could save myself some future headaches by doing something like: (deftype customer-id nil 'integer)
And using the customer-id type everywhere. Of course, this is a very trivial example and a real problem would be harder to manage. That said, with optional type checking like SBCL has it is entirely possible to fly by the seat of your pants until things start to take shape.Not that it matters too much if you go with the tried and true method of tossing out the first two prototypes, but that's another discussion.
Which is what pro-dynamic-typing say about correctness, so we have come full circle.
Just because keywords and symbols exist doesn't mean the hypothetical programmer who would return -1 as a special value in a static language will not do so in a dynamic language. But in the statical language when the sum type is used it will prevent people from passing the result into an arithmetic function when more code is added in the future (in an ideal world tests would catch it, but in an ideal world the sum type would have been used from the very beginning).
There are trade-offs between static and dynamic typing, and while dynamic typing allows us to write code more quickly, things balance out when we include the time lost by type matching errors that static type would protect us from.
It's like the C vs Rust discussion but with less potential for leaking important customer data all over the web.
The older I get the more I realize that what makes something great to use isn't all about the language, but the surrounding environment, and how pleasant _that_ is to use. Personally I think I will most likely not Lisp for much longer because I'm seeing many other languages have much nicer to use ecosystems, even if they probably pay less.
Also, emacs isn’t really more complex to use than IntelliJ or Eclipse
Rust OTOH feels highly malleable and the tooling is always improving. The community seems to care about a good user experience across several domains - web, systems, networking, cryptography, desktop gui, and over the last 2 - 3 things are really coming together as coherent whole.
In other languages I hop around from class defs to class defs, different files. Just richocheting all over the file system. Something about LISP removes a lot of the ricochet. It's a weird sensation.
But I don't use it outside of Scripting .NET Apps anymore other than when needing to perform quick calculations while I'm already in the command-line, I can bring up a quick LISP REPL with `x lisp`.
[1] https://sharpscript.net/lisp/
I sort of feel like I'm walking through an abandoned alien city and wondering what size they were, how many limbs they had, and if we share the same 5 senses or not.
- Use an array
- Load the entire file in a memory buffer and skip the reader
- Use mmap (for extra points, you can keep the entire file outside the Lisp heap but still manipulate it in Lisp)
But, also, once you hit a couple megabytes or so, it’s almost always better IMO to consume a file incrementally rather than all at once.
for js/react, there is nothing even close to reagent/shadowcljs.
lisp is thriving on frontend, and doing just fine on backend.