switch bug

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
aliztori
Posts: 119
Joined: 19 Jul 2022, 12:44

switch bug

Post by aliztori » 26 Oct 2022, 11:32

Hello why its not working with switch ?

Code: Select all

^d::

    df := 00
    Switch df
    {
        case "0": ToolTip, 1
        case "00": ToolTip, 2
    }

Return

picklepissjar
Posts: 20
Joined: 22 Oct 2022, 10:03

Re: switch bug

Post by picklepissjar » 26 Oct 2022, 12:23

Code: Select all

df := 1
Switch df
	{
	case 0:
	ToolTip, 1
	Sleep 1000
	return
	case 1:
	ToolTip, 2
	Sleep 1000
	return
}
I think its that the leading 0 in df gets ignored (0 being equivalent to 00). So try this code instead

Rohwedder
Posts: 7774
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: switch bug

Post by Rohwedder » 26 Oct 2022, 14:16

Hallo,
for it to work you need df := "00" and AutoHotkey v2.

Code: Select all

#Requires AutoHotkey v2.0-
^d::
{
    df := "00"
    Switch df
    {
        case "0": ToolTip 1 ;AutoHotkey v1.1
        case "00": ToolTip 2 ;AutoHotkey v2.0-
    }
}
Seems to be a bug in AutoHotkey v1.1

User avatar
flyingDman
Posts: 2848
Joined: 29 Sep 2013, 19:01

Re: switch bug

Post by flyingDman » 26 Oct 2022, 21:38

"Cheap and dirty" workaround:

Code: Select all

df := 00
Switch "|" df
	{
	case "|0": Msgbox, 1
	case "|00": Msgbox, 2
	}

Return
14.3 & 1.3.7

aliztori
Posts: 119
Joined: 19 Jul 2022, 12:44

Re: switch bug

Post by aliztori » 27 Oct 2022, 09:16

flyingDman wrote:
26 Oct 2022, 21:38
"Cheap and dirty" workaround:

Code: Select all

df := 00
Switch "|" df
	{
	case "|0": Msgbox, 1
	case "|00": Msgbox, 2
	}

Return
Oh That works But Why ? How ? what the point ? isnt a bug ?

User avatar
flyingDman
Posts: 2848
Joined: 29 Sep 2013, 19:01

Re: switch bug

Post by flyingDman » 27 Oct 2022, 10:07

00 is read as 0 but |00 is read as |00 because it's a string that AHK does not try to interpret a number. I chose | here but you obviously can take any character as the "dummy".
14.3 & 1.3.7

Rohwedder
Posts: 7774
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: switch bug

Post by Rohwedder » 27 Oct 2022, 10:30

Even invisible characters :)

Code: Select all

df = ​00
Switch df
{
	case "​0": Msgbox, 1
	case "​00": Msgbox, 2
}
Return

RussF
Posts: 1311
Joined: 05 Aug 2021, 06:36

Re: switch bug

Post by RussF » 27 Oct 2022, 11:09

I find this interesting:

Code: Select all

MsgBox, % 1 = 1       ; True
MsgBox, % 1 + 1       ; 2
MsgBox, % 1 = 01      ; True
MsgBox, % 1 + 01      ; 2
MsgBox, % "1" = 1     ; True
MsgBox, % "1" + 1     ; 11
MsgBox, % "1" = 01    ; False
MsgBox, % "1" + 01    ; 101
I'm sure it has to do with the loose (or nonexistent) typing of variables where AHK tries to "interpret" what you are trying to accomplish. Having much more experience in strongly typed languages, this has been a source of annoyance with AHK. I always just make it a point to "type" my own variables and never intermix types.

Russ

lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: switch bug

Post by lexikos » 27 Oct 2022, 23:12

The cases RussF has pointed out can be explained by the documentation.
For historical reasons, quoted numeric strings such as "123" are always considered non-numeric when used directly in an expression
Equal (=), case-sensitive-equal (==), and not-equal (<> or !=). If both inputs are numbers or numeric strings, they are compared numerically; otherwise they are compared alphabetically. ...
Note: In AutoHotkey v1, a quoted string (or the result of concatenating with a quoted string) is never considered numeric when used directly in an expression.
By contrast, the Switch documentation does not specify how the values are compared (numerically or non-numerically). When the expressions/values are being compared by switch/case, they are not being "used directly in an expression". I wrote more in the other topic.

"1" + 1 is not addition and does not relate to the types of the values, just the syntax. I'm not sure whether it is documented outside of the changelog. It only applies to v1.0.95+ and not v2.
If an operator which can accept either one operand (&x) or two numeric operands (x & y) follows a quoted literal string, auto-concat occurs and the operator is applied only to the right-hand operand. This is because quoted literal strings are always considered non-numeric and are therefore not valid input for numeric operators. For example, expressions like "x" &y and "x" ++y now work.

RussF
Posts: 1311
Joined: 05 Aug 2021, 06:36

Re: switch bug

Post by RussF » 28 Oct 2022, 06:24

Thank you @lexikos for the clarification, although I had to read your quotes very carefully to understand the nuances. The key phrase seems to be
This is because quoted literal strings are always considered non-numeric
In AHK, if you use the operand of "1234" directly, it is always a string of characters. However, If you define x := "1234", then x can be a number or a string, depending on context. Am I correct?

That would explain:

Code: Select all

x := "1"
y := "2"
a := 1
MsgBox, % x + y     ; result 3
MsgBox, % "1" + "2" ; result 12
MsgBox, % x = 1     ; result True
MsgBox, % x = "1"   ; result True
MsgBox, % x = a     ; result True
MsgBox, % a = "1"   ; result True
MsgBox, % x + a     ; result 2
This ambiguity is further explored in Caching.

I realize that many modern languages have moved toward the loosely typed model, but for an old goat like me, a string is a string and a numeric value is numeric, and never the twain shall meet without conversion, regardless of whether they are literal or in variable form.

Thank you for the enlightenment.

Russ

lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: switch bug

Post by lexikos » 28 Oct 2022, 18:57

RussF wrote:
28 Oct 2022, 06:24
The key phrase seems to be
This is because quoted literal strings are always considered non-numeric
I wouldn't say that is "the key phrase". It is just explaining the rationale for a syntax exception ("a" + b is always interpreted as "a" . +b). The syntax exception exists regardless of the runtime behaviour or type system.

In AHK, if you use the operand of "1234" directly, it is always a string of characters. However, If you define x := "1234", then x can be a number or a string, depending on context. Am I correct?
That is close enough, but be careful of generalizing quirks as they are not always consistent. It is better to understand them in context. Also, I think saying that a value "can be a number" is too inaccurate. In some contexts, a string value can be converted to or evaluated as a number.

Again,
Equal (=), case-sensitive-equal (==), and not-equal (<> or !=). If both inputs are numbers or numeric strings, they are compared numerically; otherwise they are compared alphabetically. ...
Note: In AutoHotkey v1, a quoted string (or the result of concatenating with a quoted string) is never considered numeric when used directly in an expression.
For the purpose of deciding whether to compare the values as numbers or numeric strings, a quoted string is never considered numeric. In other words, a quoted string is never compared numerically.

The first quote was missing similar context:
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. For example, if the variable X is blank, the expression X+1 yields a blank value rather than 1.

For historical reasons, quoted numeric strings such as "123" are always considered non-numeric when used directly in an expression (but not when stored in a variable or returned by a function). This non-numeric attribute is propagated by concatenation, so expressions like "0x" n also produce a non-numeric value (even when n contains valid hexadecimal digits). This problem can be avoided by assigning the value to a variable or passing it through a function like Round(). Scripts should avoid using quote marks around literal numbers, as the behavior may change in a future version.
So for the purpose of determining whether the inputs are valid for a math operator, a quoted string is always considered invalid, and will cause the result to be "" (in v1).

I realize that many modern languages have moved toward the loosely typed model,
I do not believe the vagueness and quirks of the v1 "type system" (if it can be said to have one) were motivated by modern language design principles. AutoHotkey started out with syntax like AutoIt v2, no expressions and no type model. Up until (I think) v1.0.48, variables were only able to contain strings. The quirk with quoted strings predates that; it was most likely an optimization measure, avoiding the need to evaluate whether the string is numeric (because quote marks were presumed to show that the author intended it to be non-numeric).

RussF
Posts: 1311
Joined: 05 Aug 2021, 06:36

Re: switch bug

Post by RussF » 29 Oct 2022, 11:26

This is all great information. Thank you @lexikos for taking the time to discuss this.

Does AHK v2 share the same mutability for numeric strings, or is it more strongly typed?

Russ

lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: switch bug

Post by lexikos » 29 Oct 2022, 17:21

RussF wrote:
29 Oct 2022, 11:26
Does AHK v2 share the same mutability for numeric strings, or is it more strongly typed?
What does it mean for the mutability to be the same, or for the types to be stronger or weaker? v1 doesn't have a consistent type system in the first place. If you want to know about v2, there is detailed documentation.

RussF
Posts: 1311
Joined: 05 Aug 2021, 06:36

Re: switch bug

Post by RussF » 29 Oct 2022, 17:47

lexikos wrote:What does it mean for the mutability to be the same
In other words, can a string of numbers be treated as a numeric value when use in certain ways?
lexikos wrote:or for the types to be stronger or weaker?
I think I answered that with
RussF wrote: a string is a string and a numeric value is numeric, and never the twain shall meet
Thank you for pointing me to the docs. Does this not seem contradictory to you?
...so that str := "123" is always a string and int := 123 is always an integer. Consequently, str needs to be converted every time it is used as a number...
and 5 paragraphs below is:
So for example, 54 and "530" are compared numerically...
What happened to " "123" is always a string"? How do you compare a string to a binary value? This is what I mean by strong typing (or lack thereof).

Russ

lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: switch bug

Post by lexikos » 29 Oct 2022, 19:16

RussF wrote:
29 Oct 2022, 17:47
Does this not seem contradictory to you?
It is not. You are likely conflating the value itself with how the value is used. A string is a string, even if you are able to convert it to something else, implicitly or explicitly. Type(str) and Type(int) will tell you what type the value has. Once you convert the value, you may have both the original value and a new value of a different type (or just the latter).
I wrote:Also, I think saying that a value "can be a number" is too inaccurate. In some contexts, a string value can be converted to or evaluated as a number.
I think I answered that with
No, you did not answer my question before I asked it.

You seem to be referring to a level of strictness where no implicit conversions are ever performed. That would be at the far end of a spectrum, and it says nothing about how you quantify the degrees of strength. Type systems are complex; merely saying that one system is more or less strongly typed than another is not very meaningful. I could say "yes, v2 is more strongly typed than v1", but that would - or should - only lead to more questions, which you can answer by reading the documentation.
How do you compare a string to a binary value?
The most practical way is to parse the string to produce another binary value, then compare the two binary values, although technically in that case the string value is not being compared. If you want to compare a string to a binary value more directly, you can do it by parsing the string and using modulo on the binary value.
This is what I mean by strong typing (or lack thereof).
I don't think that's what you mean. What you're not saying is what alternative behaviour you might be expecting; it's not about how you compare values of two different types, but whether such a thing is even allowed and what result the attempt will have.

RussF
Posts: 1311
Joined: 05 Aug 2021, 06:36

Re: switch bug

Post by RussF » 30 Oct 2022, 08:37

Thank you again @lexikos, for indulging me. I find this dialog refreshing and educational. Also, please understand that I think AHK is a phenomenal language and you deserve exceptional kudos for your work in maintaining and enhancing it. I use it every day in a production environment and must rely on it, which is why I cannot make the move to v2 until a stable version is released.

All I'm trying to do is point out something that I feel is inconsistent and a potential trouble spot for new users, as evidenced by the post that started this thread. (I struggled with the whole % thing for months before finally understanding it.) We seem to be dancing in circles, however, and you clearly have issue with my use of the term "typing". Perhaps I am using it incorrectly, but I don't know any other way to express what I mean.
lexikos wrote: What you're not saying is what alternative behaviour you might be expecting
Using my example from above:

Code: Select all

x := "1"
y := "2"
a := 1
MsgBox, % x + y     ; result 3
MsgBox, % "1" + "2" ; result 12
MsgBox, % x = 1     ; result True
MsgBox, % x = "1"   ; result True
MsgBox, % x = a     ; result True
MsgBox, % a = "1"   ; result True
MsgBox, % x + a     ; result 2
x and the literal "1" should be identical. Assuming ASCII for simplicity and ignoring any length or string termination bytes, they are (should) be stored in memory identically, as an ASCII character with the value of 0x31.
a and the literal 1 are also identical, stored in memory as 0x01 (assuming a single byte length). The fact that x and "1" have a quantitative value of 1 in our numbering system is irrelevant, they are still a "string" of ASCII characters, just like "a" or "abc". Programmatically evaluating x = 1 and a = "1" as true, in my opinion is wrong, as they have two different binary representations in memory.
lexikos wrote: A string is a string, even if you are able to convert it to something else, implicitly or explicitly.
My point EXACTLY. The fact that AHK implicitly converts it sometimes, but not always, depending on context, can be very confusing. As I stated above, I had to read the docs several times to try and get a handle on when and where these implicit conversions occur. In most other languages, evaluating If x = 1 would produce an error because they are two different types. You would have to use something like If Val(x) = 1, If Val("1") = 1 or If Str(a) = "1", and do the conversion explicitly. Knowing that you HAVE to do the conversion yourself rather than wondering (or looking up) whether you have to, depending on the particular context), is far less confusing to me.

So, we agree that a conversion must take place to compare variables or literals of two different types. When I refer to "strong" or "loose" typing, I mean that in a stronger typed language, you must do that conversion explicitly - every time - consistently, so there is never any question. A looser typing does that conversion for you - sometimes - depending on context - go look it up to be sure when your code breaks. :?

Russ

lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: switch bug

Post by lexikos » 30 Oct 2022, 16:57

RussF wrote:
30 Oct 2022, 08:37
The fact that AHK implicitly converts it sometimes, but not always, depending on context, can be very confusing. As I stated above, I had to read the docs several times to try and get a handle on when and where these implicit conversions occur.
Numeric strings: A string of digits (or any other supported number format) is automatically interpreted as a number when a math operation or comparison requires it.
Have you found any exceptions other than the literal quoted strings, which I have said is specific to v1?

In most other languages, evaluating If x = 1 would produce an error because they are two different types.
In my experience, implicit conversion is very common in scripting languages.
Knowing that you HAVE to do the conversion yourself rather than wondering (or looking up) whether you have to, depending on the particular context), is far less confusing to me.
You won't get the protection from forgetting to do the conversion, but you're free to do it explicitly.
So, we agree that a conversion must take place to compare variables or literals of two different types.
Some interpretation of values must occur for a comparison to take place. As I said, it is possible to interpret the characters of a digit string while also interpreting the decimal places of a binary number and compare the two, without converting one to the other. So I don't think either point is particularly relevant.
When I refer to "strong" or "loose" typing, I mean that in a stronger typed language, you must do that conversion explicitly
I would call that a strongly typed language, which AutoHotkey clearly does not have. There are degrees to everything, so to ask if it is more strongly typed is a different question to whether implicit conversions are allowed.

RussF
Posts: 1311
Joined: 05 Aug 2021, 06:36

Re: switch bug

Post by RussF » 31 Oct 2022, 07:09

lexikos wrote: Have you found any exceptions other than the literal quoted strings, which I have said is specific to v1?
No, not personally. The post that started this thread was what initially brought the issue to my attention. It was new to me, probably because, out of habit, I have always explicitly converted strings when needed and never had any problems.
In my experience, implicit conversion is very common in scripting languages.
While I have been writing BAT and CMD scripts ever since the first IBM PC came out in the early '80s, AHK is pretty much the only other scripting language I have used (unless you want to include interpreted BASIC back in the day). All others are compiled or pseudo-compiled.

Thanks again @lexikos. This has been a great discussion.

Russ

Post Reply

Return to “Ask for Help (v1)”