> Thus, if you're looking to get started with programming in Common Lisp, then there are 2 options:
The author misses the third, most classical, and constantly useful option: doing it all yourself. Despite the scary name, there's not all that much to do, and this approach is the most widely supported in the community. The checklist is:
* SBCL/CCL (from your package manager or from official binaries),
* Slime/Sly (manually, or via `(ql:quickload quicklisp-slime-helper)`, or via using an Emacs distribution, such as Spacemacs with its common-lisp layer, which already contains preconfigured slime/sly).
There, you're good to go.
Using some sort of toolkit which enables interactive and incremental programming (such as Swank/Slynk on the Lisp side and any Slime/Sly client on the editor side) is an ABSOLUTE MUST while doing Lisp. If you're allergic to Emacs and therefore can't use Slime/Sly, use:
Yes, this is definitely an option and it really should have been mentioned but given that even https://common-lisp.net/downloads recommends that one use portacle to get going quickly for newbs, it seem prudent not go too far off-track :).
Too complicated. Those quicklisp and slime is not easy for starter (but sort of essential as lots of functions can be obtained via this distribution manager).
The approach he tried is using as simple as one can. I guess the only thing missing is if you were mac and windows user ...
Last week, I shared a 35 line ~/.emacs (as a Show HN post) that turns Emacs into a Common Lisp development environment pretty quickly: https://github.com/susam/emacs4cl .
It provides a good middle ground between configuring Emacs manually by installing SLIME, Paredit, etc. yourself with M-x package-install commands and installing Portacle. It promotes a do-it-yourself approach to setting up Emacs for Common Lisp programming quickly while understanding each step of the set up process and each line of ~/.emacs well.
Yes - Portacle is an amazing piece of software and also the way to go for someone who just wants to check Lisp out on Mac/Win/Linux, but it also has its issues, e.g. with some systems that depend on foreign libraries. Also, if someone already has emacs set up and preconfigured, there's no point in adding another emacs instance with a distinct configuration for long-term programming.
Get the community editions of either Allegro or LispWorks and taste what the actual experience of Common Lisp development environments used to be like.
Does Clozure still exist for Mac? I don't follow MacOS anymore, but it used to have a pretty decent GUI.
(Not as good as its ancestor, Macintosh Common Lisp, which also had a GUI builder and other cool stuff, but recommending OS9 apps these days is probably pushing it)
What are the major selling points of Allegro and LispWorks over Emacs with Slime/Sly with regard to the IDE point of view? (Asking so we can skip the graph database and GUI libraries; I'm particularly interested in the developer environment.)
They have a bit more polished UI than Emacs has, which even in the GUI version is mostly a thin shell around a fundamentally character-based UI. Personally, I have stuck mostly to Slime and Emacs, as it works well and I prefer the native Emacs feel. Another advantage of the Emacs route is, that it works with most Lisp implementations, so I was able to use Slime with SBCL and Allegro, sometimes in the same Emacs session :)
That's not even an attempt at making an actual answer.
Emacs + Slime already has a REPL, compilation and/or loading of select forms or whole files, syntax highlighting, auto-indentation, completions, debugger, inspector, stepping, cross-references, and most of the other fancy things that are usually associated with IDEs. What do Allegro and LispWorks have that Emacs + Slime don't? What are their selling points? What features make them unique?
Allegro is the only Lisp with a RAD like GUI designer. Other than that, the IDE is alright but I hate how outdated it looks (they don't even have syntax highlighting and they expect me to put up with an ugly X11 app on macOS). Allegro's selling point is definitely not the IDE and I very much prefer Slime over it.
LispWorks also has an interface builder but only works on Windows I'm afraid. I wouldn't say their IDE offers much over Slime if you are a power user, but I really like their function/class browser over using all the slime-who-* commands and how easy to use their debugger is. What sets it apart is that thanks to CAPI it is trivial to build graphical user interfaces to make your own development experience a bit nicer: for example opening up a filesystem dialog instead of asking the user to retype a string, building a graphical monitor to provide insights on the performance of your Lisp image... You get the picture. It feels very Smalltalk-ish.
I am a schemer today, and my experience with them is over 10 years old. I suspect slime has covered some of the distance between the two.
The debugging, tracing and profiling facilities were a lot better than what sbcl+slime offered and there were lots of fancy things like prefilling of inline caches for CLOS.
Clojure mindset/recommendations diverge from (any) Lisp though - they prefer using primitives everywhere instead of creating proper abstractions and mini libraries/languages as in any other Lisp.
While the OP, by "Lisp", means "Common Lisp" - you're aware that following this old meme of "Clojure is not a real Lisp" only causes interpersonal fires and brings no real benefit, I hope?
It kinda is. There have been countless debates about Clojure not being a real Lisp, Scheme not being a real Lisp, Janet not being a real Lisp, Lisp not being a real Lisp, and IMO they've only created circle jerks, tons of "my Lisp has a longer cons cell than yours"-style arguments, and overall made the landscape a worse place.
If you're interested, search for "is an acceptable Lisp" and/or "is not an acceptable Lisp" and read all the articles, their comment sections, and the Hacker News dumpster fires that ensued. Maybe they would be amusing if only they weren't happening in my language community.
Dangling parens are the loose closing parens on separate lines. I.e. this:
(defun plus (x y)
(+ x y)
)
instead of this:
(defun plus (x y)
(+ x y))
It suggests the author tires to balance parens manually/visually rather than using a proper editor mode. An understandable and common mistake of a newbie, but looks bad when you are writing a tutorial.
The lisp community has very well established formatting conventions. You pretty much never see closing parens on their own line like this except when reading code written by beginners (or some special cases like package export lists for example, where one might want to leave the list "open" for adding new symbols, similar to a trailing comma in some other languages).
> The lisp community has very well established formatting conventions. You pretty much never see closing parens on their own line like this except when reading code written by beginners
Why is that? Space efficiency? As an outsider, I find the "wrong" example more readable.
Once you use Lisp a bit, the parentheses fade away.
It's like bicycle riding. As a beginner one thinks those supports wheels at the sides of the bicycle are absolutely necessary. One is constantly struggling to keep upright. Once you can ride a bike without them, one asks if they were ever necessary. Then one never thinks consciously about keeping balance.
I must disagree. I see a lot of CAR and CDR calls in code that I see daily.
Also, it's a style error to use FIRST and REST when one operates on cons cells, because those imply a different meaning - that one operates on lists. Sure, the language doesn't care whether you use CAR or FIRST, but the programmer does - and they might know that you treat a cons cell as a pair unto its own, rather than an element of a linked list.
Feel free to substitute the Python version of getting the first and rest of a list (well, the array that Python calls a list). My comment is not about names, but semantics.
That would be another thing then where the two Lisps are very far apart, and Python is closer to one of them.
Lists are not mutable in Clojure, they are “technically mutable” in R6RS Scheme, but it requires opening up a specific module that many Scheme implementations do not even provide unless compiled with specific flags.
> Common Lisp's evaluation semantics are a language of it's own practically at this point and are very far removed form most languages.
Huh? What do you mean? The separate function namespace? Evaluation rules in CL, strictly speaking, are very simple.
* Symbols evaluate to variable values, lists evaluate to function/macro/special operator calls, and everything else evaluates to itself.
* The first element of a list is either a symbol that names a function/macro/special operator, or a lambda form that denotes an anonymous function.
* If we're calling a function, evaluate all argument forms and apply the function to them; if we're calling a macro, pass all argument forms as-is into the macroexpansion function; if we're calling a special operator, it's up to the implementation to make sense of this.
What's this "a language of its own" that you mean?
Ok; One thing that makes this not obvious is that common lisp is a huge language, and scheme is a small one. And since common lisp is multiparadigm, you can work with it in ways that are very much not not like scheme. But you can also use a subset with a very similar paradigm.
Some of it is philosophical I suppose. Fundamentally they are both lisps. Both opinionated about what that means, but they are lisps.
The fundamental objects in the language are congruent. I find them quite similar for REPL driven exploratory design, in a way that python never quite gets. Although there is a deep schism on macro hygiene, they both have deeply integrated macros. They both allow for clean functional approaches and deep recursion in practice. Both get low level enough to get decent performance from the language itself (unlike python).
I guess what I'm saying is I can write CL code that feels very scheme like in approach and also is comfortable in the language. The same is not close to true of python.
> They both allow for clean functional approaches and deep recursion in practice.
Please tell me what kind of functional approaches Common Lisp and Scheme allow that Python doesn't.
Scheme is the only one o the three that has t.c.e. as a language feature, of course.
> Both get low level enough to get decent performance from the language itself (unlike python).
Scheme is far, far more performant than C.L. and that's due to language design choices.
> I guess what I'm saying is I can write CL code that feels very scheme like in approach and also is comfortable in the language. The same is not close to true of python.
I think you might simply not know how to or believe that it feels more Scheme like simply because it's written in a similar syntax.
Even JavaScript started as a Scheme dialect that later was given alternative syntax, mind you.
There is however one big thing: and that is that Python lacks true block scope, which both Scheme and Common Lisp have, but on the flip-side Common Lisp has dynamic variables, and different cells for functions and values. as well as `setf`.
> Scheme is the only one o the three that has t.c.e. as a language feature, of course.
Though Common Lisp implementations have been providing it for decades. 't.c.e.' is an optimization feature of various Common Lisp compilers.
> Scheme is far, far more performant than C.L. and that's due to language design choices.
That's not the case.
Actually Common Lisp has a lot of language features which make it performant: stack allocation hints, type hints, inline declarations, compilation semantics, implementation specific feature limits, etc. One of the design goals of Common Lisp was to support optimizing compilers on various platforms.
I've mostly been staying out of this thread because I really don't know what the point of this discussion is, but:
> Scheme is far, far more performant than C.L. and that's due to language design choices.
That's nonsensical. You're comparing language specs for performance, and not implementations here. Both can achieve high levels of efficiency from their code, depending on the implementation decisions taken by the particular compiler/interpreter you're electing to use, as well as which data structures and mechanisms you elect to use from each language.
> Scheme is far, far more performant than C.L. and that's due to language design choices.
Even if that claim is empirically pretty dubious it's idiosyncratic at best to compare putative design impacts of specifications (rather than implementations) between CL and scheme ... when python is in your mix.
I suspect this isn't going anywhere useful so I'm out.
Every now and then I see posts like this and yet, the Lisp languages never took off after the 2000s. I understand that there might be some value to learning Lisp, but much of the things that made Lisp attractive before are already available in Python, Java, etc. and I see no "enlightment" in learning Lisp.
This comment is going to get downvoted heavily here, but it's high time every one accepted the fact that the Lisp family is almost dead and move on.
> the Lisp languages never took off after the 2000s
> I see no "enlightment" in learning Lisp
> the Lisp family is almost dead
You're conflating popularity with value, and the two are very different.
Moreover, you're missing the fact that most of the features that were invented in Lisps (like GC, lambdas, first-class functions, and REPLs) are now wildly popular, with every modern language having taken several ideas from Lisp.
Furthermore, you don't seem to understand that a language is not the sum of its parts. Python, Java, C++, and the rest of the languages that have been grafting on Lisp features do not have the unifying design philosophy that Lisp does, which is precisely the "enlightenment" that you don't think exists.
Finally, by the nature of "enlightenment", you can't see or understand it until it hits you. As someone who is stubbornly refusing to learn Lisp, you by definition cannot judge whether or not you might have a galaxy-brain moment if you attempt to learn it. (it's perfectly possible that you'll learn it and have no moments of revelation, but you can't even tell whether or not that will be the case until you try)
The alternatives that you mention are still highly subpar when it comes to e.g. the incremental and interactive programming style that is highly common with Lisp. Java fails at it miserably by pretending to be a dynamic language, and I have not seen* Python used in a way in which one usually programs with Lisp - so, keeping the process alive all the time and sending commands to interact with it, like one does with Slime/Sly.
This has some obvious negative consequences, such as high feedback loop time - in Lisp, the compilation delay is usually imperceptible, especially when compared to running javac or python.
The "it's high time every one accepted X" is a meaningless comment because it presents an opinion as if it were a fact. Therefore, please accept my downvote.
*if such toolkits exist, please point me towards them - I've always wanted to see one in practice.
It's easy to get to a shallow similarity with Python. I use elpy for Python development in emacs.
My development style is highly iterative and I tend toward functional paradigms. I build up a Python program by evaluating lots of small pieces, slowly building those into the structure of my program. I don't write code into a saved file without first evaluating it in a linked REPL session.
Python does not support the same style of connecting to a live process, like Lisp does. Nor does it have the same facilities of redefining components in a running system.
The surface level actions look similar between my Lisp development and my Python development.
> I have not seen* Python used in a way in which one usually programs with Lisp
not sure what you have in mind, but i use 'elpy' regularly within emacs, and typically test/load functions incrementally into a python repl buffer, or interact with the repl directly
Please take a look at Lisp macros. I finally got it at some point. It is a way of generating code on the fly. After I understood under what circumstances macros can abbreviate code, every other language will look unnecessarily verbose.
This is enabled by the fact that code in Lisp is also written in the form of lists. Code is data, data becomes code if you write a macro to process the data.
For example, is the following data or code?
(book
(author "Jonathan swift")
(title "A Modest Proposal"))
It definitely looks like data. But it can be made into code using an appropriate macro.
What probably Lisp trails in is type inference and bleeding edge libraries.
> It definitely looks like data. But it can be made into code using an appropriate macro.
to chime in, it also can be made into 2 systems - one which defines 'book' as an in-memory object which can be inspected, and one which, say, defines a remote database object - your 'language spec' is the syntax, and you can implement multiple implementations, or replace subsystems as you build up the bigger thing - e.g. 'now my hashtables are persisted to disk', etc
SBCL type inference is actually getting better and better over time, giving you pretty effective gradual typing. Additionally, a Common Lisp implementation called SICL is in the works, with an advanced compiler and type inference engine.
Your comment is a sign that you should write more lisp, not less. After you've written enough lisp, you may go back to other languages but then you'll really know why you use those.
There are essentially 2 possibilities:
- you need huge or specialized libs not available elsewhere: Python, Java, etc.
- you need extreme speed, binary size or memory control: C, Rust, etc.
For what's it's worth, people have been saying this since the late 80s, and probably earlier. The fundamentals of the argument haven't really changed much although as you note some individual lisp features & approaches have been bolted onto mainstream languages with varying success. For the things that lisps are really good at, these languages still aren't.
It is hard to be dead, when its soul lives on Java, Julia, Python, WebAssembly....
The enlightenment comes from the Zen master understanding why those languages are halfway through Lisp, and grow oneself how to improve them to reach parity with the master copy of the universal God language.
I have felt the "sense of enlightenment" referenced in two languages: Common Lisp and Elixir. Not two distinct senses, but the same sense, twice. I've also coded productively in Scheme and Clojure without feeling the same sense.
Watch someone like Notch code in Java; it's possible to achieve it without whatever language feature people think is essential. However, if it's easier to achieve in Lisp, then Lisp will always have value. The enlightenment isn't essential for application development, but it points the gun away from your foot surprisingly often.
> much of the things that made Lisp attractive before are already available in Python, Java, etc. and I see no "enlightment" in learning Lisp.
I have not found englightenment either, but I could not find another production-grade language that can model anything like a tree (eg. abstract syntax trees) and let its user extend the language itself without the language authors.
The author misses the third, most classical, and constantly useful option: doing it all yourself. Despite the scary name, there's not all that much to do, and this approach is the most widely supported in the community. The checklist is:
* SBCL/CCL (from your package manager or from official binaries),
* Quicklisp (by downloading it from https://quicklisp.org/),
* Emacs (in any preferred way),
* Slime/Sly (manually, or via `(ql:quickload quicklisp-slime-helper)`, or via using an Emacs distribution, such as Spacemacs with its common-lisp layer, which already contains preconfigured slime/sly).
There, you're good to go.
Using some sort of toolkit which enables interactive and incremental programming (such as Swank/Slynk on the Lisp side and any Slime/Sly client on the editor side) is an ABSOLUTE MUST while doing Lisp. If you're allergic to Emacs and therefore can't use Slime/Sly, use:
* slimv/vlime for vim,
* Alive for VSCode,
* Slyblime for Sublime,
* atom-slime for Atom.