|
Well, I'm not seeing as much activity on CL. But for me, it's mostly a practical reason. I can easily use Clojure or sprinkle some around in most enterprise context because it runs in a symbiosis with existing platforms like the JVM, the CLR, and the various Javascript VMs. So it's much more usable in my day to day. I also feel that CL and Racket have embraced types a lot more. Doesn't CL have a fair bit of static typing already? And with Racket, Typed Racket has pretty much pioneered the concept of gradual typing now being applied to JS, Python and Ruby. I know Racket also explored contracts, and has a lot of great ideas. But I feel overall it's missing the: "and we dog food it all on real business use cases in production" aspect that Clojure has. And for CL, it doesn't seem to have as much in terms of contracts, data DSLs, immutability, simpler primitives, etc. It feels more like a traditional mutable, OOP, dynamic language. It has nailed down the interactive development part though. I don't want to put it down as I'm interested to try more of CL, but overall, it just doesn't seem as active or opinionated anymore. If anything, CL seems to lack any form of opinion, and goes more for the: we just add all features of every other language. Which is a quality on its own, but not driving the discussions forward either. |
Second, compilers can use type information (or inlining hints, etc.) to compile efficient machine code, which you can inspect with the built-in function 'DISASSEMBLE.
Third, types are used in the CLOS system to support efficient multiple dispatch for multimethods, and the rest of the CLOS and MOP machinery that makes it a very "non-traditional" (despite CLOS being first to ANSI standardize) OOP system with a lot more power than other fashionable languages provide. I'm basically in agreement with the title of http://www.smashcompany.com/technology/object-oriented-progr... with the caveats that Lisp is different and an exception (even if not perfect, there's an unfortunate mismatch in methods not allowing any type for dispatching on, though you can work around it in a similar fashion to Clojure's multimethods of dispatching on a runtime value) and that carefully designed Java can make the forced OOP tolerable.
CL is also super dynamic and lets you redefine basically everything so none of this is truly "static", and that's why compilers will warn rather than error, and runtimes while developing will preserve your state and drop you in a debugger instead of destroying state, printing a stacktrace, and giving up, because you can fix it and recompile that little bit or rerun after defining a missing variable. CL's conditions and restarts system has yet to be convincingly cloned by other languages.
Contracts, DSLs, immutable data structures, simple primitives, and other things (some not present in any other languages) are available in CL... My own reading has found that a lot of them have been there or in the predecessors to the CL standardization or in things built on top since for a long time (some well before I was born) and explored by big production business applications, not just academic exercises... Some of course are more modern transplants as they haven't gotten popular until recently. But for the things that were there already, in a sense the discussions have already been done and may help explain the lack of driving force for them now. In other languages I see them driving themselves close to where CL already is more often than driving to a completely new place (but then CL provides and lets you go there too, or at least somewhere close). You're free to use these things in CL, or not; you're right that it's not an opinionated language and I'd argue never was. Fortunately there's enough capability for modularization that we can have different opinions (e.g. the meaning of syntax like [Click me] in a UI component) and still trivially share code. It's a shame that Clojure code and CL code can't be trivially shared.