Functions: April 4, 2013
Functions: April 4, 2013
April 4, 2013
Functional Programming
Functions
Dening functions
In Common Lisp, we can use DEFUN macro to dene functions with name:
>(DEFUN <fct-name> <param-list> [<doc-string>] <body>)
Side effect: A FUNCTION object is created and stored in the function cell of <fct-name> Dene explicitly a FUNCTION object, via a -expression (using the LAMBDA macro)
or, abbreviated: >(setq <var> #(LAMBDA <param-list> <body>))
DEFUN macro
Remarks Any symbol can be used as a function name. <param-list> species the list of variables that will be used to hold the arguments passed to the function when its called. <doc-string> is an optional documentation string; it can be retrieved with the built-in DOCUMENTATION function.
Functional Programming
Lambda expressions
The LAMBDA macro species a nameless function, also known as a -expression: (LAMBDA <param-list> <body>) -expressions are not forms they can not be evaluated. -expressions can be used to build forms.
A form is a list of the form (<meth> <arg1> ... <argn>) where <meth> is either a function name or a -abstraction.
Functional Programming
Lambda expressions
The LAMBDA macro species a nameless function, also known as a -expression: (LAMBDA <param-list> <body>) -expressions are not forms they can not be evaluated. -expressions can be used to build forms.
A form is a list of the form (<meth> <arg1> ... <argn>) where <meth> is either a function name or a -abstraction.
Example
>(defun sqr (x) (* x x)) sqr > (sqr 3) 9 >(lambda (x) (* x x)) #<FUNCTION :LAMBDA (X) (* X X)> >((lambda (x) (* x x)) 3) 9
Functional Programming
Notes funcall is used when we know the number of arguments. apply is used when the number of arguments is unknown.
Functional Programming
Both DEFUN and LAMBDA expect the specication of a list of parameters <param-list> Both DEFUN and LAMBDA have an implicit block construct which binds the list of parameters to the argument values of function calls. General form of <param-list>
<param-list> ::= (<var>* [&optional <opt-par-spec>*] [&rest <var>] [&key <key-par-spec>* [&allow-other-keys]] [&aux <aux-par-spec>*])
where &optional, &rest, &key and &aux are special symbols, known as -list symbols.
Functional Programming
Lists of parameters
Required and optional parameters
<var>* indicates a xed number of required mandatory parameters. Function calls must provide values for them. <opt-par-spec>* species zero or more optional parameters: <opt-par-spec> ::= (<var> <init-value> <svar>) where
<var> is the variable name <init-value>: implicit value, when no argument is given for it. <svar>: variable which is bound to T when an argument is provided for <var>, and to nil otherwise.
<svar> indicates there presence of <var>
Functional Programming
Optional parameters
(lambda ... &optional <opt-par-spec>* ... ) <opt-par-spec> ::= (<var> <init-value> <svar>)
Functional Programming
The arguments that remain after we bind the mandatory parameters are bound as a list to <var> Example >((lambda (a &optional b &rest c) (list a b c)) 1 2 3 4) (1 2 (3 4)) >((lambda (a &optional b &rest c) (list a b c)) 1 2) (1 2 nil) >((lambda (a &optional b &rest c) (list a b c)) 1) (1 nil nil)
Functional Programming
where <kword>: keyword associated with the parameter variable <var>: variable name <init-value>: implicit value svar: indicates the presence or absence of a corresponding argument for <var>
Functional Programming
Functional Programming
Argument order is irrelevant &rest does not affect the bindings to &key arguments &allow-other-keys allows to use keywords which were not specied in the -list of parameters.
((<kword> <var>)) is equivalent to ((<kword> <var>) nil) ((x) <expr>) is equivalent to ((:x x) <expr>) ((:x x)) is equivalent to (x) and to x
Functional Programming
>(defun foo (x &optional y &key z) (list x y z)) foo >(foo 1 2 :z 3) (1 2 3) >(foo 1) (1 nil nil) >(foo 1 :z 3) ;will signal an error
Functional Programming
>(defun foo (x &optional y &key z) (list x y z)) foo >(foo 1 2 :z 3) (1 2 3) >(foo 1) (1 nil nil) >(foo 1 :z 3) ;will signal an error
keyword :z is taken as a value to ll the optional y parameter, leaving only the argument 3 to be processed.
Functional Programming
>(defun foo (x &optional y &key z) (list x y z)) foo >(foo 1 2 :z 3) (1 2 3) >(foo 1) (1 nil nil) >(foo 1 :z 3) ;will signal an error
keyword :z is taken as a value to ll the optional y parameter, leaving only the argument 3 to be processed. At that point, Lisp will be expecting either a keyword/value pair or nothing and will complain.
Functional Programming
Auxiliary parameters
&aux <aux-par-spec>* allows to dene variables which are local to the function body.
<aux-par-spec>::= (<var> <expr>)
Functional Programming
Auxiliary parameters
Exercise Figure out what is the meaning of the arguments of the following denition:
(lambda (ob1 ob2 &optional (op1 ob1 s1) (op2 (if s1 op1 ob2)) &key (k (list ob1 ob2 op1 op2) s2) &aux (a (and s1 s2))) ...)
Functional Programming
Functions
We distinguish global functions (dened with DEFUN) and local functions (dened with FLET and LABELS). FLET construct (flet ((<f-name1> <par-list1> <e> <e> ... <e>) (<f-name2> <par-list2> <e> <e> ... <e>) ... (<f-namen> <lista-parn> <e> <e> ... <e>)) <expr> <expr> ... <expr>)
Functional Programming
FLET functions
>(defun foo (x) (+ x 1)) foo >(flet ((foo (x) (- x 1))) (foo 10)) 9 >(foo 10) 11
Functional Programming
Local functions
LABELS construct (labels ((<f-name1> <par-list1> <e> <e> ... <e>) (<f-name2> <par-list2> <e> <e> ... <e>) ... (<f-namen> <lista-parn> <e> <e> ... <e>)) <expr> <expr> ... <expr>) Locally dened functions can refer to each other. Locally dened functions can also be dened recursively.
Functional Programming
LABELS
Example
>(defun foo1 (x) (+ x 1)) >(flet ((foo1 (x) (- x 1)) (foo2 (x) (foo1 x))) (foo2 10)) 11 >(labels ((foo1 (x) (- x 1)) (foo2 (x) (foo1 x))) (foo2 10)) 9
Functional Programming
Can not be called outside the FLET or LABELS constructs. The visibility area for BLOCK and TAGS can not be affected by FLET and LABELS The visibility area of variables can not be affected by FLET and LABELS
Functional Programming
Example Construct and return a function that increments its argument with a specied value:
>(defun adder (n) #(lambda (x) (+ x n))) >(setq ad3 (adder 3)) >(funcall ad3 5) 8 >(funcall (adder 4) 5) 9
Functional Programming
Example A function that builds the function g f from the function arguments f and g >(defun compose (f g) #(lambda (x) (funcall >(setq f1 #(lambda (x) (+ g1 #(lambda (x) (* > (funcall (compose f1 g1) 10 > (funcall (compose g1 f1) 16 f (funcall g x)))) x 1)) x x))) 3) 3)
Functional Programming
Dene a function sum-f such that (sum-f f n) computes 1 the sum n i =0 f (i ) >(defun sum-f (f n &aux (sum 0)) (dotimes (i n sum) (setq sum (+ (funcall f i) sum)))) >(defun sqr (x) (* x x)) >(sum-f sqr 4) 14
Functional Programming
Functional arguments
The following calls are equivalent: (apply (apply (apply (apply f f f f (1 2 3)) 1 (2 3)) 1 2 (3)) 1 2 3 nil)
Example >(defun sumf1 (f n &rest x &aux (sum 0)) (dotimes (i n sum) (setq sum (+ (apply f i x) sum)))) >(sumf1 * 4 2) 12 >(sumf1 + 4 1) 10
Functional Programming
Functional arguments
The functional argument can be a symbol (function name) lambda-expression function denition lexical closure
Functional Programming
Quiz
Dene a function map such that (map f (a1 . . . an )) computes the list ((f a1 ) ... (f an )). Dene a function zip such that (zip f (a1 . . . am ) (b1 . . . bn )) computes the list (c1 . . . cp ) where
p = min(m, n) ci = f (ai , bi ) for 1 i p.
3
Dene a function iter such that (iter f n) returns a function g which has the following property:
g (x ) = f (f (. . . f (x ))) for all x .
n times
If n = 0 then g (x ) = x .
Functional Programming