While working with Gauche, sometimes you encounter
a value printed as
#<undef>, an undefined value.
gosh> (if #f #t) #<undef>
It is a value used as a filler where the actual value doesn’t matter, or there’s no other suitable value, or the binding hasn’t been calculated.
Do not confuse undefined values with unbound variables;
A variable can be bound to
#<undef>, for it is just
an ordinary first-class value. On the other hand, an
unbound variable means there’s no value associated with the variable.
#<undef> may be used in certain
occasions to indicate that a value is not provided for
the variable. For example,
the toplevel variable can be bound to
#<undef> if it is
(define variable) form (see Definitions).
An optional procedure parameter
without default value is bound to
#<undef> if an
actual argument is not given (see Making procedures).
Note that it cannot be distinguished from the case
a value is actually provided, and the value just happens
#<undef>. If you get an
you can say at most is that the value doesn’t matter.
You shouldn’t let it carry too much meanings.
#<undef> value is counted as true value in generalized
since it is not
#f. However, branching based on
is dangerous—a procedure that is defined to return unspecified value
may merely returning
#<undef> as a provisional value; it will
change the return value in future. Since the return value isn’t specified,
no one should be using it. The code that tests such result value as
a generalized boolean may break if the procedure changes the return value.
In fact, we’ve found that there are quite a few code that accidentally tests
#<undef> return value in conditionals. They can be seeds
for future bugs, so we added a feature to warn when
is used in the test of branches. You can turn it on with
setting the environment variable
In future, we may turn it on while testing.
One typical case of such accidental use of
and-let*; the following code assumes
#<undef>, which is counted as a true value, and expects the control
to proceeed to the next clause. It’ll break if
#f in some cases.
(and-let* ([var (foo x y z)] [ (print var) ] ;; branch on #<undef> [baz (bar var)]) ...)
Being said that, there are a couple of procedures to deal with undefined values.
#t iff obj is an undefined value.
Returns an undefined value.