in reply to Re^3: 'return:' instead of 'return'
in thread 'return:' instead of 'return'

Naturally I ran it. Had it returned '1', as I had expected, I would have told my friend "here's a bug, fix it". Since it actually worked, I'll have to go to him and say "here's why I think this is bad style".

As for your second snippet, I don't know that that answers the question - or maybe the problem is that my question just doesn't make sense. In your example 'return' exits the subroutine and the subroutine then evaluates to '3'. But what does 'return' evaluate to?

This code:
perl -wE 'sub fn{ return 3 and die("bury me where this arrow lands") } + say fn'
also prints 3, but I assume the die is not executed because the subroutine has exited, not because the 'return' did not evaluate to true. I can't think of an example which would clearly show the difference (between what return evaluates to and what the subroutine evaluates to) maybe because there really isn't a difference?


- Boldra

Replies are listed 'Best First'.
Re^5: 'return:' instead of 'return'
by jethro (Monsignor) on Jun 12, 2009 at 11:04 UTC
    Yes, there is no difference and why should there be any? return exists because you might want to leave the subroutine in the middle instead of at the end or leave from more than one location in the subroutine. And it exists to make it explicit what value is returned, it makes the program easier to read and less errorprone. If you have Damian Conways book 'Perl Best Pratices' at hand, it gives an example why explicit returning is better style, in section 'Implicit Returns'
      Yes, there is no difference and why should there be any?
      I don't know, maybe you could use it to force other Best Practices, eg:
      sub close_all { my $self = shift; $success = 1; foreach( $self->files ) { $success = $_->close && $success } return $success or die("You must check the return value of close_all +"); }
      Where return would only evaluate to true if the calling program read the value of the call.

      (Yes, I know you can already do this with the cpan module Want).


      - Boldra

        Leaving aside Corions excellent answer why the built-in return never returns a value, if it did I would expect it to return the same value it returns to the caller. I.e. print return 3; would print 3. Returning a boolean value would only make sense if there were a chance return might fail or return might not always return from the subroutine. Then true or false would inform about the success of the operation.

        You always have the option to write your own function 'myspecialreturn()' that returns only on some conditions (like the result of Want for example).

Re^5: 'return:' instead of 'return'
by JavaFan (Canon) on Jun 12, 2009 at 12:10 UTC
    But what does 'return' evaluate to?
    When in doubt, don't consult Perlmonks. Read the documentation. Not only do you get your answer faster, it isn't buried between posts that don't answer your questions. It also doesn't require other people to read the documentation for you.
    $ perldoc -f return return EXPR return Returns from a subroutine, "eval", or "do FILE" with th +e value given in EXPR. Evaluation of EXPR may be in list, scal +ar, or void context, depending on how the return value will be + used, and the context may vary from one execution to the next + (see "wantarray"). If no EXPR is given, returns an empty li +st in list context, the undefined value in scalar context, an +d (of course) nothing at all in a void context. (Note that in the absence of an explicit "return", a subroutine, eval, or do FILE will automatically return +the value of the last expression evaluated.)
      This still doesn't explain what 'return 3' evaluates to, just what it returns. I'm very sorry if you feel reading my posts was a waste of your time, JavaFan, I don't feel that reading yours was a waste of my time, so I thank you for your patience.


      - Boldra

        In a coroutine/continuationless language, return never evaluates to a value. It only transfers control to the caller one level up the call stack. You can see this for Perl by looking at the following code:

        Q:\>perl -wle "my $foo; sub f { $foo = return 'bar' }; f(); print $foo +" Use of uninitialized value in print at -e line 1. Q:\>perl -wle "my $foo='x'; sub f { $foo = return 'bar' }; f(); print +$foo" x

        In neither case, $foo was changed, because return does not have a "expression value" in Perl.

        If Perl was a language that had real continuations (Coro left aside), you could invent in that alternate universe a value to be returned from return 'bar', which would modify the flow of control:

        sub f { my $position_of_caller = return 3; # f() will be '3', eventually my $alternative = return 5; # f() will be '5', eventually print "Now we return a value:"; $alternative->(); # return 5 to caller # will we get here? Possibly, through the "yield" call. CONTINUATION: print "We are continuing here?"; }; f(); yield; # transfers control to the label CONTINUATION

        Coro has something like this, and having different strains of execution throughout your program allows you for example to have something like threads except without the locking problems. You won't get true parallelism through it, and playing with bare continuations can bet quite complex soon.

        An interesting question is for example what would/should happen if you call f() twice without an intervening yield; statement.

        The problem here Boldra is that you have been given the correct answer multiple times, and you are not accepting it. Let me restate it for you (and I intend this respectfully):

        The label is created. The last value is returned in your example.

        You followed with examples that do not reflect your problem and continued to resist the answer. Next time, give an example that is the problem. That way no one will feel as if their time was wasted.

        Lastly, sometimes I feel as if folks hope their problem will result in a mystery or bug. This one is user error; please accept it.
        This still doesn't explain what 'return 3' evaluates to, just what it returns.
        It seems you think there's a difference between 'evaluating to', and 'returning'. Could you explain what you think the difference is, and could you give an example of a statement that, according to you, evaluates to something, but returns something else?