Page 1 of 2
Break, continue - allow expression mode
Posted: 01 Jul 2014, 05:40
by trismarck
A similar functionality was requested in the past by HotkeyIt
here.
When 'exiting' from a _function_, it _is_ possible to use the expression mode with
return:
Code: Select all
fun() {
; do something
return, this, a+b, c*d, Errorlevel := 0
}
When 'exiting' from a _loop_ (by using either
break or
continue), it is _not_ possible to use the expression mode with
break - a line before
break has to be added to evaluate any expression prior to 'exiting' from the loop:
Code: Select all
Loop,
if(a = b) {
c++ ; <--
break
}
Often times,
break is inside of an if() statement. Because the expression can't be in the same line where the command
break is, brackets have to be used with the if() statement.
Code: Select all
Loop,
if(a = b) { ; <--
c++
break
} ; <--
If
break would allow expression mode (like
return already does), the four-line if() statement above could be converted to just two lines:
Re: Break, continue - expression mode
Posted: 01 Jul 2014, 05:57
by tank
Sounds like a distinction without a difference. I can't think of any language where break/continue operate on an expression. I am not saying anything bout the value of doing it , only that no where else has that value made it into a language
Return exists within a function to send a result back to the caller. It for this reason accepts an argument. Notice that return outside a function will not accept argument.
Re: Break, continue - expression mode
Posted: 01 Jul 2014, 05:59
by HotKeyIt
I added breakif and continueif in AutoHotkey_H but then noticed that AutoHotkey v2 supports one line if statement which is even better
Code: Select all
Loop
If (A_Index < 10), continue
else if (20 > i:=A_Index), break
I left it in AutoHotkey_H v1, so you can do:
Code: Select all
Loop {
continueif A_Index<10
breakif (20 > i:=A_Index)
}
Re: Break, continue - expression mode
Posted: 01 Jul 2014, 06:50
by trismarck
Tank wrote:Sounds like a distinction without a difference. I can't think of any language where break/continue operate on an expression. I am not saying anything bout the value of doing it , only that no where else has that value made it into a language
Yes, I should have been more clear: the first parameter of
break is _not_ an expression. The first parameter is a _constant_ that is either empty, a number or a string. What I'm after is to _leave_ the first parameter of
break as it is now and just allow an expression to be the second, non-existent parameter of
break.
As for the functionality of
break in other languages - we could be the pioneers in doing that
![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
.
Tank wrote:Return exists within a function to send a result back to the caller. It for this reason accepts an argument. Notice that return outside a function will not accept argument.
Didn't know that, thanks. Not sure if it's a good idea to allow expressions be part of
return outside of functions (at first glance, nothing _bad_ would happen).
HotKeyIt wrote:Code: Select all
Loop
If (A_Index < 10), continue
else if (20 > i:=A_Index), break
Code: Select all
Loop {
continueif A_Index<10
breakif (20 > i:=A_Index)
}
That I like.
Could something like this be added too? :
Code: Select all
If (A_Index < 10), continue
else if (20 > A_Index), break, , i := A_Index
If
A_Index less than 20, break and set a few variables along the way.
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 07:19
by Coco
trismarck wrote:Perhaps this could be implemented then:
Code: Select all
If (A_Index < 10), continue
else if (20 > A_Index), break, , i := A_Index
If
A_Index less than 20, break and set a few variables along the way.
Well, you can already do this if you put it in a block. There is no real benefit other than one-liner statement...
If you're after shorter, one-liner statement(s), I'd rather have:
Code: Select all
if (A_Index > 20) { i := A_Index; some_var := some_value; break }
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 07:27
by Coco
Workaround:
Code: Select all
b := "Hello World"
Loop {
if (A_Index > 10 && dummy:=(true, i:=A_Index, a:=b))
break
}
MsgBox %i%
MsgBox %a%
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 08:01
by tank
ok so i want to understand something
the entire purpose is to reduce lines of code and not use handlebars
{}
trismarck wrote:What I'm after is to _leave_ the first parameter of break as it is now and just allow an expression to be the second, non-existent parameter of break.
Break accepts a label reference not just any string or integer. a distinction WITH a difference
Hotkeyit is using an expression to operate break/continue a distinction AND a difference
your OP
trismarck wrote:If break would allow expression mode (like return already does), the four-line if() statement above could be converted to just two lines:
Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
Loop,
if(a = b)
break, , c++
seems to indicate you just want to execute an unrelated expression on the same line?
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 08:11
by trismarck
Tank wrote:seems to indicate you just want to execute an unrelated expression on the same line?
Yes, that's exactly the case. Just like with
return.
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 08:22
by trismarck
To clarify: I _don't_ want the _result_ of the evaluation of the expression being the non-existent second parameter of break to trigger the break or not. Moreover I'd say that that would be impossible by design. I just want to evaluate some expression before break exits the loop. Just like it is already possible to evaluate an expression before return exits the function.
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 08:28
by tank
So then one solution would also be to allow break to operate in
multistatement
thus would not offer a second parameter to break but instead offer this
Code: Select all
c=0
a=1
b=1
loop 5
if (a = b)
++c, break
msgbox % c
Unfortunately break seems to only operate when it is the only statement on the line of code so either IEA requires code change
sidenote: if this were allowed almost every function Sean ever wrote would have been 3 lines func name and opening handlebar 1 long statement and a closing handlebar. cause that fella abused
multistatement for performance
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 08:41
by Coco
tank wrote:sidenote: if this were allowed almost every function Sean ever wrote would have been 3 lines func name and opening handlebar 1 long statement and a closing handlebar. cause that fella abused
multistatement for performance
![Laughing :lol:](./images/smilies/icon_lol.gif)
@trismarck:
See workaround above, if you are after shorter code...
there'll be a slight performance hit though due to the evaluation+object Edited: removed usage of object
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 08:46
by trismarck
To clarify further: (from the point of view of AHK _1.1_)
Tank wrote:Unfortunately break seems to only operate when it is the only statement on the line of code so either IEA requires code change
At compile time, when Autohotkey parses each line of the script, Autohotkey determines, if the line of the script is:
- one of the predefined commands or whether the line is
- an expression or
- something else I have no idea about
(lets say this happens after continuation sections were processed).
Because of the following limitation: for a given line of code to be interpreted as a _command_, that line of code has to _start_ with the name of the command, a given line of code _can't_ start with an _expression_ and at the same time be followed with a _command_ - as it is the case here:
The command has to be the first 'token' of the line:
Note also that I don't know how Autohotkey _2_ works in this context.
Tank wrote:
sidenote: if this were allowed almost every function Sean ever wrote would have been 3 lines func name and opening handlebar 1 long statement and a closing handlebar. cause that fella abused multistatement for performance
Yes, I've seen that. I guess the only thing Sean was concerned about was the 512 token limitation
![Laughing :lol:](./images/smilies/icon_lol.gif)
.
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 08:52
by tank
Coco the problem with adding something like that is that it complicates the If and must be certain to evaluate as true or false or else it affects the logic. In addition this isnt about a conditional break/continue its about being able to execute an unrelated expression same line as the break without the curly braces
@trismarck
there are already exceptions to that with many of the window functions can be executed on same line without being so called tokens of each other. But your right it does open a rather dangerous precedent. by not making the statement part of break/continue it would continue to draw a need for other exceptions
How would multiple expressions be handled by your idea?
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 09:21
by trismarck
Tank wrote:How would multiple expressions be handled by your idea?
In case of
return, the first parameter can be an expression. Because of that, it is possible to just add a sub-expression separator (a comma) and evaluate whatever is needed (as 'yet another' sub-expression). I'd like to have the same functionality for
break. What I want would have been already possible with
break if expression mode was allowed for the first parameter of
break. This isn't the case - the first parameter of the
break command _has to_ be a constant (a constant that is the name of the existing label / a number that identifies one of the nested Loop statements).
Coco wrote:Code: Select all
b := "Hello World"
Loop {
if (A_Index > 10 && dummy:=(true, i:=A_Index, a:=b))
break
}
MsgBox %i%
MsgBox %a%
Yes, I'd like this to be improved:
Code: Select all
b := "Hello World"
Loop {
if (A_Index > 10)
break, , true, i:=A_Index, a:=b
}
MsgBox %i%
MsgBox %a%
To implement this,
break could have an implicit second parameter, for which the expression mode is allowed. Then, after the expression is evaluated,
break does _nothing_ with the parameter being the result of the evaluation of the expression.
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 09:51
by tank
i think i understand your idea now but i would never ever ever write such a line of code even if i could
i mean the point of break is to stop here not to stop here and do these other things first
returns point is to go back to where you came from. with functions to return with a value
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 10:34
by Coco
It makes the code look more confusing... no benefit at all except for one-liner multistatements. Why avoid the braces?
From an observer's standpoint:
Code: Select all
b := "Hello World" ; assignment
Loop { ; something that repeats a series of commands
if (A_Index > 10) ; condition
break, , true, i:=A_Index, a:=b ; ... what's this??
}
MsgBox %i%
MsgBox %a%
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 15:55
by trismarck
Tank wrote:I mean the point of break is to stop here not to stop here and do these other things first
returns point is to go back to where you came from. with functions to return with a value
Break is a command. Every command has parameters. Some of the parameters can be expressions. Expressions are evaluated before the command is called. From the point of view of how Autohotkey works, this is perfectly logical I'd say.
Coco wrote:It makes the code look more confusing
Perhaps the reasoning behind creating the forum thread will sort this out. This is what I originally wrote:
Code: Select all
obj := ["aaa", "bbb", "aaa", "ddd", "eee", "aaa"]
for each, val in obj, Count := 0, found := false {
if(val = "aaa")
Count++
if(Count = 3) {
result := val, found := true
break
}
}
MsgBox, % found
I wanted to shorten this up to:
Code: Select all
for each, val in result, Count := 0, found := false {
if(val = "aaa")
Count++
if(Count = 3)
break, , result := val, found := true
}
In this example,
break works as sort of a mini-
return from the Loop function and just like it is the case with
return,
break could _also_ evaluate an expression on the same line, before 'exiting'.
Break could be considered a
return that doesn't return a value, but that _does_ evaluate an expression before returning. I mean
break, similar to
return, makes the flow of execution jump to the 'address' where the end of the loop/function call was.
I'd consider the above to be more readable than doing all of the assignments inside of the if() statement:
Code: Select all
for each, val in obj, Count := 0, found := false {
if(val = "aaa")
Count++
if(Count = 3 && (1, result := val, found := true) )
break
}
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 16:24
by HotKeyIt
In v2:
Code: Select all
obj := ["aaa", "bbb", "aaa", "ddd", "eee", "aaa"]
for each, val in (Count := 0, found := false, obj)
if (val = "aaa" && Count++) && (Count=3 && result:=val && found:=true),break
ListVars
Pause
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 19:12
by Coco
trismarck wrote:I'd consider the above to be more readable than doing all of the assignments inside of the if() statement:
That was a workaround to satisfy your need for a shorter code, I wouldn't really use it nor suggest it as a practice.
trismarck wrote:Break is a command. Every command has parameters. Some of the parameters can be expressions. Expressions are evaluated before the command is called. From the point of view of how Autohotkey works, this is perfectly logical I'd say.
Break is more like a control flow statement rather than a command. If it were one, I would expect this to work for v2, but nope, it doesn't...:
Code: Select all
for k, v in ['ABC', 'DEF', 'GHI']
if (v == 'DEF'), break() ; Command(s) can be called using function syntax -> this throws an error
You can use
until in this scenario... nonetheless, I'd rather use braces..
Code: Select all
obj := ["aaa", "bbb", "aaa", "ddd", "eee", "aaa"]
for each, val in obj, Count := 0, found := false {
if(val = "aaa")
Count++
} until (Count == 3, result := val, found := true)
MsgBox, % result
Re: Break, continue - allow expression mode
Posted: 01 Jul 2014, 21:07
by lexikos
Coco wrote:It makes the code look more confusing... no benefit at all except for one-liner multistatements.
This.