||= and &&= operators

Discuss the future of the AutoHotkey language
formicant
Posts: 9
Joined: 21 Jan 2018, 21:06

||= and &&= operators

24 Jan 2018, 13:15

A use case:
We don’t know if the object exists and want to initialize it if not.

In 1.1, we have to write:

Code: Select all

if(not objectWhoseExistenceIsQuestionable)
  objectWhoseExistenceIsQuestionable := initialValue
In 2.0a, we can also write:

Code: Select all

objectWhoseExistenceIsQuestionable := objectWhoseExistenceIsQuestionable || initialValue
I think it would be nice to be able to write like that:

Code: Select all

objectWhoseExistenceIsQuestionable ||= initialValue
formicant
Posts: 9
Joined: 21 Jan 2018, 21:06

Re: ||= and &&= operators

25 Jan 2018, 04:29

(…or should I post this to the Wish List section?)
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: ||= and &&= operators

25 Jan 2018, 04:37

What would &&= do? :think:

Cheers.
formicant
Posts: 9
Joined: 21 Jan 2018, 21:06

Re: ||= and &&= operators

25 Jan 2018, 09:45

Helgef wrote:What would &&= do? :think:
Obviously, a &&= b should be equivalent to a := a && b.

E.g.

Code: Select all

totalSuccess := true
for index, item in items
{
  itemSuccess := Process(item)
  totalSuccess &&= itemSuccess
}

MsgBox(totalSuccess
  ? "All items processed successfully"
  : "Some items processed with errors")
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ||= and &&= operators

25 Jan 2018, 10:27

Code: Select all

a &&= b ;proposal
a := a && b

a &= !!b ;where a is known to be 1 or 0 ;workaround
a := a & !!b ;where a is known to be 1 or 0
Good enough?
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
formicant
Posts: 9
Joined: 21 Jan 2018, 21:06

Re: ||= and &&= operators

26 Jan 2018, 10:11

jeeswg wrote:

Code: Select all

a := a && b
Reads well when the first argument is short.
But, for example, in the actual code I’m writing, I had to write:
this.Layouts[layout.Level] := this.Layouts[layout.Level] || { }
and
this.Combinations[combinator][length] := this.Combinations[combinator][length] || new Dictionary

Isn’t the purpose of +=, *=, .= etc operators to avoid such long constructions? So why not ||=?
jeeswg wrote:

Code: Select all

a &= !!b ;where a is known to be 1 or 0 ;workaround
Looks cryptic and strange.
The a |= !!b construction cannot be used for initialization like above.
jeeswg wrote:

Code: Select all

a := a & !!b ;where a is known to be 1 or 0
Combines the disadvantages of the two methods above.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: ||= and &&= operators

26 Jan 2018, 20:24

So why not ||=?
Implementation difficulty vs. rarity and suitability of use.

&& and || use short-circuit evaluation, and therefore do not work like any other binary operator. All of the current compound assignments are a simple case of flagging the operation as an assignment and then handling it as its sub-operation (add, subtract, whatever). At least for assignment to a variable.

Objects are supported through pre-processing and trickery to avoid evaluating the sub-expressions more than once. The expression this.Combinations[combinator][length] += 1 is effectively broken up into sub-expressions this.Combinations[combinator], length, 1. These are converted to postfix tokens which, when evaluated, leave three values on the stack (the object, length, 1). Then comes the trickery, which is like this:
  • After the first two sub-expressions, insert GET-IN-PLACE(2). When executed, this takes the 2 top-most values on the stack (the object and length), retrieves the property's current value, but leaves both values on the stack along with the new value.
  • After the third sub-expression, insert ADD(2) and SET(3).
&& and || require more work in both cases, to support short-circuit evaluation. They are essentially unary postfix operators which perform a conditional jump. If the first operand satisfies the short-circuit condition, it is pushed back onto the stack and the jump is performed. Otherwise, the remainder of the expression is evaluated.

I suppose that x[y] ||= z should not be equivalent to x[y] := x[y] || z:
  • x and y should be evaluated only once (as for current compound assignment operators).
  • Perhaps the assignment should not be performed if the current value satisfies the short-circuit condition. In other words, x[y] || (x[y] := z).
Also, ||= is not 100% suitable for its apparent purpose, since a defined value of zero will be treated the same as an undefined value. What you really want is a null-coalescing compound assignment.

Return to “AutoHotkey Development”

Who is online

Users browsing this forum: No registered users and 50 guests