12 ms·
A road to Lisp: Why Lisp
- AlexeyBrin 2mo agoThe website seems to have a bug with syntax highlighting. Pieces of code included in the post text are black, you can still see the actual text if you select it with your mouse. Same bug on Chrome desktop and on Safari on iPad
- jdw64 2mo agometoo
- dsizzle 2mo agoMy first thought was that the article was redacted lol
- hermitcrab 2mo agoI get this on both FF and Chrome.
- cjm42 2mo agoThis is the classic example of why you should always set the foreground color when changing the background color. Otherwise you end up with <code> blocks that are black-on-black. It probably works fine if your browser is in dark mode. A workaround is to open one of the code elements in the browser's debugger and add color: white to the :not(pre) > code style.
- harshreality 2mo agoMacOS Chrome? The code blocks look fine to me in linux {firefox, chromium, brave}. I think they're all using Qt.
- lgas 2mo agoLooks fine to me in Chrome on Mac.
- AlexeyBrin 2mo agoNow, it looks fine to me too. I tested it in Chrome,Firefox, Safari on macOS and on Safari on an iPad yesterday when I wrote my comment and in all cases there were black lines all over the the place. The author corrected the problem, see https://news.ycombinator.com/item?id=48855382 https://news.ycombinator.com/item?id=48855382
- silcoon 2mo agoThanks for reporting. I fixed the error as soon as I read your comment.
- sroerick 2mo agoI must admit - I still don't understand macros. I get that they're code that's generated at compile time. But I don't understand how that's different than a function which evaluates other functions. I guess the latter would actually be evaluated at runtime? I think I get it conceptually but I'm not sure I have the muscle memory to reach for them. Anybody here have an "ah hah!" Moment with macros?
- wild_egg 2mo agoThere's a bit of a mental model flip to make maybe. > they're code that's generated at compile time They're code that generates code at compile time. Macros can actively walk the AST of the parameters they process and rewrite them completely into new shapes. That transformed AST is what then actually gets compiled.
- efficax 2mo agoSure, macros are functions that take functions as input, and produce new functions as output. But they take the function's symbols as input and produce a new set of symbols. So a macro can extend the syntax of the language without having to modify the core language system. Anyway, what's unique about Lisp macros vs say, Rust macros, or C style preprocessors, is "homoiconicity". The data structure that a Lisp macro takes as an input, the lisp code, is the same data structure that the language uses normally (S-expressions, lists...), so writing a macro requires few new language skills compared to writing normal lisp (again, compare writing Rust macros, a dark art in comparison).
- gf000 2mo agoAt the same time, you get a mushy tree as input, instead of a properly typed AST "object" with accessible "function name", "method parameters" everything that you can just refer to. It will be the third arguments' 2nd arg with s-exprs, following your arbitrary pattern you figured you want to use. So it's very arguable which is easier to use, sure for some "party tricks" lisps will win, for anything more useful my vote would go with rust/Scala macros for sure. So again, you win nothing by homoiconicity, the by-the-compiler implemented parse function is more complex in rust, which is 100% abstracted away.
- arikrahman 2mo agoAll roads lead to Lisp
- sph 2mo agoWhat has Lisp ever done for us?
- arikrahman 2mo agoThe aqueducts!
- vindarel 2mo agoFlight search (Google's ITA Software), underground planning (SISCOG), CAD software (PTC Creo et all), the Gollum face (Mirai), automation of document extraction, renewable energies resource planning (3E), project management (planisware), games (Kandria), Maxima, a faster pgloader (https://tapoueh.org/blog/2014/05/why-is-pgloader-so-much-faster/ https://tapoueh.org/blog/2014/05/why-is-pgloader-so-much-fas...), hackernews (was rewritten to SBCL: https://lisp-journey.gitlab.io/blog/hacker-news-now-runs-on-top-of-common-lisp/ https://lisp-journey.gitlab.io/blog/hacker-news-now-runs-on-...), first reddit… https://lisp-screenshots.org/ https://lisp-screenshots.org/ https://www.lispworks.com/success-stories/ https://www.lispworks.com/success-stories/ also Emacs (for another dialect).
- deleted 2mo ago[deleted]
- sph 2mo agoYeah but apart from SBCL, Viaweb, Hacker News, Emacs, Clojure, Scheme, Racket, garbage collection, macros, homoiconicity, the REPL, S-expressions, symbolic computation, what has Lisp ever done for us?
- dang 2mo ago...booleans, conditional expressions, first-class functions, lambdas, closures, eval...
- zbentley 2mo agoThere are some truly powerful and unique things about Lisps, but I wish articles like this would stop including REPLs and hot-reloading. The former have been table stakes for interpreted languages (and some compiled ones!) for years, and the latter is neither unique nor particularly widely used (hot reloads have to tangle with state and patching, so resetting the world for ease of reasoning is considered a best practice for a reason).
- taeric 2mo agoLargely agreed. I do think it is worth highlighting how many advanced parts of hot-reloading have already been covered in Common Lisp. Same with highlighting how the REPL is largely not used to directly type into, but is instead a very powerful interface for tools to interact with a running image. But, again agreed that simply these existing are not that notable today.
- spinningarrow 2mo ago> The former have been table stakes for interpreted languages I used to think so too back in the day when I was getting into Clojure. It was much later when I realized that when Lisp people talk about the REPL they’re usually talking not so much about the interactive CLI where you can evaluate commands easily but more so the ability to connect your program to a live session where you can quickly evaluate forms within your text editor and in the context of your running application, which enables much more interactive development than in other interpreted languages.
- dismalaf 2mo agoYou've been able to do this in Ruby since I can remember. Not a lot of editors take advantage of it though...
- iLemming 2mo agoNo. There is real, palpable, practical, functional difference between working a Lisp REPL and a REPL in a non-homoiconic languages - Ruby, Python, Haskell, etc. Every single stage there in Read-Eval-Print-Loop differs. Man, it gets so exhausting trying to convince every PL critic who grabs a single (or a couple) of axis of any language and tries to dispute the value of a language without ever understanding the holistic, overall experience working with it. Like, I don't understand, do people think that tons of Clojurians or Common Lispers who fall in love with the language after decades of working and getting seasoned in literally dozens of different PLs are on some kind of delusional trip or something? Guys, just take a gander at Clojurians Slack; see what people are working on, what kind of stuff they're building; check their profiles. Many of them are the battle-scarred veterans of coding. Sure, some of them may have wrong opinions, but surely they can't be all wrong, can't they?
- BellsOnSunday 2mo agoI thought this was going to be https://web.archive.org/web/20120106121645/http://wiki.alu.org/The_Road_To_Lisp_Survey https://web.archive.org/web/20120106121645/http://wiki.alu.o.... Brings back memories of following comp.lang.lisp, not least as a sort of soap opera. Lots of characters and drama, as well as programming wizardry.
- GMoromisato 2mo agoProgramming is in tension between the Light Side and the Dark Side. The Light Side is about preventing the programmer from making mistakes: Get rid of go-tos! Add static types! Do not allow a bug to be expressible. The Dark Side is about giving power to the programmer: Macros? Obviously. Operator overloading? Self-modifying code? Multi-line reg-exps? Go to town! The Light Side knows programmers are flawed and imposes constraints. The Dark Side trusts programmers with power. Neither side is correct all of the time, and a good programmer learns both. Lisp is interesting in that it is clearly Dark Side programming (the programmer can do anything) but it's still admired by Light Side programmers. Maybe there's something about the simplicity of the language that makes it seem platonic--almost incorruptible. Or maybe Lisp is so pure that it embodies both Light Side and Dark Side, like a god that spawned the programming universe.
- rogue7 2mo agoKind of agree, but in my view preventing the programmer to make mistakes is futile. I have seen awful stuff in languages made to prevent errors. It's much better to give all the power to the programmer, to allow him to fix his mistakes rather than fantasising about preventing them.
- pfdietz 2mo agoI'm not big on static type checking in most situations -- adequate testing should find the type errors too -- but one place it looks very useful is avoiding data races in multithreaded programs. See Rust.
- bigpeopleareold 2mo ago... or Ada.
- malkia 2mo agoHah, didn't think of it this way... To me it was if it allows live updates (+support for them) or not :)
- 2mo ago
- malkia 2mo agoI've been wondering - Is lisp (common lisp, clojure, scheme) easier for iterative work with LLMs?
- gentooflux 2mo agoI've found LLMs to be bad at balancing parenthesis. I've also found them to be less likely to hallucinate library types in dynamic languages, they tend to hallucinate arguments to library functions/methods instead.
- iLemming 2mo ago> LLMs to be bad at balancing parenthesis Because you treating Lisp just like any other (non-homoiconic) PL. Give an agent a true Lisp REPL to mess around, and you'd be surprised. Things get very interesting. I still don't understand why more people don't do that - isn't that obvious first thing anyone should figure out? Like I can't even imagine working with Lisp without a REPL and structural editing - I'd immediately fail at balancing parens. Why do you expect a [dumber] machine would do any better?
- klibertp 2mo agoYeah. In my GToolkit setup, I started with giving it eval. At first, it tried to "rebuild the world" for each task, but we gradually settled on a set of images for specific tasks that can be rebuilt as a separate step and are otherwise cached. That gave us fast eval, and it kinda snowballed from there. I thought I would need to implement some IPC into a live image, but the startup is fast enough that it doesn't matter too much. The agent now has both the textual source (in Tonel) on disk and can easily query a live image via CLI. What do you think about making the agent write type annotations? There are built-in forms in CL, and in Smalltalk, I settled for pragmas for now. They are not checked, but since I started using them, I think the rate of one- or two-shotting solutions has gone up.
- mechanicum 2mo ago> I've found LLMs to be bad at balancing parenthesis. I think that was true last year. In my experience, it’s no longer the case with Claude Code or Codex.
- klibertp 2mo ago> So why Lisp (or when) > [...] among its extensibility, its interactive environment, the REPL, and a lot of other features we haven’t touched yet. It is the combination of all of them that makes Lisp programming what it is. Agreed. However, although the alternatives are few, they do exist. Today, I'd like to convince you (whether you're OP or a commenter) to give one of them a try. I'm talking about GToolkit[1]: Smalltalk/Pharo-based reimagining of Smalltalk as a productive environment for modern system design, analysis, and implementation. It's based on Pharo and its VM, but with GT-specific extensions and replacements, developed on GitHub in both Smalltalk and Rust. I used both Common Lisp and Smalltalk over the years for some of my side projects. Technically, the environments are comparable: image-based, live, interactive development is central to both. Lisp is easier to fit into modern workflows: it's still just files on disk. If you ignore the REPL and treat the image as a bundler, you can have a Java- or Python-like development workflow. You can gradually adopt the more interactive ways of working with the codebase. Smalltalk was historically more of an "all or nothing" approach, but nowadays it supports Git-based workflows as first-class, with GToolkit providing additional tools directly. GT is tied to a single IDE, but that IDE is genuinely powerful, pragmatic, and easy to customize: the entire IDE is Smalltalk code[2] that lives in the image beside your code, so you can live-edit any part of it at any time. The languages differ, most obviously in the object model (single inheritance and message sends in Smalltalk, and multiple inheritance with multimethods in CLOS), but I don't think one is strictly better than the other for the vast majority of code. You just need to structure your code differently. Both systems are very dynamic, so neither is like Java or C++. After quite a few projects in both, I am convinced that this difference doesn't matter. Both languages have very simple syntax. Smalltalk doesn't have macros; instead, it has an extensible/replaceable compiler for method bodies. This capability is used, for example, for compiling grammars into parsers/lexers in SmaCC. It's not as convenient for control-flow abstraction as CL's macros, but Smalltalk tends to make them out of blocks (lexical closures with non-local exits) plus actions on thisContext. In practice, I never found either language too limiting in what I could express, and both have small, regular basic syntax. TL;DR: Common Lisp and GToolkit Smalltalk offer comparable technical merits, with the most pronounced difference being GT's built-in, high-quality IDE, which open source Lisp lacks. The IDE (and the capability to build cross-platform, but natively rendered GUI apps) is the major selling point of GToolkit, but the bigger reason to consider it is social. Lisp had a bit of a renaissance from 2005 to 2015, but ~it has since died down~ (EDIT: After checking a bit, it's more like there are similar levels of development now, but it's just varied, and I personally hit a few areas where nothing new happened for a while. Or in other words, the hopes of CL getting catapulted to mainstream by the wave of adoption didn't materialize, and the adoption seems to have largely plateaued, with a slight upward trend since then.) A lot of great things for Lisp appeared in that time: ASDF and Quicklisp being prime examples. Unfortunately, the momentum was lost, and since then, the rate of development has plummeted. It's still a solid proposition because of its stability, which means a lot of old code still works perfectly well, but it's a double-edged sword: it would take a hundred miracles in a row for CL to get a plausible M:N concurrency story, for example. This isn't true for Smalltalk, and doubly so. There's a small but active community around Pharo, mostly academics and hobbyists (IME; and it's from a decade ago, so YMMV). Pharo itself is already a "Smalltalk-like" language, and it regularly gets features that are not in original Smalltalk (stateful traits and slots (reification of class and instance variables) are good examples). It continues to evolve, and each version brings notable improvements to the language, the VM, and the class library. In CL, since there are many implementations maintained by various groups and the standard is set in stone, adopting extensions to the standard is incredibly hard and time-consuming. You can, of course, commit to a single implementation, but there are only 2 or 3 implementations that are actively developed and trying to do something "new"; they are all experimental and incomplete. And while SBCL has quite a few nice features, its codebase was a bit hard for me to grok (read: days on end of banging my head against a wall, then giving up; I'm much more comfortable messing with Smalltalk bytecode compiler). Secondly, GToolkit is driven by a group of coders[3] who have established a profitable consultancy. It's being developed around a single vision that the authors swear helps them achieve their projects' goals. Even if you're not sold on moldable development[4] as a methodology, GToolkit gives you all the tools you might need in a modern development and then adds tons of domain-specific tools and utilities that might be useful after just a bit of adjustment. The whole environment is built to make such adjustments as painless as possible, too. The only problem I experience with GToolkit is the lack of structured, book-like documentation. The GToolkit book is closer to the PHP wiki or a bundle of tutorials than something like the Rust book. It's not that the docs aren't there - they often are, but finding them effectively is a bit challenging. I found that simply cloning all the repos that GT consists of (tens, if not hundreds, but there's automation for that) and pointing an agent to the directory with them is often enough to quickly find what I'm looking for (if the built-in Spotter fails and I'm too lazy to construct an in-image search). TL;DR: GToolkit/Pharo move much faster than the CL world, and while the number of maintainers might be similar (honestly hard to estimate, though), the effort on the GT side is more centralized and, in my opinion, heads in a better direction. If you want an extensible, live, dynamic environment that shares many of Common Lisp's strengths, but is more polished, more actively maintained, and feels more modern, take a look at GToolkit. (Disclaimer: no affiliation, just a programmer who likes to explore unpopular languages). [1] https://gtoolkit.com/ https://gtoolkit.com/ [2] Some parts are implemented as Rust dynamic libraries and called from Smalltalk via FFI. [3] https://feenk.com/ https://feenk.com/ [4] https://moldabledevelopment.com/ https://moldabledevelopment.com/
- abetusk 2mo agoThere are many articles extolling the virtues of Lisp. I would like to see some articles that have a level-headed criticisms or critique of Lisp, it's ideas and it's place in the ecosystem of languages. Articles like this, and the PG articles it references, amount to "if you know, you know". I understand the appeal and I understand the explicit and implicit arguments this article is making. Computer programming has matured quite a bit in the past 60 years. I would like to see more articles that are more considered in their examination.
- erichocean 2mo agoHere you go: https://www.marktarver.com/bipolar.html https://www.marktarver.com/bipolar.html It's been discussed many times on HN.
- dang 2mo agoand strangely relevant again in the age of LLMs - https://news.ycombinator.com/item?id=48126840 https://news.ycombinator.com/item?id=48126840
- patrec 2mo agohttps://www.tamaspapp.eu/post/common-lisp-to-julia/ https://www.tamaspapp.eu/post/common-lisp-to-julia/
- coffeemug 2mo agoAs a language Lisp is great (though the ecosystem is limited). It has two flaws-- it's very open-ended so unless you're talented and disciplined you can fall into a rabbit hole of hacking fun Lisp stuff and not actually getting any work done. Other languages have this problem, but Lisp I think more so. The second flaw is that it eats perfectly capable minds for years and the results don't justify the time investment. Python or whatever is fine. I wish I took most (but not all) of the time I invested in Lisp and put it into something else instead.
- vkazanov 2mo agoHeh, i want to both disagree and agree. I started with pascal and then C++. And then discovered Emacs and Lisp. Boy, that was a revelation! Never ever in my life shipped a line of lisp code to production. My real life code was always Python or C++ or Java or C. All of my lisp was toys and emacs tweaks (50k loc in my config!). But most of production code is gone from my life. I am a mid-level engineering manager now. I mostly write texts, or messages, or emails, or slides... and still use emacs and lisps for fun and profit and competitive programming. Not a single production-grade lisp LOC in 20+ years. But, OTOH, i contributed to emacs, tinkered with compilers and interpreters and prog. lang. internals - all because Lisps made it interesting for me. And, in a way, this brought me closer than ever to the job of my dreams: i work for a major player in static analysis space. So yes, you are right and wrong at the same time.
- frwrfwrfeefwf 2mo ago[dead]
- frwrfwrfeefwf 2mo ago[dead]
- GMoromisato 2mo agoOf course you feel this way. You just finished reading SICP or maybe you binged PG essays last weekend. But eventually you'll read Simon Peyton Jones and start screaming about functional programming and algebraic type systems. Then, if you're lucky, you'll get a real job and realize that languages are just a tiny part of software engineering. I'm excited for you to experience that journey.
- throwaway81523 2mo agoWadler's old article comparing Miranda (a Haskell forebear) to Scheme might be a better place to start. https://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.pdf https://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87....
- jimbokun 2mo agoThis was a very pleasant read.
- jake_and_fatman 2mo agoI see what you did there. "Of course that's your contention. You just got finished readin' some Marxian historian -- Pete Garrison probably. You're gonna be convinced of that 'til next month when you get to James Lemon, and then you're gonna be talkin' about how the economies of Virginia and Pennsylvania were entrepreneurial and capitalist way back in 1740. That's gonna last until next year -- you're gonna be in here regurgitating Gordon Wood, talkin' about, you know, the Pre-revolutionary utopia and the capital-forming effects of military mobilization." Good Will Hunting (1997)
- mindslight 2mo agoDo you like Apple ]['s? You've got a good point. Code generally needs to be read more than it is written. At the very least, you realize this as you try to revisit something you had done previously and are left scratching your head. Encapsulating the complexity in a custom DSL can be great for simplifying all the code you write in the DSL. But it also raises the stakes - if you ever have to revisit the DSL implementation the complexity is there lurking.
- frwrfwrfeefwf 2mo ago[dead]
- awolven 2mo agoI've been programming Lisp too long to appreciate it's features. It is not until I watch in shock and horror how people sabotage themselves in the popular and economically less risky languages that I suddenly come to appreciate Lisp again.
- frwrfwrfeefwf 2mo ago[dead]
- kensai 2mo agoMy question always remains. Which variety/implementation of Lisp is it worth it to learn as a hobbyist and which as a professional?
- wk_end 2mo agoAs a professional - assuming you mean “which can I put on my resume to get a job working in that language” - probably (not necessarily!) none, or maybe Clojure. As a hobbyist, probably all of them. It’s worth at least trying to go through SICP in Scheme (use Racket with the SICP language), it’s worth learning CL (use SBCL) to fully appreciate everything the Lisp world has to offer without compromises, it’s worth learning Clojure because it’s, frankly, a little bit cleaner and more elegant than CL in many respects.
- silcoon 2mo agoNext week I will try to answer your question with a new post. Stay tuned!
- frwrfwrfeefwf 2mo ago[dead]
- deterministic 2mo agoI would be very interest in seeing how "getting lisp" enables you to write software that is more successful than the C and C++ software that runs the world. Perhaps you have written software in Lisp demonstrating this? Something you can show us?
- __patchbit__ 2mo agoThe reference text on time keeping used to be implemented in Lisp. Alan Kay says a lot of problems with C/C++ go away when using the higher math more easily expressible in Lisp and like minded languages. Jürgen Schmidhuber says the problem with computers from a mathematician's point of view are the numbers.
- deterministic 2mo ago> Alan Kay says a lot of problems with C/C++ go away when using the higher math more easily expressible in Lisp and like minded languages That doesn't match my experience at all. Math and numbers are in general not a problem except when (say) implementing triangle hit detection in a game (something I did) where the precision of 32 bit floats does matter. > Jürgen Schmidhuber says the problem with computers from a mathematician's point of view are the numbers. That is probably true if you are a mathematician. Most people aren't. Having said that, LEAN (for example) is written in C++ and used heavily by mathematicians.
- anthk 2mo agoGo ate a big lunch from Java, C and a bit of C++ as a systems' language, which Go was designed as "C sucessor without the C++ bullshit". Even the most modern C (Plan9/9front, not what the ANSI C comitee vomits in every iteration) it's a very different beast. Still, Common Lisp it's in places where trying to build such kind of software in C/C++ would be a reciper for disasters. https://www.lispworks.com/success-stories/index.html https://www.lispworks.com/success-stories/index.html
- tehjoker 2mo agoI played a little bit around with LISP but I was astounded when I saw that you run programs using the live REPL. I thought, how can you reliably deploy a finished program if it can get messed with at any time? Why isn't there a way to compile to a binary?
- Jtsummers 2mo ago> I was astounded when I saw that you run programs using the live REPL. That's one way, you stopped too early in your investigation though. You can produce binaries, though the precise mechanism will vary by your implementation. And there's no reason to use the REPL for it. You can create an executable file with something like this: (defun main () ...) ; do whatever you need in here for program launch (sb-ext:save-lisp-and-die "my-program" :executable t :toplevel #'main) And then `sbcl --load program.lisp` (or whatever you name it) and it'll produce a binary for you. Other implementations will have other methods of achieving the same thing. Or, if you don't need a binary, you can have something like this: (defun main () ...) (main) And then run `sbcl --load program.lisp`. That will compile and execute it without ever invoking the REPL. (NB: Using a function named main isn't strictly necessary, I named it that for the example. Name it whatever you want.)
- tehjoker 2mo agoThank you, that's very helpful to know!
- greatony 2mo agoJust working a very powerful dynamic workflow feature in my agent product. And guess what, LISP is the one I chose for the generated workflow. LoL
- phyzix5761 2mo agoI'm working on a Lisp dialect which is far from done and changing every day but I thought I would share it: https://github.com/lodenrogue/hith https://github.com/lodenrogue/hith It uses python for the interpreter.
- vaylian 2mo agoNeat. What is the primary use case for this dialect?
- phyzix5761 2mo agoIts general purpose. For now I'm trying to build out all the basic language features. Once its built I'll use it as my daily driver for whatever I'm coding. It's a lisp so it can be used for anything since macros have been implemented. You can create your own syntax using macros.
- criddell 2mo agoI’m guessing there’s some way for a Lisp program to load a DLL and call a function in it so writing a Windows application using the Windows App SDK is likely possible. The one part I can’t imagine is how do you pass a Lisp function as a callback?
- rmunn 2mo agohttps://www.quicklisp.org/beta/UNOFFICIAL/docs/cffi/doc/Tutorial_002dCallbacks.html#Tutorial_002dCallbacks https://www.quicklisp.org/beta/UNOFFICIAL/docs/cffi/doc/Tuto... has some pointers (which might be harder to understand unless you have read the rest of https://www.quicklisp.org/beta/UNOFFICIAL/docs/cffi/doc/Tutorial.html#Tutorial https://www.quicklisp.org/beta/UNOFFICIAL/docs/cffi/doc/Tuto... first). The short version (which I might be mangling in my attempt to shorten it) is, since Lisp is so very good at creating code, you have your Lisp program create a C function that will be passed as the callback to the API. Then the C function that you created will convert the C data structures to Lisp data structures, and call the Lisp function with those Lisp data structures. If you're really good at Lisp, you can write that automatic-callback-creation function yourself. But if you're really, really good at Lisp, you will just use one of the ones that other people have already written, e.g. `define-alien-callable` from https://www.sbcl.org/manual/#Calling-Lisp-From-C https://www.sbcl.org/manual/#Calling-Lisp-From-C or some other similar FFI.
- pjmlp 2mo agoYes, Allegro Common Lisp, and Lisp Works support this just fine.
- frwrfwrfeefwf 2mo ago[dead]
- gf000 2mo agoAgain, fallacy by Turing completeness. It's actually harder to make something not Turing complete - in and of itself this property is absolutely useless and tells you nothing about how practical something is.
- ux266478 2mo agoThe inflection of the copula "can be" is exactly the problem, as is the 'anything computable'. There's a reason Isabelle is used as a proof assistant, and Prolog isn't. The former guarantees sound, mathematical rigor that can't be trivially violated. The latter doesn't. Prolog is much more powerful and flexible than Isabelle. Power and flexibility are disastrous for safety. As someone else said elsewhere in this thread, safety is about restrictions. In this case, it actually runs deeper than this, there are structural issues which prevent them from being sound right from the beginning. It's the mere fact that the whole behavior of your DSL can be silently changed without touching the module it's defined in, or the file it's being imported into. A well-meaning junior, in a completely different department, can completely destroy your invariants in a completely unrelated part of the codebase. Whether by shadowing runtime functions, or a package-level collision that exists upstream. Even Scheme's hygienic macros don't actually solve this, they just make it less likely. At the point in which you have no behavioral guarantees of semantics, you do not have a safety mechanism at all. > There is no 'evaluative indirection' because a macro is a _compiler_ and the underlying code can be extremely alien to the DSL semantics. This is a trivial contradiction. That is precisely evaluative indirection. Yes, stacking multiple compilers on top of each other, especially when their semantics are non-isomorphic, is a massive burden of mental overhead. Given you already have this problem with the mapping between Lisp and binaries, adding even more complicated layers on top of it is a recipe for disaster. Particularly because: you are going to make mistakes in your logic. Macros provide no means to stop you from blowing your own leg off when writing them. That is not what they are designed for. Finally, you cannot escape the awkwardness of the underlying metaprogramming system, you will always have to wrestle with quotation and quasiquotation. You have to define a DSL before you can use it. Only at the point in which you treat and use Lisp like an unserious toy, rather than the powerful tool that it is, can the fantasy of "macros are a safety mechanism" begin to make sense.
- holgerschurig 2mo agoIt's really fun: I read so many propaganda on Lisp here that by now we should all be coding in it. Don't we get perhaps weekly posts like this? But ... somehow almost everyone simply ignores this propaganda --- that's actually the way we ought to handle propaganda! Funny that it works with Lisp, but not with many political topics where it can be shown that propaganda really works. My experience with Lisp is somewhat special-cornered. I only know Emacs-Lisp, and that not great. And for me, Lisp an out, outdated and confusing thing. I don't know ANY other programming language that elected assembler mnemonics to be "high"-level expression: car and cdr. While I love Emacs, they claim all the time that is has 100% discovery through build in doc. But that is only 70% true. It doesn't exist in Lisp like it does in other languages. For example, I have an association list. Now, what functions exist that uses them? I can't use the equivalent for (dir alist), alist.dir(), or use some LSP for that. I can't even look in the symbols, because operators are written like assoc or assq with not logic. And then there are either prefixes to them (rassoc) or postfixes (assoc-string). That there is no namespace is soooo 1970. I mean, even Turbo-Pascal had namespaces. Typechecking is nonexistant. At least we have byte-compiling. And note that I don't croak about the parenthesis. While I find it mildy weird that I as a human program in almost-AST, Emacs has superp support for the parenthesis. So people croaking about them just had never had a good editor IMHO. Now, one can argue that Emacs Lisp != Common Lisp. But these propaganda articles don't tend to promote one specific Lisp, they only talk in generals. So I can apply this general principle and compare it to the tiny corner of these awful language family.
- Panzerschrek 2mo agoCan I write a game using OpenGL in Lisp?
- nmdev 2mo agoYes. Kandria [1] is a great example of someone doing exactly this. There's a bunch of information on the development here [2] and the code is open source [3]. [1] https://kandria.com/ https://kandria.com/ [2] https://reader.tymoon.eu/article/413 https://reader.tymoon.eu/article/413 [3] https://codeberg.org/shirakumo/kandria https://codeberg.org/shirakumo/kandria
- Panzerschrek 2mo agoInteresting. I didn't thought it's possible.
- peter_retief 2mo agoThe real test of a programming language is its readabilty. I looked at lisp many times and it just doesn't do it for me.
- _ph_ 2mo agoThat might be, on the other side, I consider Lisp highly readable, but quite a few modern languages quite unreadable. For example parsing type signatures with a complex syntax. Any style of writing you are not familiar with will require a lot of training. Try reading anything written in the Greek alphabet for example.
- peter_retief 2mo agoFair enough.
- BeetleB 2mo agoIf you've not grown up accustomed to C-style syntax, I assure you that C is less readable. Even a for loop is crazy in C.
- vindarel 2mo agoDon't miss out, we had new excellent editors and tools being released in the last months: Mine: a complete, single-download application that comes with everything needed to experience the interactive and incremental development programming workflow, including hot-reloading and on-the-fly debugging. For CL and Coalton. https://coalton-lang.github.io/20260424-mine/ https://coalton-lang.github.io/20260424-mine/ OLIVE: a new hand-made plugin for VSCode. ICL: a new REPL for the terminal and the browser with advanced features. as a bonus: a JupyterLite kernel based on JSCL that runs 100% in the browser. find them all: https://lispcookbook.github.io/cl-cookbook/editor-support.html https://lispcookbook.github.io/cl-cookbook/editor-support.ht...
- frwrfwrfeefwf 2mo ago[dead]
- gf000 2mo agoWell, compilers have layers - you ain't outputting assembly from the AST layer directly, usually there is some kind of IR. Like LLVM have plenty of layers. And for a simple DSL you can usually just use a sufficiently expressive language, no need for macros. Like kotlin/Scala has html DSLs that look pretty decent. For anything more complex though, you can't just "compose stuff", a type system is a global property so for that you literally have to write something way more complex than a local macro should contain.
- deterministic 2mo agoI use plenty of DSL's in my daily work maintaining 1 million+ lines of C++ code used by very large companies around the world. No macros needed or wanted. More than 90% of the production code is generated from DSL's. Outside of C++, Haskell has many great examples of powerful DSL's implemented without macros. The problem with macros is the compile/run time cost. I could have implemented those DSL's using C++ templates (which are Turing complete by the way) but I prefer not to.
- frwrfwrfeefwf 2mo ago[dead]
- gf000 2mo agoThere are plenty of languages with macros though, nothing special about lisps. And no, language semantics absolutely don't compose. Like you can't just do some kind of optimization in one place if you do some mutation on it in another place. Optimizations work on global assumptions that every part of the codebase have to abide by. Any part not doing it will make the whole thing crumble - and "there is no stuck in lisp" is exactly why you can't have your cake and eat it too.
- Charon77 2mo agoI really love the idea of lisp but feels like the learning curve is steep. Sure you can learn basic lisp in an hour or so but then? You need to learn emacs, all of the plugins, module systems. Maybe I just don't know where to start.
- vindarel 2mo agoStart here with Common Lisp 8-) https://lispcookbook.github.io/cl-cookbook/getting-started.html https://lispcookbook.github.io/cl-cookbook/getting-started.h... To learn the language, look at the good books out there (Touretzky's etc). ps: you don't need to learn Emacs. A terminal even is enough. See the Cookbook/ Editors section.
- davidpapermill 2mo agoThis is well-written. I always thought that the "answer" to programming would be that one day everyone would use Lisp and with awesome tooling and libraries things would be wonderful. In fact, my plan for retirement was to build high-quality libraries for a Lisp language to accelerate this process. Does the rise of AI bring an end to this dream? Is that, once again, we have solved the problem by adding more cruft? Rather than a superintelligent AI writing in the best programming language available, we're going to just spam lots of Python code until it works? Does this matter? I don't know, I just wanted a world of elegance.
- WillAdams 2mo agoI've always wondered what would have happened if the first "Interface Builder" >Jean-Marie Hullot created "SOS Interface" in Lisp for the Macintosh while working at INRIA (1984) which was the first modern "interface builder." https://denninginstitute.com/itcore/userinterface/GUIHistory4.html https://denninginstitute.com/itcore/userinterface/GUIHistory... had become a mainstream Mac product rather than being co-opted for NeXT and use w/ Objective-C. LISP clicked with me (when taking a comparative language class in college I was the only one who managed to do all of the LISP homework) and learning it was a lot of help in using TeX. I just wish that there was: - a nice native or cross-platform GUI toolkit for it which was opensource - an easy way to distribute projects as stand-alone compiled code
- shevy-java 2mo ago> After getting comfortable reading code with so many parentheses I never managed to get over the (). Ruby has a very flexible syntax, compared to many other languages, in that you can omit syntax in many cases. For instance, using () for method calls is largely, for the most part, optional. So when I have the python code: cat = Cat() cat.meow() I find it worse than the ruby code: cat = Cat.new cat.meow (Though you can use () in ruby there too; but most people won't do so as there is little point in that.) This is a superficial issue though. Python's biggest mistake is to require implicit self. It always feels as if I need to hand-hold python and trying to explain to it what an object is and what self is. In ruby I don't have that issue. Note that I find both languages fine, but ruby is "more" object oriented than python is, for many reasons. Lisp is quite different though. I had some exposure to it via scheme and while it can be fun, I feel that lisp is a worse programming language than either ruby or python. The old game haxima/nazghul was given up eventually, primarily due to lack of time, but also because the author was no longer convinced of scheme (the core of the engine is in C if I recall correctly). He tried to switch to python, though, which did not work (but, again, I think it was mostly due to lack of time). The scheme code in haxima/nazghul was quite interesting (https://sourceforge.net/projects/nazghul/ https://sourceforge.net/projects/nazghul/ if you want to look at the scheme code there), but I much prefer either ruby or python there. Although it would be interesting to have DSLs that would really focus on the game or project at hand, like in the old Zak McKracken game.
- rirze 2mo ago> the ruby code: ``` cat = Cat.new cat.meow ``` As a non-Ruby user, this confuses me. Why can't `Cat.new` be a function reference? Does Ruby explicitly disallow this (i.e. passing around a function)?
- wizzwizz4 2mo agoYou can do this, but there's no syntax. Instead, call the `method` method with `:new` as its argument.
- darkinvisible 2mo agoI just read the (cool!) article...didn't see a single CAR or CDR --was using them quite a bit... last century!
- doug_durham 2mo agoIn commercial practice DSLs are an anti-pattern. Someone will create an under-documented DSL that only they understand and move on. The following programmers have to try to decipher this strange language. It is almost always a better idea to use standard language structures and features. Code is read more than it is written.
- js8 2mo agoHate to break it to you, but every time you create a function, you're creating your own language, specific to the domain. I suspect what you're actually objecting to is a lack of referential transparency, which is a problem in many languages (including Lisp, to be fair).
- doug_durham 2mo agoI’m not referring to trivial functions nor classes. I talking about things like overloading operators, or changing the default idioms of the language. This means that a person can’t read the code without fully understanding the entire class structure. For the most part DSLs are highly personal. What one person thinks is a great formalism that make it easy to reason about the problem, to everyone else is spaghetti code.
- martinflack 2mo agoIn Lisp, those following programmers can simply macroexpand. With modern tools they can even do it inside their editor, co-located as replacement text in the same source file, connected to a live Lisp environment, if they wish. A great example is Common Lisp's own LOOP macro - if someone's usage is difficult to understand, you simply ask Lisp to expand it into the more verbose non-LOOP fundamental calls, and you don't need to understand anything about LOOP. In fact you can replace the LOOP form with the expanded code. That's a key difference from DSL's in most other languages where the DSL code is really data structures that are interpreted.
- js8 2mo agoPersonally, I grew beyond this. I tried Common Lisp, Forth and Haskell. I enjoyed books On Lisp and Let Over Lambda. Now I think the best programming language is Barry Jay's Triage Calculus, which is close to combinatory logic or untyped lambda calculus. But unlike lambda calculus (which is easily expressed in TC), triage calculus has a built-in quoting and introspection (similar to Lisp's CAR and CDR), which lets you easily add typechecking. So in TC, you can have any syntax you want, just by building the correct abstraction. It's truly an ultimate programming language. TC shows that there is a false dichotomy between programming language features and syntax on one hand, and the function/API definitions in the standard library or user code on the other hand. Every time you write a piece of code intended to be reusable, you're adding to the language. It can all be expressed as some term in TC. All the syntactic squibbles are a matter of habit. Although one syntactic feature you really want in TC is the let over lambda abstraction, because it's somewhat annoying to order combinators by hand.
- wild_egg 2mo agoDo you mean Tree Calculus? https://treecalcul.us https://treecalcul.us
- js8 2mo agoYes, although I wish he would call it properly triage calculus (see https://treecalcul.us/specification/ https://treecalcul.us/specification/), because although the languages are almost identical in power, the original tree calculus and triage calculus rules lead to different programs.
- sunshine-o 2mo agoI am fascinated by lisp but only had the time to mess with clojure for about a year. My weird take is that lisp would have a better shot if one would replace the parentheses with square brackets. It might just be me but the round parenthesis make it visually painful to look at code blocks. I feel square brackets would fix that.
- ballislife30 2mo agoInteresting read
- digikar99 2mo ago[dead]
- frwrfwrfeefwf 2mo ago[dead]
- deterministic 2mo ago> go ahead and learn common lisp macros Lisp macros used to be the one advantage Lisp had over other programming languages. However nowadays macros are common. There are even languages that has more than one flavour of macro system (Haskell has both a typed and non-typed flavour of macros). However I personally prefer custom code generators instead of macros. The problem with macros, for the kind of large scale systems I work on, is understanding macros with N layers of abstraction, and also the compile/run time cost of using them. Also, you can write code generators in any language and generate code for any language. Which is a huge advantage. I (for example) use code generators that generate C++, Java, Typescript, SQL, PDF's, interface descriptions, protocol specs etc. Whatever is required by a customer or other members of the team I can generate without demanding that they use a specific programming language. Don't get me wrong. I love playing around with macros. However I have decided not to use them for real work.
- frwrfwrfeefwf 2mo ago[dead]
- frwrfwrfeefwf 2mo ago[dead]