6 ms·
I’ve never did anything serious with Common Lisp, but my light experience on it was that - the idea that almost all language constructs are user-implementable
by goranmoomin 5y ago
I’ve never did anything serious with Common Lisp, but my light experience on it was that
- the idea that almost all language constructs are user-implementable with macros is quite impressive (but I don’t buy the argument that “real” macros are only able in s-exprs)
- and the REPL-driven development model was a really beautiful and seamless experience.
But… every time I try to use it on some code, I find too many warts and inconsistencies that I just didn’t want to spend too much effort in making it work. It’s a beautiful language in it’s own ways, but the other parts are too ugly (to me, of course).
I’m fine with it being a lisp or not; I just want a clean language with macros baked in (and becomes the basis of most language features), and with a REPL-driven development model as a first class citizen (with interactive restarts and all).
Unfortunately it seems a pipe dream… so I’m stuck here.
[0]: https://mikelevins.github.io/posts/2020-12-18-repl-driven/ https://mikelevins.github.io/posts/2020-12-18-repl-driven/
- the_duke 5y agoJanet [1] is a clean, modern LISP. Clojure is also an option, but of course that comes with a heavy JVM burden. [1 ]https://janet-lang.org https://janet-lang.org
- ogogmad 5y ago> Janet is a clean, modern LISP. This does seem cleaner. I have some questions though: - What about the interactive environment like the one in Common Lisp? It's not enough to only have a "REPL", I think. - There are so many Lisp dialects. Is this one going to remain obscure? - What's the library situation?
- db65edfc7996 5y ago>What about the interactive environment like the one in Common Lisp? Never used a "real" Lisp REPL, but Conjure[0] seems like it ticks a lot of boxes. >Is this one going to remain obscure? There are only a ~dozen mainstream languages. Once you get outside of the popular zeitgeist, you have to appreciate exactly what you are getting. It takes a lot of dedication to become fluent in a language/ecosystem, so it is no surprise that people are reluctant to switch to a novel platform. Clojure is far more likely to ever become mainstream (owing to the huge JVM ecosystem), but even that seems to have only limited industry penetration. [0] https://github.com/Olical/conjure https://github.com/Olical/conjure
- fuzzythinker 5y agoClojure doesn't need JVM. You can run it with GraalVM either directly [1] or via Babashka [2]. Both are great options for get into Clojure since there's almost no startup time like JVM and you don't have to be burdened with learning and heaviness of JVM stack. [1] https://github.com/oracle/graal https://github.com/oracle/graal [2] https://github.com/babashka/babashka https://github.com/babashka/babashka
- avmich 5y ago> Clojure doesn't need JVM. You can run it with GraalVM... Hm. https://en.wikipedia.org/wiki/GraalVM https://en.wikipedia.org/wiki/GraalVM "GraalVM is a Java VM and JDK based on HotSpot/OpenJDK, implemented in Java..." https://en.wikipedia.org/wiki/Clojure https://en.wikipedia.org/wiki/Clojure "Other implementations of Clojure on different platforms include: - Babashka,[82] Native Clojure scripting language leveraging GraalVM native image and Small Clojure Interpreter.." I guess you mean that some particular implementation of JVM isn't needed. But in general Clojure has "j" in its name, it wouldn't make sense without JVM at all.
- LesZedCB 5y agowell, there's also ClojureScript and recently, ClojureDart - neither dependent on the JVM
- fuzzythinker 5y ago"a Java VM" =/= the JVM most people's understanding of the word.
- didibus 5y agoNo, you don't need GraalVM either, it is only built with GraalVM, but it is usable as a single static native binary with no other dependencies. Think how say CPython needs GCC to build itself, but to use Python as a user you don't need GCC, only the compiled CPython interpreter. This is the same for Babashka Clojure, you only need GraalVM to build it, but as a user you only need the compiled Babashka interpreter. There's also Self-hosted Clojurescript which only needs a JS VM. And there is Clojure CLR which only needs a CLR VM. And you've got Clojerl that only needs BeamVM. But Babashka is probably the one you'd want to try, since it is dependency free, just download the binary and put it on your PATH.
- rawoke083600 5y agoAlso look at author's joy web framework build on janet ! Really cool. [0] https://github.com/joy-framework/joy https://github.com/joy-framework/joy
- giraffe_lady 5y agoI don't necessarily recommend it as a general purpose language across many uses right now, but I've been working in lua a lot and fennel has really impressed me. It only adds special forms and doesn't change the runtime semantics at all, so you can drop it into any lua runtime for a strictly better dev experience, or target luajit or whatever but that's not relevant to me. I haven't used its macro system yet but it looks fine and pretty much like clojure's. I only ever wrote a handful of macros over years of working in clojure so ymmv anyway. Also it has pattern matching, which is ridiculously powerful and smooth in lisps, and it still boggles my mind that clojure doesn't seem aware of that. Again I haven't used this language yet for anything that didn't require lua, so I'm not sure how that'll go. I'll definitely consider it next time I need a lightweight scripting language though.
- jrvarela56 5y agoYou can use this library to get pattern matching in Clojure: https://github.com/clojure/core.match/wiki/Overview https://github.com/clojure/core.match/wiki/Overview
- Decabytes 5y ago> (but I don’t buy the argument that “real” macros are only able in s-exprs) The Rhombus project in Racket^1 is an attempt to fix a lot of things about Racket and S-exprs but one of the goals is creating a syntax that is able to be manipulated as easily a s-exprs. > By “macro-extensible,” we mean that Rhombus users should be able to extend the syntax of Rhombus in much the same way that Racket users can extend the syntax of Racket. Complex syntactic extensions such as object and class systems, static type checkers, and pattern matching should be implemented as libraries while still providing a surface syntax familiar to users of these features in other languages. 1. https://github.com/racket/rhombus-prototype/blob/master/resources/state-of-rhombus.md https://github.com/racket/rhombus-prototype/blob/master/reso...
- wtetzner 5y agoSee also Honu: https://www.cs.utah.edu/plt/publications/gpce12-rf.pdf https://www.cs.utah.edu/plt/publications/gpce12-rf.pdf
- Decabytes 5y ago> The surface syntax is responsible for some grouping, but not all. This requires that the parser understand the program’s bindings and expand macros to get a complete picture of a program’s structure. Interleaving the parsing of a token stream with macro expansion in this fashion is called enforestation, and it allows macros to extend the syntax of conventional languages. The Honu research language pioneered this technique. Rhombus takes inspiration from Honu!
- Kototama 5y ago> but I don’t buy the argument that “real” macros are only able in s-exprs Metaprogamming can be done also semantically in other languages. Elixir for example has also macros and a good part of the core of the language is written with them. When writing a macro you then get an AST in input (represented with tuples in Elixir) and give another AST as output. I think Rust has something similar. The reason why s-exps are better to write macros is that the AST has the same form has the code you write in the editor. This way textual code and code as data have the same representation, making it easier to reason and manipulate the code.
- HerrMonnezza 5y agoJulia [1] has macros (not necessarily based on s-exprs though you can use s-exprs if you want) and a REPL [2] with some decent tooling (e.g., [3] [4]) [1]: http://julialang.org/ http://julialang.org/ [2]: https://www.youtube.com/watch?v=CRiD12Y75wM https://www.youtube.com/watch?v=CRiD12Y75wM [3]: https://timholy.github.io/Revise.jl/stable/ https://timholy.github.io/Revise.jl/stable/ [4]: https://kristofferc.github.io/OhMyREPL.jl/latest/ https://kristofferc.github.io/OhMyREPL.jl/latest/
- lispm 5y ago> (but I don’t buy the argument that “real” macros are only able in s-exprs) There are macros in non-s-expr languages. Usually then one needs to manipulate an AST data structure. That has consequences in those cases: a) the macro forms need to be parsed according to a syntax, usually a predefined syntax b) the AST data structure adds some complexity, which makes simple things more complex, but can also be a help For Common Lisp a) means that the code enclosed in a macro does not need to conform to a predefined syntax and the macro is responsible to parse it. A typical example is the LOOP macro: (LOOP for i from a to b by 2 when (> a (foo b)) maximize (sin b)). That's a whole different sublanguage, which does not look like the typical nested lists based notation. It uses symbols as syntactic words in a complex syntax, which otherwise would not be valid Lisp. You can see what it does: one can add arbitrary syntax. Which is good and bad at the same time. b) means for Common Lisp that there is certain meta-level model, where the language can be used to program itself via procedural macros. Now one has to deal with code, where one can program on a meta-level which looks like the normal level. That's also good and bad. Good because one can apply all the knowledge and tools on the meta-level, too. Bad because it means that a programmer may see in a debugger code-generating code and the programmer sees code constructs which have code generators behind it. In a Lisp interpreter (one which processes Lisp source code at runtime), this will also be visible at runtime. In a language which uses AST data structures, the code in AST representation looks very different from the written code. In Lisp the code as data looks the same as the written code. The experience is widely different from programming in other programming languages and not that easy to learn: programming a language on a meta-level in itself. Most programming we see seems to happen without that self-programmability capability.
- wtetzner 5y agoI've always liked the approach Honu takes: https://www.cs.utah.edu/plt/publications/gpce12-rf.pdf https://www.cs.utah.edu/plt/publications/gpce12-rf.pdf
- momentoftop 5y agoI don't like REPL driven development. REPLs are celebrated as some sort of achievement in interactivity, but they're hopelessly puny, barely imitating a UNIX shell. When I write Emacs Lisp, I don't have a REPL. I just put point at the end of a random s-expression in a random Emacs-mode buffer, hit C-x C-e, and it gets evaluated. Or I do "eval-print-last-sexpression" to get the output on the next line. If I put my emacs in an org-mode code block, I'll get the output nicely formatted by org-mode. I can get close to this in Common Lisp with SLIME, but I've never found it as tight as Emacs Lisp. But Emacs lisp is still puny. Common Lisps had much higher aspirations than SLIME and a crappy UNIX-based Lisp executable. Allegro and Lispwerks still run on the philosophy that your IDE is just some live code in your lisp image, and you extend that image via the GUI. The same philosophy pervades (non-GNU) Smalltalk implementations. This is the sort of thing that still makes Lisp (and Smalltalk) absolutely stand out among programming languages, and it will be a crime when it is inevitably forgotten and we are left dumbfounded by the banality of REPL driven development.
- mickeyp 5y agoEmacs does have a REPL (`M-x ielm'), and it works well.
- submeta 5y agoDidn't know about that, although I have been using Emacs for over ten years! Tried `M-x ielm`, `(help) RET`, wow! Will explore it. Been only using the scratch buffer and `C-x C-e` to evaluate sexpressions.
- mickeyp 5y agoI wrote about all the way of doing this here: https://www.masteringemacs.org/article/evaluating-elisp-emacs https://www.masteringemacs.org/article/evaluating-elisp-emac...
- submeta 5y agoAh, it's you Mickey! Got your book. Excellent! Thank you for writing it, and thank you for all the valuable stuff you put out there re learning Emacs.
- rottc0dd 5y agohttp://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.h...
- mbrodersen 5y agoMany languages have support for REPL driven development (Haskell, F#, …) It isn’t unique to LISP. Remember Basic programming on the old C64/ZX Spectrum computers? REPL driven development :)
- mikelevins 5y agoI disagree. I think it’s useful to distinguish repl-driven development from development that merely has incidental access to some kind of repl. That’s the topic of this blog post: https://mikelevins.github.io/posts/2020-12-18-repl-driven/ https://mikelevins.github.io/posts/2020-12-18-repl-driven/
- mbrodersen 5y agoFair enough.
- medo-bear 5y agoyou are eagerly missing the point :) the REPL in those languages have a fraction of the capability in Common Lisp