These years in Common Lisp: 2023-2024 in review(lisp-journey.gitlab.io) |
These years in Common Lisp: 2023-2024 in review(lisp-journey.gitlab.io) |
Another thing all modern Lisps have since the 1980's, is all major data structures, not only lists as many think when discussing Lisp.
Having to use accessor functions or destructuring macros instead of just a period or -> is often annoying too. The lack of syntax has cons as well as pros.
Coalton progress is discussed briefly in the OP: https://lisp-journey.gitlab.io/blog/these-years-in-common-li...
Radiance[0] is a more traditional web-framework, with interfaces for backend-storage, web-servers, templating, authentication &c.
Hunchentoot gives you basic route definitions out-of-the-box (bring your own database), and for something more full-featured there is CLOG[1] and Reblocks[2]
0: https://shirakumo.github.io/radiance
Live image manipulation isn't quite as useful as it once was for runtime program deployment. But it's still a differentiating feature for incremental and interactive development—before you compile binaries to deploy. Tools like Jupyter notebooks don't come close for actual (especially professional) software development.
Eventually, I expect this to be a relationship similar to Java and Scala or Clojure.
FP predates Haskell by decades.
When I learnt Lisp, Lisp and Scheme were FP, Miranda was still around, and Caml Light had just started being known outside INRIA.
I really dislike revisionism regarding what it means to be FP.
https://en.m.wikipedia.org/wiki/The_Art_of_the_Metaobject_Pr...
(object -> slot)
and transforms it to (slot object)
"->" should be unused
[some-numbers 0]
...to get the first (many programming languages make this mistake, using 0 to refer to the first element of a collection, so we can forgive CL for this) element. But I'm curious how you can write... (object -> slot)
...without getting an error about OBJECT not being a valid function or macro.The 1962 dated Lisp 1.5 Programmer's Manual already describes a 0 based array feature. Lisp was clearly one of the historic instigators of zero based array, rather than just playing along.
CL-USER> (get-macro-character #\()
SB-IMPL::READ-LIST
You can write `(set-macro-character #\( 'sb-impl::read-list)` and everything continues to work just fine. You can also jump-to-source and modify it if you want -- though it's cleaner to just copy it out to your own project, that's what I did for a quick hack/proof of concept. Essentially I added before the existing (when...) which handles the special dot syntax: (when (and (eq firstchar #\-)
(eq (peek-char t stream t nil t) #\>))
(read-char stream t) ; actually read the nextchar > to discard it
(let ((next-obj (read stream)))
(sb-impl::flush-whitespace stream rt)
(return `(slot-value ,@listtail ',next-obj))))
I won't claim this is good or proper, but it shows that it's quite feasible. We've turned (foo -> bar) into (slot-value foo 'bar). CL-USER> (defclass vec2 ()
((x :initarg :x)
(y :initarg :y)))
#<STANDARD-CLASS COMMON-LISP-USER::VEC2>
CL-USER> (defparameter vec (make-instance 'vec2 :x 3 :y 4))
VEC
CL-USER> (vec -> y)
4
CL-USER> (read-from-string "(print (vec -> x))")
(PRINT (SLOT-VALUE VEC 'X))
18
Personally I wouldn't use this even if it was more properly/carefully implemented. (There's really no reason to replace the default left-paren reader, and no reason we have to have a space surrounding the "->". One thing I like about the infix reader macro package https://github.com/quil-lang/cmu-infix is that it doesn't care about spaces, I can write #I(1+1 + 4) and get 6.) I'm quite happy putting my class in its own package, and thus getting the primary tab-completion behavior I care about. e.g. "(ma:<tab>" could complete to "(math:" and then "(math:v<tab>" could complete to a list of options like "vector-x" "vector-y" or so on. I also like the somewhat unusual approach of naming my accessors with a dot prefix, e.g. (.x vec) and (.y vec), or even (math:.x vec) if I haven't imported the symbol.”The first high-level functional programming language, Lisp, was developed in the late 1950s…”
In the 80s, things like immutability just weren't pragmatic due to memory constraints, and CL was designed with pragmatism in mind. Scheme could be argued as FP. Clojure certainly is. CL is not.