Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The Land of Lisp (landoflisp.com)
477 points by adgasf on Oct 6, 2017 | hide | past | favorite | 135 comments


This book comes up in #lisp on freenode every so often, and the channel is generally split on whether or not to recommend it. I generally do.

It's fun and lighthearted. Using games as a medium to teach the language is something some people enjoy, and is a lot less dry than most programming books.

It avoids taking sides on the editor war, by just ignoring it altogether and teaching Lisp. This is refreshing compared to most books, which hit you with the Emacs cinderblock to the face right in the preface.

It also stays away from ASDF and Quicklisp and even the entire package system in general, which is a lot of extra complexity that can be overwhelming to beginners at first (though they'll eventually need to learn about this if they want to continue using Common Lisp).

The main issue people have with the book is that it uses CLISP-specific code in a few places. CLISP's last release was seven years ago, and because it hasn't really been maintained it's beginning to bitrot. Folks in #lisp generally don't recommend using CLISP these days, instead recommending actively-maintained implementations like SBCL, CCL, ECL, ABCL, etc.

Using CLISP-specific code does allow the book to sidestep the issue of the library ecosystem, which is a plus. But a revamped version (or even a collection of errata) that ported the CLISP bits to a maintained implementation would make it a lot easier to recommend these days.


>The main issue people have with the book is that it uses CLISP-specific code in a few places.

This makes sense for a tutorial book, since CLISP is easy to install, very small to download (compared to SBCL), and is a fully featured (ANSI compliant) implementation. So i don't think it was a mistake to choose CLISP.

The recommendation in #lisp for SBCL over CLISP might be because SBCL is nicer to the programmer, offering more features. Also, code runs very fast under SBCL; although i suspect that CLISP compiles code faster.

(If any is interested, here is a quick overview on some of the Lisp implementations available and their salient features. (Most implementations are free)

    ECL - Embeddable Common Lisp
        allows you to compile Lisp into any 
        other system by compiling to C

    SBCL - Steel Bank Common Lisp
        Produces very fast code, 
        allows static type checking and other niceties
        a fork from the CMU CL impl.

    CLISP
        Small, easy to install and use, 
        includes readline REPL and X11 features

    ABCL - Armed Bear Common Lisp
        Allows you to run Lisp under the Java JVM 
        and call Java code, or call Lisp code from Java.

    CLASP 
        Compiles Lisp to the LLVM, provides C++ interop

    ACL - Allegro Common Lisp
        Commercial Lisp, fast, feature rich
        includes a Prolog implementation, CLIM GUI
        and other nice stuff.

    LispWorks
        Commercial Lisp, fast, feature rich,
        includes an IDE, Java Interface, 
        and CLIM 2.0 implementation, more features. 

    ParenScript
        This is a small subset of CL that gets translated
        (in the server) to javascript

    JSCL
        A Lisp implementation that runs under Javascript,
        providing a REPL and Lisp interpretation on the
        browser, for a subset of the CL language.
)


I'd add one more very popular implementation:

  CCL - Clozure CL
     Produces fast native code; compiles faster
     than SBCL. Also has some MacOS-specific goodies.
People sometimes use both CCL and SBCL at the same time, to have faster compiling during development via CCL and then better runtime performance of the released version via SBCL.

I used to use CCL for hobby gamedev back when SBCL had some troubles on Windows (they're gone now); now I only use it on Raspberry Pi (AFAIK SBCL couldn't utilize multiple cores on ARMs last time I checked (which was a years ago)).


Thanks TeMPOraL! I'll try CCL then!


It is also because CLISP is unmaintaned. But the only implementation dependant code I remember is the socket code.

But CLISP wasn't unmaintaned when the book was written más its default REPL is much better than other implementations. It was a good choice at the time.


> CLISP is unmaintaned

AFAIK, it is not really unmaintained, the developers just haven't done a release in years. When I fire up CLisp on openSUSE Tubmbleweed (their rolling release distro), it says

    Welcome to GNU CLISP 2.49.60+ (2017-06-25) <http://clisp.org/>
That would make me think that development might have slowed down, but not stopped.


Yet, if you visit that URL, you are greeted with :

    Current version:	2.49 (2010-07-07)
Seems like the patch level on openSUSE is provided by the package maintainer, not CLISP. It looks like Debian Wheezy is at "2.49-8.1", Ubuntu Xenial is at "2.49-9ubuntu1", FreeBSD Ports is at "2.49_6", but also marked deprecated/expired as of 2014.

I'd venture that the maintainer is applying patches to the upstream source to keep it running on the OSes when they update ABIs, etc.


The most recent commit to the source tree (https://sourceforge.net/p/clisp/clisp/ci/tip/tree/) was today.

Not sure how much that is worth - with no release in seven years, I would guess there is not much going on. But it is still more than nothing.


CLASP is for me the most exciting CL implementation right now. Compilation to the LLVM is a huge advantage.

Sadly, it's a one-man thing. And CL seems quite stagnant.

I wish one implementation triumphed over the others, and CL progressed beyond its ANSI standard.

Clojure has many interesting things. So does Racket. The Lisp landscape is too fragmented. And thus libraries are a huge problem.


>I wish one implementation triumphed over the others

That would be terrible. Part of the nice things of CL is that you can choose the implementation according to what you need. For example ECL if you want to embed your lisp code with C code. ABCL if you really need to call lots of Java libs (or have Java code call your Lisp code easily), and so on. We're talking about mature, proven, tested implementations.

If one implementation triumphed over others, over time we'd be in a position similar to, say, Python or Clojure, where there is only one or two implementations, besides some experimental implementations, and nothing else.

Something that needs to be mentioned is that CL is truly standardized; if you have a code written in Common Lisp, chances are it will compile straight away on most of the implementations (ECL, ABCL, SBCL, etc), with no change needed. So having many implementations does not mean there is any kind of fragmentation in the language.

>and CL progressed beyond its ANSI standard.

CL is one of the most extensible languages out there, so it has already progressed way beyond the ANSI standard. The standard doesn't need modification to support new things. There are already many libraries giving you things that are not in the standard (like sockets or threads) but in a portable and standarized way.


But the whole idea, to your own point, is that there are lisps everywhere, compiling to everything and each having specialized additional features for the local needs, yet the ansi core remains intact, so everyone can use every one of those lisps (if they really are lisps...I’m looking at you, clojure!) [ED: I’m good with RSR5 too ... Jerry Sussman himself calls scheme a Lisp!]


> Compilation to the LLVM is a huge advantage

Is it? Advantage over what?

> And CL seems quite stagnant

That's good then, since he can better catch up.

> Sadly, it's a one-man thing.

He can always reuse code from other implementations. Though I agree that it is too much work for a single person to create a quality implementation of Common Lisp.

Problem seems to be that there is not enough interest in another implementation based on an un-explorered infrastructure (LLVM).

> CL progressed beyond its ANSI standard

It has. In implementations and libraries.


> The main issue people have with the book is that it uses CLISP-specific code in a few places. CLISP's last release was seven years ago, and because it hasn't really been maintained it's beginning to bitrot. Folks in #lisp generally don't recommend using CLISP these days, instead recommending actively-maintained implementations like SBCL, CCL, ECL, ABCL, etc.

Note that CLISP is actively maintained; the most recent change was three hours ago: https://sourceforge.net/p/clisp/clisp/ci/63508ea11cf0b2062ca...

I have no idea why the maintainer hasn't released a new version since 2010. Doesn't make any sense to me.

I use SBCL, but CLISP is still alive.


Last I heard they were looking for a maintainer: http://article.gmane.org/gmane.lisp.clisp.general/14256

Has someone stepped up?


From the commit history, looks like Bruno Haible & Sam Steingold are still doing it.


> This is refreshing compared to most books, which hit you with the Emacs cinderblock to the face right in the preface.

While if they use Emacs' lisp features that approach could be useful for some people (mainly those unfamiliar with or undecided on an editor to use), it's likely to strike others that don't already use Emacs as extremely annoying. I'm glad I haven't encountered that (but I haven't read a book on Lisp either).


This book is destined to be a classic programming book, just as "The C programming language", "The Little Schemer" or "Operating systems: Design and implementation".

I would really like to meet Conrad Barski and give him a great hug. And invite him a good beer.

Be sure to read the comic that is on the bottom of the page!!

Now, to be honest, a quicker or more practical introduction to Lisp would be the "Practical Common Lisp" book which is also superb. However, Land of Lisp is a charming book that makes you smile and feel like a nerdy (in a good way) 12 years old kid in 1982 who just got as a birthday present a brand new Commodore-64 and is eager to read the manuals!


Thanks for the kind words! Glad you enjoyed my book!


Hi doctor!

The comic at the bottom of the web page got me laughing and in tears at the same time, in particular the line: "Back in the 80s we showed you how to program without ANY bugs". Also, Java as a little tank, C# as a plane, Python as an helicopter... just brilliant. I almost rolled in the floor laughing by looking at that part of the strip.

Certainly it is prophetic, it seems we're almost reaching the point of being enslaved by bugs...

You're a good man, mr. Lisperati!

"As you know, we're in the 8th year of the Great Northern Wars against the Haskellers (there are rumors that more of our troops are defecting to the other side)!! Don't be tempted to break ranks!"


I did really like the Haskell comments...gave me a good chuckle!


> Java as a little tank, C# as a plane, Python as an helicopter... just brilliant. I almost rolled in the floor laughing by looking at that part of the strip.

Is there a special significance to the Java / Python / Ruby / C# representations? I feel like I missed the joke here, even though I enjoyed the strip as a whole.


Java as a tank - that is, slow (in development time) although resilient and all-terrain

Python as a helicopter - far more manuverable but slower than a plane and easier to take down

C# as a plane, fast and carries more cargo than an helicopter.

Ruby like some sort of convoluted laser beam weapon

Lisp dialects (on the strip) are all spaceships done using "secret alien technology". Even then, the insectoids are harder to kill than back in the 80s! What will the human+lispers alliance do? Read the strip for knowning what happens next!


I took it to mean that Java/Python/Ruby/C# were "old tools" with flaws (bugs), but LISP is a tool for the future.


I was going to jump in and say nice things about your comic, too. I really like the light-hearted dramatization of what really motivates programmers: the elimination of bugs. The fact that there are a few, discrete approaches is only obvious in a language that supports them all, like Lisp. (I think I might be a combination of CLOSest, minimalist, and continuationist). (I would point out that the multi-corists are more motivated by performance than correctness)


As an avid haskeller with a lot of respect for lisp, I've gotta say I really love the depiction of the Republic of Haskell as a police state, where side effects receive no mercy.


Wouldn’t it be more apt to say that side effects are not secondary citizens in haskell republic and they have first class support?


Yes, and the whole io-commands-as-values thing that outdoes anything the Command Design Pattern is capable of, and all that.

But given that the meme of haskell-has-no-side-effects exists, the Haskell Police State is funny.


"Follow the simple rules..."

"I hereby pronounce you guilty... of having SIDE EFFECTS!"


I started my career hacking Common Lisp (Allegro CL), these days I do Clojure, among other things.

That comic by Dr. Barski tears me up every time! Just to test, I went and read the comic again and I cried, again!

I have met Dr. Barski personally at a Clojure conference many years ago and I still remember him as an extremely kind and knowledgeable person.

Thank you for the Land of Lisp, Dr. Barski! Some day, we will be able to assemble our guilds and beat the Insectoids for good. Until then,long live language du jour!


>That comic by Dr. Barski tears me up every time! Just to test, I went and read the comic again and I cried, again!

I confess I also cried when I realized such a book existed.

It was like God telling me: "Don't be ashamed of being a nerd. You're unique and we love you."


I remember that glorious feeling :)


I was exposed to this book in my Algorithms class last year as the book to learn Lisp if we wanted to. The professor himself was a huge Lisper.


Counterpoint comic: https://xkcd.com/224/


Am I mistaken or is that Alan Kay smashing bugs in the comic? :)


LOL, that does look like Alan Kay, doesn't it? Not 100% sure what I was thinking at the time I drew it, but it's likely a coincidence...


LOL! He must be Alan Kay!!

"Gotcha!" -- Alan Kay smashing a bug


Little Schemer is worth reading if only to see a different approach to teaching. I really hope I can find time to read LoL.


I wonder if the author made new chapters free..


I've read this book, and what I love about it is that it really brings to mind the programming books of my youth, when nobody would argue that programming should be fun.

It's goofy, has bad jokes, and you learn something.

Having said that, the code style seemed quite idiomatic compared to some of the other Lisp I've seen (although I'm no expert), so I wasn't sure how valuable the lessons were.


I really liked going through Realm of Racket with my 11 year old daughter. It pretty much is the same format. It made me miss the days of typing code from a book and hit run. (Well run never really worked then it was hours of debugging but that taught me so much)



Ha yes! Bonus points when the book is for IBM Basic, and you're using a Commodore 64. Argggggg!


I loved it when they didn't say what basic it was for. My dad ended up meeting a author of a few of the programs and he said, "Oh I never got that basic program to ever run." My dad was like my 9 year old fix it and walked away. He was proud and mad. It took me weeks to get things fixed.


Oh yes. I had a TRS-80 Color Computer, and the BASIC dialect (though written by MS) was slightly different in some details, so I was usually translating things at least a little. Things like color and graphics were completely different from system to system.


LOL. I had an Atari 130XE so examples for IBM Basic, Apple ][ and Commodore didn't work either!

Even worse if the examples were for the Spectrum, which had an even more peculiar dialect!


Childhood TRS-80 user here, can commiserate.


I was a sol-20 kid


> seemed quite idiomatic

I'm not sure how that would be a bad thing. Did you mean unidiomatic?


A common complaint about Lisp code in general is that programmers tend to write code that is idiosyncratic [ED: I previously used the word "idiomatic" here in reply to the OP but was conflating terms, making this post rather irrelevant but at least it provoked a discussion] (i.e. rather than looking like templated design patterns with standard names, the program is heirarchically built of modules in a domain-specific language of the programmer's own design). This is both one of Lisp's greatest strengths to those who like it, and (I think, based on comments I've seen here and elsewhere) one of the greatest reasons it doesn't have more widespread adoption.


> rather than looking like templated design patterns

Speaking about another lisp, Clojure, it is a goal that each program finds its own design pattern. That's kinda the whole idea. Design patterns can really get in the way, unless your language requires them, which some languages do (i.e. Java where everything must be an object, so OO it is, or Apple's platforms where the MVC pattern is deeply interwoven into all the APIs).

Lisp in general is about exploring a particular problem using only the constraints of that problem, without concern for how different problems get solved. By contrast, design patterns are about forcing a common solution onto a range of different problems.


> By contrast, design patterns are about forcing a common solution onto a range of different problems.

I always viewed design patterns as providing a shared name for common solutions to common problems. And that forcing a common solution to a range of different problems was a misuse of them.

But maybe I'm wrong.


I like to think of design patterns as "TV Tropes for programming". The GoF probably intended their book to be taken in that spirot. But then design patterns became something that computer science students and job candidates got quizzed on...


> I always viewed design patterns as providing a shared name for common solutions to common problems. And that forcing a common solution to a range of different problems was a misuse of them.

Exactly, a design pattern is just that: a pattern of design, that shows up organically after you have enough systems designed in the same language. Many of the design patterns that occur in languages like C++ and Java don't show up in Lisp because Lisp is a rather different language, but then we have our own design patterns as well, things like with- macros.


>By contrast, design patterns are about forcing a common solution onto a range of different problems.

This is one of the best criticisms of Design Patterns i've ever read. Great point.


I know what you are saying, but that is not what is meant by idiomatic Lisp. Not by Lispers at least.

Non-idiomatic Lisp is typically written by beginners whose code looks more like the language they are accustomed to using previously. For instance, leaning heavily on a procedural style. And not just beginners, but also seasoned programmers that write object oriented Lisp more akin to static OOP. In other words, designing class hierarchies rather than protocols (using generic functions).

What you describe is more of a side effect of the Bipolar Lisp Programmer[1]:

> This is a BBM attitude; it works for me and I understand it. It is also the product of not needing or wanting anybody else's help to do something.

I haven't read Land of Lisp yet, so I can't really comment as to whether I'd consider it idiomatic Lisp or not. (OP meant "idiosyncratic" anyway, it seems.) Not that I'd be a good judge, anyway.

[1] http://www.shenlanguage.org/lambdassociates/htdocs/blog/bipo...


God, that link and the comic strip for the Land of Lisp are both so great! I might have to try Lisp again.

>Writing in C is like building a mosaic out of lentils using a tweezer and glue.

I cannot describe the memories and associated feelings this evokes....


"rather than looking like templated design patterns" - that is, the code goes straight to the point instead of being littered with incidental noise and ceremony? How that could possibly be a bad thing? Well, in certain software development subcultures ceremony might be a norm, but not in general.


From what I have seen, code that "goes straight to the point" is usually poorly thought out, is unmaintanable, has bugs, is difficult to extend to new use-cases, and the developer who wrote it is long gone.


No, it's the opposite - it doesn't have to drag around pointless layers of unused abstractions, and all the bugs that are there are bugs of subject matter, not of surrounding boilerplate. Such code minimizes the surface area and degrees of freedom, hence not leaving space for bugs.

The more I program, the more I'm convinced that - unless you've coded identical software many times before - code needs to grow organically and stay as focused and close to the problem as possible. Abstractions should follow naturally and be done "just in time". If they're needed, they have to be written either way, and you're not saving time by writing them up front (focused code is easy to refactor).

Of course with experience, you learn that some patterns of change are likely to occur, or that some touches of abstractions here and there are very beneficial. But beyond that, I feel the best way is to write simplest code possible, wait for it to be needed elsewhere, and then DRY up semantics.

I liked the posts of Casey Muratori, which explain roughly this mindset, calling it "semantic compression" and "compression-oriented programming": https://mollyrocket.com/casey/stream_0019.html.


You should expand this into an article or blog post!


You know what? I might actually do just that; I just need to collect my thoughts and outline some examples.


That might be (perhaps) true in other languages, but that is not the point in Lisp.


Best practices, patterns, idioms are all important no matter what language. Lisp is not special in this regard (although, I admit, Lisp developers may stick around a bit longer).


>Lisp is not special in this regard

In reality, yes, at least because of two differences:

1. Lisp is a significantly more powerful language, compared to most non-Lisp languages. Thus, many patterns and practices that are needed in other languages, are simply not needed at all in Lisp, or become far simpler.

2. Lisp is a "programmable programming language" where code is a "first class citizen" and can be manipulated as well as any other kind of data such as numbers. This opens a very different approach to programming, with its own, different "best practices".


Best practices, patterns and idioms are all tools, not religious symbols. If you treat them as the latter, you end up with things like JavaScript one-line projects that have 1kb worth of grunt/gulp/webpack config files, or with HelloWorldFactoryLightweightBridgeBuilderAbstractFacade in Java.


There is a big difference between language idioms and design patterns.


I did, of course, mean idiosyncratic. My bad


I fully conflated both words as well in my reply, don't feel too bad :)


Of course


Perhaps they meant "idiosyncratic"


Maybe "idiomatic" is considered bad because it would mean the lessons are Lisp-specific and you might hope the book teaches you programming in general?


did you mean "idiosyncratic"?


The music video is what really sold me on buying the book several years back:

https://www.youtube.com/watch?v=HM1Zb3xmvMc


I don't even have to click, I remember it after all those years. Something unique in many aspects. Beware.


There's also Realm of Racket https://realmofracket.com/ Which maybe is shorter? I don't recall.


The real question is whether it has a sequel to Grand Theft Wumpus in it


"The most violent programming example ever put on a textbook!"

http://w3.sista.arizona.edu/classes/ista450/spring15/project...


When I discovered lisp several years ago, it was indeed the textbook moment of enlightenment that you've heard about. This book was a part of that introduction for me (along with Practical Common Lisp). After working in C-like languages, I had no idea that programming could work this way as in lisp, the idea of code and data being inseparable, I even had dreams at night about run-time data structures getting expressed as quoted lists! (I kid you not!)

It is now several years later and I have earned my living ever since by working in another lisp, Clojure. And I have indeed learned a lot along the way and what I've learned does indeed translate to how I work in other languages (even C++, which I also love).

However -- it is not all roses and nicely-flavored toothpaste after a savory feast. There is one aspect to lisp programming that, by virtue of its dynamic typing, I still find myself struggling to reconcile. No matter how much I marvel at what I can do in one or two lines of lisp, I do still often find myself making dumb mistakes that a compiler would catch instantly. Without type annotations and checked structured data for everything, it can also be hard to remember what a function does, or what its variables represent, when you read the code later.

One aspect of this that has made a big difference is naming -- how you name things in lisp and dynamic languages is a skill in its own right that helps guide the readability of code in the absence of types. When I look at C++ code I've written, the verbosity of naming is a clear influence from lisp. And it is an improvement.

The other feature that occurs more often is in-line documentation. It is a joy to read Clojure programs (the good ones, anyway) where every (non-trivial or meaningful) function has a little paragraph summarising what it does. This is just good in any language, but somewhat essential in a dynamic one.

Finally, run-time contracts and things like Clojure.spec come about to help fill the void of static typing. The problem I have there is that you add back into your code a fair amount of the verbosity that was removed in the first place by using a dynamic language (just look at Clojure.spec's lengthy annotations for a function signature, and I find myself wondering... why god oh why?). At which point, I then wonder why not just go back to using a static language.

So using lisp taught me perhaps one final, frustrating lesson: there are just great things about both dynamically typed and statically typed languages, and I've learned that the fence is an awkward place to sit.


>Without type annotations and checked structured data for everything

I guess this problem you mention must be Clojure-specific, because in Common Lisp you can declare the data types of the input parameters and all return parameters, and have the compiler (i.e. SBCL) do static type checking; also the compiler can tell you which data types are accepted and returned by your function, by use of the "describe" function.

Furthermore, you can define your own types, structs, and classes, and the declarations (and static type checks) will work with them as well.


Common Lisp:

  (defmethod collide ((object1 space-ship) (object2 rocket))
    "Inline documentation for this method..."
    (the debris
      (create-debris-from space-ship))
SPACE-SHIP and ROCKET are types and classes. DEBRIS would also be a type and a class.

Use DEFTYPE, DEFCLASS, DEFSTRUCT, ... to define new types. Use CHECK-TYPE and ASSERT to have runtime checks, integrated with the condition system.


Well I can do runtime checks just as easily in Clojure, but I'm really talking about compile time checks.


You actually said:

> Without type annotations and checked structured data for everything, it can also be hard to remember what a function does, or what its variables represent, when you read the code later.

I showed you how to annotate types in Common Lisp.

You also said:

> The other feature that occurs more often is in-line documentation.

Which exists in Lisp since 80s or earlier.

> but I'm really talking about compile time checks.

  (declaim (ftype (function (integer string) cons)
		  foo))
  (defun foo (a b)
    (list a b))

  (defun bar (a) (foo "baz" a))

Running the SBCL compiler:

  ; file: /private/tmp/test.lisp
  ; in: DEFUN BAR
  ;     (FOO "baz" A)
  ; 
  ; note: deleting unreachable code
  ; 
  ; caught WARNING:
  ;   Constant "baz" conflicts with its asserted type INTEGER.
  ;   See also:
  ;     The SBCL Manual, Node "Handling of Types"

At least some type checks are done at compile time...


>Well I can do runtime checks just as easily in Clojure, but I'm really talking about compile time checks.

Take a look at this: http://ahungry.com/blog/2015-07-10-Type-Safety-and-Lack-Ther...

It shows you a 9-lines macro for CL, that allows you to declare types in a way resembling Haskell, and having the compiler do the static checks.

Very nice.

Another example is here: https://news.ycombinator.com/item?id=8598149


That's a neat example (the first one) but it's using compile time constants in the type check, which is not as impressive. You could write a similar macro in Clojure that does that.


  (declaim (ftype (function (integer string) cons)
		  foo))
  (defun foo (a b)
    (list a b))


  (declaim (ftype (function (integer) cons)
		  bar))
  (defun bar (a) (foo a a))


  (declaim (ftype (function (integer) integer)
		  baz))
  (defun baz (a) (+ (foo a "b") 42))
The SBCL compiler:

in BAR: an argument of the wrong type.

  ; in: DEFUN BAR
  ;     (FOO A A)
  ; 
  ; note: deleting unreachable code
  ; 
  ; caught WARNING:
  ;   Derived type of A is
  ;     (VALUES INTEGER &OPTIONAL),
  ;   conflicting with its asserted type
  ;     STRING.
  ;   See also:
  ;     The SBCL Manual, Node "Handling of Types"

in BAZ: the wrong return type

  ; compiling (DECLAIM (FTYPE # ...))
  ; compiling (DEFUN BAZ ...)
  ; file: /private/tmp/test.lisp
  ; in: DEFUN BAZ
  ;     (+ (FOO A "b") 42)
  ; 
  ; note: deleting unreachable code
  ; 
  ; caught WARNING:
  ;   Derived type of (FOO A "b") is
  ;     (VALUES CONS &REST T),
  ;   conflicting with its asserted type
  ;     NUMBER.
  ;   See also:
  ;     The SBCL Manual, Node "Handling of Types"


That (static type checking) is unfortunately not the part of the standard, but some implementations take extra care to help you. In particular, SBCL will do its best to use every and all type declarations you provide to both statically check and optimize your code.


I question the downsides you suggest.

There was a study done where they had two groups of people implement the same thing, one with a dynamic language, the other with its equivalent static variant.

What they found was that the people who used the dynamic language took 33% less time to complete the task. But what's interesting is students who were given the static typed variant all said they felt the type system helped them, and made them more productive.

Now, that study can be criticised in a lot of ways, but as it stands, it's still better then people's opinions.

I think it can feel like a drag sometimes in dynamic languages to figure out the type of things, and what structure the data comming into functions has, etc. But I suspect in practice, that feeling does not translate to lower productivity or higher defects.


> two groups of people implement the same thing

The obvious problem with that is that dynamically typed languages are great for prototyping things ... and implementing something quickly for a study sounds like prototyping.

But statically typed languages really shine for maintenance and refactoring.


> But statically typed languages really shine for maintenance and refactoring.

Possibly, I've not been able to find any research related to the impact of the typing discipline on maintenance.

All there is out there are studies on defect count of large code base projects. And those showed only marginal differences, certain dynamic languages like Clojure even beat out all others.

So at least in terms of maintening quality over time, dynamic languages seem to hold up to static languages.

What I've been trying to get data on is productivity over time. I know dynamic languages are more productive at the beginning, but do static languages get more productive over time is a good question. I still feel probably not, I think it's still just all a big feeling, but I've got no data on it.


My first go at lisp was working through SICP. I loved it. But I couldn't see myself using it for a medium-sized project just because static typing is that valuable to me.

Now I'm learning Racket, and Typed Racket feels great so far (despite a few awkward spots). You don't have to sit on that fence; you can switch between typed and untyped code at will.


>But I couldn't see myself using it for a medium-sized project just because static typing is that valuable to me.

See my comment above, you can have static-typing in Lisp with no problem: Type declarations are part of the Common Lisp standard[1], and implementations like SBCL (one of the best Lisp implementations out there, and free) will do static type checking.

[1] type declarations: http://clhs.lisp.se/Body/d_type.htm

"the" (type specifier for return values): http://clhs.lisp.se/Body/s_the.htm#the

EDIT: a good example here:

https://news.ycombinator.com/item?id=8598149


As with my comment about typed racket, I can't really use common lisp in my work, however clojure is very portable and I can use it (as clojurescript) as a first class language on iOS, and Mac, and the web.


I would love to use typed racket, but I cannot really use it in the environments I program for, which are largely commercial apps on Apple platforms and mobile. If I could, I would jump to it in a heartbeat.


> It is a joy to read Clojure programs (the good ones, anyway) where every (non-trivial or meaningful) function has a little paragraph summarising what it does. This is just good in any language, but somewhat essential in a dynamic one.

That is an extremely controversial statement. The trouble with comments, and with programmers, is that a certain sort of brilliant programmer is very common: their intellect is fast and powerful, but they cannot contain themselves. And while their code must execute correctly, comments provide them with a limitless heaven into which they can pour their brilliance for the rest of us to read in awe, without fear of being constrained by such tedious requirements as correctness in execution, and with no requirement for precision or economy of language.


> run-time contracts and things like Clojure.spec come about to help fill the void of static typing

If you look at clojure.spec as a replacement for a type system, you'll be frustrated. The focus is on expressiveness, not proof. It's quite a different beast.

The leverage comes from the fact specs are data, and therefore usable at runtime, which usually isn't possible due to type-erasure.

Not having a chasm between compile-time and runtime allows extending the language. You can run clojure.spec checks, or a full type system (like Typed Clojure), etc. The entire mindset is based on "there's only runtime".

The discomfort comes from comparing that to a language that has a canonical type system, and evaluates type definitions in what is essentially a separate runtime only available in the compiler. Apples, oranges.


I was greatly disappointed with this book because none of the 'Game' examples had a graphical interface to them. They are all text based.

Reading further in this thread people are suggesting Realm of Racket as an alternative and it looks like that book has much more visual game examples: https://realmofracket.com/games.html


>I was greatly disappointed (...) They are all text based.

That's not really a bad thing...

If you want graphical games in Lisp, take a look at the series called "Pushing pixels with Lisp":

https://www.reddit.com/r/lisp/comments/6d5nht/pushing_pixels...


I've been following this series and its great! I'm not saying it was a "bad thing" I'm saying it didn't meet my personal expectations for a "lets build games" book


> I was greatly disappointed with this book because none of the 'Game' examples had a graphical interface to them. They are all text based.

Chapter 19 is titled "Creating a Graphical, Web-Based Version of Dice of Doom".


Unfortunately, this web-based version is just printing text to the browser instead of a repl in the other examples.


By "text" do you mean "SVG code that is rendered into images the user can click on"? Because that's what it's doing: https://i.imgur.com/iqdZ8l4.png and I think calling that a "text based" game is wrong.


Using a local web browser as your user interface is a valid method for making user interfaces; in fact, it's a very cool and cheap one - all it takes is to embed a HTTP server in your application and have it output HTML/CSS/JS (+ SVG for extra pretty graphics).


This is the standard way to do user interfaces in Picolisp. If you've never toyed with Picolisp, check it out. It is a very opinionated lisp.

https://picolisp.com/wiki/?home


TBH, as someone who learned programming through making games (with graphics!), it disappointed me too. That said, I found it to be only a small issue (and arguably a justified decision) in otherwise great book. A lot of the game code is really separate from the issues of display. In later chapters, the book uses the web browser to provide for a graphical display. And also, come on, the type-in implementation of Robots game made half-a-page long through abusing loop and format is just plain awesome xD.


Honestly that's one of the things I loved about it. Text games will work with any language without any libraries (for the most part). If I have to use Unity or Unreal, I feel like I'm really just learning how to use a framework and not useful long term programming skills. I think grand theft wumpus uses lisp to write out dot files for graphviz to consume. They skirt around using a library for that which is what I do even in languages with graphviz support.


This looks great!

Why's Poignant Guide to Ruby really got me started in thinking for myself as a programmer. I'm looking at this book and seeing that if I read it I might fall in love with Lisp...


Yea, this definitely seems inspired by Why's style. The art is similar, the story is absurd, metaphorical, and fun. Man, I miss that guy!


I loved this book! I've always enjoyed retro text-based games and this was a fun way for me start learning a more functional style of programming (and Lisp). It was a nice contrast to my daily C++ work.


I’m so glad that this exists. Lisp (Clojure) has really brought the joy of programming back for me after 20 years.


"Simple but refined, guaranteed to blow your mind, the land of lisp"

This guy is a genius :D


I've learned LISP and Scheme, gained some useful insights, used them on a few random projects, and then dropped them.

I recommend learning them, but then switching to something like Reason / OCaml / F# / Haskell.


counter anecdote: I use and contribute to a number of Scheme programs that I use daily and would never want to switch to any static language. Life at the REPL is too good.


I am currently working on an interpreter for a Lisp-like language (it's too early to call it a dialect of Lisp) in Go.

I have not used Lisp at all over past couple of years, except for tweaking emacs, and I am beginning to understand that I have subconsciously missed Lisp.

It is amazing how little - if one really wants to - of Lisp one needs to implement in the host language before one can go on and write the rest in Lisp. Efficiency-wise, I expect that I will implement many things in Go for performance that could be written in Lisp.


I've read most of it too, but not sure it shows a lot of lisp's strengths. A lot of the programs I read them over and thought that I could do the same thing in significantly less Python code. I'm not sure what should be fixed if anything though.


that I could do the same thing in significantly less Python code

I have extensive experience with Python and i also know Common Lisp (though i'm far from being an expert there.) You can definitely write more concise code in Lisp. Not only more concise, but also easier to read, although Python is also very good at readability too. (For example, I love the fact that Python allows you to use named parameters, and when I learnt Common Lisp, i sighed with relief upon finding out you can do the same in CL.)

But once you enter the world of macros, is where you realize the possibilities go far beyond what you can do with Python. Not to mention CLOS (the Common Lisp Object System): after reading about CLOS, OOP haters might probably want to embrace OOP again, and OOP fans will get delighted at the enormous possibilities and freedom brought by that object system.

In short, Lisp is a far more powerful language than Python and also allows for more concise code, particularly if your system is complex. However, I should say that Python is far easier to learn and well featured, so that's what I recommend beginners to learn first.


> A lot of the programs I read them over and thought that I could do the same thing in significantly less Python code.

My racket code is usually many time smaller then my Python code. The nice thing about Racket/Lisp is you can just make your own tools when in Python you copy thousands of lines of code into a one line code.

The real fix that Lisp/Racket gives over Python is deployment.


Agreed on deployment.


I read through LoL, and then most of Clojure for the Brave and True. I think one of LoL's strong points is that it only ever explains things in the domain of Lisp. The Clojure book kept showing samples of what you were doing in other languages, and it kind of broke my initial ability to get in the mindset.


This is the book i give as a present to the most geeky of my friends.


I love this book and it certainly deserves some attention, but is there anything new that is newsworthy? Has a new edition been released? Just wondering if I missed something.


Nicely explained.

On a side note, I noticed with deep satisfaction that “git” is used as some kind of curse in the land of Lisp.


"Git" in British slang roughly means "jerk". See also Linus's joke about naming software after himself, mentioned elsewhere in thread.

The Monkees had a song called "Randy Scouse Git" (after a catchphrase from the britcom 'Til Death Do Us Part) the title of which was considered so vulgar in the UK that they had to release the song there under an alternative title (I think they actually used "Alternative Title").


git: (noun) an unpleasant or contemptible person


Linus Torvalds: "I'm an egotistical bastard, and I name all my projects after myself. First Linux, now git."


It's unclear if it is a curse or a deity. Could be both.


the cons chain of arrows certainly reminded me of why deep nested structural syntactic sugar is a pain..


Wow, new comic?

Previously it was a different one.


The dude on the right looks like an older version of Doug Funny.


I really enjoyed the book. An awesome intro to lisp!


Making good comics is hard.


I'll get hammered for this, but there are better books.

I still haven't figured out if this book is a vanity project written by a bored Doctor, or a sincere attempt to convey information.

I do like the Period Table though.

And maybe it's just me? I have the book on my shelf, and it's dusty.

I do feel using a comic book format to convey technical information is the way to go. It should be used more often.


Care to share some details on which books you consider better and why? Thanks!


Can you suggest some of these "better books" ?


Not him, and I adore the geekiness/goofiness of Land of Lisp, but I found Practical Common Lisp much more helpful.


I think you want to read the cartoon guide to the computer




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: