When do you think you'll get around to this?? :shock: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.
Case/Switch
It will probably be of the following syntax unless someone has a better idea:
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... }
case "a": { commands... Break }
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 labelIt will probably be of the following syntax unless someone has a better idea:
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... }
default:in favor of
case A_CaseValue: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.
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.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
default:in favor ofcase A_CaseValue:
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.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)?
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"?
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.
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...Another thing that might be quite nice is to entirely get rid of "break" within the switch().
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".One problem with this idea is how to have a case that does nothing as a means to avoid the default section.
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... :-)Another advantage of avoiding "break" is that a switch() could use "break" to exit any loop that encloses it.
Later,
Jacques.
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).A_CaseValue
Jacques.
Yes, that's it....or were you planning to interpret consecutive "case expression:" lines as a sort of "OR construct" applying to the same set of commands?
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).
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.Couldn't "break" (theoretically) take a numeric parameter indicating the number of structures from which to escape?
Thanks.
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:
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 OtherI 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.
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.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 prefer to see :
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 Otherrather than
I think it is a more concise and readable notation.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
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
can be more readable thanswitch(test) if case(1) ... else if case(2) ....
switch a Case = 1 ... case = 2 ....But again for me it isn't a necessity nor a priority. Just something more readable.
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.