I hear that the book <let over lambda> is a good book. Has any one
already read it? Please give some comment on it. I want some
suggestion before buying it.
Best Regards,
It is an excellent book for the advanced Lisper. There are preview
chapters on the website so you can decide whether you like the style.
HTH,
Tamas
The idea of this book is to explore CL macro programming beyond Paul
Graham's
_On Lisp_. So if you haven't read _On Lisp_, it probably makes no sense to
read
this one -- it heavily relies on _On Lisp_, and a lot of stuff goes
completely unexplained,
so you'd better be prepared before starting reading.
_Let over Lambda_ indeed tries to explore some more advanced macros and
techniques.
Some of them are indeed interesting and new.
Other ones are bullshit. That is, probably they are new, but far from
practical.
Another problem of the book is authors writing style and tone:
* He just loves inventing new "concepts" and terms for them.
Sometimes he uses unorthodox terminology -- "let over lambda"
is actually a closure.
* He frequently notes that Common Lisp is far superior to any other
programming language, that only most smart programmers use
Common Lisp, and that most smart programmers use only Common Lisp.
* Often you find trivialities explained in a great details -- e.g. first
chapter explains
Lisp programming basics like scope, extent, closures etc.
* And then really complex things (like how goddamn macro works) are not
explained
at all
* Another problem is that explanations might refer to really obscure
things. For example,
there are pieces of C code in the explanation about environments and
extent. So,
presumably you should know C very well to understand this.
* There are also pieces of disassembly -- essentially, x86 assember
language --
which are supposed to show how efficient things are and how it works
under the hood.
It was fine to me, because I know x86 assembly, I've seen disassemblies
before and
I like knowing how things work under the hood (actually author have
picked some good
examples, to be fair), but I imagine people who are not familiar with x86
assembly
will find this plainly weird, as book has absolutely no explanations
about what this all
means.
* Author often mentions that style is not important, while I think there is
consensus among
programmers that it is important, as it affects readability and
maintainability, and those
qualities are crucial when more than one person works on code.
* Author often goes against widespread CL practices. For example, he does
not use
asterisks to mark dynamic variables (as in *readtable*), and this is
known to be error-prone.
He does not use CLOS, but instead he makes a poor man's object system
with closures
and macros.
These advices might be plainly dangerous.
So, this book is weird. If you know Common Lisp pretty well, have read On
Lisp, know
C and x86 assembly, and are immune to arrogant tone and can ignore bad
advices, you
might find this book entertaining. Otherwise, I don't think so.
> YX> I hear that the book <let over lambda> is a good book. Has any one
> YX> already read it?
> YX> Please give some comment on it. I want some suggestion before
> buying YX> it.
>
> * There are also pieces of disassembly -- essentially, x86 assember
> language -- which are supposed to show how efficient things are and
> how it works under the hood. It was fine to me, because I know x86
> assembly, I've seen disassemblies before and I like knowing how
> things work under the hood (actually author have picked some good
> examples, to be fair), but I imagine people who are not familiar
> with x86 assembly will find this plainly weird, as book has
> absolutely no explanations about what this all means.
BTW, what would be the best way to learn how to understand the output
of disassemble? I picked up a few things from eyeballing the
disassembly of simple functions in SBCL (especially after looking at
efficiency hints), but my understanding is far from complete. I
wonder if there is a systematic way to learn this stuff.
Thanks,
Tamas
I think its a very good book. It isn't a beginners CL intro - more an
intermediate level book on macros. As such, it is probably one of the
better books I've read covering the use and definition of macros.
I find the author's writing style clear and concise, with just enough
background detail to make it easy to understand the topic. He has some
strong opinions which many lispers may not agree with, but does provide
background and rationale for these opinions, so if you don't agree at
least you can understand where he is coming from.
Perhaps my only criticism would be that the emphasis on macros may
encourage their over use. However, this is probably just my own bias. I
personally think macros are a powerful and very useful tool, but have
noticed that they are often over used by beginners. This is probably
just a result of new lispers discovering such a powerful tool for the
first time and getting a little carried away.
The first 3 or 4 chapters are a pretty good read and provide a good
basis for the latter chapters and good background. The content is not
too difficult. The latter chapters have got more 'meat' to them and take
a bit more to digest. Ther overall flow is good.
I found I also got a lot more out of other books, such as PG's On Lisp
after reading this one. I would recommend this book for anyone who has
read the basic introductory books and has done a bit of actual CL
coding. Its definitely the sort of book where you need a little hands on
experience to really appreciate the content.
Tim
--
tcross (at) rapttech dot com dot au
After having recently read the chapters that are online, I would say
you are being far, far too kind. I would keep as far away from that
book as possible.
Step one would be to learn assembly language, there must be good books
around on that still. I learned over 20 years ago on an Apple II; the
skills are transferrable.
Step two, learn how CL is implemented, and in particular how your
implementations data structures (start with conses and work up) are
implemented. That way, you'll be able to recognise the indirect
addressing loads that are effectively just car or cdr. Lexically
scoped bindings are often just indirect indexed stack relative
addressing (and you can't see at the assembly level how a lexical
symbol is mapped to a given offset until you understand *how* your
implementation is making this mapping). Then you'll need to understand
subroutine calls for when the compiler had to invoke a complex call
instead of inlining code.
Step three, figure out why the optimiser made a meal of your code
segment, and contribute an improvement to your favourite lisp
implementations compiler so that particular code sequence is optimised
for all future programmers :-)
Matt
I enjoyed it. You need to keep in mind though that this is essentially
an advocacy book. Doug goes to great lengths to show just *how*
powerful macros can be (perhaps to the extreme), and why they can be
used to solve problems in much more elegant ways than other
programming languages.
My favourite part of the book was a treatise on CL-PPCRE, which goes
into details about how exactly it transforms a regex into lisp code
and compiles it, and why that is an example of how CL can be *much*
faster than other languages. A lot of trouble is gone to to dispel the
'performance myth' about CL, and I think he did that pretty well.
Unfortunately the 'opinion' chapters at the end of the book left a
nasty taste in my mouth, and not just because I disagreed with just
about everything he said... I just don't think that stuff has a place
in an otherwise well written book.
Overall, I'd say the effort Doug went to to publish this work should
be applauded, and supported, so I did.
Matt
The acronym LOL is perfect for the book. That's what I was doing when I
wasn't cringing.
--
Rahul Jain
rj...@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
quote
The real solution to variable capture is known as the generated symbol,
or gensym for short. A gensym is a way of having lisp pick the name of a
variable for us. But instead of picking lame names like obscure-name as
we did previously, lisp picks good names. Really good names. These names
are so good and unique that there is no way anyone (even gensym itself)
will ever pick the same names again. How is this possible? In COMMON
LISP, symbols (names) are associated with packages. A package is a
collection of symbols from which you can get pointers to by providing
strings, their symbol-name strings. The most important property of these
pointers (usually just called symbols) is that they will be eq to all
other pointers (symbols) that have been looked up in that package with
that same symbol-name. A gensym is a symbol that doesn't exist in any
package, so there is no possible symbol-name that will return a symbol
eq to it. Gensyms are for when you want to indicate to lisp that some
symbol should be eq to some other symbol in an expression without having
to name anything at all. Because you aren't naming anything, name
collisions just can't happen.
end quote
I think has too many wrong/misleading statements based on my
understanding of CL. I do not know if he is sloppy or trying to keep
things simple.
Made me cringe too, but i bought it anyway. Learned about #= and
print-circle relation.
-Antony
On 2010-01-06 17:24:58 +0100, Antony said:
quote
The real solution to variable capture is known as the generated symbol, or gensym for short. A gensym is a way of having lisp pick the name of a variable for us. But instead of picking lame names like obscure-name as we did previously, lisp picks good names. Really good names. These names are so good and unique that there is no way anyone (even gensym itself) will ever pick the same names again. How is this possible? In COMMON LISP, symbols (names) are associated with packages. A package is a collection of symbols from which you can get pointers to by providing strings, their symbol-name strings. The most important property of these pointers (usually just called symbols) is that they will be eq to all other pointers (symbols) that have been looked up in that package with that same symbol-name. A gensym is a symbol that doesn't exist in any package, so there is no possible symbol-name that will return a symbol eq to it. Gensyms are for when you want to indicate to lisp that some symbol should be eq to some other symbol in an expression without having to name anything at all. Because you aren't naming anything, name collisions just can't happen.
end quote
I think has too many wrong/misleading statements based on my understanding of CL. I do not know if he is sloppy or trying to keep things simple.
Made me cringe too, but i bought it anyway. Learned about #= and print-circle relation.
Well... he is actually right a gensymed symbol can never collide, because its fresh and not interned. First I thought he will bark up the wrong tree, but if you read it completely and carefully you can see the point. The problem lies in his description of gensym generating "names" - which perhaps makes lispers get it wrong first. It makes sense if one later sees him defining (his concept of) names as synonym to symbols.
ciao,
Jochen
--
Jochen Schmidt
CRISPYLOGICS
Uhlandstr. 9, 90408 Nuremberg
mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com
<<quote snipped>>
> I think has too many wrong/misleading statements based on my
> understanding of CL. I do not know if he is sloppy or trying to keep
> things simple.
> Made me cringe too, but i bought it anyway. Learned about #= and
> print-circle relation.
This quote is out of context. One of the principles of Doug's macro
writing is that free variable capture is a *feature* of CL macros,
that gensyms are there for when you want to explicitly avoid this, and
that the duality of syntax can be exploited in interesting and
powerful ways.
He takes this so seriously that he doesn't earmuff his special
variables ...
Matt
How is earmuffing connect to this?
(defvar counter)
....
(funcall (let ((counter 0))
(lambda () (incf counter))))
A closure is silently broken because some moron have defined `counter`
variable
without earmuffs. No gensyms can fix this, the only fix is having separate
namespaces
between dynamic and lexical variables via earmuffs. This is not related to
gensyms
at all.
Well, unless you're going to have all lexical variables to be named via
gensyms.
I think this quote didn't have any wrong statements.
One sloppy thing there is that it is not a feature of gensyms, it is
a feature of fresh, uninterned symbols. It works that way for gensyms too
because they are fresh, uninterned symbols.
Another thing is how he uses "name". Reader not too familiar with Common
Lisp
will think that name is a string of symbols, as in symbol-name. But author
here is trying to explain that for Common Lisp name is not a string, but
symbol. Despite this explanation it is pretty confusing.
It would be much better to explain first that Common Lisp uses symbols
to tell whether it is same variable or not, rather than names. And then
explain
how packages work and how fresh symbols are different without using a
confusing
word "name".
A> Made me cringe too, but i bought it anyway. Learned about #= and
A> print-circle relation.
I'm sure there is a cheaper way to learn about #= and print-circle relation
:)
IMNSHO I think it did have wrong statements, that were then overridden
by correct ones. That's both confusing and leads to people quoting the
incorrect bits out of context later.
The wrong statements I saw:
- "[gensym] picks good names. Really good names. These names are so
good and unique that there is no way anyone (even gensym itself) will
ever pick the same names again."
Which is NOT why GENSYM works. In fact, GENSYM could pick FOO over and
over and work just fine, as long as each FOO was new and not interned.
- "Gensyms are for when you want to indicate to lisp that some symbol
should be eq to some other symbol in an expression without having to
name anything at all."
I have no idea what the above means, but a symbol can't be eq to some
*other* symbol, only itself.
- "Because you aren't naming anything, name collisions just can't
happen."
Nor do I understand what "you aren't naming anything" means though I
gather the author wants that to mean "you aren't interning anything."
> Captain Obvious wrote:
> > A> I think has too many wrong/misleading statements based on my
> > A> understanding of CL. I do not know if he is sloppy or trying to keep
> > A> things simple.
> > I think this quote didn't have any wrong statements.
> IMNSHO I think it did have wrong statements, that were then overridden
> by correct ones. That's both confusing and leads to people quoting the
> incorrect bits out of context later.
> The wrong statements I saw:
> - "[gensym] picks good names. Really good names. These names are so
> good and unique that there is no way anyone (even gensym itself) will
> ever pick the same names again."
> Which is NOT why GENSYM works. In fact, GENSYM could pick FOO over and
> over and work just fine, as long as each FOO was new and not interned.
The problem seems more ambiguity in what Hoyte means by "name" (he
seems to mean the symbol itself is a name, and isn't talking about the
string that is the symbol's name) than any straightforward wrongness.
Not that this is a defense of the passage; in technical writing, being
ambiguous isn't any better than being clearly wrong.
My sense, from the sections on the website and the discussion in this
thread was that /LOL/ really needs the thorough technical review and
editing, which it likely never got due to being self-published.
Cheers,
Pillsy
CR> The wrong statements I saw:
CR> - "[gensym] picks good names. Really good names. These names are so
CR> good and unique that there is no way anyone (even gensym itself) will
CR> ever pick the same names again."
"Name" is not a well-defined term, I think, so you can't claim that this is
wrong.
If a variable name in CL is actually a symbol, this actually makes sense --
gensym
generates symbols which are good and unique indeed.
CR> Which is NOT why GENSYM works. In fact, GENSYM could pick FOO over and
CR> over and work just fine, as long as each FOO was new and not interned.
You're assuming that name = symbol-name. In a broader sense name is just
something
which allows you to refer to an object, and symbol itself can be thought as
a name.
The rest is confusing as hell, indeed.
I'm afraid that won't help -- book needs major restructuring to fulfil
its promise.
I suspect that is a very fair criticism. Having read the book, some good
technical reviews and revisions would certainly improve it - but thats
probably true of all texts of this type.
There are certainly bits in the book I disagree with and there were some
parts of the book which could probably be made clearer, but I also think
its important to put all of these criticisms into context. The author
quite clearly states that the book is not an introduction to CL - in
fact, he clearly states that it is about the practicle application of
macros and even states that it follows on from the work done by PG in
"On Lisp", showing how to use the different types of macros introduced
in On Lisp. As such, I think it does a pretty good job. He also
explicitly states that it is not a book about the theory of macros.
Criticisms over not clearly defining the difference between a symbol and
a symbols name or failing to accurately and precisely explain how
gensyms work are possibly a bit harsh when you consider the books
target. The author explicitly states that the lisp programmer is
expected to be at an intermediate level or better. CL programmers at
this level should already be pretty familiar with symbols,
interned/uninterned and symbol names etc.
To some extent, I liked the book because it didn't get bogged down in
the heavier technical details when not necessary for the message the
author was trying to get across. Yes, the author did use simplified
explinations in a number of places, but that simplified explination was
as precise as it needed to be to get the concept across and allow the
reader to focus on what the main point was.
What I liked most about the book was that it gave more context to much
of the material in On Lisp. When I first read On Lisp, there was a fair
amount which I thought was interesting, but it wasn't obvious to me how
or where it could be useful. Let Over Lambda helped make this more
obvious, whihc further helped me to understand some of what PG wrote.
Of course, some of you may find this odd because PG's On Lisp was
perfectly clear to you and you can't understand how everyone doesn't
just get it if they put in the effort. All I can say is that we are all
different. some people can read ON Lisp and obtain nearly 100%
comprehension on the first reading. Others, like me, often need to read
many sources before they get that high level of comprehension.
Sometimes, its down to ability and sometimes its just down to finding an
author who suits the individuals way of thinking.
For me, Let Over Lambda was a worthwhile read. After working through it,
I was able to return to On Lisp and much that I missed or simply didn't
get previously became much clearer.
I should also mention that I possibly have a bit of bias and only have a
restricted set of materials to work from. As a blind programmer, I rely
heavily on books available in electronic form. In the CL world, there
are some good introductory texts abailable electronically, but there is
very little available that deals with slightly more advanced topics.
There is next to nothing available dealing with more advanced
application. For example, I would love to get hold of electronic
versions of PAIP or AIAMA because I've seen so many positive reviews of
PNs books. Likewise, I'd like to get access to Kleen and others that
deal with CLOS and MOP etc. When SCIP became available electronically,
it nearly destroyed my marriage because it was all I could do and think
about for two weeks! So, this possibly explains some of why I liked Let
Over Lambda. I also don't recall anything in that book that was
completely wrong - at worst, maybe a bit ambiguous and I didn't always
agree with what the author wrote, such as not using 'ear muffs' for
globals or his comments on emacs/Slime etc, but these are all pretty
minor and its healthy to have some disagreement as it helps you keep a
critical mindset, which is always improtant when reading technical
material.