@rml CLOS and MOP are better respect many Scheme OOP libraries.
Generic functions are used also in contexts different from OOP.
CL macros are easier to write.
The error and exception handling of CL is very powerful and useful.
But the real answers for me are these:
1) CL live coding (i.e. interactive REPL) is very fun and addictive
2) there are many CL compilers with different characteristics at run-time accepting the same CL code, and that you are sure that you can use in production. For example with ECL you can produce C-friendly libraries.
3) a minor detail, but I like the fact that "nil" stays for false, and every other value for "true". The code become shorter.
@rml I'm not an expert of CL, and I only played some weeks with Racket. So I'm not an expert of Scheme too.
BTW, my 2cents are that regarding CLOS, it is very complete and it is a standard of CL. So there are a lot of CL libraries using it, and it is fully integrated in the development experience.
If your OOP code is slow, you can optimize the way objects are managed, and slots are stored in RAM, using MOP. For example with MOP you can store the coordinates of point objects in a compact array (i.e. row-store), despite you access them like normal objects.
@mzan yeah, I did the Guile MOP tutorial and was extremely impressed. In general CLOS seems amazing, I need to spend more time with the Guile implementation. Its a shame that so much of the FP hoopla has caused people to think objects are evil and corellated with hazardous use of global mutable state.
@rml regarding exception handling, the correct name is "Condition System". It is an approach more similar to Erlang, where you have common code for intercepting and managing certain classes of errors in an uniform way.
I didn't understood if the limitation about Coalton are regarding run-time errors, or compile-time errors. The condition system is only about management of run-time errors or run-time exceptional conditions.
It can be used also for implementing effects, when it is sufficient a manipulation of the stack. Otherwise Scheme continuations are more powerful.
@rml regarding `nil`: in CL it stays for the empty list and for the false value. There is no false value in CL. There is no true value in CL. Everything that is not `nil` is considered a true value.
To be sincere, it is an hack respect the elegance of Haskell algebraic approach. But, it is a convention that fits very well in the CL code and its usual semantic. For example `(or (car some-list) 0)` return the first non-nil value. It seems an hack like 0 and 1 that in C is false and true, but instead it allows to write very composable code. So it is a powerful and elegant hack.
On all other points, or I agree with you, or I trust you, because you seems more knowledgeable than me.
@mzan if you ever have some time to dig into scheme I would recommend reading Dybvig's The Scheme Programming Language (book proper is about K&R size + 200 pages of examples) as well as @spritelyinst's short and straight to the goods primer on contemporary scheme programming: https://spritely.institute/static/papers/scheme-primer.html
I think TSPL will give you a pretty broad sense of what scheme has that other programming languages are lacking. Of course, you pay for that at the expense of a having large ecosystem access. But I think part of the fun of learning scheme is learning to do ad-hoc implementation of low level interfaces, treating scheme as a kind of quantum duct tape that allows you to simply pause ports as suspendable continuations, making doing lots lower level io stuff simple.
But yeah, continuations aside CLisp certainly wins when it comes to port interfaces, it has everything and more.
@rml at best of my (limited) knowledge, I think that after some time you understand if you prefer Scheme or CL. CL is a little more on the "hacking side", while Scheme is a little more on the computer-science/elegant side.
The most advanced thing I tried with Racket is some code using the Nanopass compilation framework. I were impressed. Also Typed Racket is very good and readable.
But for some inexplicable reason, I feel more productive and happy using CL. It is less elegant, but it is so much powerful and production-oriented.
So, I will not read your book, because time is limited and I had yet dedicated some time to Scheme.
@mzan
// CLOS and MOP are better in every respect to many Scheme OOP libraries
It seems to me this can be said at the level of implementation, but there isn't much "out of reach" (in terms of having to alter the scheme implementation in order to implement certain CLOS features). afaik CLOS is primarily better than for example GOOPs because its faster and very refined. But I realize I'm unfamiliar with some of the deeper functionality that CLOS might offer that would be difficult to achieve with a scheme implementation, and interested to understand what that might be.
// Generic functions are used also in contexts different from OOP
We have define-generic which works (afaik) just like CL's defgeneric. I'm interested in understanding the limitations of scheme's various CLOS implementations though, because its a topic I have a growing interest in
// CL macros are easier to write.
This is definitely true, but most major scheme implementations include defmacro. Still, I prefer hygienic macros.
// The error and exception handling of CL is very powerful and useful.
But as powerful as scheme? I know that Robert Smith said that the lack of syntax-objects are a major obstacle in providing the DX he would like to for Coalton, because they provide source location information and other very valuable introspective facilities for providing really nice errors. And that's something "out of reach" for CL
// But the real answers for me are these:
//1) CL live coding (i.e. interactive REPL) is very fun and addictive
I agree SLIME is very fun, but its not my style (I find it jarring). But if you want SLIME style debugging, MIT Scheme provides a similar experience. My ideal is the Chez "expeditor" debugger; it provides incredibly powerful reflective editing that i imagine are out of common lisp's reach due to lack of first class continuation support.
// 2) there are many CL compilers with different characteristics at run-time accepting the same CL code, and that you are sure that you can use in production. For example with ECL you can produce C-friendly libraries.
This is CL's major draw IMO
// 3) a minor detail, but I like the fact that "nil" stays for false, and every other value for "true". The code become shorter.
Nil is true for false and false for true? Sorry having trouble parsing this, perhaps because its been a couple years since I looked at CL. In scheme we have #f and '()