This 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.
> 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.
I 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 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.
As odd as it may seem, I ended up prefering car/cdr over anything else (except when access to pattern matching and destructuring). I know first/rest, head/tail or even fst/snd are clearer names, but car/cdr ended up as symbols having precisely this meaning in LISP idioms (recursion over cons-cell based lists).
Yeah, lots of this is just swapping out one awkward keyword for another.
If I were doing this I'd also get rid of the * around the hash keyword and either just go with the keyword 'hash' or replace it all together with an operator.
It's almost like lispers want the opposite of java, long verbose keywords and syntax and then as short as possible variable names.
Why not switch the parens to something that's a single keystroke? Why not get rid of the parens in most cases? In some cases this seems to make the parens problem with lisp even worse?
(loop for key being each hash-key of *hash*
using (hash-value val)
when (< (length key) 2)
do (format t "~A~%" val))
Honestly? 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.
"In spite of this, it has not had much success (at least in Japan)."
From this and the author's name (Eitaro Fukamachi), I wonder if he is not a native English speaker.
This could shed light on differences in aesthetic choices about function names. Difference between "princ" and "print", or awkwardness of "while-let1" may not resonate as much for a non-native speaker.
As 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.
Clojure 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.
Clojure 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.
In 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/. 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.
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.
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.
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 #'.
By 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.
I 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 "+").
I 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.
[+] [-] mark_l_watson|11 years ago|reply
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.
[+] [-] malisper|11 years ago|reply
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:
Although the above definition of sum-squares seems like it would be inefficient, it is roughly the same as the following: 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/
[+] [-] Immortalin|11 years ago|reply
[+] [-] ynniv|11 years ago|reply
In this case, theirs isn't the opinion that counts.
[+] [-] bachmeier|11 years ago|reply
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.
[+] [-] agumonkey|11 years ago|reply
My 1.5cents
[+] [-] bane|11 years ago|reply
If I were doing this I'd also get rid of the * around the hash keyword and either just go with the keyword 'hash' or replace it all together with an operator.
It's almost like lispers want the opposite of java, long verbose keywords and syntax and then as short as possible variable names.
Why not switch the parens to something that's a single keystroke? Why not get rid of the parens in most cases? In some cases this seems to make the parens problem with lisp even worse?
with 5 sets of parens turns into six setsthe former also required fewer shift-character keystroke combinations
while the new syntax ends up with this feels like my hands are wrestling, not typingthis just seems to be moving things around, not really improving anything
I'm not a lisper, so somebody correct me if I'm wrong
[+] [-] gongador|11 years ago|reply
http://www.lispworks.com/documentation/lw61/CLHS/Body/f_wr_p...
[+] [-] phabian|11 years ago|reply
[+] [-] TeMPOraL|11 years ago|reply
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.
[+] [-] jimbokun|11 years ago|reply
From this and the author's name (Eitaro Fukamachi), I wonder if he is not a native English speaker.
This could shed light on differences in aesthetic choices about function names. Difference between "princ" and "print", or awkwardness of "while-let1" may not resonate as much for a non-native speaker.
[+] [-] jwr|11 years ago|reply
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|11 years ago|reply
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|11 years ago|reply
[+] [-] _femp|11 years ago|reply
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.
[+] [-] Guthur|11 years ago|reply
Some of them could possible be considered for 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/
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.
[+] [-] eslaught|11 years ago|reply
https://common-lisp.net/project/iterate/
In my personal opinion, the iterate loops read better than the code samples of the main page.
[+] [-] PuercoPop|11 years ago|reply
[+] [-] unknown|11 years ago|reply
[deleted]
[+] [-] joesb|11 years ago|reply
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|11 years ago|reply
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.
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.
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
I found much of the elegance I was expecting in Haskell. But maybe Scheme is a better lisp.
[+] [-] mordocai|11 years ago|reply
[+] [-] malisper|11 years ago|reply
[+] [-] lisper|11 years ago|reply
https://github.com/rongarret/ergolib
[+] [-] arturventura|11 years ago|reply
https://news.ycombinator.com/item?id=9078444
[+] [-] wedesoft|11 years ago|reply
[1] http://www.wedesoft.de/oop-with-goops.html
[+] [-] arh68|11 years ago|reply
[+] [-] pekk|11 years ago|reply
[+] [-] latiera|11 years ago|reply
Also, Java/JVM suck ass, why would anyone willingly work with that whole mess?
[+] [-] bitwize|11 years ago|reply
[+] [-] ajarmst|11 years ago|reply