Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

v2 Issue: Equal sign (=) used to both assign and compare


  • Please log in to reply
119 replies to this topic

Poll: How should equal-sign (=) and colon-equals (:=) work in v2? (46 member(s) have cast votes)

How should equal-sign (=) and colon-equals (:=) work in v2?

  1. Leave it like v1: Colon-equals (:=) is an assignment and equals (=) is always a comparison. (16 votes [34.04%])

    Percentage of vote: 34.04%

  2. Make equal-sign (=) dual-purpose: it assigns an expression or performs a comparison, depending on context. (3 votes [6.38%])

    Percentage of vote: 6.38%

  3. Switch to the C style of using = only for assignments (never for comparisons). Double-equals (==) would compare for equality. (26 votes [55.32%])

    Percentage of vote: 55.32%

  4. Other (2 votes [4.26%])

    Percentage of vote: 4.26%

Vote Guests cannot vote
Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Not many users of C-like languages would deny that using double-equals (==) vs. single-equals (=) for comparisons is a common source of bugs. The current plan for AutoHotkey v2 is to avoid that problem by having single-equals (=) be used for both assignments and comparisons (depending on context). However, that introduces new problems in the form of ambiguities. For example:
x = y [color=red]=[/color] z  ; The second [color=red]=[/color] is ambiguous. Current plan is to treat both as assignments.
x = (y [color=red]=[/color] z)  ; Current plan is to treat the rightmost one as a comparison.
x [color=red]:=[/color] y [color=red]=[/color] z  ; Current plan is to treat the rightmost one as a comparison.
func(x [color=red]=[/color] 2)  ; Current plan is to treat it as a comparison.
x [color=red]=[/color] IsDone ? func() : y:=1  ; Current plan is to treat it as an assignment.
In conjunction with the plans in the comments above, := would continue in its role as an assignment operator in v2. This is necessary to eliminate ambiguity, but more importantly to allow assignments in places that would otherwise be comparisons such as: if Var := func()

Comments are welcome on any of the above, especially the code examples. Can you think of any other ambiguities? If more are found, it could sway the decision to some other alternative.

The main alternative to all of this is to switch over to a complete C-like syntax where = is always an assignment (never a comparison). In that case, == would be used for comparisons, and a new operator would be needed for case-sensitive comparisons. But due to it being mildly counterintuitive (especially to those without any C-like experience), this cure seems worse than the disease.

It should also be mentioned that users can practice one of the following rules to avoid most ambiguity:
1) Always use := for assignments and = or == for comparisons.
2) Always use = for assignments and == for comparisons (but this wouldn't eliminate all ambiguities, just some).

Comments are welcome. Now is the time to say something if you see a better approach.

foom
  • Members
  • 386 posts
  • Last active: Jul 04 2007 04:53 PM
  • Joined: 19 Apr 2006

2) Always use = for assignments and == for comparisons (but this wouldn't eliminate all ambiguities, just some).

Can you tell what ambiguities you are talking about?
I' would like to know what your plans are on naked string assigment. E.g. what var = thisisastring is now.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004

But due to it being mildly counterintuitive (especially to those without any C-like experience), this cure seems worse than the disease.

...or for those that don't use C-like languages when possible specifically because of a dislike of the use of this style of syntax...

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005

For example:

x = y [color=red]=[/color] z  ; The second [color=red]=[/color] is ambiguous. Current plan is to treat both as assignments.
x = (y [color=red]=[/color] z)  ; Current plan is to treat the rightmost one as a comparison.
x [color=red]:=[/color] y [color=red]=[/color] z  ; Current plan is to treat the rightmost one as a comparison.
func(x [color=red]=[/color] 2)  ; Current plan is to treat it as a comparison.
x [color=red]=[/color] IsDone ? func() : y:=1  ; Current plan is to treat it as an assignment.

Chris, If you change the first line to assume that the first = is assignment and the second is comparison, then your parsing should be easier. The first = in a line is always assignment, unless it's in a function call. Also, the first form is amibiguous as-is.

x = 1
y = 2
z = 3

x = y = z
MsgBox, x=%x% y=%y% z=%z%  ;what do you expect here?
If both = are assigning:
Option 1: x=3 y=3 z=3 (assignments occur from right to left (y=z, z=y))
Option 2: x=2 y=3 z=3 (assignments occur from left to right (x=y, y=z))
Option 3: x=y y=z z=3 (assignments occur from right to left (y=z, z=y, literal strings))
Option 4: x=y=z y=2 z=3 (assignments occur from left to right (x=y, y=z, literal strings))

x := y = z
MsgBox, x=%x% y=%y% z=%z%  ;what do you expect here?
Option 1: x=3 y=3 z=3 (assignments occur R->L, second = is assignment)
Option 2: x=0 y=2 z=3 (assignments occur R->L, second = is omparison)
Option 3: x=0 y=2 z=3 (assignments occur L->R, second = is omparison)

I think we agree that x := y = z should store the compare result in x

I think x = y = z should store 'y = z' as text in x

I think x := y := z is hard to define
1) store value of z in x and y
2) store value of y in x then value of z in y
3) store 1 (true) in x and value of z in y


Now my head hurts

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

Can you tell what ambiguities you are talking about?

The ones in the code section of my topmost post above.

I' would like to know what your plans are on naked string assigment. E.g. what var = thisisastring is now.

I think that will be covered in a future topic, but it will probably be some new operator such as the << that PhiLho proposed. I think it's best if this topic is kept focused on the equal-sign decision because I think it's important.

I think x = y = z should store 'y = z' as text in x

No, because one of the main focuses of v2 is to eliminate the use of equal-sign as a old-style operator that accepts unquoted literal strings.

If you change [x = y = z] to assume that the first = is assignment and the second is comparison, then your parsing should be easier.

I'm not too concerned about parsing (I think that is solved anyway). I want to provide good default behavior that reduces bugs in scripts caused by misunderstandings of the operators.

Also, the first form is amibiguous as-is.

The whole point of this topic is ambiguity! :) I want to resolve the ambiguity by choosing the defaults that are the most intuitive.

x = y = z

This would be a pair of assignments. And since assignments occur in right to left order (as already documented), y is assigned z, and then x is assigned y. In effect, both x and y take on the value of z.

I think we agree that x := y = z should store the compare result in x

Yes, though contrary opinions are welcome.

I think x := y := z is hard to define

That one already functions as it should in v1.0.46+. If you want details, check out the assignments section of the operator table.

Finally, this topic exists to ensure that v2's design isn't flawed before it's even developed. So if anyone has an interest in how equal-sign should work, now is the time to think about it and offer advice.

JSLover
  • Members
  • 920 posts
  • Last active: Nov 02 2012 09:54 PM
  • Joined: 20 Dec 2004

Not many users of C-like languages would deny...

...I figured you'd be saying the opposite...that users of C-like languages expect = to assign & == to compare...sure there are bugs if you mix them up...but once you finally get double equals is compare it's soo much clearer...

The current plan for AutoHotkey v2 is to avoid that problem by having single-equals (=) be used for both assignments and comparsions (depending on context).

...again this post confuses me...you're announcing nothing is changing...

...:= would continue in its role as an assignment operator in v2. This is necessary ... to allow assignments in places that would otherwise be comparisons such as: if Var := func()

...on the contrary...if = is assign & == is comparison...just support if var=func() to mean the same as your example...assign...

Can you think of any other ambiguities?

...with = being assign & == being compare...I see no ambiguities...

...and a new operator would be needed for case-sensitive comparisons.

...well I dunno about case-sensitive, but === should be a "strict type check"...like JavaScript...in the future you might implement types of vars...like number or string...or array...so...

;//number...
a=1

;//string...
b="1"

;//would return true...
if (a==b)
	msgbox, yup

;//would return false...same number but different type...
if (a===b)
	msgbox, nope
...perhaps case-sensitive would be done with RegExMatch...or something...or support perl ~= (or =~ whatever it is)...as a quickie regex match...like perl...so you can do case-sensitive or insensitive...like...

;//right side is regex...returns true...case-insensitive
if "blah"~="i)BLAH"
	msgbox, yup

;//returns false...case-sensitive
if "blah"~="BLAH"
	msgbox, nope

;//again I don't know if the perl op is ~= or =~
if "blah"=~"i)BLAH"
	msgbox, yup

...this cure seems worse than the disease.

...this "cure" seems fine...& expected...= should never have been compare...if AHKers ever try C or JavaScript they would be alarmed that what they learned in AHK don't work...so changing now would help then learn better coding...

2) Always use = for assignments and == for comparisons (but this wouldn't eliminate all ambiguities, just some).

...on the contrary...it would eliminate all ambiguities...

;//The second = is NOT ambiguous. It is assignment...
x=y=z

;//The second operator is NOT ambiguous. It is comparison...x is true if y equals z
x=y==z

;//parens shouldn't alter the outcome (compare vs assign) other than evaluation order...this would force y to equal z, then x equals the result...or the same as without parens...
x=(y=z)

;//this should be the same as x=y=z
x:=y=z

;//assign x value 2 & call func with value of x
func(x=2)

;//call func with true/false after comparison
func(x==2)

;//yeah I guess, assignment...if the new = is like :=
x=IsDone?func():y:=1

;//but shouldn't this work too?...y=1 not just need y:=1
x=IsDone?func():y=1

Useful forum links: New content since: Last visitPast weekPast 2 weeks (links will show YOUR posts, not mine)

OMFG, the AutoHotkey forum is IP.board now (yuck!)...I may not be able to continue coming here (& I love AutoHotkey)...I liked phpBB, but not this...ugh...

Note...
I may not reply to any topics (specifically ones I was previously involved in), mostly cuz I can't find the ones I replied to, to continue helping, but also just cuz I can't stand the new forum...phpBB was soo perfect. This is 100% the opposite of "perfect".

I also semi-plan to start my own, phpBB-based AutoHotkey forum (or take over the old one, if he'll let me)
PM me if you're interested in a new phpBB-based forum (I need to know if anyone would use it)
How (or why) did they create the Neil Armstrong memorial site (neilarmstronginfo.com) BEFORE he died?

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Your post above is based on the incorrect assumption that the C-like behavior of having = always be an assignment (never a comparison) is under serious consideration. It is not -- unless someone thinks it would win in a poll.

The proposal here is to make single-equal-sign become both assignment and comparison, depending on context. With this in mind, hopefully the topmost post in this topic makes more sense now.

...well I dunno about case-sensitive, but === should be a "strict type check"...like JavaScript...in the future you might implement types of vars...like number or string...or array...so...

Although I don't think it should be something put into v2, I've added it to my notes for future consideration. Thanks.

...perhaps case-sensitive would be done with RegExMatch...or something...or support perl ~= (or =~ whatever it is)...as a quickie regex match...like perl...so you can do case-sensitive or insensitive...like...

This is a good idea in the unlikely event that the majority prefers the C method.

Thanks.

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
Frankly, I overlooked most of the answers... I know that JSLover wants JS-like syntax, ie. C-like syntax.

Back to the first post: I propose to drop entirely :=, or just keep it as a legacy equivalent to assignment =.
If we want simplicity, I propose to drop the multiple assignment syntax idea. Thus, we have a very consistent behavior: only the leftmost = sign (outside function calls, of course), is an assignment. Everywhere else, it is a comparison sign.
The x = y = z as assignment idea is bad, although convenient. Bad because it would introduce yet-another-exception-to-memorize and more newbies ask for help asking why it doesn't work as expected...
So in my idea, x = y = z would be the same as x = (y = z).

Now, I am not totally against using a different symbol for assignment and comparison, as it would apply better the rule "one symbol for one function". Hey, it can be to use := as assignment and = as comparison, consistent with current behavior, less change to remember...
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006

Hey, it can be to use := as assignment and = as comparison, consistent with current behavior, less change to remember...

My idea too.
Posted Image

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

The main alternative to all of this is to switch over to a complete C-like syntax where = is always an assignment (never a comparison). In that case, == would be used for comparisons, and a new operator would be needed for case-sensitive comparisons.

I prefer this. The case sensitivity of == could depend on StringCaseSense.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005

The case sensitivity of == could depend on StringCaseSense.

Oh not! I dislike a lot those global switches, very cumbersome to use! To be clean, we have to save current state, set it the way we want, do the test, restore the state somewhere... Argh!
Of course, one can set the case sensitivity always on and use StrLower() function to do case-insensitive comparison, like it is done in most languages... Hum, the above function must be implemented, of course...
StrLower or LowStr? Or DownCaseStr? :-)
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

Of course, one can set the case sensitivity always on and use StrLower() function to do case-insensitive comparison, like it is done in most languages...

Yeah good idea, but it should be called toLowerCase() like javascript.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


JSLover
  • Members
  • 920 posts
  • Last active: Nov 02 2012 09:54 PM
  • Joined: 20 Dec 2004

I know that JSLover wants JS-like syntax...

...hehehe...I'm not sure you care...but JSLover is not short for JavaScript Lover...although that fits too...

I propose to drop entirely :=, or just keep it as a legacy equivalent to assignment =.

...that sounds good...

If we want simplicity, I propose to drop the multiple assignment syntax idea.

...nope...bad...(don't drop it...bad = bad idea to drop it)...

The x = y = z as assignment idea is bad, although convenient.

...no it's not...this way you always KNOW = assigns...

So in my idea, x = y = z would be the same as x = (y = z).

...you're example is misleading cuz you don't state what that outcome means to you...to me those expressions ARE the same, but in the end x, y & z all equal z...what you meant (I think) was x holds true/false based on whether or not y is equal to z...a comparison...but in my book parens only say which order stuff happens...it doesn't change an assign to a compare...

Now, I am not totally against...

...good this is the best option...

Hey, it can be to use := as assignment and = as comparison...

...ok I'm not totally against that, but I, like Titan, still like = meaning assign & == meaning compare...

The case sensitivity of == could depend on StringCaseSense.

Oh not! I dislike a lot those global switches, very cumbersome to use!

...shockingly I'm with PhiLho on this...auto-execute modifying settings, when used in functions...actually stay set...unless you undo you're mess...very annoying...I wish functions were like subroutines...they would reset the defaults when they finish...anyone have any comments about ~= (or =~) being a quickie RegExMatch???...regex could solve the case problem...

Yeah good idea, but it should be called toLowerCase() like javascript.

...evil Titan...suggesting that nasty JavaScript language again...don't you know PhiLho will flog you?...lol...(<--- hi that was just kidding...I love JS! {& the other JS})...however I might flog you for not capping JavaScript right...& that's not kidding!...
Useful forum links: New content since: Last visitPast weekPast 2 weeks (links will show YOUR posts, not mine)

OMFG, the AutoHotkey forum is IP.board now (yuck!)...I may not be able to continue coming here (& I love AutoHotkey)...I liked phpBB, but not this...ugh...

Note...
I may not reply to any topics (specifically ones I was previously involved in), mostly cuz I can't find the ones I replied to, to continue helping, but also just cuz I can't stand the new forum...phpBB was soo perfect. This is 100% the opposite of "perfect".

I also semi-plan to start my own, phpBB-based AutoHotkey forum (or take over the old one, if he'll let me)
PM me if you're interested in a new phpBB-based forum (I need to know if anyone would use it)
How (or why) did they create the Neil Armstrong memorial site (neilarmstronginfo.com) BEFORE he died?

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

I propose to drop entirely :=, or just keep it as a legacy equivalent to assignment =.

It can't be dropped for the reason mentioned in the top post: there needs to be some way to perform an assignment inside an expression such as: if var := func(). Otherwise, v2 would be dropping functionality already present in v1.

If we want simplicity, I propose to drop the multiple assignment syntax idea. Thus, we have a very consistent behavior: only the leftmost = sign (outside function calls, of course), is an assignment. Everywhere else, it is a comparison sign.
...
The x = y = z as assignment idea is bad, although convenient. Bad because it would introduce yet-another-exception-to-memorize and more newbies ask for help asking why it doesn't work as expected...

To me it seems the opposite. I think more people would expect x=y=z to be all assignments, not comparisons. If so, users who use such assignment methods in other languages would have to memorize an exception to the principle of least surprise. On the other hand, your idea simplifies the rule (due to less exceptions), making it easier to memorize. It would also be easier to implement.

Now, I am not totally against using a different symbol for assignment and comparison, as it would apply better the rule "one symbol for one function". Hey, it can be to use := as assignment and = as comparison, consistent with current behavior, less change to remember...

Good point; but it would void a large part of the reason for having v2. So maybe we should just stick with v1 and put up with endless bugs of users (novices and veterans alike) using = when they intended to use :=

I prefer [the C method of = and ==]. The case sensitivity of == could depend on StringCaseSense.

If that were done, I suspect we'd have many users, especially those without any C-like background (which is probably above 80%), making mistakes such as if (var = 3) and wondering why the statement is always true. In fact, that single change could create more script bugs and confusion than the current problem of accidentally using = when := was intended.

However, I've set up a poll in case the majority feels that the C method should be used.

Thanks.

foom
  • Members
  • 386 posts
  • Last active: Jul 04 2007 04:53 PM
  • Joined: 19 Apr 2006
I don't see the point of making this complicated by making it context sensitive.
= for assignment,
== for equality check,
=== for strict equality check(case sensitive),
and there are no more ambigiuties and you can drop :=.
Having a context sensitive = operator is worse than what we have got now.

Btw: i voted for "Other" because of the ===. If this counts to c syntax, can you please(if this is posible) tansfer my "Other" vote to a "C syntax" vote?