Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re^5: Unhappy returns

by ysth (Canon)
on Oct 10, 2005 at 15:23 UTC ( [id://498843]=note: print w/replies, xml ) Need Help??


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

I'd have to disagree. Every runtime statement in perl does have a return value. It's not true that foreach doesn't return anything. Ponder this piece of code:
@x = sub { 0; for (4,3,2) { 1 } }->();
What does the sub return? Is it a bug? What should it return? (It has to return something, even if it's an empty list.) Also compare to
@x = sub { }->();
and
$x = sub { 0; for (4,3,2) { 1 } }->();

Replies are listed 'Best First'.
Re^6: Unhappy returns
by Aristotle (Chancellor) on Oct 10, 2005 at 15:30 UTC

    What does the sub return?

    The foreach in your examples is a red herring. A function call is an expression. And function calls return the value of the last expression evaluated. foreach is not an expression, but in the course of its execution several of those may be evaluated.

    My statement stands. (Pun intended.)

    Makeshifts last the longest.

      Then where does the return value come from? What expression is it?
      And function calls return the value of the last expression evaluated.
      I think it is possible to have a mostly consistent understanding based on that "rule", but it involves thinking of void-context expressions as having values. IMO it is a lot simpler (and completely instead of mostly consistent) to think of every statement as having a context and a return value. This issue with for loops is one place where the two models show their difference.

        It isn't completely consistent.

        #!/usr/bin/perl use strict; use warnings; sub x { local$,=" "; print "$_[ 0 ]:", map( "[$_]", @_[ 1 .. $#_ ] ), +"\n" } x "for", sub { for( 5 .. 7 ) { 1 } }->(); x "while(5)", sub { while( 5 ) { 1; last } }->(); x "while(0)", sub { while( 0 ) { 1 } }->(); x "if(5)", sub { if( 5 ) { 1 } }->(); x "if(0)", sub { if( 0 ) { 1 } }->(); x "do{}while(0)", sub { do { 1 } while 0 }->(); x "do{}until(5)", sub { do { 0 } until 5 }->(); __END__ for: [] while(5): while(0): if(5): [1] if(0): [0] do{}while(0): [1] do{}until(5): [0]

        I admit the value returned from the function for surprised me. It returns an honest-to-goodness false (ie. an empty string) -- not even undef. (I checked.) Interesting.

        Also somewhat surprising, but not nearly as much, is that the functions with while return nothing at all.

        Because I knew about the behaviour of if – when the condition is the last thing evaluated, it is returned, while when the body runs, its last expression's value is returned.

        Which is exactly as expected by the model I described. Which is exactly what perlsub describes:

        The return value of a subroutine is the value of the last expression evaluated by that sub, or the empty list in the case of an empty sub.

        I guess Perl is simply inconsistent here.

        Update: per Re: "last expression" quiz, I added do{} pseudo-loop tests. They return a code reference. It’s probably safe to say that Perl simply has no rule, and that what you get back from a sub depends on implementation details of perl.

        Update: gack, I forgot to invoke the do subs using ->. Fixed, thanks to robin in Re^4: "last expression" quiz. No wonder I got back coderefs. The actual behaviour does not seem very consistent either, though.

        Makeshifts last the longest.

Re^6: Unhappy returns
by sauoq (Abbot) on Oct 10, 2005 at 17:01 UTC
    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.";
    
      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.

        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.";
        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://498843]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-04-25 16:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found