diff options
| author | Jonas Bernoulli <jonas@bernoul.li> | 2024-03-23 21:00:10 +0100 |
|---|---|---|
| committer | Jonas Bernoulli <jonas@bernoul.li> | 2024-03-23 21:00:10 +0100 |
| commit | 6ec15b4d6f870c09d7d7704a4f1660f9548c36e8 (patch) | |
| tree | 836e5f3e7e1f2d4e729aa4c1fdb965226a3988e2 | |
| parent | 1fb7e99e097038e97b27d85ee9f7974583ef523f (diff) | |
Make unused arguments at mandatoriness border optional by default
Previously we turned
(##list %1 &3)
into
(lambda (%1 _%2 &optional &3) (list %1 &3))
now we use
(lambda (%1 &optional _&2 &3) (list %1 &3))
The new approach is better because even if the first form would have
been "correct", the latter will nearly¹ always at least be "valid".
The same isn't true for the old approach. If we make an argument
mandatory that should be optional, and the callers does not pass that
argument, that's an error. These cases are several magnitudes more
likely.
¹ The exception being callers that check a functions *minimal* arity
to determine what arguments to pass. In the unlikely case that one
should ever encounter such a caller, one can use an explicit _%N,
as one previously would frequently have had to use _&N.
| -rw-r--r-- | llama.el | 14 |
1 files changed, 10 insertions, 4 deletions
@@ -112,14 +112,20 @@ It also looks a bit like #\\='function." (args (progn (while (and args (null (car args))) (setq args (cdr args))) args)) - (pos 0) + (pos (length args)) + (opt nil) + (args (mapcar + (lambda (arg) + (if arg + (setq opt (string-match-p "\\`_?&" (symbol-name arg))) + (setq arg (intern (format "_%c%s" (if opt ?& ?%) pos)))) + (setq pos (1- pos)) + arg) + args)) (opt nil) (args (mapcar (lambda (symbol) - (setq pos (1+ pos)) (cond - ((not symbol) - (list (intern (format "_%c%s" (if opt ?& ?%) pos)))) ((string-match-p "\\`_?%" (symbol-name symbol)) (when opt (error "`%s' cannot follow optional arguments" symbol)) |
