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

I don't see the point of making this complicated by making it context sensitive.

I tried to express the reason in my posts above. I guess I wasn't clear enough.

Having a context sensitive = operator is worse than what we have got now.

I'm surprised you feel that way given what I wrote in the last paragraph of my post above. But maybe you're thinking only of your point-of-view, not that of the infamous "typical user".

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?

=== is not even under consideration here. It's off-topic, so I'll count your vote as a vote for the C-style (though I can't easily move your vote).

Thanks.

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

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.

:?:
Again, I don't see a good reason to want to do an assignment in a test!
I mean, "saving one line of code" isn't a good reason for me! :-)
And, perhaps I misunderstand you, but this functionality doesn't exist in v.1.
:shock: I tested, it works! In 1.0.46... I suppose the relevant changelog line is: "Added assignment operators //=, .=, |=, &=, ^=, >>=, and <<=, which can be used anywhere in expressions. For example, Var .= "abc" appends the string "abc" to the end of Var's current contents." Argh!
Oh well, I still think that's a bad idea and a source of bugs, but some people will be happy with that. Or we silently remove this "feature" in next update, before anybody uses it! ;-)

[Multiple assignment idea] 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.

I prefer using different symbols anyway.

[use := as assignment and = as comparison] 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 :=

Why? As long as we drop = as assignment, there is little ambiguity.
a := b
If a = b
; Even
a := b = x
; And if you want:
a := b := x
; and at "worse"
If a := b = "foo"

Seems OK for me, but I might misunderstand something.
The last line, in my mind, is assigning b to a then comparing the result (B) to foo, but it depends on priorities.
OK, I tested, you did the reverse, first comparison, then assignment... Why not. At least it is consistent with a := b = x line.
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

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

Or we silently remove this [if var := value] "feature" in next update, before anybody uses it! ;-)

I would use this method myself and I know others use it. I think it's good to keep it because it can improve performance (though I realize performance isn't a concern in most real-world scripts).

As long as we drop = as assignment, there is little ambiguity.

So you're proposing that a line consisting simply of x = 1 would be a syntax error? Or should it be simply ignored as a do-nothing comparison (i.e. one whose result is not used and thus discarded)?

Overall, I'm a bit baffled by some of the responses in this topic so far. I thought it was pretty clear that a line like x = func() should perform an assignment in v2.

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
Oh cmon, just use the C syntax. Drop the :=.

I hate when I switch to C and continue to write := cuz of AHK :D 8)


I thought it was pretty clear that a line like x = func() should perform an assignment in v2.

It was, but it was not clear if comparison will use this symbol.

I think that foo is right.
= to assign, == to compare [OT] and === to strict compare :D [/OT]


Amen to that ! Posted Image
Posted Image

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

I think that foo is right.

So do I, JSLover said something along the same lines as well.

autohotkey.com/net Site Manager

 

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


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

Having a context sensitive = operator is worse than what we have got now.

I'm surprised you feel that way given what I wrote in the last paragraph of my post above. But maybe you're thinking only of your point-of-view, not that of the infamous "typical user".

Having to recognise a single operator is easier than having to check the relation of the operator to the rest of the expression. Do you agree?

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?

=== is not even under consideration here. It's off-topic, so I'll count your vote as a vote for the C-style (though I can't easily move your vote).

It's relevant to what i wrote which is relevant to the topic.

Chris i have the feeling that you take everything that i say a some offence against you. This truely not my intention. Its just the lack of english skills that prevents my post from being more polite. :D

Dont take this as an offence. But can it be that your against == ( well your not against it but you'd prefer =) because it would need to review the manual thoroughly to change any references from = to ==? I can totaly understand you if this is the case since that work would be donkeywork i would not want to have to do.

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

I thought it was pretty clear that a line like x = func() should perform an assignment in v2.

I am open to all solutions, including the C style. I don't like the idea that the same operator can do an assignment in some context and a comparison in other context. That's the kind of duality that drives newbies mad! :-)
So basically, we have either:
a = b ; Assignment
If a = b ; Assignment and test
If a = (b == "foo") ; Assignment and test
If a == b ; Pure test

or
a := b ; Assignment
If a := b ; Assignment and test
If a := (b = "foo") ; Assignment and test
If a = b ; Pure test

First form is close of current syntax. Somehow, it is also consistent with += .= <<= and so on.
Second form pleases C-like syntax lovers... It comes with the old risk of subtle bugs found in many C programs, the dreaded if (a = B) in place of if (a == B).
One of the reasons why I don't like this feature.
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

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

Having to recognise a single operator is easier than having to check the relation of the operator to the rest of the expression. Do you agree?

If you mean from a user point-of-view (not a parsing point-of-view), then "No" -- for reasons I tried to explain in my previous posts.

Dont take this as an offence. But can it be that your against == ( well your not against it but you'd prefer =)

I get the feeling you haven't read my other posts here completely. If you had, it should be pretty obvious that I'm in favor of the dual-purpose equal-sign operator. I'm certainly not in favor of the C method for the reason I mentioned previously.

because it would need to review the manual thoroughly to change any references from = to ==?

That thought hadn't even occurred to me. However, I realize that regardless of what changes are made in v2, all the examples in the help file will need to be reviewed and updated.

Thanks.

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

I don't like the idea that the same operator can do an assignment in some context and a comparison in other context.

Yes, but the crux is that there's no perfect solution. We're trying to decide on the lesser evil here.

1) The current method is "evil" because novices and veterans alike frequently use = when they'd intended :=.

2) The new/proposed method is evil because it has ambiguities:
x = y ; Assignment.
if x = y ; Comparison
x = y = z ; First is assignment, second is comparison.

3) Switching to a pure-C syntax (in which = is always an assignment, never a comparison) is evil because it probably does far more harm than good to users who have no C-like experience. This is because there would be countless times when such users would write if x = 3 when they'd intended to write if x == 3

It's my contention that the second method is considerably less evil (on average) than the other two.

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
Let see...
a := b ; Assignment
a := b := c ; Double assignment
a := b = c ; Assignment of result of test
a = b ; Raise an error, as it does nothing (comparison)
If a := b ; Assignment and test
If a := (b = "foo") ; Test, assignment of result of test and test
If a = b ; Pure test
If a := b and a := a + c or a -= d ; What will be the value of a? One reason why I find this syntax evil...
When I add the error on useless comparison, I no longer see any confusion or possible bug. People will pest on start to get an error on the face, then will get used to do :=. And since current users are already used to it, well all is nice and smooth. :-)
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

I get the feeling you haven't read my other posts here completely. If you had, it should be pretty obvious that I'm in favor of the dual-purpose equal-sign operator. I'm certainly not in favor of the C method for the reason I mentioned previously.

The same as you in number of situations Chris, don't blame the man for lack of time, we all make those mistakes, together with all power users on this forum.

If a := b and a := a + c or a -= d ; What will be the value of a? One reason why I find this syntax evil...

The responsibility of code writter is not to write the stupid code.
n00b will certanly not write like that.

I vote for your examples to be added to Chris notes :D
Posted Image

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

If a := b and a := a + c or a -= d

It's evaluated strictly according to precedence and associativity, so there's no ambiguity.

My whole intent with this topic is to choose the syntax that maximizes people's productivity when scripting, while minimizing the number of bugs and surprises. So further comments are welcome, especially concerning the original/top post in this topic and the poll options.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
The C style is quite similar to the dual-purpose proposal because:

1) Both see x = y as an assignment
2) Both see x == y as a comparison (though dual-purpose sees it as case-sensitive, which is seldom an issue)

One of the few differences is when you want to use the result of an assignment for some other operation. In that case:
if not (var = func()) ; C style.
if not (var := func()) ; Current and new/proposed.

So if you like the C method, the dual-purpose method seems nearly identical for the most common uses. If true, the choice between these two isn't such an issue -- unless anyone sees serious practical drawbacks to the dual-purpose equal-sign (I haven't heard any yet other than purist/theoretical concerns).

I mention this because I think it would be a serious mistake to release a v2 in which if x = y is an assignment. This would be a disservice to the 80% of users who have no C-like experience, causing them a lot of bugs and trouble.

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
First and most important of all!

x = y = z

This should always always always be two separate assignments. First, y = z. Then x = y, which is then equivalent to x = z. My intuition won't allow for anything else, and I think it would be the same way without my experience in C-esque languages. So, the first order of business is that any method, new or old, that changes this behavior is right out.

Secondly.

x = (y = z)

Ordinarily I would rant just as vicariously for this case. However, this is AHK, and in AHK I'm used to parentheses denoting an expression. Therefore, since I took the trouble to explicitly say "Hey, this is an expression," AHK should say "Okay," and do an expressiony thing: compare. If that's what you wanted to do anyway, you wouldn't write it looking like consecutive assignments... that would be incredibly confusing, both to code and to read.

What it all boils down to is this. When it's obviously an assignment - which almost always means it's the leftmost operator in an otherwise ambiguous expression - then it should assign. When it's in a cleary denoted expression (parens, if statements), it should compare.

In addition, It'd be nice if we could eliminate non-delimited string assignments with '=', and make them all expression assignments. For instance, this should assign the contents of variable "b" to variable "a", not the string "b".

a = b


Finally, I think that the distinction between '=' and '==' is very clear and intuitive. I never understood the whole issue about bugs and such because I never had a problem with them myself. However, I also think that, for someone who has never glimpsed a C textbook but needs a powerful automation tool, it would be a bit vague, or at least awkward. It makes sense to say:

If a = b

Humans are smart enough to figure things like this out from context. I think the old syntax should remain, with the only change being from strings to expressions as mentioned earlier.


Anywho, that's my two (or three) cents. If I made any grave errors of the logical variety, please call to attention my stupidity. Thank you.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
I voted for assignments done always with ":=", as in ALGOL and its derivatives. It is an endless source of coding errors if an operator means different things in different contexts, so I dislike "=" for both comparison and assignment.

"=" for case insensitive string compare, and "==" for case sensitive compare is nice, but not sufficient, because there are no similar constructs for <, >, etc.: at case sensitive compare "B" < "a", at case insensitive compare "B" > "a". It would be better to have two versions for every string comparison operator. Something like #=, #<, ... In this case we don't need "==". (But this case sensitivity is also problematic: it depends on the language, the code page, the default font, etc. A script behaves differently in different countries.)

Having "#=" one can use "==" for general comparison, and so "=" can be always used as assignment. Still, there will be many errors in scripts, like "if (a=B)...", "a=b ?..." where a will be assigned the value of b, which determines the branch of the if. In the ALGOL like syntax the corresponding error is "x = y", meant for assignment, which is much easier to spot (can be a syntax error).

An assignment has a value (which is assigned), so
x := y := z
is clear: y <- z, x <-z.

It has to be consistent with
x := y += 1
Here y <- y+1 and this value is also assigned to x.

x := y = z
is also unambiguous: x gets the result of the comparison of y and z.
x := y = z := a
This depends on the priority of the operations. Normally ":=" has the lowest priority, and so this line is in error, although it could be interpreted the same as x := y = (z := a), y is compared to the value of z := a, which is a. The result of the comparison of y and a is assigned to x.