They Called It LISP for a Reason: List Processing (2005)
gigamonkeys.com
They Called It LISP for a Reason: List Processing (2005)
1–10 of 125 posts
Re: They Called It LISP for a Reason: List Processing (2005)
#2Re: They Called It LISP for a Reason: List Processing (2005)
#3One of the best programming books (for any language) ever written IMO. Seibel has a knack for clear, readable but still technical prose that's all too rare unfortunately.
Re: They Called It LISP for a Reason: List Processing (2005)
#4One of the best programming books (for any language) ever written IMO. Seibel has a knack for clear, readable but still technical prose that's all too rare unfortunately.
I’ve been meaning to read Practical Common Lisp for some time. Would you recommend this even for complete beginners to Lisp?
I don’t recall if it has instructions on getting a dev env up and running, but if it does I imagine they’re out of date. Emacs with Sly or SLIME is what I’ve used, but I believe there are viable options for proper interactive development in vim and vs code among others.
If you just use a basic editor and paste code into a repl in a terminal you won’t be getting the experience most Lispers do.
Re: They Called It LISP for a Reason: List Processing (2005)
#5One of the best programming books (for any language) ever written IMO. Seibel has a knack for clear, readable but still technical prose that's all too rare unfortunately.
I’ve been meaning to read Practical Common Lisp for some time. Would you recommend this even for complete beginners to Lisp?
Re: They Called It LISP for a Reason: List Processing (2005)
#6One of the best programming books (for any language) ever written IMO. Seibel has a knack for clear, readable but still technical prose that's all too rare unfortunately.
I’ve been meaning to read Practical Common Lisp for some time. Would you recommend this even for complete beginners to Lisp?
The chapter on files in the Practical Common Lisp book wasn't complete enough for me to read a one line file of 800MB which is part of the Harvard Library Open Metadata archived set.
Re: They Called It LISP for a Reason: List Processing (2005)
#7This isn't just a dismissive observation. It's the heart of why Lisp is so hard to implement. When I ignored mutable cons cells, I realized I could just implement bel in Python by using actual Python lists.
t = True
nil = None
def car(l):
if l:
return l[0]
assert car(nil) == nil
assert car([]) == nil
assert car([1]) == 1
assert car([[1]]) == [1]
assert car(car([[1]])) == 1
assert car(car([(1, 2)])) == 1
def sequence(x):
return isinstance(x, (list, tuple))
def cdr(l):
if l:
if v := l[1:]:
if v[0] == ".":
if sequence(l):
if len(l) == 3 and l[1] == ".":
return l[2]
return v
assert cdr(nil) == nil
assert cdr([]) == nil
assert cdr([1]) == nil
assert cdr([1, ".", 2]) == 2
assert cdr((1, 2, 3)) == (2, 3)
assert cdr("foo") == "oo"
def join(x=nil, y=nil):
if sequence(y):
return [x, *y]
return [x, ".", y]
assert join(nil, nil) == [nil]
assert join(1, 2) == [1, ".", 2]
assert join(1, '"foo"') == [1, ".", '"foo"']
Presto, now you have car, cdr, and join (cons) in Python.This works (and works very well). You can build lists with Lisp and then pass them off to other Python libraries -- after all, they're just lists. And in the rare case where you care about mutating cons cells, you can just use a dict instead.
EDIT: See https://news.ycombinator.com/item?id=33194570 for a more thorough explanation of why mutable cons cells are problematic.
Re: They Called It LISP for a Reason: List Processing (2005)
#8Shared structure is overrated. The cases where you need a tree-like mutable structure are vanishingly small in modern times. Mostly it boils down to "just use hash tables." This isn't just a dismissive observation. It's the heart of why Lisp is so hard to implement. When I ignored mutable cons cells, I realized I could just implement bel in Python by using actual Python lists. t = True nil = None def car(l): if l: re…
Every MMU running a Unix with mmap probably disagrees!
Re: They Called It LISP for a Reason: List Processing (2005)
#9Shared structure is overrated. The cases where you need a tree-like mutable structure are vanishingly small in modern times. Mostly it boils down to "just use hash tables." This isn't just a dismissive observation. It's the heart of why Lisp is so hard to implement. When I ignored mutable cons cells, I realized I could just implement bel in Python by using actual Python lists. t = True nil = None def car(l): if l: re…
@dataclass
class Cons:
car: Any
cdr: Any
You can define a nice printer or reader for it if you want, but mutability doesn't seem to be a hindrance in implementation.Re: They Called It LISP for a Reason: List Processing (2005)
#10Shared structure is overrated. The cases where you need a tree-like mutable structure are vanishingly small in modern times. Mostly it boils down to "just use hash tables." This isn't just a dismissive observation. It's the heart of why Lisp is so hard to implement. When I ignored mutable cons cells, I realized I could just implement bel in Python by using actual Python lists. t = True nil = None def car(l): if l: re…
> Shared structure is overrated. Every MMU running a Unix with mmap probably disagrees!
There's a fascination in the Lisp world for cons cells. Specifically the cell aspect. If you represent lists as:
l = [x, [y, [z]]]
Then you can implement car as l[0] and cdr as l[1].If you require mutable cons cells, that's pretty much the only way to do it. Because if you want to set the car of cdr(l), how do you do it? You can just do
cdr(l)[0] = t
Because that's the same as l[1][0] = t
Which of course makes the list become l = [x, [t, [z]]]
But this sucks. It's always sucked, and Lispers go out of their way to ignore the fact that it sucks. I wince at having such a dismissive attitude here, but it's been the source of years of frustrations.It's a frustration because if Lisp had been implemented using vectors and hash tables instead, it'd be in a far stronger position today. Everyone uses vectors. Vectors are [1, 2, 3, 4] ... Plain old arrays! In fact, I used vectors in the above examples, and didn't even have to explain what they were. Everyone knows and understands arrays.
Lisp can work fine with vectors, if you drop the requirement of mutable cons cells. Because l becomes:
l = [x, y, z]
And cdr(l) becomes l[1:], so cdr(l) returns [y, z] -- an entirely new vector containing y and z.This might seem like nonsense, but in practice it's not. In practice, you're rarely building lists containing hundreds of thousands of elements. Usually it's much smaller lists contained in other structures, like hash tables.
And when the lists are small, you really don't care about creating new lists. The fact that cdr(l) returns a copy of l minus the first element is inconsequential. You'll ~never experience a slowdown.
And the gains are massive. You get to interface with all your native libraries using lisp algorithms. You don't have to convert from "lisp lists" to "python lists" or "javascript lists" or anything else. They're just arrays.