Re: RFC 22 (v1) Builtin switch statement
On Sat, Aug 05, 2000 at 04:10:20AM +1000, Damian Conway wrote: If a switch is considered like a loop then next would be the same as 'break' in C, as would last and redo would repeat the switch. But a switch is not a loop. True, but in perl any block is considered to be a loop that executes only once. Long and bitter experience indicates that fallthrough is a poor default (but a good *option*). I guess it's what your used to. Graham.
Re: RFC 22 (v1) Builtin switch statement
On 4 Aug 2000 14:59:06 -, Perl6 RFC Librarian wrote: %special = ( woohoo = 1, d'oh = 1 ); while () { switch ($_) { case (%special) { print "homer\n"; last } # if $special{$_} Hold it. Is that if($special{$_}) { ... or if(defined $special{$_}) { ... or if (exists special{$_}) { ... From a purist point of view, [3] makes the most sense. [1] may be more practical, in a lot of cases. [2] is somewhere in between the two, where a user could provide exceptional cases, for which this is supposed to fail. Er... something like that. -- Bart.
Re: RFC 22 (v1) Builtin switch statement
I haven't gotten my head around anything curried, except Indian food but it appears to be powerful, and a kind of like generic programming on the fly. I'd like to learn more: if someone would give a tutorial reference that would be helpful. A quick description is here: http://www.cs.nott.ac.uk/~gmh//faq.html#currying Since it's named after Haskell Curry, you might like to learn about Haskell: http://www.haskell.org/bookshelf/ Currying really is DWIM, and I find it very perlish. But it requires some unlearning of what's not possible in common procedural languages. This does all bring up an important issue. If we go with '__' or something similar (and I sure hope we do) we're likely to want to hang a whole lot of other stuff off of it (in this case it enables/simplifies important functionality of switch/case). But although __ is perlish, it's very new to perl old-hands. So is this OK? Should we expect perl 5 gurus to have to learn new stuff to get the most out of perl 6? Hmmm... When I say it that way it seems obvious that the answer is 'yes'...
Re: RFC 22 (v1) Builtin switch statement
Oh, the table thing. The switch statement is useful without learning the complete table so I don't think complexity is a big problem. People can learn what they need and ignore the rest. I agree with you that it might be nice to have an array membership operator (like "in") so that you can write: if ($x in [ 1, 2, 3 ]) ... if ( grep $x==$_, (1,2,3) ) ... Be nice if it would short-circuit in a boolean context though! Damian
Re: RFC 22 (v1) Builtin switch statement
On Sun, Aug 06, 2000 at 04:40:29AM +1000, Damian Conway wrote: Oh, the table thing. The switch statement is useful without learning the complete table so I don't think complexity is a big problem. People can learn what they need and ignore the rest. I agree with you that it might be nice to have an array membership operator (like "in") so that you can write: if ($x in [ 1, 2, 3 ]) ... if ( grep $x==$_, (1,2,3) ) ... Be nice if it would short-circuit in a boolean context though! I think we need a general way of short-circuiting out of a grep (and other list iterating funcs, if it makes sense...) We may need both success and failure short-circuits? It's a pity 'last' already has semantics there, not to mention return... Damian -- $jhi++; # http://www.iki.fi/jhi/ # There is this special biologist word we use for 'stable'. # It is 'dead'. -- Jack Cohen
Re: RFC 22 (v1) Builtin switch statement
How about adding a new keyword, hmm, 'yield'. :-) if ( grep yield $x==$_, (1,2,3) ) ... chaim "DC" == Damian Conway [EMAIL PROTECTED] writes: Oh, the table thing. The switch statement is useful without learning the complete table so I don't think complexity is a big problem. People can learn what they need and ignore the rest. I agree with you that it might be nice to have an array membership operator (like "in") so that you can write: if ($x in [ 1, 2, 3 ]) ... DCif ( grep $x==$_, (1,2,3) ) ... DC Be nice if it would short-circuit in a boolean context though! DC Damian -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 22 (v1) Builtin switch statement
I'm not sure it makes sense, I'd really like to get rid of the last propogating out of a sub. (or a grep/map). But if that doesn't fly, we do have Damian's new yield keyword available to do it. chaim "JH" == Jarkko Hietaniemi [EMAIL PROTECTED] writes: JH I think we need a general way of short-circuiting out of a grep JH (and other list iterating funcs, if it makes sense...) We may JH need both success and failure short-circuits? It's a pity 'last' JH already has semantics there, not to mention return... -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 22 (v1) Builtin switch statement
On Fri, Aug 04, 2000 at 02:59:06PM -, Perl6 RFC Librarian wrote: Howeverm it Iis possible to cause a Ccase statement to "fall-through". If a Cnext is executed within a Ccase block, control is immediately transferred to the statement following the Ccase block. For example: switch ($count) { case 0 { print "nothing\n"; next } print "fell through!\n"; case /^\d$/ { print "single\n"; next } print "fell through again!\n"; case sub{$_[0]%2} { print "odd\n" } else{ print "even\n" } } This seems backwards to me. Everywhere else in perl next would cause the next iteration of a block/loop. If a switch is considered like a loop then next would be the same as 'break' in C, as would last and redo would repeat the switch. this would mean that fallthrough would be the default and the user would need a last; to break out; Of course if a case was a block containing loops etc. the switch statement would need a label so you would type Clast SWITCH Graham.
RE: RFC 22 (v1) Builtin switch statement
Could a way be found to control the flow so that the next case (not always the one next in the order of the statment) could be executed? For example you have cases 1-10. You want all odd cases to also execute case 9 and the even cases to also execute case 10. So in case 3 you would say something like: pergo(9); Not necessary. switch ($val) { case 3 { print "three"; goto odds } case 4 { print "three"; goto evens } odds: case __%2!=0{ print "that's odd" } evens: case __%2==0{ print "that's even" } } Or for those who hate pasta: sub odds { print "that's odd" } sub evens { print "that's even" } switch ($val) { case 3 { print "three"; odds } case 4 { print "three"; evens } case __%2!=0{ odds } case __%2==0{ evens } } Damian
Re: RFC 22 (v1) Builtin switch statement
On Sat, Aug 05, 2000 at 05:09:28AM +1000, Damian Conway wrote: Not necessary. switch ($val) { case 3 { print "three"; goto odds } case 4 { print "three"; goto evens } And "goto" could be spelt "next" too? That would make sense to me, but the semantics of "last odds" or "redo odds" escape me. Perhaps "last odds" would me "evaluate the block labeled by odds, then exit the switch" and "redo odds" would me "re-evaluate this case, then jump to the block labelled odds". -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
RE: RFC 22 (v1) Builtin switch statement
Not a bad solution, at least for the example I put forth. I like the ability to have the specific as well as the general in the case statement ('2' and '__%2 != 0'). Thanks. Could a way be found to control the flow so that the next case (not always the one next in the order of the statment) could be executed? For example you have cases 1-10. You want all odd cases to also execute case 9 and the even cases to also execute case 10. So in case 3 you would say something like: pergo(9); Not necessary. switch ($val) { case 3 { print "three"; goto odds } case 4 { print "three"; goto evens } odds: case __%2!=0{ print "that's odd" } evens: case __%2==0{ print "that's even" } } Or for those who hate pasta: sub odds { print "that's odd" } sub evens { print "that's even" } switch ($val) { case 3 { print "three"; odds } case 4 { print "three"; evens } case __%2!=0{ odds } case __%2==0{ evens } } Damian
Re: RFC 22 (v1) Builtin switch statement
Does "goto odds" mean start evaluating all cases after the "odds:" label? Meaning that the below is equivalent to the above? I think this is what the original poster was asking; if not, I'd like to ask it! That's exactly what it means. switch ($val) { case 3 { print "three"; goto morecases } case 4 { print "three"; goto morecases } morecases: case __%2!=0{ print "that's odd" } case __%2==0{ print "that's even" } } Damian
Re: RFC 22 (v1) Builtin switch statement
Damian Conway wrote: This switch statement RFC seems to be built on the premise that the reason to have a switch statement is to remove a common parameter from the following limited form conditional expressions. Yes. As I point out in the paper, that's the *nature* of a switch statement. To distribute a test spatially, by factoring. One could quibble quite extensively about whether that's the nature of the switch statement, or whether that is a characteristic found in a broad class of switch statement implementations. To me the nature of the switch statement is the selection operation, not the factoring. However, while the table of 16 different ways in which two values could generate a match is interesting, it can only ever perform at most two operations per pair of types (depending on which type is found in which of the two positions). Not so: Yes so... switch ($value) { case 1 {...} # numeric equality case "a"{...} # string equality case $obj {...} # referential equality case /pat/ {...} # pattern match case %hash {...} # hash lookup case [1..10]{...} # list inclusion case __100 {...} # subroutine return } None of these perform more than one operation per pair of types. By doing the factoring, you are constraining the type and specific value of the left hand expression in your matching operation, limiting the set of operations that can be performed quite severely. I find it unlikely that the casual Perl programmer, and even many expert Perl programmers, will be able to usefully memorize the list of operations proposed for the type pairs. This inability to memorize the list will no doubt curl the corner of the switch page in the perl documentation. No. The whole point is that they just DWIM. Well, they might DWDM, but most of them wouldn't DWIM. (DWDM=do what Damian means). That said, there are some useful operations in your list that are complex to express otherwise; something should be done to make them more easily expressable if they are common. I think the fundamental purpose of the switch statement is to choose one (generally) of many cases, and that the factoring of one of the parameters is what gets in the way of having a rich set of matching operations. Just selecting one from many alternatives is a cascaded if's job. That's one way to do it, at least in Perl we don't get "endif" bloat. The defining characteristic of a switch the the factoring of some part of the comparisons. And it's an important characteristic, because it focussed the reader's mind on the commonality of the test. In this proposal, it would be the commonality of the parameter, not the commonality of the test. The test includes parameters and matching operation. The type of the second parameter must be determined before the matching operation can be determined. Hence, I think it suffices to have a single keyword for switch: not "switch", but "case". The block containing "case" would be the switch statement. "case" is simply a rename of "elsif" whose first occurrence in a block simply pretends to follow "if (0) {}". If that's the consensus, let's just have elsif. But I don't think that's the consensus. elsif makes some of the other features of your proposal harder to do: next would have to be done with goto/label, for example. And inter-case statements wind up requiring cascading blocks, because of the need to separate the else from the if. So there is room to beautify a common operation of the language with a switch statement, without the factoring. I appreciate your comments, but I certainly intend to push ahead with the proposed syntax -- as I proposed it. A very large number of people like it as it is. If I'm wrong, let Larry kill it. Well, it could be that a very large number of people like it as it is. Or it could be that a very large number of people think it is clever, and like the new, simpler, implicit operators that you've added in your big table of operators, and haven't thought about how confusing it will be to determine what is actually happening in a multi-type switch. The new operations could be achieved in more flexible ways, rather than only implicitly via the switch statement. For instance, if ( $v == @foo ) is clearly testing the size of foo against the value of $v. But switch ( $v ) { case 1: { ... } case 2: { ... } case @foo { ... } } does not! You can argue all day that it is more powerful, and you can even mention that "case scalar(@foo)" would achieve that goal, but it isn't DWIM. Damian -- Glenn = There are two kinds of people, those who finish what they start, and so on...
Re: RFC 22 (v1) Builtin switch statement
None of these perform more than one operation per pair of types. By doing the factoring, you are constraining the type and specific value of the left hand expression in your matching operation, limiting the set of operations that can be performed quite severely. [snip] In this proposal, it would be the commonality of the parameter, not the commonality of the test. The test includes parameters and matching operation. The type of the second parameter must be determined before the matching operation can be determined. No. Because the switch value can be a curried function too, so you can factor the operation as well: switch ( $x __ ) { case 0 { print "negative" } case 1 { print "unity" } case any(2..9) { print "small" } case @list { print "in range" } } if ( $v == @foo ) is clearly testing the size of foo against the value of $v. That's not "clear" at all. It's a learned idiom that *isn't* obvious without understanding. One might just as readily assume that comparison against an array disjunctively distributes the comparison across the elements. Of course, that way lies superpositions! Sigh. We clearly differ irreconcilably on this issue. I suggest that you counter-propose your version of case and we move on. Larry may well not like either! ;-) Damian
ConwayPerl (was Re: RFC 22 (v1) Builtin switch statement)
Damian Conway said: switch ( $x __ ) { case 0 { print "negative" } case 1 { print "unity" } case any(2..9) { print "small" } case @list { print "in range" } } Now _that's_ the coolest thing I've seen since, well, umm, this morning, when I read the original RFC. Damian, a lot of your RFCs integrate together to provide some pretty powerful capabilities (what a coincidence ;-) To mere mortals like myself, some of these are non-obvious. To beings of a higher plane some are non-obvious too, because some of the RFCs haven't been written yet... Is there a chance at some point you could give a high-level overview of ConwayPerl? In particular, how reduce, semi-finite lists, higher-order functions, generalised iterators, lazy evaluation of argument lists, and superpositions fit together? Maybe a little snippet of code in ConwayPerl which defines and then does some interesting operations on and reductions of columns of a sparse matrix/tensor, for instance?... I know you've got nothing else to do right now ;-)
Re: RFC 22 (v1) Builtin switch statement
Glenn Linderman wrote: For instance, if ( $v == @foo ) is clearly testing the size of foo against the value of $v. But switch ( $v ) { case 1: { ... } case 2: { ... } case @foo { ... } } does not! Then write the switch as: switch ( __ ) { case $v == 1: { ... } case $v == 2: { ... } case $v == @foo { ... } } It might take you a little while to get your head around the __ symbol. I'm not sure it's useful to think of it as a variable; poison is more like it. Or a Midas touch. Any expression it touches turns into a subroutine. All the case statement does is call the subroutine. - Ken
Re: RFC 22 (v1) Builtin switch statement
Ken Fox wrote: Then write the switch as: switch ( __ ) { case $v == 1: { ... } case $v == 2: { ... } case $v == @foo { ... } } It might take you a little while to get your head around the __ symbol. I'm not sure it's useful to think of it as a variable; poison is more like it. Or a Midas touch. Any expression it touches turns into a subroutine. All the case statement does is call the subroutine. - Ken I haven't gotten my head around anything curried, except Indian food but it appears to be powerful, and a kind of like generic programming on the fly. I'd like to learn more: if someone would give a tutorial reference that would be helpful. However, in this particular example, it is clear that you have attempted to resolve my negative example by using an extremely powerful construct to take Damian factored switch statement, and effectively unfactor it: Remove the "switch ( __ )" part, and you have exactly the syntax and functionality I suggested in my first reponse to his post. I don't attempt to claim that Damian's proposal isn't clever, isn't powerful, or isn't cool. Just that it doesn't DWIM, is hard to learn and understand because of its large table of operations, and gets most of its power from that table, together with this currying thing. I'd like to see the useful, non-trivial operations in his table available using simple syntax outside the switch statement; they could then be expressed in the switch statement conditions, or in if conditions, or while conditions, or any other useful place, rather than having the programmer be forced to contrive a switch statement to avoid writing the non-trivial operation syntax. Further, rather than have a powerful switch statement embodying all these operations, and have to use a powerful curry operation to reduce it to a simple case, wouldn't it be nicer to have a simple, easy to learn switch statement, and have more powerful operators and this curry thing when needed to achieve the complexity embodied in this RFC? Make easy things easy, and hard things possible. I'll probably counter-propose as Damian suggested, as it does, indeed, look like we are quite far apart on this issue, and it would take more than a few postings to resolve. -- Glenn = There are two kinds of people, those who finish what they start, and so on... -- Robert Byrne ___ Why pay for something you could get for free? NetZero provides FREE Internet Access and Email http://www.netzero.net/download/index.html