List Context in a Boolean Expression

Discussion in 'Perl Misc' started by h3xx, Aug 16, 2008.

  1. h3xx

    h3xx Guest

    I have a question about when things are and aren't taken to be a list
    when doing boolean comparisons. I tested the following code:

    my @foo = qw/ one two three /;
    my @bar = ();

    my @baz = @bar || @foo;
    print "@baz\n";

    This produces "one two three." Hence, we know that a list CAN be
    returned from a boolean expression. I tried it the other way:

    my @baz = @foo || @bar;
    print "@baz\n";

    This produced "3," the scalar evaluation of @foo. This is the same for
    any amount of parentheses and using the "or" operand instead of "||."
    Now, what happened?
     
    h3xx, Aug 16, 2008
    #1
    1. Advertising

  2. h3xx <> wrote:
    >I have a question about when things are and aren't taken to be a list
    >when doing boolean comparisons. I tested the following code:
    >
    >my @foo = qw/ one two three /;
    >my @bar = ();
    >
    >my @baz = @bar || @foo;
    >print "@baz\n";
    >
    >This produces "one two three." Hence, we know that a list CAN be
    >returned from a boolean expression. I tried it the other way:
    >
    >my @baz = @foo || @bar;
    >print "@baz\n";
    >
    >This produced "3," the scalar evaluation of @foo. This is the same for
    >any amount of parentheses and using the "or" operand instead of "||."
    >Now, what happened?


    See The Fine Manual: perldoc perlop, section "C-style Logical Or":
    The "||" and "&&" [...] return the last value evaluated.
    and
    In particular, this means that you shouldn't use this for selecting
    between two aggregates for assignment:
    @a = @b || @c; # this is wrong

    jue
     
    Jürgen Exner, Aug 16, 2008
    #2
    1. Advertising

  3. h3xx

    h3xx Guest

    On Aug 16, 7:21 am, Jürgen Exner <> wrote:
    > h3xx <> wrote:
    > >I have a question about when things are and aren't taken to be a list
    > >when doing boolean comparisons. I tested the following code:

    >
    > >my @foo = qw/ one two three /;
    > >my @bar = ();

    >
    > >my @baz = @bar || @foo;
    > >print "@baz\n";

    >
    > >This produces "one two three." Hence, we know that a list CAN be
    > >returned from a boolean expression. I tried it the other way:

    >
    > >my @baz = @foo || @bar;
    > >print "@baz\n";

    >
    > >This produced "3," the scalar evaluation of @foo. This is the same for
    > >any amount of parentheses and using the "or" operand instead of "||."
    > >Now, what happened?

    >
    > See The Fine Manual: perldoc perlop, section  "C-style Logical Or":
    >    The "||" and "&&" [...] return the last value evaluated.
    > and
    >     In particular, this means that you shouldn't use this for selecting
    >     between two aggregates for assignment:
    >         @a = @b || @c;              # this is wrong
    >
    > jue


    Ah. Thank you. I guess I'll just have to solve the problem using the
    tried-and-true trinary method:

    my @foo = qw/ one two three /;
    my @bar = ();

    my @baz = @bar ? @bar : @foo;
     
    h3xx, Aug 16, 2008
    #3
  4. Jürgen Exner wrote:
    >
    > See The Fine Manual: perldoc perlop, section "C-style Logical Or":
    > The "||" and "&&" [...] return the last value evaluated.
    > and
    > In particular, this means that you shouldn't use this for selecting
    > between two aggregates for assignment:
    > @a = @b || @c; # this is wrong


    That's the warning, but I don't think you quoted quite enough to explain
    the behavior. I had to look it up myself because it seemed odd to me
    that the left and right operands wouldn't be evaluated in the same
    (scalar vs. list) context.

    Scalar or list context propagates down to the right operand if
    it is evaluated.

    So the expression

    @baz = @bar || @foo;

    really means

    @baz = scalar @bar || @foo;

    The left operand is always evaluated in scalar context (it's a boolean
    test) but the right operand takes it's context from the expression it's
    used in.

    The right way to write this is:

    @baz = @bar ? @bar : @foo;

    -mjc
     
    Michael Carman, Aug 17, 2008
    #4
  5. Michael Carman <> wrote:
    >Jürgen Exner wrote:
    >>
    >> See The Fine Manual: perldoc perlop, section "C-style Logical Or":
    >> The "||" and "&&" [...] return the last value evaluated.
    >> and
    >> In particular, this means that you shouldn't use this for selecting
    >> between two aggregates for assignment:
    >> @a = @b || @c; # this is wrong

    >
    >That's the warning, but I don't think you quoted quite enough to explain
    >the behavior.


    Well, no, of course I didn't. It was a teaser ...

    > I had to look it up myself because it seemed odd to me


    .... to have you do exactly that. After all, I assume you are old enough
    not to need someone to read the man pages to you.

    jue
     
    Jürgen Exner, Aug 17, 2008
    #5
  6. Jürgen Exner wrote:
    > Michael Carman <> wrote:
    >> That's the warning, but I don't think you quoted quite enough to
    >> explain the behavior.

    >
    > Well, no, of course I didn't. It was a teaser ...
    >
    >> I had to look it up myself because it seemed odd to me

    >
    > ... to have you do exactly that. After all, I assume you are old
    > enough not to need someone to read the man pages to you.


    I read this newsgroup for discussions about Perl, not to get homework
    assignments. While I can RTFM I'd rather discuss the behavior,
    particularly when that behavior is unintuitive.

    Getting back on-topic...

    It's obvious that the left operand must be evaluated in scalar context
    because it's a boolean test. I would have expected the || operator to
    impose scalar context on the right operand as well; that just seems like
    the obvious thing to do. I find the (potential) propagation of list
    context curious. Was it a deliberate design decision or just a side
    effect? If it was deliberate then someone must have thought that it
    might be useful. Has anyone ever found an application for this behavior?
    I'm having a hard time envisioning a situation where

    @foo = $bar || @baz;

    is useful. Does anyone have an example?

    -mjc
     
    Michael Carman, Aug 17, 2008
    #6
  7. h3xx

    Dr.Ruud Guest

    Michael Carman schreef:

    > I'm having a hard time envisioning a situation where
    > @foo = $bar || @baz;
    > is useful.



    Then use it in a JAPH. Why did you write "$bar"?

    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Aug 18, 2008
    #7
  8. h3xx

    Guest

    Michael Carman <> wrote:
    > Jürgen Exner wrote:
    > > Michael Carman <> wrote:
    > >> That's the warning, but I don't think you quoted quite enough to
    > >> explain the behavior.

    > >
    > > Well, no, of course I didn't. It was a teaser ...
    > >
    > >> I had to look it up myself because it seemed odd to me

    > >
    > > ... to have you do exactly that. After all, I assume you are old
    > > enough not to need someone to read the man pages to you.

    >
    > I read this newsgroup for discussions about Perl, not to get homework
    > assignments. While I can RTFM I'd rather discuss the behavior,
    > particularly when that behavior is unintuitive.
    >
    > Getting back on-topic...
    >
    > It's obvious that the left operand must be evaluated in scalar context
    > because it's a boolean test.


    I wouldn't say it *must* do this. It could evaluate it in a list
    context, then treat that resulting list as false (for purposes of
    short-circuiting) if it is empty.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Aug 18, 2008
    #8
  9. Dr.Ruud wrote:
    > Michael Carman schreef:
    >
    >> I'm having a hard time envisioning a situation where
    >> @foo = $bar || @baz;
    >> is useful.

    >
    >
    > Then use it in a JAPH.


    I'm rather hoping that language design decisions aren't being influenced
    by how useful a feature would be in obfuscated code contests. :p

    > Why did you write "$bar"?


    To highlight that the left operand to || is evaluated in scalar context.

    Additionally, since perlop explicitly says

    @a = @b || @c; # this is wrong

    Then presumably the right[1] syntax that would make use of list context
    to the right operand would be

    @a = $b || @c;

    I can't think of any idioms that would make use of that, though.

    [1] for some definition of "right"
     
    Michael Carman, Aug 19, 2008
    #9
  10. h3xx

    Ben Bullock Guest

    On Sat, 16 Aug 2008 02:05:47 -0700, h3xx wrote:

    > I have a question about when things are and aren't taken to be a list
    > when doing boolean comparisons. I tested the following code:
    >
    > my @foo = qw/ one two three /;
    > my @bar = ();
    >
    > my @baz = @bar || @foo;
    > print "@baz\n";


    The || forces @bar into scalar context. scalar(@bar) = 0, so the left
    hand side is false, so Perl evaluates the right hand side.

    > This produces "one two three." Hence, we know that a list CAN be
    > returned from a boolean expression. I tried it the other way:
    >
    > my @baz = @foo || @bar;
    > print "@baz\n";


    The || forces @foo into scalar context. scalar (@foo) = 3, so Perl never
    evaluates the right hand side.

    > This produced "3," the scalar evaluation of @foo. This is the same for
    > any amount of parentheses and using the "or" operand instead of "||."
    > Now, what happened?


    You've really answered your own question. This is the behaviour of ||,
    forces what's on the left of it into scalar context.
     
    Ben Bullock, Sep 1, 2008
    #10
    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. VS_NET_DEV
    Replies:
    2
    Views:
    3,838
    jenny
    May 25, 2004
  2. J Leonard
    Replies:
    4
    Views:
    12,878
    Mark Space
    Jan 19, 2008
  3. jens wille

    evaluation in boolean context

    jens wille, Oct 10, 2006, in forum: Ruby
    Replies:
    6
    Views:
    112
    Robert Klemme
    Oct 11, 2006
  4. Bo Lindbergh

    List context versus list context

    Bo Lindbergh, Jun 21, 2006, in forum: Perl Misc
    Replies:
    12
    Views:
    242
    Charles DeRykus
    Jun 28, 2006
  5. Metre Meter
    Replies:
    7
    Views:
    453
    Metre Meter
    Aug 6, 2010
Loading...

Share This Page