lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

> > [...] suppose I'm writing a library which
> > defines a predicate function P. What value should P return if the
> > is not true, false or nil?

> That depends on the kind of logic you are using. If we can assume that
> not true is false (an old-style, outdated 2-value logic??) then any
> predicate should return only true/false.

> -- Roberto

Fair enough. But "pseudo-predicates" can be quite useful. By
pseudo-predicate I mean a function which returns either a false value or a
useful true value. A good example of a pseudo-predicate is strfind.

Pseudo-predicates are extremely useful, both for clarity and for
efficiency. "Logically" a pseudo-predicate returns nil (the absence of a
value) if it can't find anything better to return, but that clouds the
issue for consumers of the functions (my point above, slightly elaborated.)

Perhaps all pseudo-predicates should return "false" rather than "nil" but
that precludes the simple use of a table-lookup as a pseudo-predicate,
which is a very common Lua idiom (at least in my dialect), and the
structure of Lua makes it much simpler to return nil than false (since you
can just fall off the end of a function).

For example, an easy way to implement a set in Lua is to define a table
whose keys are the elements of the set; it is essential that non-members
not be in such a table (otherwise they would show up during an iteration.)
I don't need to use a function call for the "is-in" relation, so I don't. I
might, however, decide that it is faster and more space-efficient to code
sets in C using bit-vectors; that implementation ought to be functionally
identical. (This also speaks to the utility of a "next" tag-method, but
that's another issue.) So it's going to want to return "nil" as well;
that's the "right" answer in any case, because of the desired non-existence
of non-member keys.

Alternatively, I can try to save space by defining sets as deltas of other
sets, using an index tag-method. In that case, I might want to block
indexing by explicitly storing a false value in the delta (and somehow
working out how to do inherited iteration.)

I don't think that can be consistently resolved by looking at the
predicate, though. It can be consistently resolved in the implementation of
the object.

I think that almost all of the motivations for false are really a
manifestation of object-semantics rather than predicate-semantics. "False"
is a superficial solution which will go wrong exactly in cases where the
bug will be hard to find.

I do have yet another suggestion: now that tables have behaviour flags,
there is room for another flag which controls nil behaviour (nil deletes or
nil retains). The only problem (and its a more general problem than
nil-ness as evidenced by a discussion over Christmas about ordered tables)
is doing table-constructors properly.