function parameters

both optional and keyword parameters can include both default value AND
'providedp' predicate of whether they were provided
This commit is contained in:
efim 2022-07-28 19:10:31 +00:00
parent e5306c46e3
commit 8865b0df6a
2 changed files with 34 additions and 28 deletions

View File

@ -17,24 +17,24 @@
(define-test call-a-function (define-test call-a-function
;; DEFUN can be used to define global functions. ;; DEFUN can be used to define global functions.
(assert-equal ____ (some-named-function 4 5)) (assert-equal 9 (some-named-function 4 5))
;; FLET can be used to define local functions. ;; FLET can be used to define local functions.
(flet ((another-named-function (a b) (* a b))) (flet ((another-named-function (a b) (* a b)))
(assert-equal ____ (another-named-function 4 5))) (assert-equal 20 (another-named-function 4 5)))
;; LABELS can be used to define local functions which can refer to themselves ;; LABELS can be used to define local functions which can refer to themselves
;; or each other. ;; or each other.
(labels ((recursive-function (a b) (labels ((recursive-function (a b)
(if (or (= 0 a) (= 0 b)) (if (or (= 0 a) (= 0 b))
1 1
(+ (* a b) (recursive-function (1- a) (1- b)))))) (+ (* a b) (recursive-function (1- a) (1- b))))))
(assert-equal ____ (recursive-function 4 5)))) (assert-equal (+ (* 4 5) (* 3 4) (* 2 3) (* 1 2 ) 1) (recursive-function 4 5))))
(define-test shadow-a-function (define-test shadow-a-function
(assert-eq 18 (some-named-function 7 11)) (assert-eq 18 (some-named-function 7 11))
;; FLET and LABELS can shadow function definitions. ;; FLET and LABELS can shadow function definitions.
(flet ((some-named-function (a b) (* a b))) (flet ((some-named-function (a b) (* a b)))
(assert-equal ____ (some-named-function 7 11))) (assert-equal 77 (some-named-function 7 11)))
(assert-equal ____ (some-named-function 7 11))) (assert-equal 18 (some-named-function 7 11)))
(defun function-with-optional-parameters (&optional (a 2) (b 3) c) (defun function-with-optional-parameters (&optional (a 2) (b 3) c)
;; If an optional argument to a function is not provided, it is given its ;; If an optional argument to a function is not provided, it is given its
@ -42,10 +42,10 @@
(list a b c)) (list a b c))
(define-test optional-parameters (define-test optional-parameters
(assert-equal ____ (function-with-optional-parameters 42 24 4224)) (assert-equal '(42 24 4224) (function-with-optional-parameters 42 24 4224))
(assert-equal ____ (function-with-optional-parameters 42 24)) (assert-equal '(42 24 nil) (function-with-optional-parameters 42 24))
(assert-equal ____ (function-with-optional-parameters 42)) (assert-equal '(42 3 nil) (function-with-optional-parameters 42))
(assert-equal ____ (function-with-optional-parameters))) (assert-equal '(2 3 nil) (function-with-optional-parameters)))
(defun function-with-optional-indication (defun function-with-optional-indication
(&optional (a 2 a-provided-p) (b 3 b-provided-p)) (&optional (a 2 a-provided-p) (b 3 b-provided-p))
@ -53,18 +53,18 @@
(list a a-provided-p b b-provided-p)) (list a a-provided-p b b-provided-p))
(define-test optional-indication (define-test optional-indication
(assert-equal ____ (function-with-optional-indication 42 24)) (assert-equal '(42 t 24 t) (function-with-optional-indication 42 24))
(assert-equal ____ (function-with-optional-indication 42)) (assert-equal '(42 t 3 nil) (function-with-optional-indication 42))
(assert-equal ____ (function-with-optional-indication))) (assert-equal '(2 nil 3 nil) (function-with-optional-indication)))
(defun function-with-rest-parameter (&rest x) (defun function-with-rest-parameter (&rest x)
;; A rest parameter gathers all remaining parameters in a list. ;; A rest parameter gathers all remaining parameters in a list.
x) x)
(define-test rest-parameter (define-test rest-parameter
(assert-equal ____ (function-with-rest-parameter)) (assert-equal nil (function-with-rest-parameter))
(assert-equal ____ (function-with-rest-parameter 1)) (assert-equal '(1) (function-with-rest-parameter 1))
(assert-equal ____ (function-with-rest-parameter 1 :two 333))) (assert-equal '(1 :two 333) (function-with-rest-parameter 1 :two 333)))
(defun function-with-keyword-parameters (&key (a :something) b c) (defun function-with-keyword-parameters (&key (a :something) b c)
;; A keyword parameters is similar to an optional parameter, but is provided ;; A keyword parameters is similar to an optional parameter, but is provided
@ -72,14 +72,14 @@
(list a b c)) (list a b c))
(define-test keyword-parameters () (define-test keyword-parameters ()
(assert-equal ____ (function-with-keyword-parameters)) (assert-equal '(:something nil nil) (function-with-keyword-parameters))
(assert-equal ____ (function-with-keyword-parameters :a 11 :b 22 :c 33)) (assert-equal '(11 22 33) (function-with-keyword-parameters :a 11 :b 22 :c 33))
;; It is not necessary to specify all keyword parameters. ;; It is not necessary to specify all keyword parameters.
(assert-equal ____ (function-with-keyword-parameters :b 22)) (assert-equal '(:something 22 nil) (function-with-keyword-parameters :b 22))
;; Keyword argument order is not important. ;; Keyword argument order is not important.
(assert-equal ____ (function-with-keyword-parameters :b 22 :c -5/2 :a 0)) (assert-equal '(0 22 -5/2) (function-with-keyword-parameters :b 22 :c -5/2 :a 0))
;; Lisp handles duplicate keyword parameters. ;; Lisp handles duplicate keyword parameters.
(assert-equal ____ (function-with-keyword-parameters :b 22 :b 40 :b 812))) (assert-equal '(:something 22 nil) (function-with-keyword-parameters :b 22 :b 40 :b 812)))
(defun function-with-keyword-indication (defun function-with-keyword-indication
(&key (a 2 a-provided-p) (b 3 b-provided-p)) (&key (a 2 a-provided-p) (b 3 b-provided-p))
@ -87,11 +87,11 @@
(list a a-provided-p b b-provided-p)) (list a a-provided-p b b-provided-p))
(define-test keyword-indication (define-test keyword-indication
(assert-equal ____ (function-with-keyword-indication)) (assert-equal '(2 nil 3 nil) (function-with-keyword-indication))
(assert-equal ____ (function-with-keyword-indication :a 3 :b 4)) (assert-equal '(3 t 4 t) (function-with-keyword-indication :a 3 :b 4))
(assert-equal ____ (function-with-keyword-indication :a 11 :b 22)) (assert-equal '(11 t 22 t) (function-with-keyword-indication :a 11 :b 22))
(assert-equal ____ (function-with-keyword-indication :b 22)) (assert-equal '(2 nil 22 t) (function-with-keyword-indication :b 22))
(assert-equal ____ (function-with-keyword-indication :b 22 :a 0))) (assert-equal '(0 t 22 t) (function-with-keyword-indication :b 22 :a 0)))
(defun function-with-funky-parameters (a &rest x &key b (c a c-provided-p)) (defun function-with-funky-parameters (a &rest x &key b (c a c-provided-p))
;; Lisp functions can have surprisingly complex lambda lists. ;; Lisp functions can have surprisingly complex lambda lists.

View File

@ -111,14 +111,20 @@
(gethash "two" hash-table-2) "zwei") (gethash "two" hash-table-2) "zwei")
(assert-false (equalp hash-table-1 hash-table-2)) (assert-false (equalp hash-table-1 hash-table-2))
;; Change the first hash table to be EQUALP to the second one. ;; Change the first hash table to be EQUALP to the second one.
(setf (gethash ____ hash-table-1) ____ (setf (gethash "one" hash-table-1) "eins"
(gethash ____ hash-table-1) ____) (gethash "two" hash-table-1) "zwei")
(assert-true (equalp hash-table-1 hash-table-2)))) (assert-true (equalp hash-table-1 hash-table-2))))
;; (setf colors (make-hash-table :test #'equalp))
(define-test make-your-own-hash-table (define-test make-your-own-hash-table
;; Make your own hash table that satisfies the test. ;; Make your own hash table that satisfies the test.
(let ((colors ____)) (let ((colors (make-hash-table :test #'equalp)))
;; You will need to modify your hash table after you create it. ;; You will need to modify your hash table after you create it.
(setf (gethash "blue" colors) 1)
(setf (gethash "blue" colors) '(0 0 1)
(gethash "green" colors) '(0 1 0)
(gethash "red" colors) '(1 0 0)
(gethash "color-efim" colors) '(9 9 9))
____ ____
(assert-equal (hash-table-count colors) 4) (assert-equal (hash-table-count colors) 4)
(let ((values (list (gethash "blue" colors) (let ((values (list (gethash "blue" colors)