Live data from Hacker News

Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp

hyperpolyglot.org

41–48 of 48 posts

Re: Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp

#41
post #6

I know that the purpose of the page is to compare syntax of common lisp, racket, clojure, and emacs lisp. But some examples could be more idiomatic, for instance instead of (defun add (a &rest b) (if (null b) a (+ a (eval (cons '+ b))))) One should avoid eval and use endp instead of null: (defun add (a &rest b) (if (endp b) a (apply #'add (+ a (first b)) (rest b))))

(defparameter *a* '(1 2 3)) (setf (car *a*) 3) And this is undefined behavior because it mutates literal constant. I stopped reading further. The CL column is so bad.

The trap is using quote, with the list operator there are no issues:

    (defparameter *a* (list 1 2 3))
and of course, mutating top-level variables is bad style.

Re: Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp

#42
post #36
post #6

I know that the purpose of the page is to compare syntax of common lisp, racket, clojure, and emacs lisp. But some examples could be more idiomatic, for instance instead of (defun add (a &rest b) (if (null b) a (+ a (eval (cons '+ b))))) One should avoid eval and use endp instead of null: (defun add (a &rest b) (if (endp b) a (apply #'add (+ a (first b)) (rest b))))

The use of cl:eval alone is enough to make me believe that the CL column was never reviewed by an experienced CL programmer. I am now more suspicious of the other columns, which are languages I'm far less familiar with.

> I am now more suspicious of the other columns, which are languages I'm far less familiar with.

It's not bad but for Clojure for example it says "nil is like null in Java" but null in Java is not falsy.

And it also says that destructuring is "named parameters" but it's not so: it's just destructuring (and there are two examples of destructuring given: one for the "named parameters" which aren't named parameters, and one for "parallel assignment" of local variables).

Nothing bad but it's not possible to go into much details in such a table.

Re: Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp

#43
post #20

Nice comparison. But makes me think we'd be better off if we all just focused on a single one, and grew it, made it better. Not having 4 versions of something almost identical. Fragmentation can hurt adoption.

They are as different from one another as Java is from C# is from JavaScript.

So, not by much?

Re: Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp

#44
post #6

I know that the purpose of the page is to compare syntax of common lisp, racket, clojure, and emacs lisp. But some examples could be more idiomatic, for instance instead of (defun add (a &rest b) (if (null b) a (+ a (eval (cons '+ b))))) One should avoid eval and use endp instead of null: (defun add (a &rest b) (if (endp b) a (apply #'add (+ a (first b)) (rest b))))

Shouldn't it be (+ a (apply + b))

No, the idea is to assume for this example that + only can be used with two arguments and define a new function that can be used with any number of arguments.

Re: Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp

#46
post #26

Clojure 1.6, Emacs 24.5... These are pretty old versions, at least of those.

To be fair I think the only real differences since 1.6 you’d see are transducer versions of some of what’s in here for Clojure. The stuff expressed here is all very basic.

There is a difference with the very first line item, though minor: "clojure --version" is available. True that transducers aren't going to be a part of this comparison.

Re: Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp

#47
post #39
post #35

CL list comprehension: (loop for file across "ABCDEFGH" nconc (loop for rank from 1 to 9 collect (format nil "~C~D" file rank)))

Or with more Python-esque syntax: (let ((files (coerce "ABCDEFGH" 'list)) (ranks (loop for r from 1 to 9 collect r))) [(format nil "~a~a" file rank) (file Based on the list comprehension macro from 1991 in https://3e8.org/pub/scheme/doc/lisp-pointers/v4i2/p16-lapalm... that still works. (defmacro comp ((e &rest qs) l2) (if (null qs) `(cons ,e ,l2) ; rule A (let ((q1 (car qs)) (q (cdr qs))) (if (not (eq (cadr q1) ' Su…

I didn't try macroexpanding it yet, but when I make the 9 a runtime-parameter, I eventually get a stack-overflow with SBCL not TCO-ing the "H" binding in labels.

The comments make me think this is ported from scheme, which has precise TCO rules.

[edit] macroexpanded:

    (LABELS ((H-37 (US-38)
               (IF (NULL US-38)
                   NIL
                   (LET ((FILE (CAR US-38)) (US1-39 (CDR US-38)))
                     (LABELS ((H-43 (US-44)
                                (IF (NULL US-44)
                                    (H-37 US1-39)
                                    (LET ((RANK (CAR US-44)) (US1-45 (CDR US-44)))
                                      (CONS (FORMAT NIL "~a~a" FILE RANK) (H-43 US1-45))))))
                       (H-43 RANKS))))))
      (H-37 FILES))

Re: Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp

#48
post #17

Perhaps related, I'm maintaining a "cheatsheet" to let Python programmers see what an Elisp equivalent to typical Python functions/methods are. https://kickingvegas.github.io/elisp-for-python/

Are `(push s x)` and `(push x s)` correct for push and insert, resp.?

Oh dang, thanks for catching that. Will amend.
Post reply on HN