Re: return() in pointy blocks
Larry Wall wrote: On Wed, Jun 08, 2005 at 12:37:22PM +0200, TSa (Thomas Sandlaß) wrote: : BTW, is - on the 'symbolic unary' precedence level : as its read-only companion \ ?. No, - introduces a term that happens to consist of a formal signature and a block. There are no ordinary expressions involved until you get inside the block. (Or set a default on one of the parameters, to the extent that those are ordinary expressions.) So without a block there is a syntax error? $x = - $y; Or could this be understood as a short form of $x = - { $y } # $y from outer scope I still think the pointy looks really cute as a prefix operator for constructing rw refs. Especially if we use () to evaluate the blockref returned. For plain variable assignment this is not overly usefull because it amounts to the same as $x := $y; but in lists it is quite nice %h = { foo, 'bar', blah, - $y }; or not? %h = { foo = 'bar', blah = - $y }; hmm, can the following be interpreted as spoiling pair notation? %h = { :foobar, :blah - $y }; # would blah- $y parse at all? I think not because this works %h = { :foobar, :blah{- $y} }; Regards, -- TSa (Thomas Sandlaß)
Re: return() in pointy blocks
On Mon, Jul 04, 2005 at 07:01:00PM +0200, TSa (Thomas Sandlaß) wrote: : Larry Wall wrote: : On Wed, Jun 08, 2005 at 12:37:22PM +0200, TSa (Thomas Sandlaß) wrote: : : BTW, is - on the 'symbolic unary' precedence level : : as its read-only companion \ ?. : : No, - introduces a term that happens to consist of a formal signature : and a block. There are no ordinary expressions involved until you : get inside the block. (Or set a default on one of the parameters, to : the extent that those are ordinary expressions.) : : So without a block there is a syntax error? : : $x = - $y; Yes. : Or could this be understood as a short form of : : $x = - { $y } # $y from outer scope Could, but I'm prejudiced against implicit lexical scopes. and || and ??:: are okay as standard forms of indirect quotation, but natural languages are notorious for getting into ambiguous situations with that kind of laziness. So that's one of the features I'm slow to copy from human languages. Curlies are already short, and in Perl 6 have the (almost) universal meaning of direct quotation of code. : I still think the pointy looks really cute as a prefix operator : for constructing rw refs. Especially if we use () to evaluate : the blockref returned. For plain variable assignment this is : not overly usefull because it amounts to the same as : : $x := $y; : : but in lists it is quite nice : : %h = { foo, 'bar', blah, - $y }; : : or not? : : %h = { foo = 'bar', blah = - $y }; I don't think the semantics pass the Pooh test. It's also confusing syntactically. What state is the parser supposed to be in when it gets to the end of this: foo = 'bar', blah = - $x, $y, $z If the precedence of - is list operator (and it needs to be to gobble up pointy sub arguments), then you have to write one of foo = 'bar', blah = - ($x), $y, $z foo = 'bar', blah = (- $x), $y, $z to limit it to the first argument, and you might as well have put some curlies there. We're not going to do arbitrary lookahead to find a { to decide the precedence of - on the fly. That would be insane. : hmm, can the following be interpreted as spoiling pair notation? : : %h = { :foobar, :blah - $y }; # would blah- $y parse at all? That won't parse. : I think not because this works : : %h = { :foobar, :blah{- $y} }; That won't parse either. Larry
Re: return() in pointy blocks
Luke Palmer [EMAIL PROTECTED] writes: On 6/8/05, Piers Cawley [EMAIL PROTECTED] wrote: In other words, it outputs: Foo Foo # dies Yep. My mistake. If that works, then I think it means we can write: sub call-with-current-continuation(Code $code) { my $cc = - $retval { return $retval } $code($cc); } Which I personally think is rather cute. Even if I can't quite bring myself to believe it's that simple... Yeah, that's pretty. But that will bite people who don't understand continuations; it will bite people who don't understand return; it will even bite people who understand continuations, because they can be made in such an awkward form so easily. Having worked through the little and seasoned Schemers, I'm actually at the point where I can happily think that 'return' is deep scary magic. What I *want* is a 'proper' continuation, but this would have been close enough for government work until the real ones came along. Currently call/cc is done like this: sub call_with_current_continuation(code) { code(?CALLER_CONTINUATION); } But that might be broken in pugs at the moment. Doesn't that call code with the continuation of the caller of call_with_current_continuation, when it *should* call code with the continuation of call_with_current_continuation?
Re: return() in pointy blocks
Larry Wall [EMAIL PROTECTED] writes: On Wed, Jun 08, 2005 at 10:51:34PM +, Luke Palmer wrote: : Yeah, that's pretty. But that will bite people who don't understand : continuations; it will bite people who don't understand return; it : will even bite people who understand continuations, because they can : be made in such an awkward form so easily. Right--we don't want mere mortals to be able to get at continuations quite that easily, whether they think they want them or not. Shame. If you go monkeying with continuations without knowing what they do, then of course you deserve everything you have coming to you, but is that really any reason for making them hard to get at when you *do* need them? I'm not denying that they should be hard to get accidentally, but it would be good to know how to get them deliberately.
Re: return() in pointy blocks
Luke Palmer wrote: Says not: Boo Boo Boo ... This is clear, but I would expect the output Boo 42 because the return value of foo is a ref to a block that makes the caller return 42. This is written in my current Perl6 as foo:( : -- Block -- 42) The question is when exactly this call chain is invoked: 1) when it is assigned to $code? Or, 2) when postfix:( ) is invoked on $code? I prefer 2) because it better fits my understanding of referential semantics. About the relationship to the lazy versus eager trade-off I'm unsure. So 1) is also a good choice. With this in mind, I wonder how \ and - are related. Is $x = 3; $rw = - $x; valid syntax? And does it mean that $rw = 7; say $x; # prints 7 This can be construed as the eager version of $x = 3; $rw = - { $x }; $rw = 7; say $x; # means: say $x(); A block in a chain of references is a stop mark in a chain of refs. $x = 3; $r = - $x; $rr = - $r; say $rr(); # prints 3, because say $r; also prints 3 $rr = 7; say $r; # prints 7 say $x; # prints 3 Looks like we have found a candidate for the transparent ref creator! And I hope Juerd likes it. After all it looks *pointy* :) PS: A chain of refs can thus be reduced to the leaf lvalue with ([()] $rr) = 23; which stores a new value in $x. This might even warrant the special case of ([] $rr) = 23; -- TSa (Thomas Sandlaß)
Re: return() in pointy blocks
Luke Palmer [EMAIL PROTECTED] writes: On 6/7/05, Matt Fowles [EMAIL PROTECTED] wrote: On 6/7/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: Hi, sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? I don't like this because the function bar is getting oddly prematurely halted. Then let's put it this way: sub foo () { for 0..10 { when 6 { return 42 } } return 26; } And if that didn't do it, then let's write it equivalently as: sub foo () { map(- $_ { return 42 }, 0..10); return 26; } Do you see why the return binds to the sub rather than the pointy now? Also, we're going to be avoiding the return continuation problem with: sub foo() { return - { return 42 }; } my $code = foo(); say Boo!; $code(); Says not: Boo Boo Boo ... But: Boo Can't return from subroutine that already returned at eval line 2. My preference is for: Boo Boo Can't dereferene literal numeric literal 42 as a coderef. Actually, my preference is for not writing such silly code in the first place, but there you go.
Re: return() in pointy blocks
Well, does using - as blockref creator also give anonymous scalars? $y = - $x { $x = 3; $x }; # $y:(Ref of Block of Int) BTW, is - on the 'symbolic unary' precedence level as its read-only companion \ ?. Are they pure macros? -- TSa (Thomas Sandlaß)
Re: return() in pointy blocks
Piers Cawley wrote: My preference is for: Boo Boo Can't dereferene literal numeric literal 42 as a coderef. How do you reach the second 'Boo'? Iff - does not create a Sub but a Block instance then Luke's code can be interpreted as a much smarter version of sub foo() { enter: 42; if $?RETURN_LABEL { goto $?RETURN_LABEL } return; } say Boo!; say goto foo::enter; # goto sets up $?RETURN_LABEL say after goto; which of course prints Boo 42 after goto The smartness is in the value that prefix:{'-'} returns while in the snippet above it is explicitly coded. Or do I completely misunderstand the distinction between blocks and closures? -- TSa (Thomas Sandlaß)
Re: return() in pointy blocks
TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes: Piers Cawley wrote: My preference is for: Boo Boo Can't dereferene literal numeric literal 42 as a coderef. How do you reach the second 'Boo'? Iff - does not create a Sub but a Block instance then Luke's code can be interpreted as a much smarter version of I really wish you'd quote in more detail, it makes it a real PITA to go back and find the explanatory code. sub foo () { return - { return 42 } } my $code = foo(); # ^--- continuations points to the RHS of the assignment say Boo!; $code(); So, this is what happens. 1. foo() returns a coderef to the RHS of the assignment. 2. The coderef gets assigned to $code. 3. say Boo! 4. We invoke the coderef, which returns 14 to continuation which was current when it was created. 5. That means 42 gets returned to the RHS of the assignment 6. say Boo! 7. Try to invoke the literal 42. 8. Die. In other words, it outputs: Foo Foo # dies sub foo() { enter: 42; if $?RETURN_LABEL { goto $?RETURN_LABEL } return; } say Boo!; say goto foo::enter; # goto sets up $?RETURN_LABEL say after goto; which of course prints Boo 42 after goto The smartness is in the value that prefix:{'-'} returns while in the snippet above it is explicitly coded. Or do I completely misunderstand the distinction between blocks and closures? It seems so.
Re: return() in pointy blocks
Piers Cawley [EMAIL PROTECTED] writes: TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes: Piers Cawley wrote: My preference is for: Boo Boo Can't dereferene literal numeric literal 42 as a coderef. How do you reach the second 'Boo'? Iff - does not create a Sub but a Block instance then Luke's code can be interpreted as a much smarter version of I really wish you'd quote in more detail, it makes it a real PITA to go back and find the explanatory code. sub foo () { return - { return 42 } } my $code = foo(); # ^--- continuations points to the RHS of the assignment say Boo!; $code(); So, this is what happens. 1. foo() returns a coderef to the RHS of the assignment. 2. The coderef gets assigned to $code. 3. say Boo! 4. We invoke the coderef, which returns 14 to continuation which was current when it was created. 5. That means 42 gets returned to the RHS of the assignment 6. say Boo! 7. Try to invoke the literal 42. 8. Die. In other words, it outputs: Foo Foo # dies If that works, then I think it means we can write: sub call-with-current-continuation(Code $code) { my $cc = - $retval { return $retval } $code($cc); } Which I personally think is rather cute. Even if I can't quite bring myself to believe it's that simple...
Re: return() in pointy blocks
Piers Cawley wrote: TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes: Piers Cawley wrote: My preference is for: Boo Boo Can't dereferene literal numeric literal 42 as a coderef. How do you reach the second 'Boo'? Iff - does not create a Sub but a Block instance then Luke's code can be interpreted as a much smarter version of I really wish you'd quote in more detail, it makes it a real PITA to go back and find the explanatory code. Sorry, but I try to quote only the text that I'm really referring to, not the transitive closure of the thread at that point. If I cut too much here, I apologize. sub foo () { return - { return 42 } } What I do not understand right now is, how the first return is handled. As Luke pointed out, the inner return inevitably makes the current invocation of foo return. But you argue, that - suspends the current invocation of foo and returns it as continuation. How does that fit the pointy sub of a for loop? Is the surrounding sub suspended as well? And then one could continue right there? sub forfoo () { for 0..9 - $x { return $x; } } my $y = forfoo(); # suspends forfoo in first loop? say $y; # prints 0, and suspends forfoo in second loop say **$y; # prints the remaining invocations of forfoo? I figure that the implementation is actually straight forward. The pointy sub catches the return exception and handles it by suspending forfoo and returning the resulting continuation. my $code = foo(); # ^--- continuations points to the RHS of the assignment say Boo!; $code(); So, this is what happens. 1. foo() returns a coderef to the RHS of the assignment. 2. The coderef gets assigned to $code. 3. say Boo! 4. We invoke the coderef, which returns 14 to continuation which was current when it was created. 5. That means 42 gets returned to the RHS of the assignment 6. say Boo! 7. Try to invoke the literal 42. Hmm, I see in both cases an MMD to postfix:( ) with the then current value of $code as invocant. In the first run the target is postfix:( ):( Ref of Block :) and in the second case it's postfix:( ):( Int :). If the latter is defined to die, so be it. I opt for just returning the value. Which produces the fallout that $y = 42(); Is first of all valid syntax, and dispatches at runtime unless the compiler can proof at compile time that there can't possibly be an implementation at runtime. Thus one could write: multi sub *postfix:( ) ( 42 ) # or ( Int $x where $x eq '42' ) { return 66; # == hex 42 } A pragma like 'use hexliterals' might actually implement a general version of this idea. -- TSa (Thomas Sandlaß)
Re: return() in pointy blocks
Piers Cawley wrote: [..] then I think it means we can write: sub call-with-current-continuation(Code $code) { my $cc = - $retval { return $retval } For the records: the return here is the essential ingredient, right? Without it the block would be evaluated or optimized away to an undef or some such. $code($cc); } Which I personally think is rather cute. Me too! Even if I can't quite bring myself to believe it's that simple... I have convinced myself. How can I be of assistance on your side? -- TSa (Thomas Sandlaß)
Re: return() in pointy blocks
On Wed, Jun 08, 2005 at 12:37:22PM +0200, TSa (Thomas Sandlaß) wrote: : BTW, is - on the 'symbolic unary' precedence level : as its read-only companion \ ?. No, - introduces a term that happens to consist of a formal signature and a block. There are no ordinary expressions involved until you get inside the block. (Or set a default on one of the parameters, to the extent that those are ordinary expressions.) Larry
Re: return() in pointy blocks
TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes: Piers Cawley wrote: [..] then I think it means we can write: sub call-with-current-continuation(Code $code) { my $cc = - $retval { return $retval } For the records: the return here is the essential ingredient, right? Without it the block would be evaluated or optimized away to an undef or some such. Yes. Without the return you just get block that returns the value its last expresion to the place from which it (the pointy sub) was called, rather than to the place that the subroutine that created it was called from. $code($cc); } Which I personally think is rather cute. Me too! Even if I can't quite bring myself to believe it's that simple... I have convinced myself. How can I be of assistance on your side? How's your Haskell?
Re: return() in pointy blocks
On 6/8/05, Piers Cawley [EMAIL PROTECTED] wrote: In other words, it outputs: Foo Foo # dies Yep. My mistake. If that works, then I think it means we can write: sub call-with-current-continuation(Code $code) { my $cc = - $retval { return $retval } $code($cc); } Which I personally think is rather cute. Even if I can't quite bring myself to believe it's that simple... Yeah, that's pretty. But that will bite people who don't understand continuations; it will bite people who don't understand return; it will even bite people who understand continuations, because they can be made in such an awkward form so easily. Currently call/cc is done like this: sub call_with_current_continuation(code) { code(?CALLER_CONTINUATION); } But that might be broken in pugs at the moment. Luke
Re: return() in pointy blocks
On Wed, Jun 08, 2005 at 10:51:34PM +, Luke Palmer wrote: : Yeah, that's pretty. But that will bite people who don't understand : continuations; it will bite people who don't understand return; it : will even bite people who understand continuations, because they can : be made in such an awkward form so easily. Right--we don't want mere mortals to be able to get at continuations quite that easily, whether they think they want them or not. Larry
return() in pointy blocks
Hi, sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? --Ingo -- Linux, the choice of a GNU | To understand recursion, you must first generation on a dual AMD | understand recursion. Athlon!|
Re: return() in pointy blocks
Ingo~ On 6/7/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: Hi, sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? I don't like this because the function bar is getting oddly prematurely halted. If bar had read sub bar(Code $moo) { $moo(13); save_the_world(); } it would not have gotten to save the world. One might argue that $moo could throw an exception, but bar has a way to catch that. It seems to me that what you are asking for has the potential to cause some vary large unexpected jumps down the stack. That said, I would want the pointy subs in for loops to ask this way, so maybe this is just one of those things that one has to be ware of. Matt -- Computer Science is merely the post-Turing Decline of Formal Systems Theory. -???
Re: return() in pointy blocks
Ingo Blechschmidt [EMAIL PROTECTED] writes: Hi, sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? That's how it's defined in the relevant Apocalypse. And that's how I hope it'll stay.
Re: return() in pointy blocks
Hi, Matt Fowles wrote: On 6/7/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? I don't like this because the function bar is getting oddly prematurely halted. If bar had read sub bar(Code $moo) { $moo(13); save_the_world(); } it would not have gotten to save the world. One might argue that $moo could throw an exception, but bar has a way to catch that. yep. $moo(13) will never return. But this is not specific to pointy blocks: Consider bar return; It seems to me that what you are asking for has the potential to cause some vary large unexpected jumps down the stack. Yep. so maybe this is just one of those things that one has to be ware of. I think the reponsibility is at the user using return or other evil Codes (like, as in the example, - $val { return $val }), not the innocent subroutine programmer (bar)) -- if you play with continuations, you know what might happen. But they can be very useful, too! :) --Ingo -- Linux, the choice of a GNU | Failure is not an option. It comes bundled generation on a dual AMD | with your Microsoft product. Athlon!|
Re: return() in pointy blocks
On 6/7/05, Matt Fowles [EMAIL PROTECTED] wrote: On 6/7/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: Hi, sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? I don't like this because the function bar is getting oddly prematurely halted. Then let's put it this way: sub foo () { for 0..10 { when 6 { return 42 } } return 26; } And if that didn't do it, then let's write it equivalently as: sub foo () { map(- $_ { return 42 }, 0..10); return 26; } Do you see why the return binds to the sub rather than the pointy now? Also, we're going to be avoiding the return continuation problem with: sub foo() { return - { return 42 }; } my $code = foo(); say Boo!; $code(); Says not: Boo Boo Boo ... But: Boo Can't return from subroutine that already returned at eval line 2. Luke
Re: return() in pointy blocks
On 6/7/05, Luke Palmer [EMAIL PROTECTED] wrote: Then let's put it this way: sub foo () { for 0..10 { when 6 { return 42 } } return 26; } And if that didn't do it, then let's write it equivalently as: sub foo () { map(- $_ { return 42 }, 0..10); return 26; } Not that it's that important to the argument, but of course I mean: sub foo() { map(- $_ { return 42 when 6 }, 0..10); return 26; } Luke
Re: return() in pointy blocks
All~ On 6/7/05, Luke Palmer [EMAIL PROTECTED] wrote: On 6/7/05, Matt Fowles [EMAIL PROTECTED] wrote: On 6/7/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: Hi, sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? I don't like this because the function bar is getting oddly prematurely halted. Then let's put it this way: sub foo () { for 0..10 { when 6 { return 42 } } return 26; } And if that didn't do it, then let's write it equivalently as: sub foo () { map(- $_ { return 42 }, 0..10); return 26; } Do you see why the return binds to the sub rather than the pointy now? Also, we're going to be avoiding the return continuation problem with: sub foo() { return - { return 42 }; } my $code = foo(); say Boo!; $code(); Says not: Boo Boo Boo ... But: Boo Can't return from subroutine that already returned at eval line 2. You are right. I yield... It just made by brain hurt, now that it is somewhat fortified with caffeine I see. Matt -- Computer Science is merely the post-Turing Decline of Formal Systems Theory. -???