On Fri, Mar 19, 2010 at 08:54:02AM -0400, Ken Raeburn wrote: > On Mar 19, 2010, at 04:57, Josef Wolf wrote: > > My next question is more related to the defstruct macro. > > In line 11, defstruct stores the default initializers into the vv vector: > > > > (if (pair? f) (cadr f) '(if #f #f))) > > > > So if the field is a pair, the initializer is stored in vv. That's easy. > > But if it is not a pair, '(if #f #f) is stored. What is this good for? > > This 'if' would evaluate the 'else' part, which does not exist. So we > > would get #f as a result. So why not storing #f in the first place? Why > > is not > > > > (if (pair? f) (cadr f) #f)) > > > > used here? > > The result of (if #f #f) is unspecified, not #f, according to r5rs. That > means an implementation can produce whatever value it wants. > > Guile has a special "unspecified" value which is distinct from #f and other > values, for use when a function's return value is unspecified; in some ways > this is probably better than picking something like #f, as it doesn't cause > people unfamiliar with the distinction between a language specification and a > language implementation to start assuming that #f (or whatever) is the value > that Scheme always requires in that case. Among other things, the > unspecified value causes the REPL to not print a result: > > guile> (if #f #f #f) > #f > guile> (if #f #f) > guile> > > Using (if #f #f) here is basically saying, "the initial value is > unspecified", instead of defaulting to #f or #t or 0 or '() or any other > particular normal value.
I think I like this type of "unspecified". Much better than the "undefined behavior" definition in C. Thanks for the explanation, Ken!