2 ms·
Most of the time there just isn't any need to make a difference between the three. There are basically just two common situations where you need to be able to t
by juki 9y ago
Most of the time there just isn't any need to make a difference between the three. There are basically just two common situations where you need to be able to tell the difference:
1. Telling apart optional arguments to a function that weren't given from arguments that were given and were NIL. Typically giving a default value for the argument is sufficient to avoid the problem, but you can also add an extra parameter that tells whether the argument was given.
(defun foo (&optional (x :default-value xp))
;; X holds the argument given by the caller, or the keyword
;; :DEFAULT-VALUE if nothing was given.
;; XP is T if the argument was given, or NIL if it was not given.
)
2. Finding an item that may be NIL. Functions such as GETHASH (which looks up a key in a hash table) usually allow you to specify a default value, and they will return a second value to indicate whether something was found.
;; Increment the value of KEY in TABLE, or if the key doesn't
;; exist, use 10 as a default, increment that and set the
;; result to the table.
(incf (gethash key table 10))
(multiple-value-bind (value existsp) (gethash key table)
;; VALUE holds the value if it exists, or NIL if it doesn't.
;; EXISTSP is T if the key exists, or NIL if it doesn't.
)
Notice that in CL additional return values can be ignored if you're not interested in them, so you only need to use MULTIPLE-VALUE-BIND when you actually need it. You could also wrap it in a trivial macro if you're using it a lot.
(defmacro if-some-let ((var form) &body (then &optional else))
(let ((somep (gensym "SOMEP")))
`(multiple-value-bind (,var ,somep) ,form
(if ,somep ,then ,else))))
(if-some-let (val (gethash key table))
(format t "Found: ~a~%" val)
(format t "Didn't find.~%"))
- kazinator 9y agoYou can't make a difference; there is no three: it's all one object. If you want an empty list that isn't nil, you have to implement your own list type. If you want a symbol called "NIL" that isn't self-evaluating and Boolean false, you have to use your own package.