Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bare return; should return Nil. #306

Closed
p6rt opened this issue Sep 11, 2008 · 13 comments
Closed

Bare return; should return Nil. #306

p6rt opened this issue Sep 11, 2008 · 13 comments

Comments

@p6rt
Copy link

p6rt commented Sep 11, 2008

Migrated from rt.perl.org#58770 (status was 'resolved')

Searchable as RT58770$

@p6rt
Copy link
Author

p6rt commented Jul 6, 2008

From @masak

The `return` built-in doesn't take zero arguments, like it can in Perl
5. The attached patch fixes this.

$ cat return_undef.pl
sub f { return undef }
say f()
$ ./perl6 return_undef.pl

$ cat return.pl
sub f { return }
say f()
$ ./perl6 return.pl
too few arguments passed (0) - 1 params expected
current instr.​: 'f' pc 79 (EVAL_13​:35)
called from Sub '_block11' pc 17 (EVAL_13​:10)
called from Sub 'parrot;PCT​::HLLCompiler;eval' pc 806
(src/PCT/HLLCompiler.pir​:481)
called from Sub 'parrot;PCT​::HLLCompiler;evalfiles' pc 1088
(src/PCT/HLLCompiler.pir​:610)
called from Sub 'parrot;PCT​::HLLCompiler;command_line' pc 1267
(src/PCT/HLLCompiler.pir​:699)
called from Sub 'parrot;Perl6​::Compiler;main' pc 13257 (perl6.pir​:172)
perl6(73334) malloc​: *** error for object 0x28909b0​: double free
*** set a breakpoint in malloc_error_break to debug
Segmentation fault

$ patch -p0 < zero-arg-return.patch ; make perl6
[...]

$ ./perl6 return.pl

$

@p6rt
Copy link
Author

p6rt commented Jul 6, 2008

From @masak

zero-arg-return.patch
Index: src/builtins/control.pir
===================================================================
--- src/builtins/control.pir	(revision 29090)
+++ src/builtins/control.pir	(working copy)
@@ -26,7 +26,13 @@
 .include 'except_types.pasm'
 
 .sub 'return'
-    .param pmc value
+    .param pmc value     :optional
+    .param int has_value :opt_flag
+
+    if has_value goto have_value
+    get_global $P1, "Failure"                                  
+    value = $P1."new"()                                         
+  have_value:
     $P0 = new 'Exception'
     $P0['_type'] = .CONTROL_RETURN
     setattribute $P0, 'payload', value

@p6rt
Copy link
Author

p6rt commented Jul 6, 2008

@pmichaud - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Jul 8, 2008

From @pmichaud

Applied (with one minor change) in r29143, thanks!

Note however that TimToady on #perl6 speculated [1] that an empty return
should return the Object prototype. I'm not sure the answer was
resolved completely in that thread, however, so we'll go with returning
'undef' for now and wait for a more definitive answer before closing
this ticket.

Thanks!

[1] http://irclog.perlgeek.de/perl6/2008-06-24#i_364168

1 similar comment
@p6rt
Copy link
Author

p6rt commented Jul 8, 2008

From @pmichaud

Applied (with one minor change) in r29143, thanks!

Note however that TimToady on #perl6 speculated [1] that an empty return
should return the Object prototype. I'm not sure the answer was
resolved completely in that thread, however, so we'll go with returning
'undef' for now and wait for a more definitive answer before closing
this ticket.

Thanks!

[1] http://irclog.perlgeek.de/perl6/2008-06-24#i_364168

@p6rt
Copy link
Author

p6rt commented Jul 8, 2008

From @TimToady

On Mon, Jul 07, 2008 at 07​:16​:05PM -0700, Patrick R. Michaud via RT wrote​:
: Note however that TimToady on #perl6 speculated [1] that an empty return
: should return the Object prototype. I'm not sure the answer was
: resolved completely in that thread, however, so we'll go with returning
: 'undef' for now and wait for a more definitive answer before closing
: this ticket.

A C<return> just returns its argument list as a Capture, so it's
probably just returning the "null" Capture, presumably with Object
(undef) in the scalar slot and an empty list in the list slot and
an empty hash in the hash slot. I don't think it's returning
the Capture protoobject itself though, because I think bare return is
returning something defined, so it's just an empty container, much
like the difference between Array and [].

Larry

@p6rt
Copy link
Author

p6rt commented Jul 8, 2008

From @pmichaud

On Mon, Jul 07, 2008 at 08​:18​:36PM -0700, Larry Wall wrote​:

On Mon, Jul 07, 2008 at 07​:16​:05PM -0700, Patrick R. Michaud via RT wrote​:
: Note however that TimToady on #perl6 speculated [1] that an empty return
: should return the Object prototype. I'm not sure the answer was
: resolved completely in that thread, however, so we'll go with returning
: 'undef' for now and wait for a more definitive answer before closing
: this ticket.

A C<return> just returns its argument list as a Capture, so it's
probably just returning the "null" Capture, presumably with Object
(undef) in the scalar slot and an empty list in the list slot and
an empty hash in the hash slot.

By "(undef)" here did you mean simply that it's an undefined
Object (prototype), or that the C<undef> function now returns
Object instead of Failure (S02​:872)?

Thanks,

Pm

@p6rt
Copy link
Author

p6rt commented Jul 8, 2008

From @TimToady

On Mon, Jul 07, 2008 at 11​:43​:56PM -0500, Patrick R. Michaud wrote​:
: On Mon, Jul 07, 2008 at 08​:18​:36PM -0700, Larry Wall wrote​:
: > On Mon, Jul 07, 2008 at 07​:16​:05PM -0700, Patrick R. Michaud via RT wrote​:
: > : Note however that TimToady on #perl6 speculated [1] that an empty return
: > : should return the Object prototype. I'm not sure the answer was
: > : resolved completely in that thread, however, so we'll go with returning
: > : 'undef' for now and wait for a more definitive answer before closing
: > : this ticket.
: >
: > A C<return> just returns its argument list as a Capture, so it's
: > probably just returning the "null" Capture, presumably with Object
: > (undef) in the scalar slot and an empty list in the list slot and
: > an empty hash in the hash slot.
:
: By "(undef)" here did you mean simply that it's an undefined
: Object (prototype), or that the C<undef> function now returns
: Object instead of Failure (S02​:872)?

Hmm, well, on further reflections, it should in all likelihood be
neither of those. I can argue that it should be a special failure type
to try to get an item from a null list​: "Attempt to pull a rabbit out
of an empty hat" or some such. :)

I can also argue that a null list in item context simply promotes to
an empty array just as a list of 2 or more elements does. Given that
"return;" is not the same as "fail;", that's probably the right thing to
do.

It does treat single-item lists as special, but note that .[0] is
a no-op on a non-array. And it's really the .[0] operation that
translates to the pull-a-rabbit-out-of-an-empty-hat failure if you
hand it a null list. Well, it's probably really "Subscript out of
range"...

Which argues that bare return should be treated as returning a list
that happens to be empty (via the Capture that return always returns
to keep the return value contextually lazy).

So

  $x = nothing(); # = []
  @​x = nothing(); # = ()
  %x = nothing(); # = ()
  if nothing() {...} # always false
  $x = nothing()[0] # "Subscript out of range" failure

In other words, I think I'd like to not encourage people to use bare
return to indicate failure.

Larry

@p6rt
Copy link
Author

p6rt commented Jul 8, 2008

From @TimToady

On Mon, Jul 07, 2008 at 10​:09​:37PM -0700, Larry Wall wrote​:
: So
:
: $x = nothing(); # = []
: @​x = nothing(); # = ()
: %x = nothing(); # = ()
: if nothing() {...} # always false
: $x = nothing()[0] # "Subscript out of range" failure

But note that binding the returned capture also fails​:

  $x := nothing();

just as calling foo() without args can't bind to a sig with required
params​:

  sub foo ($x) {...}

Binding to $x is more like looking for .[0], in other words.

Note however that when you call

  foo(nothing())

you're really passing a Capture with 1 positional element, which
contains the empty Capture returned by nothing(), so $x is presumably
bound to [] by promotion of the empty list, just as

  foo(threeitems())

would bind an array of 3 elements.

Larry

@p6rt
Copy link
Author

p6rt commented Sep 11, 2008

From @moritz

A recent change in the test suite made three rakudo tests fail (although
I don't know why, they should be correcter in the new form). All of them
look roughly like this​:

sub bar { return }
ok(!defined(bar()), '... bare return statement returned undef');

(from t/spec/S04-statements/return.t)

I TODO'ed them now (to make spectest_regression clean again), and opened
this ticket instead.

Moritz

--
Moritz Lenz
http://moritz.faui2k3.org/ | http://perl-6.de/

@p6rt
Copy link
Author

p6rt commented Nov 9, 2008

From @moritz

Merging into 58770, because the discussion here is relevant over there
as well, and the original issue (the error message) is resovled.

See also​:
http://www.nntp.perl.org/group/perl.perl6.language/2008/11/msg29884.html
(bare return should now return Nil, which is undef in scalar context).

@p6rt
Copy link
Author

p6rt commented Dec 14, 2008

From @pmichaud

Now fixed in r33898, thanks!

Pm

@p6rt
Copy link
Author

p6rt commented Dec 14, 2008

@pmichaud - Status changed from 'new' to 'resolved'

@p6rt p6rt closed this as completed Dec 14, 2008
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant