Porting Common Lisp code to Clojure

2019-03-08 14:18发布

问题:

How practical is it to port a Common Lisp application to Clojure? To be more specific, what features exist in Common Lisp that do not exist in Clojure, and would have to be re-written?

回答1:

There's a list on clojure.org of differences between Clojure and other Lisps. Some other things I've noticed using Clojure:

  • Idiomatic Clojure leans heavily toward immutable data structures. Anywhere you see SETF in CL may have to be changed in Clojure to take full advantage. (You always have the option of using mutable Java data structures in Clojure, but most people don't.)

  • Clojure's multimethods are similar to CL's (arguably more powerful, because you can dispatch on things other than type) but a full-blown CLOS is not available in Clojure. Clojure uses struct instead, which is just a fancy hashmap. Java's OOP system is also available, of course. Some people are working on porting CLOS to Clojure but I'm not sure how far along those efforts are at this point.

  • Clojure macros work slightly differently than CL macros when it comes to symbol/namespace resolution. I'm not sure if I understand well enough to elucidate the differences. You don't have to mess with gensyms quite as much in Clojure though, which is nice.

  • Clojure doesn't have a condition system like CL's. You have only Java's try/catch/finally for exception handling.

  • Clojure doesn't allow user-defined reader macros.

  • Clojure doesn't have multiple return values. Destructuring in Clojure is very nice (supports lists, vectors, hash-maps, sets etc.) and it's built into more places than CL by default, so this is less of an issue than it could be.

Depending on the app and how it's written, it may be practical and straightforward to port from CL to Clojure, or it may be more practical to rewrite it from the ground up in a more functional, thread-safe way to fit better with Clojure style.



回答2:

I don't have a specific answer, but I'd recommend these resources:

  • Rich Hickey's two part talk Clojure for Lisp Programmers
  • Stuart Halloway's work on translating the examples from Peter Seibel's Practical Common Lisp to Clojure.


回答3:

There are a number of accounts of transitioning from CL to Clojure (blog, another blog, Thread on HN).

The biggest problem a lot of Common Lispers have with Clojure when they first check it out is its lack of Tail Call Optimization, which isn't possible on the the JVM.



回答4:

For idiomatic CL code it's a rewrite.

  • CL is imperative, Clojure is more purely 'functional'.
  • CL is object-oriented (CLOS), Clojure not (uses Java objects and has some OO-mechanisms)
  • Identifiers and syntax are mostly different.
  • Data structures are different.
  • CL is mostly strict (non-lazy), Clojure uses lazy computation.

Even porting the necessary infrastructure (CLOS, Error Handling, Streams) to Clojure makes little sense, since Clojure is really a different language with a different programming style.

If one does not want to rewrite the code, there is for example ABCL, which is a Common Lisp for the JVM.