in reply to Re^5: Unhappy returns
in thread Unhappy returns

It's not true that foreach doesn't return anything.

Sure it is. Otherwise, you would not have had to wrap your example for loops in a sub to try to make your point. If it returned something, you'd be able to write code like: @x = for (1) { 1 }; But, that's a syntax error. Why? Because statements don't return anything. Q.E.D.

-sauoq
"My two cents aren't worth a dime.";

Replies are listed 'Best First'.
Re^7: Unhappy returns
by ysth (Canon) on Oct 10, 2005 at 18:00 UTC
    Sure it is. Otherwise, you would not have had to wrap your example for loops in a sub to try to make your point.
    I wrapped it in a sub because that's one way to put a for loop in a non-void context. Note that the very fact that I am speaking of the "context" of a statement demonstrates that statements can be said to have return values. But also see the reply I'm about to make to Re^5: Unhappy returns.
    @x = for (1) { 1 }; But, that's a syntax error. Why? Because statements don't return anything.
    No, it's a syntax error because the whole thing is a statement that is an expression (one of the possible kinds of statement), and the expression is a list assignment which has the form expression = expression. So all you've proved is that for (1) { 1 } isn't an expression. IMO by your argument, @x = do { for (1) { 1 } }; should be a syntax error, too, and it isn't.

      by your argument, @x = do { for (1) { 1 } }; should be a syntax error, too, and it isn’t.

      Huh? do {} is an expression that evaluates a block. (And like a function call, it too returns the value of the last expression evaluated.) Blocks may contain statements. How is that inconsistent with sauoq’s point?

      Makeshifts last the longest.

        Careful, when you say "evaluates a block", you are almost coming right out and stating that a block has a return value :). Which was my point: what could it mean to evaluate a block containing only a for statement? If a for statement doesn't have a return value, it shouldn't even be valid syntax.
      Note that the very fact that I am speaking of the "context" of a statement demonstrates that statements can be said to have return values.

      Heh... uh... no. My daughter talks about Santa Claus. That doesn't demonstrate his existence.

      All you've demonstrated is that you think every statement has a return value. But, you've already stated that explicitly, so a demonstration was not necessary.

      It is true that expressions have values and it is true that expressions are statements, but, it doesn't follow from that that all statements have values.

      -sauoq
      "My two cents aren't worth a dime.";
      
        The return value of a for statement is the empty string, as the following program shows:
        #!/usr/bin/perl use strict; use warnings; my $x = do {for (1 .. 4) {}}; my @x = do {for (1 .. 4) {}}; printf "Scalar return value of for is %s\n", defined $x ? "defined" : "undefined"; printf "Scalar return value of for is %s\n", $x ? "true" : "false"; printf "Scalar return value of for is has length %d\n", length $x; printf "Scalar return value of for is '%s'\n", $x; printf "List return value of for returns %d element\n", scalar @x; printf "List return value of for contains %d undefined elements\n", scalar grep {!defined} @x; printf "List return value of for contains %d true elements\n", scalar grep {$_} @x; printf "List return value of for contains %d elements of non-zero leng +th\n", scalar grep {length} @x; printf "List return value of for equals [%s]\n", join ", ", map {"'$_'"} @x; __END__ Scalar return value of for is defined Scalar return value of for is false Scalar return value of for is has length 0 Scalar return value of for is '' List return value of for returns 1 element List return value of for contains 0 undefined elements List return value of for contains 0 true elements List return value of for contains 0 elements of non-zero length List return value of for equals ['']
        Note also that while Perl makes a difference between functions and statements (mostly for the benefit of mortals), perl doesn't. Operators, functions, statements, they're all opcodes. Here's the handling of the leaveloop opcode:
        PP(pp_leaveloop) { dSP; register PERL_CONTEXT *cx; I32 gimme; SV **newsp; PMOP *newpm; SV **mark; POPBLOCK(cx,newpm); mark = newsp; newsp = PL_stack_base + cx->blk_loop.resetsp; TAINT_NOT; if (gimme == G_VOID) ; /* do nothing */ else if (gimme == G_SCALAR) { if (mark < SP) *++newsp = sv_mortalcopy(*SP); else *++newsp = &PL_sv_undef; } else { while (mark < SP) { *++newsp = sv_mortalcopy(*++mark); TAINT_NOT; /* Each item is independent */ } } SP = newsp; PUTBACK; POPLOOP(cx); /* Stack values are safe: release loop vars .. +. */ PL_curpm = newpm; /* ... and pop $1 et al */ LEAVE; LEAVE; return NORMAL; }
        You don't have to understand what it does, but do note that it's looking at its context to determine what to leave behind on the stack.

        And here is a trace:

        perl -Dt -e '$x = do {for (1) {}}' EXECUTING... (-e:0) enter (-e:0) nextstate (-e:1) pushmark (-e:1) const(IV(1)) (-e:1) gv(main::_) (-e:1) enteriter (-e:1) iter (-e:1) and (-e:1) stub (-e:1) unstack (-e:1) iter (-e:1) and (-e:1) leaveloop (-e:1) gvsv(main::x) (-e:1) sassign (-e:1) leave
        Perl --((8:>*