Function: llama

llama is an autoloaded macro defined in llama.el.

Signature

(llama FN &rest BODY)

Documentation

Expand to a lambda expression that wraps around FN and BODY.

This macro provides a compact way to write short lambda expressions. It expands to a lambda expression, which calls the function FN with arguments BODY and returns its value. The arguments of the lambda expression are derived from symbols found in BODY.

Each symbol from %1 through %9, which appears in an unquoted part of BODY, specifies a mandatory argument. Each symbol from &1 through
&9, which appears in an unquoted part of BODY, specifies an optional
argument. The symbol &* specifies extra (&rest) arguments.

The shorter symbol % can be used instead of %1, but using both in the same expression is not allowed. Likewise & can be used instead of &1. These shorthands are not recognized in function position.

To support binding forms that use a vector as VARLIST (such as -let from the dash package), argument symbols are also detected inside of vectors.

The space between ## and FN can be omitted because ## is read-syntax for the symbol whose name is the empty string. If you prefer you can place a space there anyway, and if you prefer to not use this somewhat magical symbol at all, you can instead use the alternative name llama.

Instead of:

  (lambda (a &optional _ c &rest d)
    (foo a (bar c) d))

you can use this macro and write:

  (##foo %1 (bar &3) &*)

which expands to:

  (lambda (%1 &optional _&2 &3 &rest &*)
    (foo %1 (bar &3) &*))

Unused trailing arguments and mandatory unused arguments at the border between mandatory and optional arguments are also supported:

  (##list %1 _%3 &5 _&6)

becomes:

  (lambda (%1 _%2 _%3 &optional _&4 &5 _&6)
    (list %1 &5))

Note how _%3 and _&6 are removed from the body, because their names begin with an underscore. Also note that _&4 is optional, unlike the explicitly specified _%3.

Consider enabling llama-fontify-mode(var)/llama-fontify-mode(fun) to highlight ## and its special arguments.

Aliases

##

Source Code

;; Defined in ~/.emacs.d/elpa/llama-20260301.1253/llama.el
;;;###autoload
(defmacro llama (fn &rest body)
  "Expand to a `lambda' expression that wraps around FN and BODY.

This macro provides a compact way to write short `lambda' expressions.
It expands to a `lambda' expression, which calls the function FN with
arguments BODY and returns its value.  The arguments of the `lambda'
expression are derived from symbols found in BODY.

Each symbol from `%1' through `%9', which appears in an unquoted part
of BODY, specifies a mandatory argument.  Each symbol from `&1' through
`&9', which appears in an unquoted part of BODY, specifies an optional
argument.  The symbol `&*' specifies extra (`&rest') arguments.

The shorter symbol `%' can be used instead of `%1', but using both in
the same expression is not allowed.  Likewise `&' can be used instead
of `&1'.  These shorthands are not recognized in function position.

To support binding forms that use a vector as VARLIST (such as `-let'
from the `dash' package), argument symbols are also detected inside of
vectors.

The space between `##' and FN can be omitted because `##' is read-syntax
for the symbol whose name is the empty string.  If you prefer you can
place a space there anyway, and if you prefer to not use this somewhat
magical symbol at all, you can instead use the alternative name `llama'.

Instead of:

  (lambda (a &optional _ c &rest d)
    (foo a (bar c) d))

you can use this macro and write:

  (##foo %1 (bar &3) &*)

which expands to:

  (lambda (%1 &optional _&2 &3 &rest &*)
    (foo %1 (bar &3) &*))

Unused trailing arguments and mandatory unused arguments at the border
between mandatory and optional arguments are also supported:

  (##list %1 _%3 &5 _&6)

becomes:

  (lambda (%1 _%2 _%3 &optional _&4 &5 _&6)
    (list %1 &5))

Note how `_%3' and `_&6' are removed from the body, because their names
begin with an underscore.  Also note that `_&4' is optional, unlike the
explicitly specified `_%3'.

Consider enabling `llama-fontify-mode' to highlight `##' and its
special arguments."
  (cond ((symbolp fn))
        ((and (eq (car-safe fn) backquote-backquote-symbol)
              (not body))
         (setq body (cdr fn))
         (setq fn backquote-backquote-symbol))
        ((signal 'wrong-type-argument
                 (list 'symbolp backquote-backquote-symbol fn))))
  (let* ((args (make-vector 10 nil))
         (body (cdr (llama--collect (cons fn body) args)))
         (rest (aref args 0))
         (args (nreverse (cdr (append args nil))))
         (args (progn (while (and args (null (car args)))
                        (setq args (cdr args)))
                      args))
         (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)
                  (cond
                    ((string-match-p "\\`_?%" (symbol-name symbol))
                     (when opt
                       (error "`%s' cannot follow optional arguments" symbol))
                     (list symbol))
                    (opt
                     (list symbol))
                    ((setq opt t)
                     (list '&optional symbol))))
                (nreverse args))))
    `(lambda
       (,@(apply #'nconc args)
        ,@(and rest (list '&rest rest)))
       (,fn ,@body))))