[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)