eintr: Optional Arguments
5.3.1 Optional Arguments
------------------------
Unless told otherwise, Lisp expects that a function with an argument in
its function definition will be called with a value for that argument.
If that does not happen, you get an error and a message that says ‘Wrong
number of arguments’.
However, optional arguments are a feature of Lisp: a particular
“keyword” is used to tell the Lisp interpreter that an argument is
optional. The keyword is ‘&optional’. (The ‘&’ in front of ‘optional’
is part of the keyword.) In a function definition, if an argument
follows the keyword ‘&optional’, no value need be passed to that
argument when the function is called.
The first line of the function definition of ‘beginning-of-buffer’
therefore looks like this:
(defun beginning-of-buffer (&optional arg)
In outline, the whole function looks like this:
(defun beginning-of-buffer (&optional arg)
"DOCUMENTATION..."
(interactive "P")
(or (IS-THE-ARGUMENT-A-CONS-CELL arg)
(and ARE-BOTH-TRANSIENT-MARK-MODE-AND-MARK-ACTIVE-TRUE)
(push-mark))
(let (DETERMINE-SIZE-AND-SET-IT)
(goto-char
(IF-THERE-IS-AN-ARGUMENT
FIGURE-OUT-WHERE-TO-GO
ELSE-GO-TO
(point-min))))
DO-NICETY
The function is similar to the ‘simplified-beginning-of-buffer’
function except that the ‘interactive’ expression has ‘"P"’ as an
argument and the ‘goto-char’ function is followed by an if-then-else
expression that figures out where to put the cursor if there is an
argument that is not a cons cell.
(Since I do not explain a cons cell for many more chapters, please
DONTPRINTYET consider ignoring the function ‘consp’. How Lists are
Implemented List Implementation, and *noteCons Cell and List Types:
DONTPRINTYET consider ignoring the function ‘consp’. How Lists are
Implemented List Implementation, and Cons Cell and List Types
(elisp)Cons Cell Type.)
The ‘"P"’ in the ‘interactive’ expression tells Emacs to pass a
prefix argument, if there is one, to the function in raw form. A prefix
argument is made by typing the <META> key followed by a number, or by
typing ‘C-u’ and then a number. (If you don’t type a number, ‘C-u’
defaults to a cons cell with a 4. A lowercase ‘"p"’ in the
‘interactive’ expression causes the function to convert a prefix arg to
a number.)
The true-or-false-test of the ‘if’ expression looks complex, but it
is not: it checks whether ‘arg’ has a value that is not ‘nil’ and
whether it is a cons cell. (That is what ‘consp’ does; it checks
whether its argument is a cons cell.) If ‘arg’ has a value that is not
‘nil’ (and is not a cons cell), which will be the case if
‘beginning-of-buffer’ is called with a numeric argument, then this
true-or-false-test will return true and the then-part of the ‘if’
expression will be evaluated. On the other hand, if
‘beginning-of-buffer’ is not called with an argument, the value of ‘arg’
will be ‘nil’ and the else-part of the ‘if’ expression will be
evaluated. The else-part is simply ‘point-min’, and when this is the
outcome, the whole ‘goto-char’ expression is ‘(goto-char (point-min))’,
which is how we saw the ‘beginning-of-buffer’ function in its simplified
form.