develooper Front page | perl.perl5.porters | Postings from October 2003

RFC: changing behavior of defined() and exists()

Thread Next
Johnson, Roy
October 8, 2003 17:40
RFC: changing behavior of defined() and exists()
Message ID:
I posted this idea on comp.lang.perl, and was told that such suggestions
are more appropriate to this mailing list.

I was reviewing the age-old debate on the // operator, and saw the
various, often clunky, proposals for avoiding it. I never saw this one,
though, and it struck me as being elegant:

defined() should evaluate its arguments in a context [I'm using this
term generically] wherein only undef is false. The normal usage of
defined() is unchanged: if you give it an undef value, it returns false,
otherwise, it returns true. However, if you give it a complex Boolean
argument, all of the logical operators recognize undef as false, and
everything else as true, and logical operators yield undef instead of

    defined($v = a() || b())   ## equivalent to $v = a() // b();
    defined($v ||= a())        ## equivalent to $v //= a();
    defined($v = \( $a && $b && $c && 'full'))

The last one makes $v a reference to the first undefined value in the
list, or to the constant 'full' if all of them have been defined.
defined() itself will return the appropriate truth value for its

exists() would be exactly like defined(), except a hash lookup would
evaluate to false only if the key did not exist. Or perhaps it would be
exactly like the default context, except when using hash lookups as
Booleans. Either would allow:
    exists($h{'foo'} ||= 'default');

It might be preferred to use curlies instead of parens, to minimize
conflicts with oddly-written existing code. 

No new keywords or operators are required for this behavior. It is
straightforward and provides access to all logical operations, rather
than being specific to two. It expands the universe of expressions for
which the existing functions are useful.

It still does not make it easier to do something like:
    $a = a() // b() || c() // d();
  which would be (as it currently is):
    defined($a = a()) || ($a = b()) || defined($a = c()) || ($a = d());
"defined" is still a relatively long word

Roy Johnson

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About