AutoHotkey Community

It is currently May 27th, 2012, 12:31 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 45 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Case/Switch
PostPosted: June 20th, 2005, 6:46 am 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
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?? :shock:

_________________
Windows XP SP2


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 20th, 2005, 10:22 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
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 June 20th, 2005, 4:30 pm, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 20th, 2005, 3:20 pm 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
Looks great to me!

_________________
Windows XP SP2


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 20th, 2005, 5:22 pm 
Offline

Joined: September 7th, 2004, 9:20 pm
Posts: 275
Location: France
Glad to see that this feature will be implemented soon. Thanks a lot Chris.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 20th, 2005, 11:48 pm 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
You might want to allow us brackets for the cases, as well. It feels cleaner sometimes.

Code:
case "a":
{
   commands...
   Break
}

_________________
Windows XP SP2


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 21st, 2005, 1:26 pm 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2005, 4:28 am 
Offline

Joined: November 16th, 2004, 6:38 am
Posts: 153
Location: New York
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
Code:
default:
in favor of
Code:
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2005, 4:59 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
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
Code:
default:
in favor of
Code:
case A_CaseValue:
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"?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2005, 5:33 am 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2005, 6:16 am 
Offline

Joined: November 16th, 2004, 6:38 am
Posts: 153
Location: New York
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2005, 6:29 am 
Offline

Joined: November 16th, 2004, 6:38 am
Posts: 153
Location: New York
I wrote:
A_CaseValue
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 25th, 2005, 2:56 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 22nd, 2006, 4:21 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
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.

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Re: Case/Switch
PostPosted: February 22nd, 2006, 6:34 pm 
Offline

Joined: December 28th, 2005, 10:46 am
Posts: 99
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 23rd, 2006, 10:21 am 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Mmm, that's a matter of taste, so arguing over it is probably a waste of time :-P

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.

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 45 posts ]  Go to page 1, 2, 3  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group