Re: syntax: multi vs. method
Jonathan Lang writes: My apologies for the break in the chain of responses; I lost your reply before I could reply to it, and had to retrieve it from the list archives. Luke Palmer wrote: Well, multi is no longer a declarator in its own right, but rather a modifier. Synopsis Exegesis 6 show this. I don't know about Exegesis 6, Then you should probably read it. It is the most recent of the documents, so what it says is closest to the current thinking. Plus, it's a fun read. but Synopsis 6 (http://dev.perl.org/perl6/synopsis/S06.html) is still showing multi to be a declarator on par with sub, method, rule, and macro. Now that I look, yes, that's true. It's wrong. I think this makes things even clearer, and has a fine-grained but elegant control over the scope of the routine. Agreed; I'd like something like this to be implemented. This easily allows for multisubmethods and even multimacros (provided you have yourself a polymorphic object at compile time). For the record, subs never have invocants as currently described - so you could easily say that any sub that has an invocant is actually a submethod: sub touch ($a: $b) {...} would be synonymous with: submethod touch ($a: $b) {...} Hmm. Well, that depends on whether calling works like it does in Perl 5. That is, given: multi sub touch (Foo $a: $b) {...} Is this legal: my $x = new Foo; $x.touch; I haven't been able to deduce this. I also think it's important to say multi explicitly every time you mean it. It allows the compiler to warn you when you're just being stupid about scoping as opposed to actually wanting to overload the routine. From a design perspective, it makes it clear that this method introduces logical control-flow in addition to performing a task. That's probably good programming advice; but it should remain advice rather than being a requirement. Spoken like a true Perl programmer :-) I don't see the win in losing the Cmulti keyword though. Sure, there are 5 fewer characters, but declarations aren't a place where concise and terse are synonymous. IMO, a colon is too small a character for such a large distinction. Misunderstanding the rule slightly can lead to overriding instead of overloading... reminds me of C++ [1]. If you allow the distinction between a method and a multimethod to be determined implicitly, you can, if you choose, ignore the submethod and multi keywords altogether with minimal loss of capabilities: submethod touch ($a) {...} multi watch ($a, $b) {...} would be equivelent to sub touch ($_: $a) {...} method watch ($a, $b:) {...} Luke [1] While I haven't the hatred for C++ that quite a few people on this list do, I definitely consider it an advanced language, by which I mean there are subtle variants in the rules that cause wildy different behaviors. Beginners (and intermediates) still struggle with this one: class Base { public: virtual int num() const { return 10; } } class Derived : public Base { public: int num() { return 20; } } int main() { Base* b = new Base; Base* d = new Derived; cout b-num() endl; // 10 cout d-num() endl; // 10 !! } Now why the heck did the call to d-num() return 10??!!! Because they missed a Cconst in the overriding of num(), hiding it instead. This is precisely what would happen if you missed a colon in adding a multimethod. Sorry, I don't want to inflict this kind of pain on Perl programmers.
Control flow variables
I was reading the most recent article on perl.com, and a code segment reminded me of something I see rather often in code that I don't like. Here's the code, Perl6ized: ... ; my $is_ok = 1; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { $is_ok = 0; last; } } if $is_ok { push @moves: [$i, $j]; } ... I see this idiom a lot in code. You loop through some values on a condition, and do something only if the condition was never true. $is_ok is a control flow variable, something I like to minimize. Now, there are other ways to do this: if (0..6 == grep - $t { abs(@new[$t] - @new[$t+1]) }) { ... } But one would say that's not the cleanest thing in the world. Python pulled this idiom out in to the syntax (yay them), with Celse on loops. The else block on a python loop executes only if you never broke out of the loop. That's a great idea. So, in Perl's postmodern tradition, I think we should steal that idea. I'm a little uneasy about calling it Celse, though. Maybe CFINISH would do, making the example: for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { last; } FINISH { push @moves: [$i, $j]; } } I'd also like to say that while converting the rest of this sub to Perl 6, I realized how much I love the ..^ and ^.. operators. I was wondering whether people had forgotten about them :-). Luke
Re: Control flow variables
[EMAIL PROTECTED] (Luke Palmer) writes: I was reading the most recent article on perl.com, and a code segment reminded me of something I see rather often in code that I don't like. The code in question got me thinking too; I wanted to find a cleaner way to write it, but didn't see one. So, in Perl's postmodern tradition, I think we should steal that idea. I agree, but (as usual) would like to consider whether there's a way to solve a general problem rather than solving a specific problem by throwing additional syntax at it. (which sadly seems to be fast becoming the Perl 6 way) Given that we've introduced the concept of if having a return status: my $result = if ($a) { $a } else { $b }; Then why not extend this concept and have a return status from other control structures? for 0..6 - $t { last if abs(@new[$t] - @new[$t+1]) 3; } or push @moves: [$i, $j]; Of course, these things have consequences; I'm not sure whether we really want people saying push @moves:[$i, $j] unless last if abs(@[EMAIL PROTECTED])3 for 0..6; -- The course of true anything never does run smooth. -- Samuel Butler
Re: Control flow variables
Simon Cozens writes: [EMAIL PROTECTED] (Luke Palmer) writes: I was reading the most recent article on perl.com, and a code segment reminded me of something I see rather often in code that I don't like. The code in question got me thinking too; I wanted to find a cleaner way to write it, but didn't see one. So, in Perl's postmodern tradition, I think we should steal that idea. I agree, but (as usual) would like to consider whether there's a way to solve a general problem rather than solving a specific problem by throwing additional syntax at it. (which sadly seems to be fast becoming the Perl 6 way) Well... it is and isn't. At first sight, it makes the language look huge, the parser complex, a lot of syntax to master, etc. It also seems to me that there is little discrimination when adding new syntax. But I've come to look at it another way. Perl 6 is doing something (many things, really) that no other language has done before: making it very easy to add new syntax to the language. So modules that introduce new concepts into the language can add new syntax for them without working with (ugh) a source filter. And some of these new syntaxes in the core language will actually be in standard modules, if they're not commonly used. Just like traits. But even when they're not, Perl is a generic, multiparadigm language. It covers and supports many concepts, and new concepts grafted onto an existing but unfit syntax make things harder. Humans are pretty good at syntax. Many times mathematicians make up new syntax when they introduce a new concept: making it easier to think about, and easier to recognize. I'll also point out that FINISH isn't really extra syntax, just extra vocabulary. Given that we've introduced the concept of if having a return status: my $result = if ($a) { $a } else { $b }; Ack! We have? It does make sense if we want to be able to implement Cif as a regular sub... I guess. Yuck. Then why not extend this concept and have a return status from other control structures? for 0..6 - $t { last if abs(@new[$t] - @new[$t+1]) 3; } or push @moves: [$i, $j]; Of course, these things have consequences; I'm not sure whether we really want people saying push @moves:[$i, $j] unless last if abs(@[EMAIL PROTECTED])3 for 0..6; That's illegal anyway. Can't chain statement modifiers :-) But a close relative would be possible: push @moves: [$i, $j] unless for 0..6 { last if abs(@[EMAIL PROTECTED]) 3 } Yeah, how about no. :-) Luke
Re: Control flow variables
Luke Palmer: Well... it is and isn't. At first sight, it makes the language look huge, the parser complex, a lot of syntax to master, etc. It also seems to me that there is little discrimination when adding new syntax. Correct. But I've come to look at it another way. Perl 6 is doing something (many things, really) that no other language has done before: making it very easy to add new syntax to the language. Well, that's hardly a new concept for a programming language. So modules that introduce new concepts into the language can add new syntax for them without working with (ugh) a source filter. And some of these new syntaxes in the core language will actually be in standard modules, if they're not commonly used. Just like traits. This is good. This is what I like to hear. This is why the answer to all these stupid syntax questions should be Look, if you need it, just put it in a module when we're done. But can we please get on with getting Perl 6 designed and out the door, now? But it isn't, and I don't know why it isn't, and so we end up spending loads of time discussing things that can be punted out to modules. Designing Perl 6 is hard enough; let's not try to fill CP6AN at the same time. I'll also point out that FINISH isn't really extra syntax, just extra vocabulary. It's extra special cases, which come to the same thing. my $result = if ($a) { $a } else { $b }; Ack! We have? It does make sense if we want to be able to implement Cif as a regular sub... I guess. Yuck. Yep, we did. Of course, the nice thing about it is that it allows do_thing() if if ($a) { $b } else { $c }; That's illegal anyway. Can't chain statement modifiers :-) Bah, should be able to! But a close relative would be possible: push @moves: [$i, $j] unless for 0..6 { last if abs(@[EMAIL PROTECTED]) 3 } Yeah, how about no. :-) That's the thing, see. By saying no, we're saying control structures like 'if' will be able to return a value, but control structures not like 'if' won't, and that means we need to remove at least three words from 'When syntax or semantics change, it will always be a change for the better: for greater consistency, for more intuitability, for extra Do-What-I-Meanness.'... ;) -- Resist the urge to start typing; thinking is a worthwhile alternative. -- Kernighan and Pike
Re: Control flow variables
On Tue, 18 Nov 2003, Simon Cozens wrote: Luke Palmer: That's illegal anyway. Can't chain statement modifiers :-) Bah, should be able to! Will be able to. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Control flow variables
[EMAIL PROTECTED] (Dan Sugalski) writes: Luke Palmer: That's illegal anyway. Can't chain statement modifiers :-) Will be able to. I thought as much; Perl 6 will only be finally finished when the biotech is sufficiently advanced to massively clone Larry... -- quidity Sometimes it's better not to pedant.
RE: Control flow variables
-Original Message- From: Luke Palmer [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 9:21 AM To: Language List Subject: Control flow variables I was reading the most recent article on perl.com, and a code segment reminded me of something I see rather often in code that I don't like. Here's the code, Perl6ized: ... ; my $is_ok = 1; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { $is_ok = 0; last; } } if $is_ok { push @moves: [$i, $j]; } ... This is what I was talking about when I mentioned being able to do: cleanup .= { push @moves: [$i, $j]; } a few weeks ago. Treat code vars like code, not like sub-refs. =Austin
Re: Control flow variables
Austin Hastings writes: Luke Palmer wrote: I was reading the most recent article on perl.com, and a code segment reminded me of something I see rather often in code that I don't like. Here's the code, Perl6ized: ... ; my $is_ok = 1; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { $is_ok = 0; last; } } if $is_ok { push @moves: [$i, $j]; } ... This is what I was talking about when I mentioned being able to do: cleanup .= { push @moves: [$i, $j]; } a few weeks ago. Treat code vars like code, not like sub-refs. I'm not sure I know what you mean with regard to this example. Exemplify further, please? Luke =Austin
Re: Control flow variables
On Tue, 18 Nov 2003, Simon Cozens wrote: [EMAIL PROTECTED] (Dan Sugalski) writes: Luke Palmer: That's illegal anyway. Can't chain statement modifiers :-) Will be able to. I thought as much; Perl 6 will only be finally finished when the biotech is sufficiently advanced to massively clone Larry... Not because of this. It's easier to allow it than not allow it. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Control flow variables
[EMAIL PROTECTED] (Austin Hastings) writes: This is what I was talking about when I mentioned being able to do: cleanup .= { push @moves: [$i, $j]; } This reminds me of something I thought the other day might be useful: $cleanup = bless {}, class { method DESTROY { ... } }; Of course, it probably wouldn't work in this context because you couldn't guarantee that the destructor will be called at the point of loop exit, but I like the anonymous class syntax anyway. -- I've looked at the listing, and it's right! -- Joel Halpern
Re: Control flow variables
On Tue, 18 Nov 2003, Simon Cozens wrote: [EMAIL PROTECTED] (Austin Hastings) writes: This is what I was talking about when I mentioned being able to do: cleanup .= { push @moves: [$i, $j]; } This reminds me of something I thought the other day might be useful: $cleanup = bless {}, class { method DESTROY { ... } }; Of course, it probably wouldn't work in this context because you couldn't guarantee that the destructor will be called at the point of loop exit, but I like the anonymous class syntax anyway. $cleanup = bless {}, class : impatient { method DESTROY { ... } }; That'll probably do it, at the expense of extra runtime block exit overhead until the object dies. If you just want a block exit action, then: add_block_exit_action(\foo); or something similar will do it. (Though we could add new syntax for it if you really want... :-) Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Control flow variables
-Original Message- From: Luke Palmer [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 10:49 AM To: Austin Hastings Cc: Language List Subject: Re: Control flow variables Austin Hastings writes: Luke Palmer wrote: I was reading the most recent article on perl.com, and a code segment reminded me of something I see rather often in code that I don't like. Here's the code, Perl6ized: ... ; my $is_ok = 1; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { $is_ok = 0; last; } } if $is_ok { push @moves: [$i, $j]; } ... This is what I was talking about when I mentioned being able to do: cleanup .= { push @moves: [$i, $j]; } a few weeks ago. Treat code vars like code, not like sub-refs. I'm not sure I know what you mean with regard to this example. Exemplify further, please? Quoting Luke Palmer from weeks back: From: Luke Palmer [mailto:[EMAIL PROTECTED] Jeff Clites writes: Austin Hastings writes: Speaking to the practical side, I have written code that has to disentangle itself from the failure of a complex startup sequence. I'd love to be able to build a dynamic exit sequence. (In fact, being able to do Cblock .= { more_stuff(); };/C is way up on my list...) I've wanted to do that sort of thing before, but it seems simpler (conceptually and practically) to build up an array of cleanup subs/blocks to execute in sequence, rather than to have a .= for blocks. (Another reason it's handy to keep them separate is in cases in which each needs to return some information--maybe a status which determines whether to proceed, etc.) But this is already supported, in its most powerful form: wrap block: { call; other_stuff() } Luke Which begs the question of whether there's a way to get a handle to the current Cfor/C loop from within? LOOP: for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { wrap Block(): { call; handle_error(); }; last; } } # handle_error() called here? (Yes, this would presume that the Ccall/C came first, since how could it interpolate the call otherwise. It's a limitation of the wrap-as-append philosophy.) =Austin
s/// in string context should return the string
s/// in string context should return the string after substituion. It seems obvious to me but I mention it because I can't find it in the apocalypses. -- stef
Re: Control flow variables
OOPS, totally miss-read your code, ignore my first part of my last message. -- [EMAIL PROTECTED] [EMAIL PROTECTED]
Re: Control flow variables
Luke Palmer wrote: I was reading the most recent article on perl.com, and a code segment reminded me of something I see rather often in code that I don't like. Here's the code, Perl6ized: ... ; my $is_ok = 1; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { $is_ok = 0; last; } } if $is_ok { push @moves: [$i, $j]; } ... What's wrong with: for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { push @moves: [$i, $j]; last; } } I see this idiom a lot in code. You loop through some values on a condition, and do something only if the condition was never true. $is_ok is a control flow variable, something I like to minimize. Now, there are other ways to do this: if (0..6 == grep - $t { abs(@new[$t] - @new[$t+1]) }) { ... } But one would say that's not the cleanest thing in the world. and very unreadable, (even if that's heresy :-) ) Python pulled this idiom out in to the syntax (yay them), with Celse on loops. The else block on a python loop executes only if you never broke out of the loop. That's a great idea. So, in Perl's postmodern tradition, I think we should steal that idea. I'm a little uneasy about calling it Celse, though. Maybe CFINISH would do, making the example: for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { last; } FINISH { push @moves: [$i, $j]; } } Violates least surprise, if the 'if' is true for '$t == 6' due to the ambiguity between 'last' on '$t==6' and falling out the bottom of the loop. Maybe you want FINISH_EARLY instead? -- [EMAIL PROTECTED] [EMAIL PROTECTED]
Re: Control flow variables
On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote: Given that we've introduced the concept of if having a return status: my $result = if ($a) { $a } else { $b }; Would that then imply that sub blah { ... # 1 return if $a;# 2 ... # 3 } ...would return $a if $a was true, and fall through to (3) if it was false? [EMAIL PROTECTED] (Dan Sugalski) writes: Luke Palmer: That's illegal anyway. Can't chain statement modifiers :-) Will be able to. I was under the strong impression that Larry had decided that syntactic ambiguities prevented this from happening. (Now, of course, you will ask me for a cite to the thread, which I can't even begin to find at this point...) MikeL
RE: s/// in string context should return the string
As a Bvalue where possible, so they can cascade and nest. =Austin -Original Message- From: Stephane Payrard [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 12:19 PM To: [EMAIL PROTECTED] Subject: s/// in string context should return the string s/// in string context should return the string after substituion. It seems obvious to me but I mention it because I can't find it in the apocalypses. -- stef
RE: Control flow variables
-Original Message- From: Michael Lazzaro [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 2:06 PM To: [EMAIL PROTECTED] Subject: Re: Control flow variables On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote: Given that we've introduced the concept of if having a return status: my $result = if ($a) { $a } else { $b }; Would that then imply that sub blah { ... # 1 return if $a;# 2 ... # 3 } ...would return $a if $a was true, and fall through to (3) if it was false? It sure should, provided there were a correct context waiting, which would quite nicely address another WIBNI thread a couple of months back about a quick return under those conditions. Very nice. =Austin
Re: Control flow variables
Austin Hastings writes: -Original Message- From: Michael Lazzaro [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 2:06 PM To: [EMAIL PROTECTED] Subject: Re: Control flow variables On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote: Given that we've introduced the concept of if having a return status: my $result = if ($a) { $a } else { $b }; Would that then imply that sub blah { ... # 1 return if $a;# 2 ... # 3 } ...would return $a if $a was true, and fall through to (3) if it was false? It sure should, provided there were a correct context waiting, which would quite nicely address another WIBNI thread a couple of months back about a quick return under those conditions. I don't think so. I say that all the time to mean precisely: if $a { return } And I don't think people are ready to give that up. In particular, if we kept our bottom-up parser around, this particular construct would cause an infinite-lookahead problem. So for ambiguity's sake, Cif $a should not be a valid term without a block following. Luke
Re: Control flow variables
Austin Hastings writes: -Original Message- From: Michael Lazzaro [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 2:06 PM To: [EMAIL PROTECTED] Subject: Re: Control flow variables On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote: Given that we've introduced the concept of if having a return status: my $result = if ($a) { $a } else { $b }; Would that then imply that sub blah { ... # 1 return if $a;# 2 ... # 3 } ...would return $a if $a was true, and fall through to (3) if it was false? It sure should, provided there were a correct context waiting, which would quite nicely address another WIBNI thread a couple of months back about a quick return under those conditions. Oh, and if you really want to do that return thing without using a Cgiven, you can just: sub blah { return $a || goto CONT; CONT: ... } I don't see what's wrong with that. :-p Luke
Re: Control flow variables
Would that then imply that sub blah { ... # 1 return if $a;# 2 ... # 3 } ...would return $a if $a was true, and fall through to (3) if it was false? It sure should, provided there were a correct context waiting, which would quite nicely address another WIBNI thread a couple of months back about a quick return under those conditions. I don't think so. I say that all the time to mean precisely: if $a { return } And I don't think people are ready to give that up. In particular, if we kept our bottom-up parser around, this particular construct would cause an infinite-lookahead problem. So for ambiguity's sake, Cif $a should not be a valid term without a block following. So, just to make sure, these two lines are both valid, but do completely different things: return if $a; return if $a { $a } MikeL
Re: Control flow variables
Luke Palmer started a discussion: I see this idiom a lot in code. You loop through some values on a condition, and do something only if the condition was never true. $is_ok is a control flow variable, something I like to minimize. Now, there are other ways to do this: if (0..6 == grep - $t { abs(@new[$t] - @new[$t+1]) }) { ... } But one would say that's not the cleanest thing in the world. Only because you overdid the sugar. : if grep {abs(@new[$^t] - @new[$^t+1]) 3} 0..6 { ... } is pretty clean. But, in any case, handling exceptional cases are what exceptions are for: try { for 0..6 - $t { die if abs(@new[$t] - @new[$t+1]) 3; } CATCH { push @moves: [$i, $j]; } } As regards return values of control structures, I had always assumed that: * scalar control structures like Cif, Cunless, and Cgiven return the value of the last statement in their block that they evaluated; * vector control structures like Cloop, Cwhile, and Cfor in a list context return a list of the values of the last statement each iteration evaluated; * vector control structures like Cloop, Cwhile, and Cfor in a scalar context return an integer indicating the number of times their block was iterated. So we might also write: for 0..6 - $t { last if abs(@new[$t] - @new[$t+1]) 3; } 7 and push @moves: [$i, $j]; Damian
Re: Control flow variables
Michael Lazzaro wrote: So, just to make sure, these two lines are both valid, but do completely different things: return if $a; Means: if ($a) { return } return if $a { $a } Means: if ($a) { return $a } else { return undef } Damian
RE: Control flow variables
-Original Message- From: Damian Conway [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 4:02 PM To: Language List Subject: Re: Control flow variables Luke Palmer started a discussion: I see this idiom a lot in code. You loop through some values on a condition, and do something only if the condition was never true. $is_ok is a control flow variable, something I like to minimize. Now, there are other ways to do this: if (0..6 == grep - $t { abs(@new[$t] - @new[$t+1]) }) { ... } But one would say that's not the cleanest thing in the world. Only because you overdid the sugar. : if grep {abs(@new[$^t] - @new[$^t+1]) 3} 0..6 { ... } is pretty clean. But, in any case, handling exceptional cases are what exceptions are for: try { for 0..6 - $t { die if abs(@new[$t] - @new[$t+1]) 3; } CATCH { push @moves: [$i, $j]; } } As regards return values of control structures, I had always assumed that: * scalar control structures like Cif, Cunless, and Cgiven return the value of the last statement in their block that they evaluated; * vector control structures like Cloop, Cwhile, and Cfor in a list context return a list of the values of the last statement each iteration evaluated; * vector control structures like Cloop, Cwhile, and Cfor in a scalar context return an integer indicating the number of times their block was iterated. This seems excessive, but easily discarded during optimization. On the other hand, I don't trust the last statement evaluated behavior for loops, since the optimizer could very well do surprising things to loop statements. (Likewise, however, for scalar control structures.) What does this say about order of evaluation? if @arry.length != while @arry { transmit(@arry.pop) or last; } { print Couldn't send them all.; } I'm pretty sure that has to have unspecified behavior, but ... comment? So we might also write: for 0..6 - $t { last if abs(@new[$t] - @new[$t+1]) 3; } 7 and push @moves: [$i, $j]; Damian Oh goody. Another (ab)use for named blocks: my named_block = for 0..6 - $t { last if abs (@new[$t] - @new[$t+1]) 3; } push @moves: [$i, $j] if named_block() 7; This seems hideously powerful, but at the same time dangerous. Kind of like select. =Austin
RE: Control flow variables
-Original Message- From: Luke Palmer [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 3:11 PM To: Austin Hastings Cc: Michael Lazzaro; [EMAIL PROTECTED] Subject: Re: Control flow variables Austin Hastings writes: -Original Message- From: Michael Lazzaro [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 2:06 PM To: [EMAIL PROTECTED] Subject: Re: Control flow variables On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote: Given that we've introduced the concept of if having a return status: my $result = if ($a) { $a } else { $b }; Would that then imply that sub blah { ... # 1 return if $a;# 2 ... # 3 } ...would return $a if $a was true, and fall through to (3) if it was false? It sure should, provided there were a correct context waiting, which would quite nicely address another WIBNI thread a couple of months back about a quick return under those conditions. I don't think so. I say that all the time to mean precisely: if $a { return } And I don't think people are ready to give that up. In particular, if we kept our bottom-up parser around, this particular construct would cause an infinite-lookahead problem. So for ambiguity's sake, Cif $a should not be a valid term without a block following. How on earth are you going to have an infinite lookahead problem when a semicolon is the next character? =Austin
RE: Control flow variables
On Tue, 18 Nov 2003, Austin Hastings wrote: This seems excessive, but easily discarded during optimization. On the other hand, I don't trust the last statement evaluated behavior for loops, since the optimizer could very well do surprising things to loop statements. (Likewise, however, for scalar control structures.) This shouldn't be a problem. If there's potential ambiguity then the optimization can't be applied. Modulo optimizer bugs you'll be fine. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Control flow variables
Austin Hastings writes: From: Luke Palmer [mailto:[EMAIL PROTECTED] Austin Hastings writes: From: Michael Lazzaro [mailto:[EMAIL PROTECTED] Would that then imply that sub blah { ... # 1 return if $a;# 2 ... # 3 } ...would return $a if $a was true, and fall through to (3) if it was false? In particular, if we kept our bottom-up parser around, this particular construct would cause an infinite-lookahead problem. So for ambiguity's sake, Cif $a should not be a valid term without a block following. How on earth are you going to have an infinite lookahead problem when a semicolon is the next character? Sorry, s/\$a/some-hideously-long-condition/ Luke =Austin
Re: Control flow variables
Luke Palmer wrote: My Cif/Cunless typo may have misled you, but the original example pushed only if *none* of them passed the condition. Ah, sorry, I misunderstood. So you want: push @moves, [$i, $j]; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { pop @moves; last; } } ;-) Damian
RE: Control flow variables
-Original Message- From: Dan Sugalski [mailto:[EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 4:34 PM To: Language List Subject: RE: Control flow variables On Tue, 18 Nov 2003, Austin Hastings wrote: This seems excessive, but easily discarded during optimization. On the other hand, I don't trust the last statement evaluated behavior for loops, since the optimizer could very well do surprising things to loop statements. (Likewise, however, for scalar control structures.) This shouldn't be a problem. If there's potential ambiguity then the optimization can't be applied. Modulo optimizer bugs you'll be fine. That's the problem I have with it. I'm inclined to believe that the optimization is more important than the postcondition, most of the time. On the gripping hand, I *really* like Damian's Simple Rules for Control Flow Return Values. So much so that I can easily see a bunch of idioms coming up around them. First: return if (some hideously long and possibly expensive guard); That one just rocks. It's like: $_ = expensive(); return if; Singing Frank Zappa Valley Perl .. It's .. Valley Perl like .. return if when...ever duh! / Second: I'm way not sure about how the vector context result of iteration structures will work. Specifically, what happens when a loop forks a thread, or passes to a parallelized coroutine? There may not actually BE a result. (Of course, in a right-thinking system this will be noted, and replaced by a placeholder object that will wait for the result if evaluated.) Third: The scalar count of iterations will make it seem that Cfor is a macrification of Cmap, which isn't necessarily bad. In fact, I can see this: $count = for [EMAIL PROTECTED] - $a { check($a) or last; } if ($count != @a) { fail; } Leading to: if (scalar(@a) != for [EMAIL PROTECTED] - $a { check($a) or last; }) { fail; } Which leads to Cmap/Cgrep pretty directly: if grep {!check($^a) } @a { fail; } So it should actually help with the newbie learning curve, providing an easy transition from loops to map/grep. Which really is a good thing. =Austin
Re: Control flow variables
Damian Conway wrote: push @moves, [$i, $j]; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { pop @moves; last; } } Indeed, an elegant way around the problem. So... lets call a function instead: my $is_ok = 1; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { $is_ok = 0; last; } } if $is_ok { yada() # has sideeffects... } (wrote many such constructs for cgi sanity checks and always found it mildly annoying) regards thomas -- Imagination is more important than knowledge [Einstein] begin 666 wink.gif M1TE.#EA#P`/`+,``+^_O___ M`'Y! $```$`+ `/``\```0T,$@):ITX5,'Y MQ4 GE,[EMAIL PROTECTED]PI;C9:YZYGOQK?C12R8C%7P;[EMAIL PROTECTED] ` end
Re: Control flow variables
Seiler Thomas wrote: So... lets call a function instead: my $is_ok = 1; for 0..6 - $t { if abs(@new[$t] - @new[$t+1]) 3 { $is_ok = 0; last; } } if $is_ok { yada() # has sideeffects... } That's just: for 0..6, 'ok' - $t { when 'ok' { yada() } last if abs(@new[$t] - @new[$t+1]) 3; } ;-) Damian
Re: syntax: multi vs. method
Luke Palmer wrote: Jonathan Lang writes: Luke Palmer wrote: Well, multi is no longer a declarator in its own right, but rather a modifier. Synopsis Exegesis 6 show this. I don't know about Exegesis 6, Then you should probably read it. It is the most recent of the documents, so what it says is closest to the current thinking. Plus, it's a fun read. OK; I just finished it. Apparently, there's a distinction between multimethod and multi sub, and it's a distinction which renders one of my points invalid. A multimethod has multiple invocants and handles dispatching based on the types of said invocants. A multi sub has no invocants; instead, it has a subset of its parameters (seperated from the others by a colon) which it uses for dispatching purposes. As such, multi sub ($a: $b) {...} already has meaning, in that dispatching will be decided strictly off of $a's type. So the following three declarations cover very similar (but not quite identical) things: multi sub call ($a: $b) {...} submethod invoke ($a: $b) {...} method check ($a: $b) {...} All three of these use multiple dispatching. The only distinctions are that invoke and check can be called using method-like syntax, whereas call cannot; and check pays attention to inheritence, whereas call and invoke do not. In the case of multiple dispatch variables, the situation gets a bit messier as I understand you: multi sub call ($a, $b: $c) {...} multi submethod invoke ($a, $b: $c) {...} multi method check ($a, $b: $c) {...} Why do we suddenly need to append the multi keyword to submethod and method? Because it has a different meaning for method or submethod: with sub, the multi keyword means use multiple dispatching, and so we use it any time that we have one or more dispatch parameters; with submethod and method, multiple dispatching is assumed and the keyword means use more than one invocant. IMHO, we should choose one of these definitions for multi and stick with it. If you go with use multiple dispatching, multi becomes redundant for method and submethod; if you go with allow more than one dispatch parameter, then you ought to be able to declare a multiply dispatching sub with a single dispatch parameter without using the multi keyword. Personally, I think that the first definition is the less confusing one. If you choose it, you'll never have need to use the multi keyword in conjunction with method or submethod, restricting its use in practice to cases where multiple dispatching doesn't normally occur (subs and macros, mostly). In those cases, one _could_ implicitly determine whether the sub or function is multiply dispatched by looking for the colon in the signature; but I tend to agree in these cases that requiring the multi keyword might be a good idea. = Jonathan Dataweaver Lang __ Do you Yahoo!? Protect your identity with Yahoo! Mail AddressGuard http://antispam.yahoo.com/whatsnewfree
Re: Control flow variables
Joseph Ryan wrote: Not to be a jerk, but how about: my $is_ok = 1; for @array_of_random_values_and_types - $t { if not some_sort_of_test($t) { $is_ok = 0; last; } } if $is_ok { yada() # has sideeffects... } That's just: given @array_of_random_values_and_types - @data { for @data.kv, [EMAIL PROTECTED] - $i, $t { when [EMAIL PROTECTED] { yada() } last if not some_sort_of_test($t); } } ;-) Damian
Re: Control flow variables
On Tuesday, November 18, 2003, at 06:11 PM, Joseph Ryan wrote: Not to be a jerk, but how about: my $is_ok = 1; for @array_of_random_values_and_types - $t { if not some_sort_of_test($t) { $is_ok = 0; last; } } if $is_ok { yada() # has sideeffects... } Isn't that just: for @array_of_random_values_and_types, 'ok' - $t { when 'ok' { yada(); last } last unless some_sort_of_test($t); } IOW, the topic is only 'ok' when all of the items in the array have been processed, which in your code is what happens when some_sort_of_test($t) returns a true value. Regards, David -- David Wheeler AIM: dwTheory [EMAIL PROTECTED] ICQ: 15726394 http://www.kineticode.com/ Yahoo!: dew7e Jabber: [EMAIL PROTECTED] Kineticode. Setting knowledge in motion.[sm]
Re: Control flow variables
David Wheeler wrote: On Tuesday, November 18, 2003, at 06:11 PM, Joseph Ryan wrote: Not to be a jerk, but how about: my $is_ok = 1; for @array_of_random_values_and_types - $t { if not some_sort_of_test($t) { $is_ok = 0; last; } } if $is_ok { yada() # has sideeffects... } Isn't that just: for @array_of_random_values_and_types, 'ok' - $t { when 'ok' { yada(); last } last unless some_sort_of_test($t); } IOW, the topic is only 'ok' when all of the items in the array have been processed, which in your code is what happens when some_sort_of_test($t) returns a true value. And also if @array_of_random_values contains 'ok'. - Joe
Re: Control flow variables
David Wheeler wrote: Isn't that just: for @array_of_random_values_and_types, 'ok' - $t { when 'ok' { yada(); last } last unless some_sort_of_test($t); } IOW, the topic is only 'ok' when all of the items in the array have been processed Unless, of course, the string 'ok' is also one of the random_values_and_types. Hence my alternative solution. Damian
Re: Control flow variables
On Tuesday, November 18, 2003, at 06:44 PM, Joseph Ryan wrote: And also if @array_of_random_values contains 'ok'. D'oh! See Damian's solution, then. ;-) David -- David Wheeler AIM: dwTheory [EMAIL PROTECTED] ICQ: 15726394 http://www.kineticode.com/ Yahoo!: dew7e Jabber: [EMAIL PROTECTED] Kineticode. Setting knowledge in motion.[sm]
Re: syntax: multi vs. method
I think most everyone is missing the new simplicity of the current conception of multi. It's now completely orthogonal to scoping issues. It merely says, I'm putting multiple names into a spot that would ordinarily demand a unique name. In other words, what a name means in a given scope is a kind of invariant--there's no magic hocus pocus in which multimethod dispatch suddenly steals calls from ordinary method dispatch. This is actually more powerful than the usual multimethods. To get the usual behavior of multimethods in other languages, you have to explicitly declare the multimethods in global space: multi sub *add( Foo $foo, Bar $bar ); If you write: multi sub add( Foo $foo, Bar $bar ); then the current package has multiple add routines, but they aren't global. If you write: multi my sub add( Foo $foo, Bar $bar ); then the current *lexical* scope has multiple add routines! If you write: multi method add( $self: Foo $foo, Bar $bar ); then there are multiple add methods in the current class. Note the invocant is not optional in this case. Also, there's an implied second colon after $bar, indicating the end of the arguments to be considered for multi dispatch. (You can put as many colons as you want in any multi declaration--each subsequent colon indicates that the preceding additional argument or arguments are to be used as tie breakers, just as Foo and Bar are being used for tie-breaking in the method above.) Likewise for submethods: multi submethod add( $self: Foo $foo, Bar $bar ); In essence, the compiler could implement multi by taking any such set of identically named routines and implementing them as a single routine with switching logic to tell the types apart. One ramification of all this is that true multimethods must always be called as subroutines, not as methods. I hope this clarifies things a bit. Well, more than a bit... Larry
Re: [perl] RE: s/// in string context should return the string
- Original Message - From: Austin Hastings [EMAIL PROTECTED] To: [EMAIL PROTECTED]; [EMAIL PROTECTED] Sent: Tuesday, November 18, 2003 3:04 PM Subject: [perl] RE: s/// in string context should return the string As a Bvalue where possible, so they can cascade and nest. Excuse me. I know enough C++ to know the difference between an lvalue and an rvalue, but what the heck is a BValue? Joe Gottman
Re: [perl] Re: syntax: multi vs. method
- Original Message - From: Jonathan Lang [EMAIL PROTECTED] So the following three declarations cover very similar (but not quite identical) things: multi sub call ($a: $b) {...} submethod invoke ($a: $b) {...} method check ($a: $b) {...} All three of these use multiple dispatching. The only distinctions are that invoke and check can be called using method-like syntax, whereas call cannot; and check pays attention to inheritence, whereas call and invoke do not. Also, I assume that invoke and check will have access to $a's private data members and methods, while call will not. Joe Gottman
Re: syntax: multi vs. method
Larry Wall writes: If you write: multi method add( $self: Foo $foo, Bar $bar ); then there are multiple add methods in the current class. Note the invocant is not optional in this case. Also, there's an implied second colon after $bar, indicating the end of the arguments to be considered for multi dispatch. (You can put as many colons as you want in any multi declaration--each subsequent colon indicates that the preceding additional argument or arguments are to be used as tie breakers, just as Foo and Bar are being used for tie-breaking in the method above.) So what is the, ahem, submethod for determining the dispatch within the tie-breaking cascades? A simple sum of differences? Cartesian distance? Luke Larry