160 likes | 179 Views
The programming language LISP has a unique capability to return multiple values or none at all from a single function call. By using functions like values, floor, ceiling, and multiple-value-bind, LISP can efficiently handle multiple return values. This guide covers topics such as receiving and ignoring extra return values, using multiple-value-call and multiple-value-list, as well as dealing with unlimited and optional arguments using &rest, &optional, and &key parameters.
E N D
Multiple Returns and Extra Parameters “LISP is unique in its capability to return more than one value (or no value at all) from a form. This neatly avoids the problems which other languages are prone to when more than one object is produced or affected by a function.” -Star Sapphire Common Lisp Refernce Manual
Returning Multiple Values • Any mathematical function returns exactly one value, and that’s usually true in LISP • The exception to this is values (values S-expression*) • Takes an arbitrary number of return values and returns all of the separately
>(floor 10.5) 10 0.5 >(+ (floor 10.5) 7) 17 >(ceiling 3.2) 4 -0.79999999999999982 >(+ (ceiling 3.4) (floor 2.8)) 6 Extra return values are ignored if they aren’t expected Floor, Ceiling
Returning with Values >(defun print-and-return-nothing () (format t "Hi") (values)) PRINT-AND-RETURN-NOTHING >(print-and-return-nothing) Hi >(values) >(values 1 (car '(a b)) 2) 1 A 2
Receiving Multiple Values • multiple-value-bind operates like let, except local variables are initialized by the multiple return values • If there are more variables than values, those left over will be nil • If there are more values than variables, the extra values are discarded
Multiple-Value-Bind Examples >(multiple-value-bind (x y z) (values 1 2 3) (list x y z)) (1 2 3) >(multiple-value-bind (x y z) (values 1 2) (list x y z)) (1 2 NIL)
Other Multiple Value Functions • multiple-value-call applies a given function to the multiple values returned by some function >(multiple-value-call #'+ (values 1 2 3)) 6 • Multiple-value-list collects the values returned into a list >(multiple-value-list (values 1 2 3)) (1 2 3)
Returns multiple values indicating the current data and time >(get-decoded-time) 33 37 17 9 9 2008 1 NIL 5 Seconds Minutes Hours Day Month Year Day of Week Daylight Savings Time Zones West of GMT Get-Decoded-Time
Unlimited Arguments • Some functions take an indefinite number of arguments (+, *, etc.) • To indicate a parameter that may occur zero or more times, put &rest in front of it • The variable following &rest will be bound to a list of the remaining arguments
&rest Example >(defun test-rest (a b &rest c) (list a b c)) TEST-REST >(test-rest 'a 'b 'c) (A B (C)) >(test-rest 5 6) (5 6 NIL) >(test-rest 'a 56 27 'b 'foo 'y 60) (A 56 (27 B FOO Y 60))
Optional Argument • An optional argument is one that may or may not be present • Indicated with &optional • Can specify in three ways • name: defaults to nil • (name default): defaults to default • (name default supplied-flag): defaults to default, and supplied-flag is t if given, nil otherwise
&optional Example >(defun test-optional (a &optional b (c 3) (d 4 e)) (list a b c d e)) TEST-OPTIONAL >(test-optional 1) (1 NIL 3 4 NIL) >(test-optional 1 2) (1 2 3 4 NIL) >(test-optional 1 2 6) (1 2 6 4 NIL) >(test-optional 1 2 7 9) (1 2 7 9 T)
Keyword Arguments (1) • A keyword is a symbol whose first character is colon (:) • Can’t have values changed • Predicate for keywords is keywordp • Indicated with &key
Keyword Arguments (2) • Three ways to specify keyword arguments • name: called with :name, default is nil • (name default): defaults to default • (name default supplied-flag): as with optional parameters • In all of the above, name can be replaced with (:keyword name), where :keyword is used in the call, and name within the function definition
&key Example >(defun test-key (a &key b (c 3) (d 4 e) ((:key f) 5)) (list a b c d e f)) TEST-KEY >(test-key 1) (1 NIL 3 4 NIL 5) >(test-key 1 2) Error >(test-key 1 :b 2) (1 2 3 4 NIL 5) >(test-key 1 :c 12) (1 NIL 12 4 NIL 5) >(test-key 1 :d 14) (1 NIL 3 14 T 5) >(test-key 1 :key 30) (1 NIL 3 4 NIL 30) >(test-key 1 :key 17 :d 14 :b 13 :c 15) (1 13 15 14 T 17)
Combining &rest, &optional and &key • Required arguments first • &optional must precede &rest • When combining, the results can be counterintuitive >(defun test-together (a &optional b (c 3) &rest d &key e) (list a b c d e)) TEST-TOGETHER >(test-together 10 :e 13 :e 14) (10 :E 13 (:E 14) 14) >(test-together 10 11 12 :e 13 :e 14) (10 11 12 (:E 13 :E 14) 13)