<sjl_> CL code from the early 90's runs just fine on SBCL from a month ago
<sjl_> But trying to run five-year-old python/ruby/scala makes me hate life.
This echoes his earlier blog post, volatile software:http://stevelosh.com/blog/2012/04/volatile-software/
I kind of have the feeling that fighting bitrot is sjl's main motivation for CL.
I am missing something?
Which is to say, core Python may be fairly backwards compatible, but once you pip anything, well...
> In Common Lisp you can certainly choose to panic on or ignore errors, but there’s a better way to work. When an error is signaled in Common Lisp, it doesn’t unwind the stack. The Lisp process will pause execution at that point and open a window in your editor showing you the stack trace. Your warrior’s sword is hovering over the monster, waiting for you. At this point you can communicate with the running process at the REPL to see what’s going on. You can examine variables in the stack, or even run any arbitrary code you want.
This doesn't seem like something that's particularly difficult to do with c/gdb.
Well, why don't you do it, then? Not trying to be snarky(not much anyway), but I feel you are seriously under-estimating the work involved. Either that, or the description does not make it clear enough.
It's a full blown REPL. We are not talking about just printing out the code at that point, or maybe mutating a variable on the stack. We can execute arbitrary code and even replace entire sections of code with new code, and then hit continue and it works as if nothing happened, only now running the new (and hopefully corrected) code. Just the memory management implications of doing this in C would be very interesting.
Note that you can also do this over a network connection. NASA folks used this to great effect to patch Deep Space-1. Lisp machines also used this capability over the entire OS. I have also used a similar mechanism (with Chicken Scheme) to do incremental development on iOS, without having to do the whole xcode deploy/run cycle.
The closest analog I can think of today is a browser's "console", which lets you do similar things for javascript code.
Java and .NET allow for partial edit-and-continue, but they aren't as powerful as Lisp/Smalltalk.
I have caught a condition in StumpWM (a window manager written in Common Lisp) and done something useful with it. A completely different beast. Practical Common Lisp has a solid example that may be a bit enlightening (http://www.gigamonkeys.com/book/beyond-exception-handling-co...).
(setf *print-case* :downcase)
in your .sbclrc (or whatever the equivalent is for your implementation) and never have to see all-caps again.And yeah, the default upcasing is ugly and inelegant, but they were trying to support the caps-only machines & code still in use at the time. It’s one of the key things I’d change in a modern Lisp standard.
But you have to admit: when the default print-case is one of the worst things in a language, that language is doing pretty well.
[1] https://franz.com/support/documentation/10.0/doc/case.htm
https://twitter.com/stevelosh/status/1034147772440760320?s=1...
I have a similar experience. Started out learning Clojure because it was 'practical', stayed with Common Lisp because I had less tooling setup to deal with. To be fair, that was because the Emacs integration for clojure depended on a specific CVS revision of Swank and I was starting out with Emacs. The situation has greatly improved regarding Clojure tooling. Still not as good as CL.
With time I've found CL to be much more flexible than Clojure and less opinionated so you'll be able to explore different paradigms.
That said if you want to write an SPA, go with ClojureScript. It has a good dev UX story (Figwheel <3) and Webpack will have already lowered your expectations regarding build systems to so setting up a ClojureScript project will seem less of a hassle.
Common Lisp is all about choices and flexibility. Do you want pattern matching? You can get it but it's not shoved down your throat. Same for STM. Same for immutable data structures. Same for Java interop.
On the other hand, Clojure is lacking fundamental features of Common Lisp that are extremely powerful: conditions & restarts, programmable debugger, programmable reader, programmable compiler through compiler macros, dumping images & native code compilation not to mention advanced code analysis and optimization capabilities.
1. Excellent syntax and library support. It is my first Lisp, but I can't how I programmed without macros and persistent data structures.
2. I hate the stack traces. I've used both Clojure and Clojurescript (mainly cljs), and the stack traces for errors are nearly indecipherable. To be fair I am using React (not Reagent), but I don't find it too much better with other libraries.
3. I hate the build system. It is fractured and there are too many mediocre options. shadow-cljs is the best one I've used, and it works okay not great. I also hate that I can't distribute standalone binaries. I have used pkg, which distributes Node project as binaries, but the binaries are huge (something like 85MB+)
4. The core functional language is excellent, but protocols, types etc. seem much more ad-hoc and not well-designed. I'm used to object oriented (Python) and I find the lack of focus on an object-system a bit unsettling.
I have no clue if Common Lisp fixes these issues or brings new ones.
> My advice is this: as you learn Common Lisp and look for
> libraries, try to suppress the voice in the back of your
> head that says “This project was last updated six years
> ago? That’s probably abandoned and broken.” The stability
> of Common Lisp means that sometimes libraries can just be
> done, not abandoned, so don’t dismiss them out of hand.
I have found this to be true in my own experience. The perception of stagnation is, however, a common initial objection to folks working in CL for the first time.Since Common Lisp is an interactive programming language and is meant to be used interactively (think Smalltalk, not Python) it is common practice to (interactively) load a library in a Common Lisp image and explore it (interactively). One can see what symbols are exported from packages, what these symbols are used for and (interactively) retrieve their documentation. All of this takes place within the editing environment (ideally Emacs) in a rapid feedback loop (again think Smalltalk, not Python) that feels seamless and tremendously empowering.
At the end of the day, though, I prefer Lisp. I like that it's standarised; I like that so much code runs in just about every implementation; I like that — as someone noted elsethread — in Lisp it's not uncommon for libraries to be done.
I like that Lisp is much more complete than Scheme. Standarised places are great. Standardised extensible types are wonderful. I don't like that so many in the Scheme community are so very opposed to adding to the language, no matter how painful the lack (witness the abject failure of R6RS).
CLOS is amazingly good, better than any object system in any other language I've used. Scheme doesn't have a standard version.
I think that multiple namespaces is a huge feature. A lot of Schemers disagree, but I don't see a good reason for functions, macros, classes, tags &c. to share a namespace, and it makes programs more obtuse.
I don't care for Scheme's separate Boolean types, nor for the way it splits NIL, () & #f. They make code less concise, for no terribly good reason IMHO. Maybe that's a matter of taste, but I think it reflects the pragmatism of Lisp vice the idealism of Scheme.
Lisp has standardised compiler macros. Lisp's normal macros are, I believe, more powerful than Scheme's (as I understand it, one can implement Scheme macros in Lisp but not Lisp macros in Scheme).
Scheme's dynamic-wind is broken, while UNWIND-PROTECT isn't.
Scheme's continuations in general are really awesome, but make it slightly too difficult to optimise code. I think it's great to have them available in an educational language, but not so great to have them in a general-purpose industrial language meant for real programs.
Generally, when I come across some corner of the Lisp standard I don't understand, some years later I'll recognise how incredibly valuable it is to be able to have it, and how great it is that every implementation has it. I never come across any corner of the Scheme standards, because they have no corners. Whenever I write Scheme I'm not really writing Scheme — I'm really writing guile or whatever.
Scheme's a wonderful language for teaching C.S. concepts like continuations & computer science in general — it's not IMHO a good language for industrial-strength software.
Racket is a single implementation of what used to be a Scheme but has now grown to be something else entirely different. It's really cool — I just wish everyone involved had spent that time on SBCL & portable Common Lisp libraries instead. It's a free world, of course!
I think the most important plus for CL is that CL is image-based, and that every important thing is already standardized, either on the ANSI standard, or de-facto via mature libraries.
- https://github.com/CodyReichert/awesome-cl - http://quickdocs.org/
And note that CLiki does not cover all that it's out there.
Anyone has tried both Slimv and Vlime for Vim? What are the differences? Which one gives an experience closer to that of SLIME?
Vlime was made after Neovim gave Vim a kick in the ass to add async, and it takes advantage of all of it. This lets its implementation be a lot cleaner and more stable, at least from what I've experienced.
One thing I do that makes the REPL a lot nicer: I run the actual SBCL process inside a Neovim terminal split (with rlwrap). This gives me an actual REPL like you would expect, not just Vlime's "REPL" (which is essentially two separate buffers, one for input and one for output).
I like slimv a lot better myself, and prior to that I made due with a gnu screen split-window terminal with a vim plugin that would send stuff from one screen panel to the other (used that for Python, Clojure, and Node sometimes too). I tried using vlime somewhat recently, but it just felt off, hard to express everything I didn't like but maybe the experience of having to launch your REPL separately was the beginning (slimv just finds your lisp on the path). You're encouraged to compile whole files at once rather than bit by bit (perhaps sensible for Real Work), the REPL buffer is read-only which is quite bizarre to me, and the default key bindings make less sense. Feature-wise it seemed comparable since they both use Swank. The tutorial at https://kovisoft.bitbucket.io/tutorial.html which follows a classic SLIME demo vid is nicer than the vim-tutor for vlime.
The way I work around this is to run the SBCL process inside a Neovim terminal split (with rlwrap). That way I get a vanilla SBCL REPL plus the stability of Vlime.
My current road to Common Lisp is working through Peter Norvig's book Paradigms of Artificial Intelligence Programming [0]. It's not a direct route to the kind of programming most people do nowadays, but I hope to at least get a taste of what it was to be a researcher in classical AI.
You can also then add deep-learning based samplers. It's all connected.
One suggestion: checked again just now and SBCL is still not production-ready on Windows (for the understandable reason of insufficient volunteers); perhaps the recommendation for that platform should be changed to CCL?
It only has a warning for threading code that has been left there for years. But I use it on windows with no problems.
On the other hand Clozure CL is a very very good implementation with a loooooooooooooooooooooooooooooooooooooooooooooooooong history (emphasis added) being used in production stuff.
But don't limit yourself to SBCL and CCL -- take a look also at ECL, ABCL, CLASP, etc.
Going to give CCL a try.