On 4/13/07, Daniel Silverstone <dsilvers@digital-scurf.org> wrote:
> Erm, plus and plus-equals are intrinsically different operations.
>
> a = a + b
>
> => a = add(a, b)
>
> a += b
>
> => a:increment(b)
...
> What you see as a convenient shorthand for a = a + b, I see as an
> incredibly scattered minefield of doom where conflation between mutation
> and simple arithmetic will cause terrible pain for all those who enter
> it.
Drastic words, but I absolutely agree.
This could be my C/C++ origins shining through, but operators like +=
sure appear to suggest in-place modification. That is, the code "A +=
B" looks like it's saying "do something to A with B", not "create a
new object from A and B, and rebind A to it".
In-place modification make sense to me in languages where variables
primarily *store* objects, but when variables simply refer to objects,
things get murkier. For example, Python has operator +=, which is
allowed, but not required, to modify the original object. (Indeed the
original object might be immutable, and so can't be incremented
in-place.) This causes confusion:
>>> a1, b1 = 1, ['a']
>>> a2, b2 = a1, b1
>>> a2 += 1
>>> b2 += ['b']
>>> print a1
1
>>> print b1
['a', 'b']
So now coders have to understand why b1 has changed but a1 hasn't.
(IMO, maybe this is less bad in Python, a language which makes lots of
inelegant but pragmatic choices. Lua has a Scheme-like elegance,
which would be sullied by this sort of confusion.)
One way around this is, as Glenn Maynard suggests, to make "A += B" be
pure syntactic sugar for "A = A + B". But I dislike this for a couple
of reasons. One is that += sure seems to suggest in-place mutation
(though as I said, this could be a C++ bias). In the past, users have
asked on this list how to override assignment. This reflects a
misunderstanding of how variables work, but it seems more likely that
people will want to override +=, and will be disappointed by the
answer.
Another problem is, even if += is purely sugar, the rules involved are
more complicated than a first glance suggests. What does the
following mean?
foo().x, bar.y.z, baz += a, b, c
Certainly the coder doesn't expect foo() to be called twice.
Likewise, if bar is a proxy table with side effects, you probably
don't want y to be read twice. So what we really want is for the
above to behave like:
do
local _1 = foo()
local _2 = bar.y
_1.x, _2.z, baz = _1.x + a, _2.z + b, baz + c
end
And I don't think there's anything *intrinsically* wrong with that
sort of syntactic sugar. But Lua is such a beautiful, small language,
and because of that, I don't think saving the few extra characters
typed in "value = value + 1" is anywhere near worth the complexity.
Greg F