8 ms·
> the language isn’t CLOS all the way down I'm curious what you mean by this, why it's needed or would be a good thing, etc. As a multi-paradigm language, I'm
by dwc 8y ago
> the language isn’t CLOS all the way down
I'm curious what you mean by this, why it's needed or would be a good thing, etc. As a multi-paradigm language, I'm not seeing why CL should have a particular paradigm "all the way down".
- throwaway487548 8y agoUniformity, which is a really good thing. Surely you could say (class-of 3) or (class-of nil) or (class-of '(1 2 3)) but technically these values are not objects, like it is in, say, Scala, which is a real-world example of how good it is to have a uniform language (everything is an expression, every value is an instance of a class, and therefore everything is uniformly high-order, uniformly typed (unlike Java with distinctions of so-called primitive types) etc, etc.
- e12e 8y agoBut would such a common lisp be better than something like Dylan?
- mikelevins 8y agoIt would not be better than circa-1992 Dylan. It would be better than present-day Dylan, though. My opinion only, of course.
- junke 8y agoEvery value in CL is an instance of class. Some of those classes are built-in classes, which are restricted for performance reason. You do not inherit from Int in Scala either, since it is marked as "final", as far as I know.
- throwaway487548 8y agoIn Scala an integer has methods, like everything else, unlike it is in Java and C++, and this is the point and the big deal. 3 + 2 is actually 3.+(2) which is the right thing.
- junke 8y ago"+" is a function, what makes it "right" to be a method?
- jhbadger 8y agoa function is just a method that returns a value. Why make a special case for it? Of course you can go the other direction and allow functions to return nothing (or a representation of nothing like nil). That's fine too.
- pfdietz 8y agoYou mean, what makes it right to be a generic function that has methods? First, + does dynamic dispatch based on the types of its arguments. It does different things when adding fixnums, vs. integers, vs. rationals, and so on, as well as a default method that signals a type error (in safe code). So it has methods, even if they aren't necessarily implemented as standard methods (but they could be). Secondly, a user might want to make + work on other, user-defined classes (for example, if he user wanted it to work on a class representing quaterions). To make that work, the user would have to be able to add methods for those classes. One can imagine many CL builtins being implemented as generic functions to which users could add methods. This would be consistent with the standard.
- kbp 8y agoYou can specialise generic functions on built-in classes in standard CL. Lisp methods are specialisations of generic functions; they don't belong to a class in the way methods do in eg C++. The issue you're talking about is that not all functions are generic functions in Common Lisp, and you can't specialise ordinary functions. There's nothing stopping you from doing (defmethod add ((x number) (y number)) (+ x y)) (defmethod add ((x string) (y string)) (concatenate 'string x y)) or whatever (multiple dispatch, too), and you could even call it + instead of ADD if you wanted (but not COMMON-LISP:+, so other code would continue to work; your packages could import your + instead of the standard one).
- dwc 8y agoUniformity through imposing one paradigm on everything isn't attractive at all to me, especially for a paradigm I have no interest in using and avoid when I practically can.
- mikelevins 8y agoIt's good because it offers the opportunity to simplify and rationalize the type system and associated protocols without losing features. In the early 1990s I worked on an experimental Newton OS written in Dylan. At that time, Dylan was still called "Ralph," and it was basically an implementation of Scheme in which all datatypes were CLOS classes. It was "CLOS all the way down." Ralph offered substantially the same affordances and conveniences as Common Lisp, but with a simpler and more coherent set of APIs. Ralph was easier to learn and remember, and easier to extend. To illustrate why, consider finite maps. The idea of a finite map is a convenient abstraction with a well-defined API. Common Lisp offers a couple of convenient ways to represent finite maps, and it's easy to build new representations of them, but there's no generic API for finite maps. Instead, each representation has its own distinct API that has nothing particularly to do with anything else. By contrast, Ralph had a single well-defined API that worked with any representation of finite maps, whether built-in or user defined. The upshot is a library of datatypes that is just as rich as Common Lisp's, but with a simpler and more coherent set of APIs, and an easy standard way to extend them with user-defined types that also support the same APIs. There are signs in the Common Lisp standard that people were already thinking in that direction when the standard was defined. See the sequence functions, for example. Ralph, designed by Common Lisp and Smalltalk implementors, carried that thinking to its logical conclusion, and the result was something like a tidier Common Lisp. Twenty-eight years later, Ralph is still my favorite of all the languages I've used for serious work. Its development system, Leibniz, remains my favorite development system. My favorite current tools are Common Lisp systems, but that's because I can't have Ralph and Leibniz anymore.
- mindcrime 8y agoMy favorite current tools are Common Lisp systems, but that's because I can't have Ralph and Leibniz anymore. You said below that you don't find modern day Dylan to be as valuable. I don't know much about Dylan, either the pre-1992 version or the newer version(s), but I'm curious if you would elaborate on why the older Dylan was so much superior to modern Dylan in your view?
- mikelevins 8y ago