 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
ComradeF
Joined: 16 May 2005 Posts: 42 Location: Dallas, TX, USA
|
Posted: Mon Jun 20, 2005 6:46 am Post subject: Case/Switch |
|
|
| Chris' to-do list wrote: | | A simple select/switch/case structure as an alternative to a series of ""else if"" statements. This might also help with the lack of support for the OR conjunction. |
When do you think you'll get around to this??  _________________ Windows XP SP2 |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Mon Jun 20, 2005 10:22 am Post subject: |
|
|
I think you're right that this is important. I'll try to get it done within the next 30 days.
It will probably be of the following syntax unless someone has a better idea:
| Code: | switch MainExpression
{
case expression1: ; i.e. if MainExpression matches this, its commands will run.
...commands...
break
case expression2:
...commands...
break
default: ; If MainExpression doesn't match any of the above cases, this happens.
...commands...
} |
Last edited by Chris on Mon Jun 20, 2005 4:30 pm; edited 3 times in total |
|
| Back to top |
|
 |
ComradeF
Joined: 16 May 2005 Posts: 42 Location: Dallas, TX, USA
|
Posted: Mon Jun 20, 2005 3:20 pm Post subject: |
|
|
Looks great to me! _________________ Windows XP SP2 |
|
| Back to top |
|
 |
Nemroth
Joined: 07 Sep 2004 Posts: 262 Location: France
|
Posted: Mon Jun 20, 2005 5:22 pm Post subject: |
|
|
| Glad to see that this feature will be implemented soon. Thanks a lot Chris. |
|
| Back to top |
|
 |
ComradeF
Joined: 16 May 2005 Posts: 42 Location: Dallas, TX, USA
|
Posted: Mon Jun 20, 2005 11:48 pm Post subject: |
|
|
You might want to allow us brackets for the cases, as well. It feels cleaner sometimes.
| Code: | case "a":
{
commands...
Break
} |
_________________ Windows XP SP2 |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Tue Jun 21, 2005 1:26 pm Post subject: |
|
|
| Thanks. Hopefully that will work automatically because blocks/braces can already be used anywhere, even if there is no if/else/loop/function above them. |
|
| Back to top |
|
 |
JBensimon
Joined: 16 Nov 2004 Posts: 130 Location: New York
|
Posted: Fri Jun 24, 2005 4:28 am Post subject: |
|
|
| Chris wrote: | It will probably be of the following syntax unless someone has a better idea:
| Code: | switch MainExpression
{
case expression1: ; i.e. if MainExpression matches this, its commands will run.
...commands...
break
case expression2:
...commands...
break
default: ; If MainExpression doesn't match any of the above cases, this happens.
...commands...
} |
|
For the sake of syntactic symmetry, you may want to consider providing a variable (e.g. A_CaseValue) that reflects the result of "MainExpression" so that, among other possible uses, you can do away with the special label in favor of
Unrelated to the above, a question: I assume the use of "Break" in the sample syntax means that command execution will otherwise "fall through" from one case to the next. In this scenario, would the intervening case expressions be evaluated or would they be skipped (which matters if they involve functions with side effects)?
Jacques. |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Fri Jun 24, 2005 4:59 am Post subject: |
|
|
| JBensimon wrote: | | For the sake of syntactic symmetry, you may want to consider providing a variable (e.g. A_CaseValue) that reflects the result of "MainExpression" so that, among other possible uses, you can do away with the special label in favor of | That is great. There have been numerous times when I have to scroll back up to the top of a long switch() to find out what it was switching on so that I can write a sub-switch or an if/then involving the switch's main expression. The word "default" might still be more readable than "case A_CaseValue", but perhaps both can be supported.
| Quote: | | I assume the use of "Break" in the sample syntax means that command execution will otherwise "fall through" from one case to the next. In this scenario, would the intervening case expressions be evaluated or would they be skipped (which matters if they involve functions with side effects)? | That's a very good point. Clearly for performance reasons they should be skipped. If it's not to difficult, I'll try to ensure that this happens.
Another thing that might be quite nice is to entirely get rid of "break" within the switch(). This is because although the "fall through" behavior sounds nice in principle, I think it is hardly ever used except with cases that are immediately adjacent to each other. If this is done, adjacent cases would have to become a special exception that is recognized as a "conglomerate case". One problem with this idea is how to have a case that does nothing as a means to avoid the default section. Perhaps an empty pair of braces would serve.
Another advantage of avoiding "break" is that a switch() could use "break" to exit any loop that encloses it.
Do you see any problems with avoiding "break"? |
|
| Back to top |
|
 |
ComradeF
Joined: 16 May 2005 Posts: 42 Location: Dallas, TX, USA
|
Posted: Fri Jun 24, 2005 5:33 am Post subject: |
|
|
MAYBE you could add both case AND switch... and they could do different things.
One of them could utilize breaks, and the other could skip them. I was trying to think of a reason to NOT avoid using 'break', but I couldn't think of one because the entire point of this case/switch is to choose ONE condition, perform its results, and be done. But other languages require the 'break' in there because the script will keep performing all the conditions that follow unless you add breaks. It's sort of an inversed if-else chain -- a weird concept I guess, but perhaps it could be useful sometime.
I have no idea. Just brainstorming. But if you're only going to add it one way, I don't think we really need required breaks. It's implied. _________________ Windows XP SP2 |
|
| Back to top |
|
 |
JBensimon
Joined: 16 Nov 2004 Posts: 130 Location: New York
|
Posted: Fri Jun 24, 2005 6:16 am Post subject: |
|
|
| Chris wrote: | | Another thing that might be quite nice is to entirely get rid of "break" within the switch(). | I tend to agree: on the one hand, eliminating "fall-through" removes a capability from the language, but on the other hand (1) the capability in question is rarely useful, (2) the syntax is simplified, and (3) it makes the "switch" feature more intuitive for beginners (I think people would tend to forget about the need for "break"). Members of these forums may have other thoughts however: there might be some popular algorithms out there that rely on fall-through behavior. Maybe you could decide based on whichever seems most efficient (or easiest) from an implementation standpoint...
| Quote: | | One problem with this idea is how to have a case that does nothing as a means to avoid the default section. | I'm not sure I understand: in the absence of fall-through, wouldn't a "case expressionX:" followed immediately by another have the effect of doing nothing for that case? ... or were you planning to interpret consecutive "case expression:" lines as a sort of "OR construct" applying to the same set of commands? If so (which by the way is a special case of fall-through behavior), a do-nothing case could still be achieved either with your empty braces idea (the empty statement) or with other do-almost-nothing commands like "Sleep, 0".
| Quote: | | Another advantage of avoiding "break" is that a switch() could use "break" to exit any loop that encloses it. | Very true. It's actually always bothered me somewhat (in all structured languages that offer some sort of break feature) that it is capable only of escaping from the innermost "structure" in which it is found. Couldn't "break" (theoretically) take a numeric parameter indicating the number of structures from which to escape? (i.e. "Break, 1" would be equivalent to "Break", "Break, 2" would mean "Break then Break again", etc.) Not that I personally mind using "GoTo" all that much...
Later,
Jacques. |
|
| Back to top |
|
 |
JBensimon
Joined: 16 Nov 2004 Posts: 130 Location: New York
|
Posted: Fri Jun 24, 2005 6:29 am Post subject: |
|
|
That was a poor naming suggestion. Since the overall construct is a Switch (not Case) statement, I should have suggested "A_SwitchValue" (or something else with "switch" rather than "case" in the name).
Jacques. |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Sat Jun 25, 2005 2:56 am Post subject: |
|
|
| JBensimon wrote: | | ...or were you planning to interpret consecutive "case expression:" lines as a sort of "OR construct" applying to the same set of commands? | Yes, that's it.
By the way, although the lack of a need for "break" has the big advantages mentioned above, it also has one fairly serious drawback: Anyone used to programming in C-like languages will find themselves using "break" automatically. This will cause script bugs that might be hard to detect whenever a switch() is enclosed in a Loop (since the break would exit the loop rather than the switch).
| Quote: | | Couldn't "break" (theoretically) take a numeric parameter indicating the number of structures from which to escape? | This idea is already on the to-do list. It's might be a little complicated to implement, but I think it would be worthwhile.
Thanks. |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Wed Feb 22, 2006 4:21 pm Post subject: |
|
|
The more I think of it, the more I find it redundant and obsolete...
Obviously, IF expressions became more powerful with expressions since the time the topic was created: we have OR, AND, NOT, etc.
Using Switch/Case may please those coming from C and related languages, but if it is necessary and performant in C (optimized machine code jumping to right location), it is probably inefficient for interpreted languages.
A similar discussion was raised in the Lua list, and many shown that this can be done natively within the language. AutoHokey doesn't have functions as first class citizen (Lua can put functions in tables, pass them as parameter and return value, etc.), but has powerful IF expressions that can do something similar, or even more flexible. Remember that C switches are limited to numbers, only one of them per case. Pascal allows ranges. Better, not perfect.
JSLover shown that you can do that in pure AHK, keeping the switch syntax for those hooked to it.
AutoHotkey allows cases to have multiple values, sub-strings and values in a range:
| Code: | a = Droopy
a = Foobar
a = flat iron
If a in Snoopy,Doopey
MsgBox One
Else If a contains Foo,Bar
MsgBox Two
Else If a = Droopy
MsgBox Three
Else If a between anvil and hammer
MsgBox Four
Else
MsgBox Other
|
I even didn't used expressions...
For those still wanting such a command, what would it provides beyond that? The only problem is the repetition of the variable. But if the variable name is long, you can make a temporary shorter one. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
Demokos
Joined: 28 Dec 2005 Posts: 84
|
Posted: Wed Feb 22, 2006 6:34 pm Post subject: Re: Case/Switch |
|
|
| Planned Features wrote: | | A simple select/switch/case structure as an alternative to a series of ""else if"" statements. This might also help with the lack of support for the OR conjunction. | I'm agree it isn't a necessity nor an high priority, but I think it makes the code more readable, witch is a good thing.
I prefer to see : | Code: | a = flat iron
Select a
Case in Snoopy,Doopey
MsgBox One
Case contains Foo,Bar
MsgBox Two
Case = Droopy
MsgBox Three
Case between anvil and hammer
MsgBox Four
Default
MsgBox Other
| rather than
| PhiLho wrote: | | Code: | a = flat iron
If a in Snoopy,Doopey
MsgBox One
Else If a contains Foo,Bar
MsgBox Two
Else If a = Droopy
MsgBox Three
Else If a between anvil and hammer
MsgBox Four
Else
MsgBox Other
|
| I think it is a more concise and readable notation.
And probably internaly it is not someting very complicated to do, as may be (a part of) the code used for the If ... Else If structure may be used for the case one. May be I'm wrong...
For the JSlover "solution", I think it's, as we say in our beautifull country, "un emplātre sur une jambe de bois" !!!! (a plaster on a wooden leg) (Sorry JSLover, absolutely no offense !!!)
I can't see how | JSLover wrote: | | Code: | switch(test)
if case(1)
...
else if case(2)
....
|
| can be more readable than | Code: | switch a
Case = 1
...
case = 2
....
| But again for me it isn't a necessity nor a priority. Just something more readable. |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Thu Feb 23, 2006 10:21 am Post subject: |
|
|
Mmm, that's a matter of taste, so arguing over it is probably a waste of time
Some remarks:
- Your proposal make sense (if switch is to be implemented) and is (more or less) consistent with current syntax: there is no real need for the colons (end of line marks the end of the case, unlike in C where you can stack the whole switch on one line...); but marking the scope of the switch with braces seems sensible.
- I prefer Case Droopy instead of Case = Droopy
- There is no break, so no fallthrough. I think this is better: if some code is common to several cases, you can put it in a function or a Gosub target.
- The advantage isn't paramount, unless the variable name is very long, but you can take a shorter (temporary) name for the construct
- A similar shortening could be achieved with a ElseIf or Elif keyword. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|