[HN Gopher] Successful Lisp: How to Understand and Use Common Li...
___________________________________________________________________
Successful Lisp: How to Understand and Use Common Lisp (1999)
Author : medo-bear
Score : 143 points
Date : 2023-05-14 08:51 UTC (14 hours ago)
(HTM) web link (dept-info.labri.fr)
(TXT) w3m dump (dept-info.labri.fr)
| susam wrote:
| Seems like a nice book. I like that it gets into the fundamental
| stuff like setq, cond, let, list, cons, etc. quickly enough in
| the 3rd chapter. In my opinion, the sooner these concepts are
| introduced in a book, the better.
|
| I have found, at least from my own experience, that a programming
| language is best learnt by a mix of diving straight into it and
| writing small software that you care about with it and then
| supplementing that experience with the study of existing
| literature.
|
| When I began learning computer programming two decades ago, it
| was pretty much necessary to buy a good book and read as much of
| the book as possible chapter by chapter. For example, the first
| programming language book that I read was K&R and I read that
| cover to cover. It was quite formative in my journey of learning
| to program the computer. It took me a long time to start writing
| useful software but when I did, I had a pretty thorough knowledge
| of C.
|
| I have come to realise that these days, it is not uncommon for
| aspiring programmers to jump straight into developing software
| with a programming language determined by requirements. Not
| everyone has the time to read a book cover to cover. In fact, I
| myself learnt Python by jumping straight into developing tools
| that I needed for myself with it and then followed the official
| Python tutorial. My Common Lisp story was different. I began
| learning CL directly by browsing the Common Lisp Hyperspec
| (CLHS). It is not an approach you would find anyone recommending,
| and for good reasons.
|
| If someone wants to get started with quickly developing tools
| using Common Lisp, I would suggest bookmarking
| https://lispcookbook.github.io/cl-cookbook/ which is a great
| resource to look up common recipes for common tasks. Special
| thanks to @vindarel for maintaining the Lisp Cookbook. Don't let
| the parentheses scare you. With proper tooling, they are no more
| distracting than, say, braces in other languages.
| vrglvrglvrgl wrote:
| [dead]
| vindarel wrote:
| It's a good book!
|
| Modern companions would be:
|
| - the Cookbook: https://lispcookbook.github.io/cl-cookbook/
| (check out the editors section: Atom/Pulsar, VSCode, Sublime,
| Jetbrains, Lem...)
|
| - https://github.com/CodyReichert/awesome-cl to find libraries
|
| Also:
|
| - https://stevelosh.com/blog/2018/08/a-road-to-common-lisp/
|
| - https://news.ycombinator.com/item?id=34321090 2022 in review
| macmac wrote:
| The Steve Losh link is dead for me. Here is one from the
| Wayback Machine:
| https://web.archive.org/web/20230505132018/https://stevelosh...
| ur-whale wrote:
| > Lisp, which seems to go to great lengths to isolate you from
| the details of machine organization.
|
| Right there, along with Haskell is exactly why Lisp was never an
| option for me. And much like the author, I've been subjected to
| the darn thing multiple times since an early age (the 80's).
|
| [EDIT]: and most notably missing from the list: The Lisp
| ecosystem is pretty much impossible to understand.
|
| There are so many flavors of the darn thing none of which are
| interoperable with the others.
|
| Every time I found something written in some random dialect of
| Lisp, there's always a missing piece to get it to run on my
| machines unless it's a 20 line coding exercise.
|
| I've also never found a list that explains why "this Lisp is
| different from that Lisp because ..." .
|
| Everyone in that world seems to assume their favorite patois is
| the best thing since sliced cheese.
|
| Seen from the outside, it's a giant mess.
|
| Makes it impossible to pick the right tool for the job.
| anthk wrote:
| There's the Common Lisp standard with the Quicklisp library
| manager being almost fully compatible with SBCL, ECL, Clisp...
| (the performance will vary a lot, tho), and then there's
| Scheme, the LISP cousin.
|
| For programming, the best env for CL it's Emacs and Slime, and
| for Scheme there's Emacs and Geiser. For further programming,
| Org-babel from Org-Mode wth the accompanying modules for
| Slime/Geiser with ob-scheme or ob-lisp.
|
| Emacs with Org-Babel it's like having an anotated REPL with
| options to put anotated marks, graphics and/or export it to ODF
| or PDF. Kinda like the Python/Jupyter notebooks but with
| superpowers.
| whartung wrote:
| Part of the problem is that most anything that uses
| S-expressions is called a Lisp. And there are dozens of these
| languages.
|
| You see a headline "Did amazing thing using Lisp!!" and find
| that it's actually more "Did amazing thing with A Lisp", and,
| typically, not the Lisp you like to use.
|
| Nobody calls C, Java, C#, C++, Pascal, D, etc. an "Algol" or
| whatever generic term might apply to this family of languages.
| "DOOM is written in Algol". But this happens all the time with
| Lisps.
| packetlost wrote:
| > And there are dozens of these languages
|
| No, there are way, _way_ more than that.
| wudangmonk wrote:
| I feel the exact same way about Python, and Javascript and
| everyone seems to use and sometimes even likes those giant
| messes so we can assume for sure that giant messes aren't
| really the problem here.
| user6723 wrote:
| Statically typed Lisp for the win https://carp-
| lang.github.io/carp-docs/core/Pointer.html
| tmtvl wrote:
| Indeed, I also like statically typed Lisp:
| https://quickref.common-lisp.net/defstar.html
|
| EDIT: to be fair, Coalton seems even more interesting than
| defstar, but it has issues with mutation.
| reikonomusha wrote:
| Hindley-Milner has the very standard and well-known problem
| with _polymorphic_ mutation [1]. There is no issue with
| setting an array of floats or something like that. It 's only
| when you assign a polymorphic value cell with one type, then
| subsequently with another type.
|
| This is not unique to Coalton. Any HM-based language that
| defines mutation primitives has it, including Haskell and
| OCaml. These languages don't "solve" it a sense most people
| think, instead they provide some sort of restriction or
| workaround to the HM theory to make mutation constructs
| feasible. There's a huge space of possible solutions,
| including ensuring functional purity with monads (Haskell) to
| using weak polymorphism (OCaml) to using Wright's _value
| restriction_ (eliminate invalid mutations, but also eliminate
| tons of reasonable, valid programs).
|
| Coalton developers know of the HM deficiency and described it
| very well here [2]. It looks like they're building out more
| important parts of the language that affect their users more
| seriously (e.g., adding records) before making a hugely
| consequential design decision around mutation, which people
| don't seem to bump into much.
|
| It doesn't seem to have stopped them from building
| interesting software in the slightest. [3]
|
| [1] https://en.wikipedia.org/wiki/Value_restriction#A_Counter
| _Ex...
|
| [2] https://github.com/coalton-lang/coalton/issues/84
|
| [3] https://coalton-lang.github.io/20220906-quantum-compiler/
| schemescape wrote:
| Just started reading this and, as a newcomer, I'm finding it
| helpful because it explains not just _what_ things do, but _how_
| they work (for example: the keyword package). I haven't gotten
| far, but it's an encouraging start.
| bhiply wrote:
| Is Lisp being used today for anything particularly significant,
| like C and JavaScript are, or is it merely a niche academic
| language, like Haskell and Rust?
| vindarel wrote:
| yes
|
| https://github.com/azzamsa/awesome-lisp-companies
|
| http://lisp-lang.org/success/
|
| industrial theorem prover, design of Intel chips, quantum
| compilers...
|
| and little me, being more productive and having more fun than
| with python to deploy boring tools (read a DB, format the data,
| send to FTP servers, show a web interface...).
| tmtvl wrote:
| If you consider Rust (is in the Windows and Linux kernels,
| powers Discord,...) a niche academic language, then I guess
| Common Lisp (used for the Grammarly backend, powers ITA
| software) is a niche academic language as well.
| the_duke wrote:
| If you consider Rust an academic language, you are quite a few
| years out of date.
|
| The language is in production at Google, Facebook, Amazon and
| Microsoft (including making it into the Windows kernel), and is
| slowly being included in Linux as well.
| esjeon wrote:
| Rust has been a practical language since the beginning. Not
| every experimental stuffs are _academic_ , especially when
| concepts are not rigorously formulated. Rust has been a
| rolling language ever since it was created, so is hardly
| formal.
| BaculumMeumEst wrote:
| Not really. It has some great ideas but its library ecosystem
| is weak and it has a fair amount of footguns and jank.
|
| It's fun to use but it doesn't really make sense to use it for
| most serious software projects, particularly those that want
| collaborators.
| jossclimb wrote:
| What value would learning Lisp provide, if you're not curious and
| learning for the love of learning, or you're not an emacs user?
| ra1231963 wrote:
| [flagged]
| packetlost wrote:
| Software is such a vast industry with a lot of different
| goals, viewpoints, and tools. Such a close-minded and
| wasteful statement, I find it hard to believe you are as
| successful as you say. Something is only a waste of time if
| you get _nothing_ out of it, but that 's not for _you_ to
| determine for someone else.
| jstx1 wrote:
| [flagged]
| anthk wrote:
| CL is used in pretty serious contexts (read: avionics) with
| little changes over time. JS has the weekly framework
| syndrome.
| matheusmoreira wrote:
| It's hard to describe. Implementing Lisp is the best way to
| understand just how powerful the ideas are. I thought I had a
| reasonable understanding of the language but making my own
| still changed me.
| xh-dude wrote:
| Lisp is profound, not esoteric - the ideas apply in any
| language
| gjvc wrote:
| _What value would learning Lisp provide, if you 're not curious
| and learning for the love of learning, or you're not an emacs
| user?_
|
| What do you want?! A dollar value addition to your salary?
|
| To answer your question: Knowing about an important and highly
| influential part of the industry in which you work.
|
| If that sort of thing is not important to you, by all means let
| it pass you by.
| Jach wrote:
| The value depends on what you already know and whether you want
| to substitute potentially inferior versions of the thing to
| acquire or make use of the knowledge. I'll list some ideas of
| useful concepts you may or may not have picked up already.
|
| First, a lot of languages have closures these days, do you know
| them and more generally how to tastefully use higher-order
| functions? When Java 8 came out, I could see a difference
| between programmers who had useful experience or instruction
| (Scheme + SICP is still great on this) using closures elsewhere
| prior, excited programmers who were using them for the first
| time even if frequently not tastefully, and old programmers who
| had never strayed outside their lane and look at any new
| language feature or evolution that they now have to learn and
| contend with to keep up with a shady eye, never mind the
| potential benefits.
|
| Second, some languages have something like macros, how familiar
| are you with metaprogramming? Maybe you'll be satisfied with
| C++? A comparison from the author of the CLASP implementation
| who is an expert in both langs: Lisp macros are to C++
| templates as poetry is to IRS tax forms.
|
| Third, do you know OOP, or perhaps you know it quite well from
| things like Java/Python/C++/Ruby/JS and dislike it? The Common
| Lisp Object System (CLOS) was the first ANSI standardized OOP
| system and yet it's a lot different from other attempts. In
| particular, it does not couple classes together with methods,
| they are defined separately which avoids a lot of common OOP
| problems while giving you multiple dispatch for free
| (eliminating some verbose design patterns too). It's also got
| less commonly seen things like metaclasses (with a whole book
| written on just the meta-object protocol highly praised by Alan
| Kay), multiple inheritance, a way to redefine classes and
| reshape existing objects at runtime (overload an 'update-
| instance-for-redefined-class method), and a poor man's initial
| support for maybe 70-80% of the value of aspect oriented
| programming with :before/:after/:around method combinators out
| of the box that can be further augmented if needed for the full
| value. Some of the ideas can be had with effort (perhaps done
| for you already via libraries) in other langs.
|
| Fourth, do you know about conditions and restarts, a way to
| handle errors that's not just goto error or classic stack-
| unwinding exceptions? There's a whole (short) book ("The Common
| Lisp Condition System: Beyond Exception Handling with Control
| Flow Mechanisms") on just this topic if individual
| chapters/essays elsewhere aren't enough for you. I don't know a
| good alternative for getting this concept, thus the value of it
| may be limited to whether you can actually use it or an
| imitation (the book author did implement a version for Java:
| https://github.com/phoe/cafe-latte).
|
| Fifth, do you have experience in incrementally writing and
| debugging a program as it's running, or have you only ever done
| the usual edit > compile > run > observe and repeat cycle?
| Common Lisp is still the best for this, Clojure is ok, Java
| with JRebel gives you maybe 80-90% of the practical benefits.
| TDD maybe gives 20-30% of the practical benefits while being
| tedious. Some people definitely do not like the style, but if
| you haven't seen the style to determine that for yourself,
| you're missing out. (And if you're freaking out about error
| checking, you can get some compile-time warnings from SBCL
| about bad types or missing functions and so forth; they're just
| warnings instead of errors because you can fix them as you go,
| you can redefine (even if you're in a debugger context) and
| continue rather than restart everything and lose any state. In
| SBCL, redefining a function also recompiles it for you.
| 'compile and 'compile-file are standardized built-in functions
| to the language you can invoke at runtime, rather than a
| separate program.)
|
| As for editors, you don't have to use emacs. (I prefer vim.)
| https://lispcookbook.github.io/cl-cookbook/editor-support.ht...
| gives a list of alternatives besides those two. The main things
| IMO that you need as far as editor support goes: highlight
| matching parens (basically everything), and ability to talk to
| the running Lisp to provide the features of my fifth point. To
| elaborate even further on that, such support gives you
| redefinition, debugging (breaking/stepping/tracing),
| disassembling, intellisense-style function doc and even symbol
| auto-complete, and jump-to-code/cross-referencing features, all
| part of Lisp itself and conveniently/portably accessed with
| regular Lisp code talking to the editor typically over a socket
| rather than needing to be implemented externally. The main
| development feature, editor or otherwise, still lacking from
| anyone (though someone was working on this, I haven't followed
| up in a long while) is mass auto-refactoring; in practice it's
| not a huge limitation because you don't couple things as
| heavily as in other languages that necessitate frequent huge
| refactorings, and you can use the same sorts of tools people
| used just fine prior to semantic mass-refactoring tools
| becoming more common. (I use Grepper with vim for mass-rename.)
| Fowler's 2nd edition of "Refactoring" uses JavaScript with no
| fancy tools in part just to show the point that the discipline
| isn't tool dependent anyway.
| Barrin92 wrote:
| Common Lisp is a big, general purpose language and
| implementations like SBCL are fast so you can pretty much write
| whatever you want in it. Having a fast, high level expressive,
| dynamic language with a powerful macro system is generally
| where Lisps excel. And if you like functional programming
| there's Clojure.
| aa-jv wrote:
| Fast implementation of working app logic that can later be
| turned into an app-generator for any other language with great
| ease.
| jossclimb wrote:
| What does that mean? Why not start in my native preferred
| language?
| kazinator wrote:
| * * *
| [deleted]
| [deleted]
| teddyh wrote:
| "LISP is worth learning for a different reason - the profound
| enlightenment experience you will have when you finally get it.
| That experience will make you a better programmer for the rest
| of your days, even if you never actually use LISP itself a
| lot."
|
| -- <http://www.catb.org/~esr/faqs/hacker-howto.html#skills1>
| gjvc wrote:
| Still working and waiting for that profound enlightenment
| experience. Still hopeful.
| jimbokun wrote:
| Maybe you had already picked up the concepts of Lisp from
| other languages.
|
| Although the approach to macros is still quite distinctive.
| To the point that if a language has Lisp like macros, it's
| probably considered a Lisp.
| ra1231963 wrote:
| [flagged]
| dang wrote:
| HN is doing great if it has all the Lisp and Haskell users.
| [deleted]
| jurgenaut23 wrote:
| 23 years old, add the date please
| bradrn wrote:
| (1999), that is.
| Narishma wrote:
| I think it's older than that going by this quote from the
| first chapter.
|
| > The Lisp development systems on both my Mac and my PC run
| comfortably in anywhere from 4 to 8 megabytes of RAM. Less in
| a pinch. The integrated C++ development environments take
| anywhere from 12 to 20 megabytes. Both have comparable tools
| and facilities.
| [deleted]
| lukego wrote:
| Probably pretty up-to-date, then :)
| theshrike79 wrote:
| Too bad, I was actually excited to see what kind of problem
| would benefit from Lisp in the 2020s
| pjmlp wrote:
| Anyone relying on a dynamic language with state of the art
| compilers instead of rewriting code in C and Fortran for
| usable performance.
| moonchild wrote:
| Extant lisp compilers are not 'state of the art'; that they
| are is a bad meme. SBCL certainly attains very usable
| performance, though.
| pjmlp wrote:
| They certainly are, when compared with many alternatives.
| moonchild wrote:
| Which alternatives? Sbcl:
|
| - Requires manual type annotations to achieve remotely
| reasonable performance
|
| - Does no interesting optimisations around method
| dispatch
|
| - Chokes on code which reassigns variables
|
| - Doesn't model memory (sroa, store forwarding, alias
| analysis, concurrency...)
|
| - Doesn't do code motion
|
| - Has a decent, but not particularly good gc
|
| Hotspot hits on all of these points.
|
| It's true that if you hand-hold the compiler, you can get
| fairly reasonable machine code out of it, same as you can
| do with some c compilers these days. But it's 80s
| technology and it shows.
| bo-tato wrote:
| It seems with the massive amounts of money and full time
| engineers JVM has to be far more advanced technically,
| but does it actually make a difference? I don't know
| anything about compilers I just know LuaJIT is faster
| than any dynamic language on the JVM, SBCL is much faster
| than lisp on the JVM, chez scheme is much faster then
| scheme on the JVM, pypy is faster than jython. For
| statically-typed GC languages that should be comparable
| to Java, Go and Ocaml are famous for having very simple
| and fast compilers (fast as in they compile quickly
| without doing much optimization) and they don't perform
| any worse than Java.
| pjmlp wrote:
| First of all you're missing Alegro and LispWorks.
|
| Secondly, we are speaking about dynamic languages over
| here, that keep using C and Fortran.
| mm007emko wrote:
| I have LispWorks (I like the IDE) and although the
| hybbyist, non-commercial licenses are not out-of-reach
| for many (if not most) people, many (even companies)
| prefer running on free-of-charge stuff. My current
| employer doesn't even pay for PyCharm (main language at
| my current workplace is Python) and they are dirt cheap
| compared to e.g. Microsoft MSDN Subscription.
|
| I didn't stress the garbage collector enough so I can say
| that LW is faster or slower than other CL
| implementations. I'm currently doing an algorithmic
| research where the strain on garbage collector is not
| really that big, it's mainly about numerical performance
| and SBCL is by far the best from what I tried - LW, SBCL,
| CCL, Clisp, ABCL, ECL. Garbage collector takes usually
| 1-2% of run time which isn't that bad. I suppose that if
| I stressed it more than LW garbage collector would
| outperform SBCL but that's only my theory based on target
| audience of LW.
|
| If you have experience with Allegro and LispWorks and can
| compare it to other implementations, could yous hare it,
| please? I'm quite curious. There isn't much on the
| internet about this topic.
| moonchild wrote:
| I agreed with you that sbcl has usable performance (like
| c and fortran compilers). I disagreed that its
| performance is state of the art or particularly
| commendable.
|
| Are allegro and lispworks appreciably better? My
| understanding was that lispworks, at least, forked from
| cmucl a long time ago and put less work into python than
| sbcl did.
| sillymath wrote:
| What language don't require type annotations to achieve
| good performance?, more specifically tell me any
| programming language that can beat sbcl at speed without
| using type annotations.
| moonchild wrote:
| self, javascript (v8), java (hotspot; generics are
| latently monomorphised according to hotness; also see
| 'invokedynamic'), apl (apl\3000)
| AnimalMuppet wrote:
| I don't think you can say that java "doesn't use type
| annotations".
| tmtvl wrote:
| Well, technically you do have the _var_ keyword now.
| var x = MyAwesomeClassFactoryBeanTemplate.getBean().getFa
| ctoryInstance().createNewMyAwesomeClass(foo, bar);
| kirankp89 wrote:
| I am not super familiar with Java but that syntax
| typically implies type inference, which is not the same
| as not needing type annotations.
| bcrosby95 wrote:
| Not only is it type inference, it's limited to locally
| declared variables.
| hayley-patton wrote:
| Not having used them, I'd expect the Truffle
| implementations of Python and Ruby to do well, seeing as
| Graal handles #2-5 of moonchild's list. From there #1
| might fall out. (Apparently the fancy GCs for #6 are only
| in the Enterprise Edition though?)
|
| I'm working on a better, parallel but still far from Java
| state-of-the-art GC for SBCL
| <https://zenodo.org/record/7816398> - which presumably is
| some skin in the game.
| anthk wrote:
| Yeah, state of the art GC, but SBCL and ECL run circles
| on performance compared to any Java turd, even if being
| AOT compiled with GRAAL.
|
| Just compare the Nyxt web browser with any Java monster
| out there.
| hayley-patton wrote:
| Do they? I had to help SBCL with bounds checks (read:
| disable them) when porting the Java NonBlockingHashMap to
| Common Lisp. Perhaps still too micro- a benchmark, and
| I've indeed made turds with Spring, but the rest of
| HotSpot would do wonders on non-turd programs. (Would
| also expect Graal with JIT to be faster than AOT after
| warmup, but no experience there.)
| mm007emko wrote:
| I use SBCL for research in nature-inspired algorithms. Not
| only you can use the same fast linear algebra libraries
| (BLAS, Lapack) as for instance NumPy does, recently they
| added support for SIMD instructions so you no longer have
| to call C or ASM code for vector (and matrix) computations
| if you have only a couple of small matrices and not on the
| "hot path" of your program. Most of the Common Lisp
| implementations used nowadays produce native code (or C or
| LLVM code which will be natively compiled).
|
| So you don't have to rewrite anything. Nowadays ML stuff is
| usually about matrix multiplications in its core so Python
| with NumPy (or a Cuda library) also delivers good enough
| performance. The native code is already there, just call
| it. You don't have to write it.
| pjmlp wrote:
| Yeah, on a very niche use case.
| avodonosov wrote:
| Also Practical Common Lisp: https://gigamonkeys.com/book/
| dang wrote:
| Related:
|
| _Successful Lisp: How to Understand and Use Common Lisp_ -
| https://news.ycombinator.com/item?id=2087140 - Jan 2011 (7
| comments)
|
| _Successful Lisp: How to Understand and Use Common Lisp_ -
| https://news.ycombinator.com/item?id=1032553 - Jan 2010 (9
| comments)
| j_m_b wrote:
| In the web-app/API dominated world of modern software development
| what advantages and tradeoffs would a CL have over Clojure?
| schemescape wrote:
| I'm definitely not qualified to answer, but other than not
| needing to worry about having a Java runtime environment, my
| impression is that Clojure doesn't have a CL-like
| condition/restart system that allows for things like
| interactively dealing with errors and re-running/redefining
| functions in the middle of experiencing an error.
|
| CL also has multiple dispatch and I'm not sure but I don't
| think Java supports that.
|
| I'm curious to see other responses. I'm also interested in the
| reverse: why Clojure over CL? (I assume integration with Java
| and immutable data structures, but there's probably more.)
| cyberbanjo wrote:
| Java I am unsure about, but Clojure does support multiple
| dispatch https://clojure.org/reference/multimethods
___________________________________________________________________
(page generated 2023-05-14 23:00 UTC)