[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Functional composition in ELisp: add `compose' function?
From: |
Stefan Monnier |
Subject: |
Re: Functional composition in ELisp: add `compose' function? |
Date: |
Sun, 14 Feb 2021 22:02:06 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
> Here's an example definition:
>
> (defun compose (&rest fns)
> (cl-destructuring-bind (fun . rest) (reverse fns)
> (lambda (&rest args)
> (seq-reduce (lambda (v f) (funcall f v))
> rest
> (apply fun args)))))
LGTM (tho I'd use `pcase-let` instead of `cl-destructuring-bind`, of
course).
Note that, sadly, you can use `nreverse` up there.
Note, also sadly, that
(compose #'not #'stringp)
will be significantly less efficient than
(lambda (x) (not (stringp x)))
So we definitely should accompany it with a compiler-macro, which should
be able to macro-expand it to something equivalent to
(lambda (&rest args) (not (apply #'stringp args)))
but note that it's still significantly less efficient than
(lambda (x) (not (stringp x)))
which I find personally quite readable. I wish the byte-compiler was
able to turn
(lambda (&rest args) (not (apply #'stringp args)))
into
(lambda (x) (not (stringp x)))
[ Among other things, I believe it could improve the efficiency of
`cl-generic.el` function calls/dispatch. ]
but it seems difficult/dangerous to do in general.
Stefan