Inconsistency with Comma (multi-statement) expressions

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Sam_
Posts: 146
Joined: 20 Mar 2014, 20:24

Inconsistency with Comma (multi-statement) expressions

25 Apr 2018, 14:23

[Moderator's note: Topic moved from Bug Reports.]

Every time I have reported a bug, it has turned out to be a misconception on my part about the expected behavior of the code, and not a real bug. That being said, I am confused about the current behavior of Comma (multi-statement) expressions.

Code: Select all

i:="1 1", i+=0
MsgBox "%i%"

Code: Select all

i:="1 1"
i+=0
MsgBox "%i%"
I expected both of these to produce the same value (1), but the first produces a blank string ("") while the second produces 1. Why is that? I'm using AHK v1.1.28.02.
User avatar
TheDewd
Posts: 1507
Joined: 19 Dec 2013, 11:16
Location: USA

Re: Inconsistency with Comma (multi-statement) expressions

25 Apr 2018, 15:07

In your first example, you're attempting to add a numerical value to a text string. The data formats are not consistent. It's like trying to add 2 + "Banana" = ??

In your second example, I believe that it's only "working" due to some strange luck, however it only appears to be capturing the first digit before the space.
Sam_
Posts: 146
Joined: 20 Mar 2014, 20:24

Re: Inconsistency with Comma (multi-statement) expressions

25 Apr 2018, 15:56

I understand that adding a number to a string is a nonsensical thing to do, but as it happens this is the single most efficient way of retrieving the first number from a string of numbers delimited by non-digits. It works with negative numbers too. I have the gut feeling this behavior was in the documentation somewhere long ago, but I haven't been able to find it now.
gregster
Posts: 8919
Joined: 30 Sep 2013, 06:48

Re: Inconsistency with Comma (multi-statement) expressions

25 Apr 2018, 16:11

The docs (https://autohotkey.com/docs/Variables.htm#Operators) say:
Operators in Expressions wrote:Known limitations caused by backward compatibility (these may be resolved in a future release):
[...]
3) The operators +=, -=, and *= treat blank variables as zero, but only when they are alone on a line; for example, y:=1, x+=1 and MsgBox % x-=3 both produce a blank result when x is blank.
Thus,

Code: Select all

y:=1, x+=1	; x treated as blank
msgbox % x	; blank
y:=1 
x+=1		; x treated as zero
msgbox % x	; 1
Your i:="1 1" is considered an error in a mathematical operation and is therefore treated as blank, but only when on the same line with the operation. Who knew??? : :ugeek:

So, if x+=1 is alone on a line, it is one of the exceptions mentioned at the beginning of the 'Operators in Expressions' section:
https://autohotkey.com/docs/Variables.htm#Operators wrote:Except where noted below, any blank value (empty string) or non-numeric value involved in a math operation is not assumed to be zero. Instead, it is treated as an error, which causes that part of the expression to evaluate to an empty string.
But this is still true for the (your) same-line case.

So, not a bug but some unfortunate backward compatibility issue... as far as I understand it :?
joefiesta
Posts: 494
Joined: 24 Jan 2016, 13:54
Location: Pa., USA

Re: Inconsistency with Comma (multi-statement) expressions

27 Apr 2018, 08:48

Sam,

As to reporting what you might think is a bug: just voice your problem in the ask for help forum. Then, if you learn it really is a bug, you should report it in the BUGS forum. (that saves the moderators the effort of now moving your issue OUT OF the bugs forum.)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Inconsistency with Comma (multi-statement) expressions

02 May 2018, 15:07

- This is *not* simply the 'strings treated as zero' issue.
- I got some very surprising results (see my example script below), in line with these comments:
Sam_ wrote:retrieving the first number from a string of numbers delimited by non-digits. It works with negative numbers too.
- Were *any* other users aware of this?
- Also, is this documented anywhere? If not, then perhaps this thread should be moved back to Bug Reports.
- Note: in AHK v2, you get blank strings for both examples. Cheers.

Code: Select all

q::
vNum := "3abc"
vNum += 1
MsgBox, % vNum ;4

vNum := "-3abc"
vNum -= 1
MsgBox, % vNum ;-4
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: Inconsistency with Comma (multi-statement) expressions

05 May 2018, 01:18

Unless it is embedded within another expression, vName += 1 is literally a call to EnvAdd.
EnvAdd
Sets a variable to the sum of itself plus the given value (can also add or subtract time from a date-time value). Synonymous with: var += value.

Code: Select all

EnvAdd, Var, Value [, TimeUnits]
Var += Value [, TimeUnits]
Var++
...
If either Var or Value is blank or does not start with a number, it is considered to be 0 for the purpose of the calculation (except when used internally in an expression and except when using the TimeUnits parameter).
There are many cases in v1 (built-in functions and commands) where numeric strings are converted to pure numbers without first verifying that the entire value is truly numeric. In that case, the C string-to-number conversion functions parse as much of the string as possible and return the result even if there is a non-numeric suffix. v2 performs more validation.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Inconsistency with Comma (multi-statement) expressions

05 May 2018, 05:08

@lexikos: Thanks very much for the info.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
joefiesta
Posts: 494
Joined: 24 Jan 2016, 13:54
Location: Pa., USA

Re: Inconsistency with Comma (multi-statement) expressions

05 May 2018, 08:48

Then, surely
In that case, the C string-to-number conversion functions parse as much of the string as possible and return the result even if there is a non-numeric suffix.
should be added to the documentation somewhere.
Sam_
Posts: 146
Joined: 20 Mar 2014, 20:24

Re: Inconsistency with Comma (multi-statement) expressions

06 May 2018, 19:37

@lexikos, Thank you very much for the explanation.

Does
lexikos wrote:Unless it is embedded within another expression, vName += 1 is literally a call to EnvAdd.
mean that using EnvAdd would be faster than using vName += 1?
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: Inconsistency with Comma (multi-statement) expressions

07 May 2018, 06:22

:eh:

No.

By "x is literally y", I mean that x and y are the same thing. That thing can't be faster than itself.

Look:

Code: Select all

a += 1
EnvAdd b, 2
c++
++d
ListLines
Pause
Result:

Code: Select all

001: a += 1
002: b += 2
003: c += 1
004: d += 1
Sam_
Posts: 146
Joined: 20 Mar 2014, 20:24

Re: Inconsistency with Comma (multi-statement) expressions

07 May 2018, 12:32

Sam_ wrote:
lexikos wrote:Unless it is embedded within another expression, vName += 1 is literally a call to EnvAdd.
mean that using EnvAdd would be faster than using vName += 1?
lexikos wrote::eh:

No.

By "x is literally y", I mean that x and y are the same thing. That thing can't be faster than itself.
You stated that vName += 1 calls the command EnvAdd. That implies that using EnvAdd directly might be slightly faster than using +=, as it presumably involves one less layer of interpretation before the underlying AHK source code to perform the addition is called.
lexikos wrote: Look:

Code: Select all

a += 1
EnvAdd b, 2
c++
++d
ListLines
Pause
Result:

Code: Select all

001: a += 1
002: b += 2
003: c += 1
004: d += 1
This on the other hand implies the different syntaxes all get translated into/interpreted as +=. One would think, then, that using += directly would be the fastest, but previous analysis indicates otherwise:
jNizM wrote:100.000.000 Loops

Code: Select all

A + B   7.822086
A - B   7.793425

A + 1   7.647965
A - 1   7.629782

A++     6.906725
A--     6.837371

++A     7.220017
--A	    7.273083
My current round of testing supports these previous findings:

Code: Select all

Results:=""

Loop, 1000
	{
	A:=1
	tic:=QPC(1)
	Loop, 1000000
		A:=A+1
	toc:=(QPC(1)-tic)
	Results.="A=A+1	" toc "`r`n"

	A:=1
	tic:=QPC(1)
	Loop, 1000000
		A+=1
	toc:=(QPC(1)-tic)
	Results.="A+=1	" toc "`r`n"

	A:=1
	tic:=QPC(1)
	Loop, 1000000
		A++
	toc:=(QPC(1)-tic)
	Results.="A++	" toc "`r`n"

	A:=1
	tic:=QPC(1)
	Loop, 1000000
		++A
	toc:=(QPC(1)-tic)
	Results.="++A	" toc "`r`n"

	A:=1
	tic:=QPC(1)
	Loop, 1000000
		EnvAdd, A, 1
	toc:=(QPC(1)-tic)
	Results.="EnvAdd, A, 1	" toc "`r`n"
	}

FileAppend, %Results%, %A_ScriptDir%\BenchResults.txt

ExitApp


QPC(R:=0){ ; By SKAN, http://goo.gl/nf7O4G, CD:01/Sep/2014 | MD:01/Sep/2014
  Static P:=0, F:=0, Q:=DllCall("QueryPerformanceFrequency","Int64P",F)
  Return !DllCall("QueryPerformanceCounter","Int64P",Q)+(R?(P:=Q)/F:(Q-P)/F) 
}
which after some averaging shows:

Code: Select all

A++              0.143022241
++A              0.14322938
EnvAdd, A, 1     0.143281911
A+=1             0.144320881
A=A+1            0.196662157
This is getting a bit OT, tho.
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: Inconsistency with Comma (multi-statement) expressions

08 May 2018, 03:12

Sam_ wrote:[That implies that using EnvAdd directly might be slightly faster than using +=,
No, it doesn't. EnvAdd var, 1 also calls EnvAdd. EnvAdd itself is a command, just as

Code: Select all

myfunction(n) {  ;  This is a function definition, not a function call.
   ...
}
...
myfunction(1)  ; This is a function call, not the function itself.
One would think, then, that using += directly would be the fastest,
Why? ListLines shows they're all the same thing. The translation is done when the script loads, before it executes. The translation of the text "a += 1" to an action type and parameters is no different to the translation of the text "EnvAdd a, 1" to the same.

The text "a += 1, Days" on a line of its own is also translated to an EnvAdd call, but "a += 1, b += 2" is translated to a postfix expression (a series of instructions that the program can execute in order). This is the source of the inconsistency, the reason being that EnvAdd can only perform addition once per call (but its parameter can be an expression which is evaluated separately).

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: catquas, Google [Bot], mikeyww, mmflume, Ralf_Reddings200244, sofista, thelegend and 133 guests