22 ms·
CL21: An experimental project redesigning Common Lisp
- mark_l_watson 12y agoThis looks cool enough but it would need a big community to really change the common lisp landscape (in my opinion). I wonder how the lazy sequence support stacks up to Clojure, Haskell, etc. support. One difficulty with promoting a more modern layer to common lisp is that Clojure is already such a productive and practical language. I have written a few common lisp books, and remain a fan of the language, and an upgrade does sound good. I am curious to hear the opinions of the heavy hitters in the common lisp world.
- ynniv 12y agoI am curious to hear the opinions of the heavy hitters in the common lisp world. In this case, theirs isn't the opinion that counts.
- malisper 12y ago> I wonder how the lazy sequence support stacks up to Clojure, Haskell, etc. support. A bit of a tangent, but I've been looking at the series library[0] recently. It makes it possible to write functional style code which is compiled into a loop for efficiency. For example: (defun integers () "Returns a series of all of the integers." (declare (optimizable-series-function)) (scan-range :from 1)) (defun squares () "Returns a series of all of the square numbers." (declare (optimizable-series-function)) (map-fn t (lambda (x) (* x x)) (integers))) (defun sum-squares (n) "Returns the sum of the first N square numbers." (collect-sum (subseries (squares) 0 k))) Although the above definition of sum-squares seems like it would be inefficient, it is roughly the same as the following: (defun sum-squares (n) "Returns the sum of the first N square numbers." (loop for i from 1 to n for square = (* i i) sum square)) I find it pretty awesome that it is possible to write code that is efficient and functional like that, but I guess series is a bit too magical to be put to actual use. [0] http://series.sourceforge.net/ http://series.sourceforge.net/
- Immortalin 12y agoI can understand the reasons why people prefer to target the CLR/JVM/LLVM/BEAM/Name-your-favorite-vm but I yearn for more compiled-to-native-languages such as Golang. As attractive as partially-compiled/interpretated languages are, I simply do not enjoy creating programs in a language that can be decompiled to source so easily. We need more languages that have decent performance instead of having to drop down to pointer optimizing in C wherever we need some performance. A functional Fortran would certainly be nice...
- one-more-minute 12y agoHave you met Julia? I don't know if I'd quite call it a functional Fortran, but it's not that far off, either.
- tempodox 12y agoSadly, Julia will not produce stand-alone executables in the foreseeable future. It's nothing more than a bit of native glue between two Python scripts. The main acceptance group doesn't use it for production, only in the lab.
- one-more-minute 12y agoStand-alone executables are on the roadmap for Julia 0.4, which is on the horizon (next six months or so).
- agentultra 12y agoSome Common Lisp implementations do compile down to machine code. An example of one I'm told is quite good is SBCL: * (disassemble #'(lambda () (loop for i from 1 upto 10 summing i))) ; disassembly for (LAMBDA ()) ; Size: 62 bytes. Origin: #x100306FE84 ; 84: BB02000000 MOV EBX, 2 ; no-arg-parsing entry point ; 89: 31C9 XOR ECX, ECX ; 8B: EB21 JMP L1 ; 8D: 0F1F00 NOP ; 90: L0: 48895DF8 MOV [RBP-8], RBX ; 94: 488BD1 MOV RDX, RCX ; 97: 488BFB MOV RDI, RBX ; 9A: 41BBA0010020 MOV R11D, 536871328 ; GENERIC-+ ; A0: 41FFD3 CALL R11 ; A3: 488BCA MOV RCX, RDX ; A6: 488B5DF8 MOV RBX, [RBP-8] ; AA: 4883C302 ADD RBX, 2 ; AE: L1: 4883FB14 CMP RBX, 20 ; B2: 7EDC JLE L0 ; B4: 488BD1 MOV RDX, RCX ; B7: 488BE5 MOV RSP, RBP ; BA: F8 CLC ; BB: 5D POP RBP ; BC: C3 RET ; BD: CC0A BREAK 10 ; error trap ; BF: 02 BYTE #X02 ; C0: 19 BYTE #X19 ; INVALID-ARG-COUNT-ERROR ; C1: 9A BYTE #X9A ; RCX Keep in mind that's with full run-time type checking and other nice debugging features. You can hint the compiler to turn these things off in your hardened code sections for even smaller, tighter code.
- eslaught 12y agoInteresting, but for looping I think a better point of comparison is iterate: https://common-lisp.net/project/iterate/ https://common-lisp.net/project/iterate/ In my personal opinion, the iterate loops read better than the code samples of the main page.
- deleted 12y ago[deleted]
- PuercoPop 12y agoLooping is still under discussion, check Dan Lentz's comments on the issue: https://github.com/cl21/cl21/issues/18 https://github.com/cl21/cl21/issues/18
- bachmeier 12y agoOne of the things I don't like about Common Lisp is the unusual names. Just on the basis of the linked page, CL21 doesn't fix that. Take princ #"Hello, ${name}\n". Why not just use print like the rest of the programming world. Okay, some languages use writeln, etc. But princ? Why not print? A little further down, we see while-let1. Why the number? If you want to call it "Common Lisp in the 21st Century" you need to clean up the syntax.
- TeMPOraL 12y agoHonestly? Mostly because Lisp conventions predate "the rest of the programming world". As for while-let1, it's a while-let with just one variable binding (I guess I'd prefer them to stick with just while-let). There's usually a very good reason behind all those "unusual names" of Common Lisp. I don't think that dumbing things up so that they look more similar to everything else in a language that is already different from anything else is the way to go.
- chrisduesing 12y agoI do. There is a reason for the success of Ruby and Python, and why Elixir is dragging Erlang in to the present. It turns out you don't just have to write your language in the shape of the machine/vm but it can be a tool conformed to the mind of the programmer. "princ" is not easy to remember, read or associate to other things one already knows. The point of a project like this should not be to save old school programmers (who won't use it anyway) a few keystrokes, it is to throw away the cruft of decades of "a very good reason" decisions for something simpler and better thought out. I really like the direction of this project, but I agree with the parent comment, it doesn't go far enough.
- bad_user 12y agoI don't know German, but I have a huntch that Romanian, my native language, is more complex than German, except that Romanian has firm roots in latin, therefore more people unfamiliar with both will have an easier time with Romanian, since we have a significant portion of our vocabulary similar to Italian or Spanish, plus we borrowed words from French, along with many neologisms coming straight from English. Just because a language is unfamiliar, that does not make it hard or complex, just because you're not speaking it. Consequently, just because a language seems superficially familiar, that doesn't make it easy to learn - for programming languages it takes weeks to understand the basic necessities, whereas it takes years to become a master, regardless of the programming language you're talking about. Also, Erlang's Prolog-like syntax sucks, not because it's unfamiliar, but because it objectively sucks.
- mordocai 12y agoBy the way, looking at the github there are 40 open issues 5 open pull requests and no changes to master for 6 months. I think this project may be dead, or at least on hold for the time being.
- malisper 12y agoIt looks like they are using the issues to keep track of feature requests.
- lisper 12y agoAnother effort along the same lines: https://github.com/rongarret/ergolib https://github.com/rongarret/ergolib
- ajarmst 12y agoOh, god. Not again. Stopped reading at "More Object-Oriented".
- jwr 12y agoAs a former common lisper, I don't see the point. Clojure is better in pretty much every respect and incorporates many fresh ideas (such as excellent concurrency support). Syntax is the least of CL's limitations. I didn't switch to Clojure because it was "easy" (quite the contrary). And no, I do not miss reader macros. Perhaps more surprisingly, I don't miss CLOS at all, much as I always admired its design. It's just... Unnecessary. What I do enjoy is STM, good performance, Java interop, ClojureScript, core.async and lots of excellent code with fresh ideas popping up all over the landscape.
- agentultra 12y agoClojure is nice and all but I wouldn't suggest it's even close to being better in many respects, let alone every respect. When I was working with it on a non-trivial project I despised the JVM stack traces, image-less environment, and lack of access to the reader. I assume that eventually Clojure will steal these ideas and adopt it in its own way... but these old, un-modern ideas of conditions and restarts, images, and reader macros are actually really useful. I hope they do take a hint.
- omaranto 12y agoI guess performance might still be a reason to prefer Common Lisp to Clojure.
- mcmancini 12y agoClojure lacks a formal spec, commercial vendor support, and doesn't have the long track record of CL. Clojure also requires JVM issues to be considered (e.g., which JVM will you use?). Don't know about C FFI with Clojure, but perhaps that's another CL advantage? For many, Clojure may be a better choice as you suggest: perhaps especially for web projects. But I think for some groups and applications, CL remains a better choice.
- bitwize 12y agoInb4 the newLISP cultists arrive.
- arh68 12y agoI think this is an okay idea, but the comparison to Clojure is really lacking. Why build on CL when you can build on Clojure? I get the inter-operability, but when Multi-Threading and Multi-Processing is listed under Deferred, Clojure could provide so much of that for free. On Clojure, etc.
- pekk 12y agoWhat if you aren't interested in targeting the JVM?
- arh68 12y agoThen I think the CLR would be a good starting point [1]. Or you could settle for single-threaded ClojureScript/JavaScript. [1] https://github.com/clojure/clojure-clr https://github.com/clojure/clojure-clr
- pekk 12y agoYou seem to be assuming that everyone writing code should be writing code for either the JVM or CLR, which is a really weird assumption.
- latiera 12y agoBecause clojure is garbage? Also, Java/JVM suck ass, why would anyone willingly work with that whole mess?
- arturventura 12y agoI've been thinking about this for a while. I've wrote some thoughts I had over the years about modernising Lisp. https://news.ycombinator.com/item?id=9078444 https://news.ycombinator.com/item?id=9078444
- Guthur 12y agoIn the examples I see nothing overly compelling which would justify fragmenting the mind share. Some of them could possible be considered for alexandria https://common-lisp.net/project/alexandria/ https://common-lisp.net/project/alexandria/. Admittedly I am not sure how alive development is but it certainly would be worth breathing new life into as it is probably the most heavily used CL library. As things like STM and lazy which Clojure has, they have been implemented at the library level for CL. https://common-lisp.net/project/cl-stm/ https://common-lisp.net/project/cl-stm/ The beauty about a Lisp is that you can easily add so much on top of the language that will feel as if it was always there. CLOS is a good example of this. In the case of JVM with CLojure, and of course others will disagree, I don't think accessing the Java ecosystem is a good thing. The mindset there is monolith "Enterprise Solutions" "Inversion of Control frameworks" which invariable mean systems that are so complex the authors don't even understand them and lets write XML above all else. Also if you want CL->Javascript; Parenscript.
- joesb 12y agoThree things I don't like about Common Lisp. 1. It has CLOS but it doesn't really embrace it in standard library. You have list, vector, hash-table, each with its own iterator function. You have lots of #with-xxx macro. All modern languages utilize the idea of common interface like #iterator or #dispoable. You can clearly see CLOS library and pre-CLOS library in CL. CL needs to eat its own dog food (CLOS) more. 2. It lacks basic practical API library, while another containing big complicate academic functions. Its #format function is probably Turing complete. It has function to format number in Roman numeral. But it doesn't have function to deal with datetime. No networking IO function. No Threading library. 3. Condition and Restart could take the idea from Dylan. Tying condition to available restarts, and making class hierarchy of them, is a better idea. This problem stems from CL not actually utilizing CLOS. Also, PACKAGE should take the idea of LOCALE, allowing easier local package rename, and less symbol conflicts problem.
- Moyamo 12y agoI agree with all your points. One of my main gripes with Common Lisp is its complexity. When I started learning Lisp, I expected to find a beautiful and elegant language, one without a need for syntax. The way C is almost an elegant assembly. Maybe I should have tried Scheme instead. Common Lisp is anything but elegant. Instead of a regular syntax, you get all these "mini-languages", like the format syntax e.g. (format t "~{~a~^, ~}" '(1 2 3)) ; prints out ; 1, 2, 3 This works fine for list, but not for vectors, which is a problem, since I needed vectors often (for random access). The loop macro is also quite powerful and complicated. e.g. (loop :for i :from 1 :to 1000 :collect (* i i)) will create a list of square of 1 to 1000. The loop macro can become really convoluted, not at all simple. The fact that Common Lisp is a Lisp-2 makes treating functions as first-class as rather awkward. I could never remember when I needed to prepend a lambda with #'. This article may be of interest http://xahlee.info/comp/Common_Lisp_quotations.html http://xahlee.info/comp/Common_Lisp_quotations.html I found much of the elegance I was expecting in Haskell. But maybe Scheme is a better lisp.
- wedesoft 12y agoI can recommend having a look at GOOPS [1] (GNU Guile's implementation of CLOS) for inspiration. It provides multiple dispatch and facilitates overloading of existing functions (such as "+"). [1] http://www.wedesoft.de/oop-with-goops.html http://www.wedesoft.de/oop-with-goops.html