Based on the text you provided, it appears to be a comprehensive comparison of functional programming features across Common Lisp, Racket, Clojure, and Emacs Lisp (specifically eml). The text compares syntax for lists, vectors, dictionaries (hashes), functions, iteration, and control flow.
Since your message ends abruptly at (handler-case, I will complete the missing Emacs Lisp syntax for catching exceptions, followed by a summary table of the key differences observed in your text.
Your text cuts off at the Emacs Lisp catch example. Here is how it typically looks to match the others:
eml)
Catch Exception
(handler-case ... (error-tag error-var) body)
(with-handlers ... (exn-type handler))
(try ... (catch ...))
(condition-case error-var body)
Full Example
(handler-case (error "fail") (error (e) "caught: ~a" (error-message e)))
(with-handlers ((exn:fail? (e) (printf "error"))) (error "fail"))
(try (throw e) (catch e "caught"))
(condition-case e (error "fail") (error "caught: %s" (error-message-string e)))
(Note: In Emacs Lisp with eml, you generally use condition-case rather than catch for exceptions, though catch exists for non-local exits like return-from.)
Here are the specific patterns found in your text:
- Lists:
- Emacs Lisp / CL:
(list 1 2 3)or'(1 2 3)(quoted). - Clojure:
'(1 2 3). - Racket:
'(1 2 3)orlist 1 2 3.
- Emacs Lisp / CL:
- Vectors (Fixed-length arrays):
- Emacs Lisp / CL:
#(1 2 3). - Clojure:
[1 2 3]. - Racket:
#(1 2 3).
- Emacs Lisp / CL:
-
Hashes (Dictionaries):
- Emacs Lisp / CL:
#hash(("key" . val) ...). - Clojure:
{"key" val}(PersistentArrayMap). - Racket:
#hash(("key" . val) ...)or(hash "key" "val").
- Emacs Lisp / CL:
-
Arguments:
- Optional args:
&optional(CL/CL),& [args](Racket),& {:kw v}(Clojure). - Rest args (variadic):
&rest(CL/CL),. rest-var(Racket),& b(Clojure).
- Optional args:
-
Multiple Return Values:
- CL/CL:
multiple-value-bind. - Clojure:
letbinding to a sequence returns a vector/list, usually handled withrestor destructuring. - Racket:
multiple-value-bind(viafor/listorvaluesfunction).
- CL/CL:
-
List Comprehension:
- Clojure:
for [x coll]orfor*for nested loops. - Emacs Lisp: No built-in comprehension; requires
dolistor manualmapcar. - Racket:
for/listorfor/vector.
- Clojure:
-
Filtering:
- CL/CL:
(remove-if-not ...)or(filter ...). - Clojure:
(filter pred coll). - Racket:
(filter pred coll).
- CL/CL:
-
loopconstructs:- Emacs Lisp:
loop [(var init) (when-test)] ... - Clojure:
(loop [i 1 :while (< i 10)] (recur (+ i 1))). - Racket:
(loop [(i 1)] (if (> i 10) (return) (recur (+ i 1)))).
- Emacs Lisp:
This comparison serves as a quick reference guide for porting code or understanding the paradigm differences between these Lisp-family dialects, highlighting how Clojure and Racket lean heavily towards functional idioms (like comprehensions and immutable maps) compared to the more imperative/structural approach often seen in Common Lisp and Emacs Lisp.