Land of Lisp (2010)
landoflisp.com
landoflisp.com
If however you want a more traditional and "from zero" introduction to Lisp, then "Common LISP - A Gentle Introduction to Symbolic Computation"[0] may be better. If you already know a little bit of Lisp and want to step up your abilities then "Practical Common Lisp"[1] is probably what you are after.
I personally think Lisp in Small Pieces is really underappreciated.
In HN tradition where we all recommend every book we've ever read similar to the submitted one (and Land of Lisp is worth reading), an overlooked recently published booklet I found is Common Lisp in the Wild: https://www.darkchestnut.com/book-common-lisp-application-de... Common Lisp is so flexible in letting you develop the way you want to develop, but if you're a professional programmer looking for a Maven-esque template of "structure your project in this familiar way without sacrificing any of the interactive Lisp dev experience, enumerate version-pinned dependencies, one-step make to build, test, run, deploy the final artifact" like I was that book's suggestions are worth the entry fee and you're left with a stable foundation to deviate from.
Yes, there exists a certain a really awful book from the 1980's about making your own Lisp in C, which has recently been reprinted in essentially its original form.
Reddit discussion: https://www.reddit.com/r/lisp/comments/6qc61v/second_edition...
Not to be confused with other books from the 1980s about doing Lisp in C, like Lisp: A Portable Implementation by S. Hekmatpour.
From a best practices point of view, it is pretty awful.
The Art of the Metaobject Protocol is truely a delightful book. While it is probably not very useful for practical programming - it isn't meant as a teaching book for beginners, it certainly is enlighting how to bootstrap an object oriented system on a common lisp without any object facilities. So if you can get hold of one, grab it!
Personally, I am not a fan of the Keene book. I know, many people here disagree with my view, but I neither like its writing style nor the programming style it presents. I would strongly recommend Practical Common Lisp instead.
There is a lot of programming style to be learned from the Art of the Metaobject Protocol.
there are not many really bad ones, but there are some and I'm not going to mention them. ;-)
1. Kaufman, Roger. A FORTRAN Coloring Book (probably the first funny programming book -- from 1978).
2. Lipovača, Miran. Learn You A Haskell for Great Good.
3. Hebert, Fred. Learn You Some Erlang for Great Good (inspired by the Haskell book).
4. Felleisen, Matthias. Realm of Racket (basically Land of Lisp for Racket. Oddly, nobody's done a "Commonwealth of Clojure" or "Society of Scheme" yet.)
Higginbotham, Daniel. Clojure for the Brave and True.
They're certainly not as colourful as brave but found the pace and coverage good
They are now freely downloadable: http://www.exemark.com/FORTH/StartingFORTHfromForthWebsitev9... http://thinking-forth.sourceforge.net/
Also, I know this is silly but I remember the book followed this guy who was supposed to be "the hero" that was always sad or concerned, or frowning, in every picture, right on to the end of the book (or so I remember it...). I know it is silly but that put me down :-p
The Haskell IRC community is a great resource as well, and probably one of the friendliest around. (#haskell on freenode)
I didn't checked recently, but I found bizarre (maybe not the right word) how the author one day decided to disappear and nuke his Internet presence.
Thanks for writing one of the most enjoyable programming books out there.
(trim-string (get-string '(some data)))
(-> '(some data)
get-string
trim-string
https://clojure.org/guides/threading_macros sin(cos(10.4));
or v = 10.4;
c = cos(v);
s = sin(c);
in Lisp one might write: (let* ((v 10.4)
(c (cos v)))
(sin c))
really old style: (prog (v c s)
(setq v 10.4)
(setq c (cos v))
(setq s (sin c))
s) (sin (cos 10.4))A(b(c)) are 2 function calls.
Hence
(A (b c))
is the fair abd equal expression. And you inside out whilst valid and in fact easier to read (as more normal) would need precedence rule in other scenario.
But those examples just not right.
SomeData.ToString().Trim()
I would like to write idiomatic Lisp code and it's getting easier to read the nested expressions but it breaks the flow to leave the expression and wrap it. Another user mentioned using a command with Emacs to escape the expression and auto wrap it. That might be what I'm looking for. (chain somedata (tostring) (trim))
It's a macro away in Lisp. But I would not use it much, since it kind of defeats the advantage of using nested expressions -> they are actually nested. This is the TXR Lisp interactive listener of TXR 215.
Quit with :quit or Ctrl-D on empty line. Ctrl-X ? for
cheatsheet.
1> [chain tostring trim-str]
#<intrinsic fun: 0 param + variadic>
2> [*1 3.4]
"3.4"
3> [[chain tostring trim-str] 3.4]
"3.4"
No ready example of a datatype that requires trimming after a string conversion! We'd have to write one: 4> (defstruct foo nil
(:method print (me stream pretty-p)
(put-string "foo " stream)))
#<struct-type foo>
5> (tostring (new foo))
"foo "
Okay we are in business: 6> [[chain tostring trim-str] (new foo)]
"foo"
Method chaining syntax is possible, but with actual methods only. Most library functions aren't methods; you have to roll your own: 1> (defstruct accum nil
(val 0)
(:method inc (me : (delta 1))
(inc me.val delta)
me)
(:method mul (me : (factor 2))
(upd me.val (* factor))
me))
#<struct-type accum>
2> (new accum).(inc).(inc).(mul 3)
#S(accum val 6)
3> (new accum).(inc).(inc).(mul 3).val
6
Support for idiom isn't the result of a conscious design decision; it just arises naturally when you have this sort of postfix syntax.TXR's dot syntax is a very straightforward sugar for Lisp structure. Basically x.y.z == (qref x y z). Whitespace is not allowed around the dot. Numbers are also not allowed: 3.4 is a floating-point constant and a.3 or 3.a are invalid. If the leading element is missing, then it's the uref (unbound ref) operator: .y.z == (uref y z). This compiles to a function resembling (lambda (obj) obj.y.z).
'(some data|)
Where | is my cursor.
And then I have a keybinding that moves my cursor to the front and wraps around like so:
(| '(some data))
So I can type the next thing:
(get-string| '(some data))
Press it again:
(| (get-string '(some-data)))
And so on.
That way, even though the code is visually nested, I can write it in logical order from what eval first to what eval last. A good editor for editing lisp code makes that possible, as I showed, and many other operations.
Basically, get yourself accustomed to a good Lisp editor such as Emacs and I'm sure you'll find that problem will disappear. For me, it's even more productive now typing wise, because I can make more structural edits to my code, which is way faster.
I've been searching for this and see there are commands for navigating s expressions but I haven't found this example. Is this a built-in command? Is there name for this action?
There isn't, as far as I know, a default keybinding for what GP did - navigate up the SEXP, wrap in parens and place point before the inner SEXP. You can get very close to it with two steps: paredit-backward-up [C-M-u] and paredit-wrap-round [M-(], though it gets confused by the hanging quote a bit. To demonstrate on GP's example:
'(some data|)
'|(some data) ; after C-M-u
'(|(some data)) ; after M-(
So the quote is in a wrong place. You could probably whip a command doing OP's thing that calls paredit-backward-up and paredit-wrap-round, with a conditional that backs up a few chars if it detects a piece of syntactic sugar attached to the SEXP (quote, quasiquote, comma, reader macro invocation). Somebody has likely already done it, or maybe there is a less known Paredit command for that - I don't know. If anyone does, please chime in.Myself, I mostly use wrapping, barfing and slurping.
--
[0] - Available in Emacs' package manager on MELPA, or here: https://github.com/emacsmirror/paredit.
[1] - http://danmidwood.com/content/2014/11/21/animated-paredit.ht...
function NestExpression()
" Get end paren pos
" Returns [0, 0] if not in parens.
let save_cursor = getpos('.')
" If line not set to zero, append
let end_paren_pos = searchpairpos('(', '', ')')
if end_paren_pos[0] > 0
execute "normal! a)"
else
" We're not in a set of parentheses
return
endif
" Return to the inside of the parentheses
call setpos('.', save_cursor)
" If line not set to zero, start insert
" mode, prepend and move cursor left
let end_paren_pos = searchpairpos('(', '', ')', 'b')
if end_paren_pos[0] > 0
call feedkeys("i( \<LEFT>")
endif
endfunction
nmap fj :call NestExpression()<cr>Enjoyed your book, currently teaching my nephew some lisp with it!
Would be interested in reading anything you write :)
extended the games a lot and even ported them later on to other languages.
thanks a lot :)
Some of the tutorials in the book use some fairy awkward conventions (e.g. using lists of symbols to create strings).
I enjoyed the book, but had to unlearn some things afterwards.
The whole Common Lisp learning is hindered by suddenly you have a function that do magic. And nil does not help.
Really wish there is a lisp book learning using the kernel (lisp 1.5 which can be easily implemented using itself).
CL-USER> (if (not-known-by-p 'you)
(author-p 'your-parent-commenter 'Loving-Lisp)
)
T
;) sorry, just approximate syntaxWe have quite a few of these books laying around, along with Practical Common Lisp.
After this book, I picked up "Practical Common Lisp" (going through that one at the moment).
So far, I found LoL to suit me less than a more traditional book like PCL, but it did help me actually get a sense of LISP.
Also, the song is catchy.. Simple but refined guaranteed to blow your mind... the land of lisp ;-)