Re: Transparent / Opaque references
Juerd wrote: $y() = 7; No, sorry, that looks to me as if $y is a reference to an lvalue sub, not like any form of referencing of scalars. I think it will come naturally to the C++ and Java folks. There the accessor kind of functions is either mapped into the name get_y() and set_y(value), or operator () is overloaded. In the latter idiom assignment actually becomes $y(7). Which might be a bit far out for Perlkind. But OTOH it looks like a function call... This idiom looks better with scalar attributes of objects: $obj.attr() = 7; # parser supports to drop the .() and $obj.attr(7); # beware, attr becomes 7 if the class of $obj works as such And it nicely gives: $y = \$obj.attr; $y() = 7; # dereffed assignment $y = 13; # detaches from $obj.attr say $obj.attr; # prints 7 I'm not sure but in Perl5 the equivalent to the second line above is $y- = 7; # postfix - is now spelled () isn't it? -- TSa (Thomas Sandlaß)
Re: reduce metaoperator on an empty list
Okay, I've made up my mind. The err option is not tenable because it can cloak real exceptions, and having multiple versions of reduce is simply multiplying entities without adding much power. So let's allow an optional identvalue trait on operators. If it's there, reduce can use it. If it's not, reduce returns failure on 0 args. Built-in addition will have an identity value of 0, while multiplication will have an identity value of 1. String concatenation will have . We can go as far as having -Inf on [] and +Inf on [], but maybe that means we have to define values that are positive and negative infinity on strings so we can get [gt] and [lt] indentity values. Those might be useful in any event. But I would like to stress that this is an *optional* property. We will only define an identity value for those operators for which it is obvious what an accumulator should be initialized to. (This is probably also the set of operators for which op= doesn't warn when the left side is undefined, so identval is doing double duty. In Perl 5 we hardwired that, so it'd be nice to generalize the concept in Perl 6.) In fact, by the accumulator argument, maybe it should be called initvalue rather than identvalue. 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. -???
Re: reduce metaoperator on an empty list
On 6/7/05, Larry Wall [EMAIL PROTECTED] wrote: Okay, I've made up my mind. The err option is not tenable because it can cloak real exceptions, and having multiple versions of reduce is simply multiplying entities without adding much power. So let's allow an optional identvalue trait on operators. If it's there, reduce can use it. If it's not, reduce returns failure on 0 args. Built-in addition will have an identity value of 0, while multiplication will have an identity value of 1. String concatenation will have . We can go as far as having -Inf on [] and +Inf on [] and still don't make sense as reduce operators. Observe the table: # of args | Return (type) 0 | -Inf 1 | Num (the argument) 2 | bool ... | bool There is a pretty fundamental difference between X,X - X operators and X,X - Y operators wrt reduce. Most languages don't even allow the latter kind, but I think it would be cool if we did. I'm not really sure what you mean by it can mask real exceptions. If the operator is defined to require 1 or more (or in the case of nonhomogeneous operators, 2 or more) arguments, then that is a real exception. err just fails to be a realistic fallback mode. In any case, I'm fairly satisfied with your conclusion (but I wasn't when I began writing this reply :-). I just think we have to give nonhomogeneous operators like some special treatment. So, from our somewhat lexical definition of reduce, I don't think an identity input is what we're looking for. We really want an identity output. Binary operators really need two such outputs: one for zero arguments and one for one argument. The one argument output can be inferred from the zero argument output (but not vice versa). So, we could define two properties: is nullaryvalue(-Inf) is unaryfunction({ 1 }) And, of course, if nullaryvalue is not defined, then we die (or fail) when zero arguments are given. unaryfunction will default to { op(nullaryvalue, 1) }, or { $_ } if nullaryvalue was not defined, unless the output type is incompatible with the input type (in which case we have to die even with one argument). We could also define the unaryfunction automatically if a default value is given for one of the arguments of a binary operator. But this all ceases to be a problem for list-associative operators, which presumably take a list of arguments rather than just two. That reminds me, how are , , etc. defined anyway? How can we tell them to be list-associative with each other? Luke
Re: reduce metaoperator on an empty list
On Tue, Jun 07, 2005 at 09:41:49PM +, Luke Palmer wrote: : and still don't make sense as reduce operators. Yeah, I keep confusing them with min and max. : That reminds me, how are , , etc. defined anyway? How can we tell : them to be list-associative with each other? Because they're all of that specific precedence level, which is defined to work that way by fiat, I suspect. (Other operators have to be explicitly declared as list associative, and even then are only list associative with themselves, not with all other operators in their precedence level.) I suppose it could be construed as some kind of default property on the actual precedence level, but it's not clear that that would be a useful generalization. Larry
Re: reduce metaoperator on an empty list
On 6/7/05, Larry Wall [EMAIL PROTECTED] wrote: On Tue, Jun 07, 2005 at 09:41:49PM +, Luke Palmer wrote: : and still don't make sense as reduce operators. Yeah, I keep confusing them with min and max. : That reminds me, how are , , etc. defined anyway? How can we tell : them to be list-associative with each other? Because they're all of that specific precedence level, which is defined to work that way by fiat, I suspect. (Other operators have to be explicitly declared as list associative, and even then are only list associative with themselves, not with all other operators in their precedence level.) I suppose it could be construed as some kind of default property on the actual precedence level, but it's not clear that that would be a useful generalization. Okay, I was referring more to the implementation. How do we tell apart: 3 4 = 5 == 5 From 3 lt 4 = 5 != 5 ? Luke
Re: reduce metaoperator on an empty list
Luke Palmer wrote: and still don't make sense as reduce operators. Observe the table: # of args | Return (type) 0 | -Inf 1 | Num (the argument) 2 | bool ... | bool Let's look at the type of one of the many `reduce' variants in Haskell; foldr1 :: (a - a - a) - [a] - a This is the Perl6ish; sub reduce( ::Code{( ::(someType), ::(someType) ) returns ::(someType)} $func, Array of ::(someType) ) returns ::(someType); ie, the function $func supplied must take and return arguments of a single type. So you have come to the same conclusion as the FP folk :-). Here I'm using ::(foo) as a coined syntax for a parametric type to the definition. `someType' need not be defined anywhere else, but must be the same within the application of a definition. IMHO we still need to make some movements towards a specification for how this sort of thing is specified... I just think we have to give nonhomogeneous operators like some special treatment. So, from our somewhat lexical definition of reduce, I don't think an identity input is what we're looking for. We really want an identity output. When I last looked, in pugs, functions that return bool types are currently setup to return one or the other argument when used with reduce; like there is a similar; multi sub reduce( ::{Code( ::(someType) $a, ::(someType) $b ) returns bool} $func, Array of ::(someType) ) returns ::(someType); This gives meaning to operators like [], which would return the maximum value from a list. Sam.
Re: reduce metaoperator on an empty list
On Tuesday 07 June 2005 23:41, Luke Palmer wrote: On 6/7/05, Larry Wall [EMAIL PROTECTED] wrote: Okay, I've made up my mind. The err option is not tenable because it can cloak real exceptions, and having multiple versions of reduce is simply multiplying entities without adding much power. So let's allow an optional identvalue trait on operators. If it's there, reduce can use it. If it's not, reduce returns failure on 0 args. Built-in addition will have an identity value of 0, while multiplication will have an identity value of 1. String concatenation will have . We can go as far as having -Inf on [] and +Inf on [] and still don't make sense as reduce operators. Observe the table: # of args | Return (type) 0 | -Inf 1 | Num (the argument) 2 | bool ... | bool How about using initvalue twice for empty array, ie. always pad to at least two values? So $bool = [] @empty_array; # is false (-Inf -Inf) $bool = [=] @empty_array; # is true (-Inf = -Inf) Which would make some sort of sense - in an empty array there's no right element that's bigger than it's left neighbour ... And if the case [] @empty_array should return true it's easy to use ?? ::. Just my ¤0.02. Regards, Phil