11 ms·
I've heard CL is famous for having advanced libraries and language features decades before other languages get them. What are some interesting libraries or lan
by MichaelBurge 4y ago
I've heard CL is famous for having advanced libraries and language features decades before other languages get them.
What are some interesting libraries or language features developed since 2005 that haven't yet made their way to other languages? Not a simple "Do X" library that a C programmer could easily copy, but something more like CLOS, contracts, or pattern matching that are cross-cutting.
- eadmund 4y agoCoalton comes to mind: https://github.com/coalton-lang/coalton https://github.com/coalton-lang/coalton It adds static typing to Common Lisp, while (I believe) still allowing one to escape to the dynamic world when needed. Sure, there are statically-typed languages, but I don't know of another dynamic language in which something like Coalton has been done.
- math-dev 4y agoIts not very smart to add static typing to Lisp, goes against the strengths of the language. At that point just program in another language, there’s a lot of benefit of static typing that IDEs can take advantage of but for anyone half decent at Lisp, they wouldn’t feel any need for static typing (outside of compiler optimisations, which is a different thing). Now in terms of interesting things, check out European Lisp Symposium https://european-lisp-symposium.org/ https://european-lisp-symposium.org/ The talks from this year were highly entertaining The other really cool thing in CL IMO is Allegro Cache - in memory datastore that is a joy to use
- pjmlp 4y agoThanks for sharing, nice to see SisCog still at it.
- medo-bear 4y ago> Its not very smart to add static typing to Lisp [...] (outside of compiler optimisations, which is a different thing) i think this is precisely the point of coalton. cl allows quite handy compiler optimizations and having the option to drop into a native statically typed environment just gives more bang to your lisp ;) coalton is not lispy, sure, but neither is the loop macro, yet it is probably the most powerful looping mechanism in any language :)
- math-dev 4y agoThose already exist and have been used by many. Coalton is a set of macros to make it easier for to write with the safety rails of static typing. Now if I write in Swift, for example, static typing is great, because the IDE can give a lot of hints during development. Non lisp languages have quite idiosyncratic syntaxes for various constructs, so static typing really does help a lot there. In large code bases in those languages it also helps a lot because they do not have the power of Lisp macros to reduce syntactical complexity via a Domain Specific Language. Now with Common Lisp, with a powerful generic functions and object system, with runtime dispatch and introspection that far exceeds other languages, plus with the abstraction power of macros, trying to add static typing guard rails simply doesn’t make any sense. I rather program in TypeScript if I am so far removed from the core essence of CL development. Each language has its strengths and the dynamic nature of CL is one of its biggest strengths (with the lack of a GUI and interop with other tools being its largest deficiencies today). Static typing in Lisp is like trying to fit a square plug in a round hole. If somebody wants so much guard rails, other languages are much more suitable because they have been designed (quite successfully if I may add) in that way. TLDR; As per On Lisp by PG, lisp code should be built in layers over each other and hence static typing is unnecessary. Furthermore generic dispatch provides similar features to some extent (although i recommend combining with closer mop and catching edge cases etc)
- Kototama 4y ago> lisp code should be built in layers over each other and hence static typing is unnecessary It could help for refactoring though.
- medo-bear 4y ago> Static typing in Lisp is like trying to fit a square plug in a round hole. If somebody wants so much guard rails, other languages are much more suitable because they have been designed (quite successfully if I may add) in that way. i belive the author of the coalton package is not very concerned with IDEs or putting up safety nets for developers. i think he uses coalton for making optimizing compilers. think of it as cl+ml not as cl+ts EDIT: typos
- 4y ago
- Tabular-Iceberg 4y agoDid they record the talks this year?
- math-dev 4y agoI think so, try asking on reddit or IRC if you still can’t find them via some google fu
- rscho 4y agoRacket. With typed racket.
- CraigJPerry 4y agoIn VSCode when my cursor is inside an s-exp, i can press Alt+Shift+E and it instantaneously shows the result of that call inline in the editor. If i change the code at all, i just press the same key combo and see the new result. It remembers all the state of what i've done up to that point too so i don't need to mess around setting up the call with data to feed in for example. The closest i can find to replicating this is the various hot-reload implementations in other languages but they all incur some kind of delay (naturally, because they're all doing a lot more work behind the scenes) which ruins the use of this feature, it stops you using it to evaluate your thought process in realtime. They also don't render the results inline - mostly because the syntax of JS/TS and other languages doesn't really lend itself to this kind of usage.
- darthrupert 4y agoJupyter notebooks manage to replicate a somewhat similar experience.
- CraigJPerry 4y agoHmmm, somewhat but it’s missing the ergonomics to the point that it can’t be used the same way. The best analogue i can come up with is a sql session connected to a live database.
- pjmlp 4y agoIt is a nice approximation, but fails short of the whole experience. Imagine that your shell was like those notebooks, and not only you can interact with the whole OS, you can even change existing notebooks dynamically by reloading code that they depend on, e.g. a displayed image gets a new effect added to it.
- greymalik 4y agoWhat extensions are you using for this?
- CraigJPerry 4y agohttps://github.com/nobody-famous/alive https://github.com/nobody-famous/alive
- sleepycatgirl 4y agoMight be not exactly what you ask about, but, REPL-driven development. (Though, to be more accurate, it is more of image based development, rather than REPL, which is quite big difference) Function does not work? Change it , re-evaluate, and call the function again. No need for constant restarting, re-compiling or so. All on-the-fly, Once you get used to it, it's really something else. Its simply unique, also without sacrificing performance (Because it is quite performant)
- jstx1 4y agoDoesn't everyone in data science do this too with Python/R/Julia? I don't think that it's a unique Common Lisp feature.
- jhgb 4y agoNot quite. For example, languages like Python typically have generative class definitions -- meaning that a class definition always creates a new type, with no existing object instances being objects of that class. In comparison, Common Lisp has provisions for adapting old instances to match a new definition of an already existing class, including lazy updates. Taken to extreme, this allows for such things as large on-disk object databases (since presumably you don't want to convert a billion objects on the disk the moment you add a field to a class).
- knome 4y agoThe erlang language provides a similar facility for replacing code and updating object state without ever bringing the program to a halt.
- phoe-krk 4y agoThe main difference is that Erlang is very strict about the kind of programs it will run (purely functional green-thread-esque processes and OO systems that utilize message passing and code that is modified must be swapped in/out at strictly defined points in program lifecycle), whereas CL is a fully mutable environment where modification can happen at any time during program lifecycle. Much more powerful, which comes with benefits as much as it comes with the amount of guns to blow your feet off with.
- newtwilly 4y agoPeople are talking about REPL development, and they are right, but one of the best things that you can do with CL that you can't do with other REPLs, such as Clojure, is... at least using Slime in Emacs, probably other editors too... when there's an error/exception or whatever, you drop right into the stack at the error location. You can see all the values of the variables. You can evaluate expressions. Travel up the stack and do the same things. That is SO powerful, and can save so much time debugging simple errors.
- mikelevins 4y agoYou can also edit the values and change other definitions while you're roaming the stack. Smalltalk can do it, too.
- ngcc_hk 4y agoWhilst it is good the browser side windows provide also quite a lot of information about the JavaScript info. Perhaps as js came from scheme …
- pmoriarty 4y agoLisp syntax and simplicity is my biggest selling point for Lisp vs other languages (except for Scheme, which is even more elegant). Some people hate Lisp's heavy reliance on parenthesis and there have been so many languages that try to make a "Lisp without parenthesis", but to me they're missing half of what makes Lisp great. I find programming in and reasoning about Lisp way, way easier than other languages. There's very little syntax to stand in the way or remember and the verbose way Lisp is written helps make Lisp programs self-documenting and way easier to understand than other languages. This is super useful when doing a lot of language hopping or when coming back to the language/program after being away from it for a long time. Because of this I can quickly come back up to speed with the program and it also makes more larger and more complex programs more comprehensible -- that is, of course, if you don't use macros to turn Lisp in to some harder to understand language.
- sleepycatgirl 4y agoOh yea, definitely, With rainbow parentheses, and paredit, the experience is top tier
- dwringer 4y agoRainbow parentheses are such a great invention I can't understand why it isn't standard nearly everywhere.
- rmckayfleming 4y agoI've found rainbow block-level highlighting to be even better: https://github.com/alphapapa/prism.el https://github.com/alphapapa/prism.el
- dwringer 4y agoI kind of wish editors focused on having different highlighting modes the way some strategy games have different map modes. I sometimes find myself changing to random language modes in emacs just to see different highlighting schemes that focus my attention on the code in different ways. I also do like rainbow block highlighting but it's not something I want all the time.
- Jach 4y agoWell, there are lots of "do x" libs that I don't think a C programmer could easily copy, but hey, we're all Turing complete here... As for language features, historically Lisp was not always first for some particular feature, but because of earlier design decisions that still haven't been made by newer languages, it can usually implement innovative features from other languages or PL research papers as libraries without having to update the language spec or an implementation itself. So we have immutable collections, laziness, takes on pattern matching, various concurrency models, more sophisticated type systems... One very recent library that might be of interest is "just" a new regex library (https://applied-langua.ge/posts/omrn-compiler.html https://applied-langua.ge/posts/omrn-compiler.html) but it leverages one unique design choice Lisp made in that you have access to the language's compiler at runtime, it's not a fenced-off separate program only used to create a runtime executable. The compiler can (and in SBCL's case does) optimize and produce assembly code, SIMD instructions can be used too, so this regex lib is very fast while not being that much code.
- zozbot234 4y ago> but it leverages one unique design choice Lisp made in that you have access to the language's compiler at runtime, it's not a fenced-off separate program only used to create a runtime executable. This is best understood as having no phase separation between compile time and run time. Effectively, languages that are so designed do everything at compile time, up to and including running the actual program. Though sometimes they can practically recover the phase separation by "extracting" a program that can be compiled in a single step and ran as a conventional binary. For example, a LISP program for doing math may support "extracting" a custom function evaluator or numerical-symbolic solver written in FORTRAN.
- pjmlp 4y agoI don't want to start a language war, given that I like both languages anyway, you should have a look at https://github.com/hanickadot/compile-time-regular-expressions https://github.com/hanickadot/compile-time-regular-expressio... However even counting with upcoming C++23 features, Lisp is much more ergonomic for this kind of stuff.
- daniel-cussen 4y agoOh I'd love to share it, I just can't. Well I made one that did make its way to Fortran by being independently developed, the Lisp version was in 2011 and the Fortran I think...2017. The brute forcer in AI-Feynman. https://github.com/SJ001/AI-Feynman/blob/master/aifeynman/symbolic_regress_mdl5.f90 https://github.com/SJ001/AI-Feynman/blob/master/aifeynman/sy... I talk about it in my portfolio, it's Guesser 1.0 and Guesser 2.0. https://github.com/daniel-cussen/portfolio/blob/master/portfolio.pdf https://github.com/daniel-cussen/portfolio/blob/master/portf...
- hajile 4y agoFirst-class functions, lambdas, and closures are mostly unheard of in the top 20 programming languages. Aside from JS, you're pretty much out of luck. Proper tail calls. Technically not part of the CL spec, but implemented by the best CL variants (and by scheme), they allow a lot of expressive power. You won't find this ANYWHERE on the top 20 except for JS where it is technically part of the spec, but Google and Mozilla refused to implement leaving just Safari/JSC to have 100% ES6 spec compliance 7 years after the spec was finished. Macros get overstated perhaps, but there are almost zero non-lisp languages that implement them and none of them implement macros ergonomically. In a language like JS, you'll often see a kind of DSL where they attempt to use closures and super-dynamic objects to create templates. I see this a lot in React where you'll have huge config objects passed in and then very extensive branchy and loopy code to turn all the bits on an off. This is a poor man's macro. In a lisp, you would do all this stuff at compile time with all that inefficient branchy stuff executed once at compile time rather than millions of times on each of the thousands/millions of machines your code is running on. The REPL has been mentioned several times, but it really is that good and nothing from other languages compares. People stress about "writing unit tests" because technically correct types doesn't mean your program actually works. In my time writing JS vs TS, I've seldom found that type errors were the problem aside from making the type checker happy. Most errors are in what the code actually does or does not do. The instant feedback from the entire system is far superior to unit tests because it can catch things that your unit tests might not be testing for. Dynamic, but definable types is another advantage. You start out without a bunch of specific types which is better for getting things done, but can then add in type hints either as documentation or as a way for the compiler to spit out fast code. People may be down on dynamic code, but the truth is that the world is dynamic and runtime type checks are far safer than static types where they are then thrown out and you hope for the best. Because of the REPL-driven development, type errors are almost non-existent in practice.
- wtetzner 4y ago> First-class functions, lambdas, and closures are mostly unheard of in the top 20 programming languages. Aside from JS, you're pretty much out of luck. This was true at one point, but most popular languages have them now, don't they? Even C++ and Java have them now (and have for a while).
- dannyobrien 4y agoThe one that sticks out for me is condition handling, particularly restarts. I'm someone who reads books about programming more than I actually program, so I don't know how actually practical Lisp's ability to do extremely sophisticated responses to error conditions and the like (including choosing where to throw to programmatically at the error site) is. It strikes me that it might be one of those things -- like hot-reloading -- where there are so many factors that it's mostly impossible for humans to get right. But!! I've never seen it in any other language, and I think about it a lot. @phoe-krk's book on it, https://news.ycombinator.com/item?id=24867548 https://news.ycombinator.com/item?id=24867548 is very good.
- orthecreedence 4y agoThis isn't an exact answer to your question, but I have to say macros. Going from CL (and scheme probably too) to macros in any other language is like going from a lambo to a tricycle. It's one of the things I miss most about CL. I also love the live-editing aspect of CL. When I was doing game programming with it, being able to replace functions while running was incredibly useful. You don't have to re-create all your state, you can jsut live-edit a function and boom fix a bug or add a new feature right there. Very good for exploratory programming with lots of otherwise-hard-to-replicate state.
- reddit_clone 4y agoWell put. I agree on both points. CL has a very advanced TDD. You actually develop by executing snippets in REPL and pull them all together in a function (already tested!).
- lisper 4y agoI don't know about "since 2005" but there are two features in the original CL spec which I find indispensable but which still have not made it into any other languages (AFAIK): 1. Generic functions 2. Being able to redefine a class and have existing instances of that class be automatically updated to conform to the new definition
- dotancohen 4y agoWhen would you ever legitimately use #2? If e.g. an API wants to support monkey patching that's a decision that can be made. But thinking that any e.g. plugin or addin could could redefine extant class instances sounds like a nightmare, and a security issue just waiting to happen.
- moonchild 4y agoIn longrunning/high-availability applications, this sort of thing is necessary in order to avoid restarting and losing uptime or state. E.G. per nasa: > The Remote Agent software, running on a custom port of Harlequin Common Lisp, flew aboard Deep Space 1 (DS1), the first mission of NASA's New Millennium program. Remote Agent controlled DS1 for two days in May of 1999. During that time we were able to debug and fix a race condition that had not shown up during ground testing. (Debugging a program running on a $100M piece of hardware that is 100 million miles away is an interesting experience. Having a read-eval-print loop running on the spacecraft proved invaluable in finding and fixing the problem (from https://flownet.com/gat/jpl-lisp.html https://flownet.com/gat/jpl-lisp.html)
- dotancohen 4y agoInteresting, thank you!
- lisper 4y agoAny code modification is a potential security issue. There is nothing special about dynamic class redefinition in this regard. I use it for development and deployment. I can deploy new code without having to take my application down. In fact, not only do all my existing instances get updated, but I also use an ORM [1] that automatically updates my database tables too. [1] https://github.com/rongarret/ergolib/blob/master/layer1/sql.lisp https://github.com/rongarret/ergolib/blob/master/layer1/sql....