After reading this article about readable closures, I check that:
Since closures are byte-code function objects, they print readably. You can capture an environment in a closure, serialize it, read it back in, and evaluate it. That’s pretty cool! This means closures can be transmitted to other Emacs instances in a multi-processing setup (i.e. Elnode, Async)
So since we can do that, we can also write closures? Should this be a real possibility and will have a real use?
Writing a normal closure
ELISP> (setq counter (let ((x 0)) (lambda () (cl-incf x))))
(closure
((x . 0)
t)
nil
(cl-incf x))
ELISP> (funcall counter)
1 (#o1, #x1, ?\C-a)
ELISP> counter
(closure
((x . 1)
t)
nil
(cl-incf x))
Writing a literal closure:
ELISP> (setq even-counter '(closure ((x . 0) t) nil (cl-incf x 2)))
(closure
((x . 0)
t)
nil
(cl-incf x 2))
ELISP> (funcall even-counter)
2 (#o2, #x2, ?\C-b)
ELISP> even-counter)
*** IELM error *** More than one sexp in input
ELISP> even-counter
(closure
((x . 2)
t)
nil
(cl-incf x 2))
So they both work, and are the same type, since they don't will have non-readable types (i.e buffer) inside they will work equally. further more they are the same type:
ELISP> (type-of even-counter)
cons
ELISP> (type-of counter)
cons
But I couldn't find any constructor for building a closure. So I suppose that his is one of the cases of homoiconicity of lisp. To Sum up:
- Will be useful to write/build literal closures?
- Should it be a good practice? any example?
- Why the closure is not a real type instead of
cons
?