//= operator alternative

Discussion in 'Perl Misc' started by Roy Johnson, Oct 7, 2003.

  1. Roy Johnson

    Roy Johnson Guest

    I apologize for being so late to this party, but I do think I have an
    idea worth considering.

    //= will be forthcoming in perl6 to handle defaulting undefined values
    (vs. merely false ones). In the threads discussing it, there was some
    noise made about needing another operator for exists, and maybe a
    special alternative to the (ever so rarely used) &&=, etc.

    It occurred to me that maybe what ought to be done was to make tests
    act as assigners (or yield lvalues, sort of) in certain situations --
    in particular, in situations where ||= or &&= is specified, assign to
    the argument being tested:

    defined($var) ||= 'default';
    exists($hash{$key}) &&= 'replacement';

    To me, this reads pretty well. From a syntax standpoint, it's very
    irregular, but that hasn't stopped Perl in the past.
     
    Roy Johnson, Oct 7, 2003
    #1
    1. Advertising

  2. Roy Johnson

    Roy Johnson Guest

    Having thought about it some more, I got a much better, more
    comprehensive idea.

    Change the behavior of defined() thus: it provides a context in which
    only undefined values are false. Boolean operators return undef rather
    than empty string.

    Then this would work exactly like you'd expect:
    if (defined($a or $b)) { ...

    and you could do

    defined($v ||= a() || b());

    exists() would be exactly like defined(), except that when checking a
    hash value, only non-existent keys return false.

    It's straightforward, and it addresses a lot of things that people
    grouse about. For larger areas, there could be pragmas "use defined"
    and "use exists". I don't know how useful/popular those would really
    be.

    In a hurry tonight, but wanted to get this out there. Please think
    about it a little and comment.
     
    Roy Johnson, Oct 8, 2003
    #2
    1. Advertising

  3. Roy Johnson wrote:
    >Having thought about it some more, I got a much better, more
    >comprehensive idea.
    >
    >Change the behavior of defined() thus: it provides a context in which
    >only undefined values are false. Boolean operators return undef rather
    >than empty string.
    >
    >Then this would work exactly like you'd expect:
    > if (defined($a or $b)) { ...


    well, the problem with contexts is that you're going to face
    awkward propagation problems like this one :
    if (defined(foo()) { ... }
    sub foo { $a or $b }
    I understand that Perl 6 will have more contexts that Perl 5, so
    maybe will it have a defined-boolean context in addition to the regular
    boolean one. (I don't think so, though.)

    --
    Unprimed is not *NIX
     
    Rafael Garcia-Suarez, Oct 8, 2003
    #3
  4. Roy Johnson wrote:
    >//= will be forthcoming in perl6 to handle defaulting undefined values
    >(vs. merely false ones). In the threads discussing it, there was some
    >noise made about needing another operator for exists, and maybe a
    >special alternative to the (ever so rarely used) &&=, etc.


    // and //= will be present in perl 5.10.

    >It occurred to me that maybe what ought to be done was to make tests
    >act as assigners (or yield lvalues, sort of) in certain situations --
    >in particular, in situations where ||= or &&= is specified, assign to
    >the argument being tested:
    >
    >defined($var) ||= 'default';
    >exists($hash{$key}) &&= 'replacement';
    >
    >To me, this reads pretty well. From a syntax standpoint, it's very
    >irregular, but that hasn't stopped Perl in the past.


    At first sight, I like this syntax. It think it could be implemented in
    Perl 5 without too much pain. (Perl 5 language suggestions should be
    directed at the perl 5 porters mailing list, by the way.)

    --
    Ungrateful is not *NIX
     
    Rafael Garcia-Suarez, Oct 8, 2003
    #4
  5. Roy Johnson

    Roy Johnson Guest

    (Rafael Garcia-Suarez) wrote in message news:<>...
    > well, the problem with contexts is that you're going to face
    > awkward propagation problems like this one :
    > if (defined(foo()) { ... }
    > sub foo { $a or $b }


    It's lexical, so there's no propagation problem. You're in normal
    perl-truth-context unless you're lexically enclosed in another. foo
    evaluates $a and $b in its own context, and returns whatever it
    normally returns. The defined() interprets that as true, unless it is
    undef. That is exactly how that code would work today. If $a is
    normal-perl-false, $b is returned, and is evaluated in defined()
    context.

    More of how I see it:

    In this context, variables are checked for definedness first, and if
    defined, then return whatever their value is to the expression. That
    is to say, they are not autovivified until assigned to, or passed to
    subroutines. Details on that may get sticky. I am not a Perl
    technician.

    defined() itself will return appropriate truth values for whatever
    context it is in. That means you don't want to do:
    $v = defined( a() || b() || c());
    unless you want a boolean result for the whole expression, but
    defined($v = a() || b() || c());
    if you want $v to get the first defined value. Compare that with
    defaulting for undefined $v:
    defined($v ||= a() || b() || c());

    <And in a different followup>:

    > // and //= will be present in perl 5.10.


    So I have heard. Where do I look to find how they will work? The
    reason I consider it the wrong solution is that, according to an old
    document,
    if ($a // $b)
    doesn't mean "if either is defined". To get that, you have to do ($a
    // $b // 0), which is distinctly kludgy. What we really want is a way
    to provide a different truth context, hence:
    if (defined($a || $b))
    It reads beautifully to me.

    The drawbacks I have thought of are pretty minor. It is possible,
    since exists() and defined() both technically take expressions, that
    some weirdly-written code would change behavior. The best example I
    could think of:
    # Find the first false value and tell me whether it is defined
    defined( $a && $b && $c && $d )

    If block notation were used, it would be new syntax, and that has some
    appeal, considering the special nature of the beast. It doesn't behave
    like a function, after all.
    defined { $v = $a || $b || $c };

    One advantage of // is that you can switch context easily:
    # Defined or true or defined or true
    $v = $a // $b || $c // $d;
    The defined() context would buy you nothing here. I don't see that as
    a major issue.

    The original syntax I proposed:
    defined($v) ||= $a;
    could be syntatic sugar for
    defined($v ||= $a);
    but that raises the question of what to do when you have more on the
    right than a simple value:
    defined($v) ||= $a || $b;
    Is that
    defined($v ||= $a || $b);
    or
    defined($v) || ($v = $a || $b);
    ?

    The latter strikes me as correct.

    Thanks for your comments.
     
    Roy Johnson, Oct 8, 2003
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jakob Bieling

    Q: operator void* or operator bool?

    Jakob Bieling, Mar 5, 2004, in forum: C++
    Replies:
    2
    Views:
    589
    Rob Williscroft
    Mar 5, 2004
  2. John Smith
    Replies:
    2
    Views:
    427
    Ivan Vecerina
    Oct 6, 2004
  3. Alex Vinokur
    Replies:
    4
    Views:
    3,056
    Peter Koch Larsen
    Nov 26, 2004
  4. Alex Vinokur
    Replies:
    3
    Views:
    5,033
    Jeff Schwab
    Mar 20, 2005
  5. kretik
    Replies:
    5
    Views:
    299
    kretik
    Jun 19, 2008
Loading...

Share This Page