[HN Gopher] Understanding the Power of Lisp (2020)
       ___________________________________________________________________
        
       Understanding the Power of Lisp (2020)
        
       Author : susam
       Score  : 47 points
       Date   : 2022-01-02 18:36 UTC (4 hours ago)
        
 (HTM) web link (joshbradley.me)
 (TXT) w3m dump (joshbradley.me)
        
       | mark_l_watson wrote:
       | While I don't disagree with Josh's blog, concentrating on just
       | language features leaves out the style of Lisp development:
       | bottom up REPL style development. When I have to use Haskell or
       | Python, I find myself working as if I were using Lisp: I still
       | favor the REPL and building up from primitive functions to the
       | top level application. This is probably a bad habit but it is the
       | way I work. BTW, using the standard Emacs support for Python
       | works very well: load a file, then re-evaluate just changed
       | classes and functions (not Lisp, but a good work flow anyway).
        
         | convolvatron wrote:
         | do you struggle with bottom-up-Haskell? I always associated
         | Haskell with a very opinionated top-down process
        
           | tikhonj wrote:
           | I've done a lot of Haskell, and my approach tends to be a mix
           | of the two. There's a natural split:
           | 
           | * types let me play with the architecture and interfaces top-
           | down
           | 
           | * the REPL lets me write more complex logic bottom-up
           | 
           | Usually there are a few "hotspots" in the codebase that
           | require a lot of logic and are easier to develop bottom-up;
           | the rest of the codebase is focused more on organization,
           | domain modeling and information flow, where top-down design
           | works really well. In actual practice I expect my mode tends
           | to vary even more than that, but this division seems like a
           | good approximation of how I think about it.
        
           | mark_l_watson wrote:
           | I like Haskell, but my Haskell skills are weak. I experiment
           | in the REPL to see what works and then write functions in an
           | editor. Also, I like writing pure Haskell code, and when I
           | need to do network or file access, etc., then I find
           | appropriate code on the web that I can learn from. So, my use
           | of Haskell is fairly simplistic. I even wrote a very short
           | book using the small subset of Haskell that I am comfortable
           | with and use for my own projects.
        
             | exdsq wrote:
             | When I worked in Haskell I always found a type-driven top-
             | down approach helped me work out what I needed to do
             | literally starting from something like _App :: Input - >
             | Output_
             | 
             | Out of interest where are you working such that you're
             | using Lisp? Pretty sure I've actually asked you before ha,
             | but can't remember. Every-time I get burned out with
             | frameworks and polygot development I end up daydreaming of
             | using a stable language like common lisp for the remaining
             | ~40 years of my career.
        
               | mark_l_watson wrote:
               | I have used Common Lisp for a ton of paid work since
               | 1982. That said, in the last 7 years people have paid me
               | to do deep learning work, so that work uses Python.
               | Follow the money.
               | 
               | I am deeply bound up in Common Lisp because of my
               | history. However, if I may make a suggestion: you might
               | want to take a careful look at Racket: easy to make
               | standalone apps, good libraries, large community, and if
               | you don't like Emacs, the Racket IDE is really pretty
               | good. Sit in on one of the online Racket conferences to
               | see many kinds of cool applications and libraries people
               | use Racket for.
        
         | klipt wrote:
         | I feel like the bottom up style is possible in static languages
         | like C++ too, except instead of manually testing small
         | functions in the repl, you can write small unit tests for them
         | instead. In a way it's even better because a test written once
         | can be run many times, while testing in the repl requires a
         | manual test with every change.
        
           | jlarocco wrote:
           | That works in Lisp, too though, but it's easier and faster to
           | run the tests in the REPL, so you get the best of both
           | worlds.
           | 
           | When I write Lisp I usually start testing in the REPL,
           | iterate until the test code gets to be a few lines long, and
           | then copy it over to the package's unit tests. Then I can
           | keep iterating on both the test code and the code being
           | tested.
           | 
           | I'll do something like this in the REPL:
           | (ql:quickload :mylibrary.test) (mylibrary.test:my-test-
           | function)
           | 
           | "mylibrary.test" will depend on "mylibrary", so quickload
           | will load both packages when they've been changed, and I can
           | re-run the test quickly using Alt-P to call up the previous
           | REPL input.
           | 
           | And the REPL is also really great for "what if" testing that
           | you may not want to keep forever, like, "What happens if I
           | call this function with an invalid parameter?" Hopefully
           | there's a test for that, but it's often a lot faster to just
           | call the function and see what happens rather than go dig
           | through the test code and lose your focus.
        
           | gumby wrote:
           | This is how I develop in C++, though I am a Lisp programmer
        
           | nwallin wrote:
           | constexpr and static_assert make this a ton easier in C++. If
           | your "unit tests" are static_asserts, the IDE will just
           | highlight the broken parts.
           | 
           | C++17 made this minimally useful, and things got
           | spectacularly better with C++20 and constexpr vector/string.
           | 23 is shaping up to move even more of the standard library to
           | constexpr.
        
       | theamk wrote:
       | A fun exercise when reading posts like those is to mentally
       | compare to TCL. It is somewhat uglier - TCL's lists are multi-
       | valued; and newlines are signficicant, introducing difference
       | between "script" and "command".
       | 
       | Still, the basic eval command looks remarkably similar in lisp vs
       | TCL.
        
       | phoe-krk wrote:
       | The thing is that trying to understand "the power of Lisp" via
       | the toy interpreter from The Roots of Lisp[0] is like trying to
       | understand "the beauty of the sea" after seeing a single five-
       | minute YouTube video explaining it.
       | 
       | It will give you the basic idea, but it won't tell you about
       | macros, reader macros, compiler macros, and having the whole
       | language always available to build your abstractions on; it won't
       | tell you about CLOS, including multiple dispatch, metaclasses, or
       | method combinations; it won't tell you about the condition system
       | and programming from inside the debugger; it won't tell you about
       | live recompilation and live coding; it won't tell you about the
       | JVM interoperability of Clojure, Kawa, or ABCL; it won't tell you
       | about Racket's tower-of-languages approach to programming; I can
       | keep on going for a while. And, since most Lisp dialects and
       | implementations are nowadays compiled, either to native code or
       | to bytecode, the just-interpreting approach doesn't even work
       | very well.
       | 
       | Articles like this are fun, but they end up completely missing
       | the point. This isn't "the power of Lisp"; it's just the very,
       | very, very beginning. The rabbit hole goes much deeper.
       | 
       | [0] http://www.paulgraham.com/rootsoflisp.html
        
         | rmbyrro wrote:
         | I've learned Clojure. Tried and failed to see this unique power
         | of macros.
         | 
         | Truly asking for help: can you help explain what can I do with
         | macros that I cannot do with functions? Or, maybe, cannot do
         | with high quality or low complexity using functions?
        
         | agumonkey wrote:
         | here's how to leverage the pretty printer to transpile lisp
         | into pascal https://merl.com/publications/docs/TR93-17.pdf
        
           | phoe-krk wrote:
           | TIL. This is cursed. Have an upvote.
        
             | agumonkey wrote:
             | Hey, I didn't even realize who I was answering to. Btw
             | there's a part 1 online too
             | https://merl.com/publications/docs/TR91-04.pdf
        
               | phoe-krk wrote:
               | _> Hey, I didn 't even realize who I was answering to._
               | 
               | The best kind of comments are the ones which respond to
               | the _what_ as opposed to the _who_. :D
        
             | [deleted]
        
           | gumby wrote:
           | That's hilarious to me because I remember someone at UT wrote
           | a pascal compiler in Lisp so TeX would run on the lispm.
        
       | vincent-toups wrote:
       | I'm programming in Lisp (Chez Scheme) now.
       | 
       | I've been a serious Lisp programmer (recreationally and sometimes
       | professionally) for around 10 years and I have programmed in
       | Common Lisp, Scheme, my own weird dialects, Emacs Lisp, etc.
       | 
       | At this point I feel like almost everything written about Lisp is
       | silly. Taken as a language family as a whole, there isn't much
       | that separates Lisp from most of the other languages that are out
       | there _except_ syntax-transformations or macros which, frankly,
       | most people should never use.
       | 
       | For me, the best thing about Lisp is the regularity of the
       | syntax. What I like least about almost all other programming
       | languages is all the useless syntactic doodads and wingdings. The
       | brackets, the indentation sensitive stuff, the unneeded
       | complexity that languages insist on associating with what is and
       | must be the denotation of a tree, in the end.
       | 
       | The other great thing about the language is that you must use
       | `let` or `lambda` to introduce variable bindings and their scope
       | is, therefore, always perfectly clear.
       | 
       | Despite these niceties, Lisp isn't going to make you into a super
       | programmer. It won't really help you solve hard problems. It
       | might help you quickly solve easy problems, but in the end, most
       | of the job of a software engineer is grappling with conceptual
       | problems with which Lisp is only sort of helpful.
       | 
       | As long as I'm holding forth, I will say that I enjoy programming
       | in Scheme _much_ more than I enjoy Common Lisp, which feels
       | incredibly, uselessly, and old-fashionedly complex with all sorts
       | of weird corners to stub your toes on.
        
         | [deleted]
        
       | dreamcompiler wrote:
       | Note that the examples in the "cdr" section are incorrect.
       | (cdr '(x a))       ; does not return a, it returns (a)
       | (cdr '((x a) y))       ; does not return y, it returns (y)
       | (cdr '((x a) (y b)))       ; does not return (y b), it returns
       | ((y b))
        
         | DonaldFisk wrote:
         | The author might be new to Lisp, and I hope what I write
         | doesn't discourage him. There are some other mistakes:
         | ((ab . c) . d . nil)
         | 
         | isn't a valid s-expression. Maybe it should be
         | ((ab . c) d . nil)
         | 
         | Also,                   (eq '(a b) '(a b))         ; (a b) is a
         | list and cannot be evaluated by eq
         | 
         | eq works fine on lists. It returns T iff its arguments are the
         | same object (i.e. are at the same memory location, or are small
         | enough integers or floats). If they're copies (as is the case
         | in the above), it returns NIL. If this isn't what you expect,
         | you should probably be using equal.
        
           | lispm wrote:
           | don't count on (eq '(a b) '(a b)) being NIL. In Common Lisp
           | it can be T. From what I read of Racket, it could be true,
           | too.
        
       ___________________________________________________________________
       (page generated 2022-01-02 23:00 UTC)