4 ms·
If I remember correctly, LFE is a Lisp2 Joxa (just like Clojure) is a Lisp1, thus maybe more apt http://joxa.org http://joxa.org
by berdario 10y ago
If I remember correctly, LFE is a Lisp2
Joxa (just like Clojure) is a Lisp1, thus maybe more apt
http://joxa.org http://joxa.org
- glogla 10y agoI'm curious, what are the practical differences? I know what the theoretical differences are, but do you have any experience with how lisp1 and lisp2 are different in daily use?
- berdario 10y agoI'm afraid I don't have a satisfactory answer for you. I just prefer to pass around functions/closures as values, and being able to invoke them like any normal function, instead of having to call an helper `apply`/`invoke`/`call` function on them (depending on the language) That's why I said: "maybe more apt"... if OP doesn't care at all about that difference, and it's not among the details that they'd want to replicate from Clojure, it's perfectly ok to ignore
- patrec 10y agoI never found the funcall argument terribly convincing, because there is no reason it couldn't be much more concise. And it allows you to avoid silly variable names like lst or fst. In Common lisp to refer to a function as a variable you do (function f) or as (read-table) syntactic sugar #'f. You could easily use destructuring to write HOFs without funcall. So instead of requiring people to write (defun bad-map (f list) "Maps function `f' over `list', inefficiently." (when list (cons (funcall #'f (first list) (bad-map f (rest list))))) (bad-map #'- '(1 2 3)) A hypothetical lisp-2 could just as well allow destructuring like this: (defun bad-map (#'f list) "Maps function `f' over `list', inefficiently." (when list (cons (f (first list) (bad-map #'f (rest list))))) (bad-map #'- '(1 2 3)) The fact that higher order functions stick out a bit by the extra #' is not necessarily a bad thing IMO; it helps when reading unfamiliar code to know immediately what arguments are functions and which ones are just plain objects.
- lispm 10y agoIn Common Lisp in your first example it's not (funcall #'f (first list) ...) but (funcall f (first list)) ... f is already a function object. We could write a macro for that or a new version of defun. Here just a macro lisp1fy: (defmacro lisp2fy ((&rest calls) &body body) `(flet (,@(loop for (f . args) in calls collect `(,f ,args (funcall ,f ,@args)))) (declare (inline ,@(loop for (f . nil) in calls collect f))) ,@body)) (defun bad-map (f list) "Maps function `f' over `list', inefficiently." (lisp2fy ((f a)) (when list (cons (f (first list)) (bad-map f (rest list))))))
- patrec 10y agoYeah, braino -- thanks. A custom binding form would be another way to do it, but I'd prefer the pseudo-destructuring -- cleaner and more concise. I'd hope a new lisp-2 dialect would come with better destructuring support for defun and binding forms anyway (destructuring-bind, multiple-value-bind and flet could all be subsumed by let if (values ...) (function ...) where valid left hand patterns).
- rvirding 10y agoI just felt that as you can many functions with the same name but with different arities (number of args) at the top-level why shouldn't I be allowed to have it deeper down as well. Also this means that I can only sometimes refer to a function with just its name, when it is at the top-level you need need both name and arity. This means that Lisp-1 doesn't really fit anyway so why let it limit you?