Elisp: Function Parameters (optional, rest)
Optional Parameters
To have optional parameters, add &optional
at the end of parameter list. Any parameter after that is optional.
- When optional parameter is not given in a function call, the function gets nil for it.
- If a function received a nil as argument for one of its optional parameter, there is no way for a function to know if it is specified by caller or omitted.
;; defining a function with 2 optional params named cc and dd (defun ff (aa bb &optional cc dd) "test optional params" (interactive) (message "%s %s %s %s" aa bb cc dd)) ;; call it (ff 1 2) ;; "1 2 nil nil" (ff 1 2 3) ;; "1 2 3 nil" (ff 1 2 3 4) ;; "1 2 3 4"
Rest Parameters (Unspecified Number of Parameters)
To specify unspecified number of parameters, add &rest name
after the last parameter. In the function, value of name is a list, or nil if not given.
You can have both &optional
and &rest
, in that order.
;; defining a function with rest parameters (defun ff (aa bb &rest cc) "test rest arguments" (message "%s" cc) ; cc is a list ) ;; test (ff "1" "2" "3" "4") ;; ("3" "4")
No Default Values
- Emacs lisp does not support parameter default value.
- Emacs lisp does not support parameter type checking.
Function Keyword Parameters (Named Parameters)
Emacs lisp does not support named parameter.
But by emacs convention, it is emulated using Property List
(defun my-f (x &rest keyword-args) "demo of using plist as optional named params with defult values. Return a string of valid argument values. X is required param. KEYWORD-ARGS is any number of pairs of key and value. The following keys are recognized: :a default to 1. :b default to 2. :c default to 3. Any other key value are ignored." (interactive) (let ((a (or (plist-get keyword-args :a) 1)) (b (or (plist-get keyword-args :b) 2)) (c (or (plist-get keyword-args :c) 3))) (format "param values: x %s, :a %s, :b %s, :c %s" x a b c))) (my-f 3 :b 4 :xx 9) ;; "param values: x 3, :a 1, :b 4, :c 3"
Here's a alternative workaround based on passing a Association List (inspired from JavaScript passing object).
(defun my-g (x &optional xOpt) "demo of using alist as optional named param with defult values. Prints args received. x is required param. xOpt is optional. If given, must be an alist. keys are strings. \"y1\" default to 1. \"y2\" default to 2. \"y3\" default to 3. any other key are ignored." (interactive) (let ((y1 (or (cdr (assoc "y1" xOpt)) 1)) (y2 (or (cdr (assoc "y2" xOpt)) 2)) (y3 (or (cdr (assoc "y3" xOpt)) 3))) (message "param values: x %s, y1 %s, y2 %s, y3 %s" x y1 y2 y3))) (my-g 3 '(("y2" . 99))) ;; prints ;; param values: x 3, y1 1, y2 99, y3 3