If you do Common Lisp, keep in mind that Guy Steele's _Common Lisp: the Language_¹ is much more than a specification (while not a textbook).
_________
¹ CLtL; the full text is available on the Internet.
@vnikolov @spook
I would recommend looking into Scheme, which is a revised, modern Lisp invented in the 70s.
While imperative style is prominent in Lisp, it is commonly frowned upon in Scheme, which still allows imperative style but encourages functional programming.
The canonical book is SICP, https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/index.html
The imperative style was very much frowned upon in all Lisps until Common #Lisp introduced SETF, which sold the pass. We had RPLACA and RPLACD in much the same way as #Prolog has the cut operator: ugly hacks, shameful to use, to get around the inadequacies of our machines.
I still think it's best to think of Common Lisp as not Lisp at all but more Fortran-with-brackets.
Modern Lisps like #Clojure use immutable data, which makes imperative style impossible.
@simon_brooke @vnikolov @spook
Ah, that makes so much sense; I've always wondered.
So that's why so much "Lisp" code looks so terrible...How sad!
Thanks for educating me.
@janneke @vnikolov @spook Well, you know, my view is controversial. And back in the 1980s when we were really fighting wars about the future of #Lisp (yes, the barbarians won, hence Common Lisp), we used to say 'some people can write FORTRAN in any language' -- which is actually more or less true. I have seen some dreadful code in #Scheme in my day, and some very elegant code in Common Lisp.
The modern Lisps -- #Clojure, #Jank etc. -- are worth looking at. They really do encourage good style.
Real Programmers™ can write bad programs in any language.
And they do.
Ha ha only serious...
P.S.
Someone said that Algol was a big improvement to many languages that came after it.
To some extent this is true about Fortran as well.
(The proverbial devil in the proverbial details, of course.)
@simon_brooke Back in the 1990's I programmed Perl professionally and it was truly amazing to see the reactions of other Perl programmers to functional Perl. Mostly negative but occasionally like a bolt of enlightenment.
I suppose it shouldn't be that surprising that it has good syntactic support for call-with style functions, as Perl has everything in there somewhere
«Refer to things by value, don't try to mutate references, use closures, and things are easier.»
Indeed.
Without prejudice, as bureaucrats say, this (broadly) matches my experience with other languages, otherwise quite different.
(Like Java and Python.)
On the lesser topic.
There are at least two notable things about `setf'
(the first one smaller, the second one bigger).
I. It eliminates the need for explicit setters.
If you know how to write a form to get something, you automatically know how to write a form to set it.
II. Modify macros become available.
To illustrate with `incf':
(let ((h (make-hash-table)))
(incf (gethash 'foo h 0))
(gethash 'foo h))
works and evaluates to 1.
(Does not fail trying to increment a non-existent element.)
This is noticeably different from the typical operation of `+='.
See also `define-modify-macro'.
I'll leave the greater topic, mutability and immutability, for another day.
_________
Disclosure
I am a descendant of barbarians, who settled in the old Roman province of Thracia.
Civis serdicensis sum.
🙂
@simon_brooke "The imperative style was very much frowned upon"
It really was not. It was the normal way of writing code. Bunch of TAGBODY, GOTO and other things. SETF pre-dates Common Lisp by many years.
Here is some old fun EH code: https://tumbleweed.nu/r/attic/sys46/file?ci=tip&name=lispm2/eh.316&ln=120-149
That uses SETF.