This page is no longer maintained — Please continue to the home page at www.scala-lang.org

+=: Compiler magic?

7 replies
Philipp Dörfler
Joined: 2010-05-24,
User offline. Last seen 42 years 45 weeks ago.
Greetings,

I've stumpled upon the method += of scala.collection.immutable.Set lately and wondered why that's even possible:
scala> var meep = Set(1)
meep: scala.collection.immutable.Set[Int] = Set(1)

scala> meep += 2

scala> meep
res3: scala.collection.immutable.Set[Int] = Set(1, 2)
(Scala 2.8.1)
Is there some kind of compiler magic involved? I'd be interested in knowing what's going on there in greater detail.
I wasn't able to find that method in the scaladoc, either.

Kind regards
--
~ Philipp
Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: +=: Compiler magic?

On Saturday November 20 2010, Philipp Dörfler wrote:
> Greetings,
>
> I've stumpled upon the method += of scala.collection.immutable.Set
> lately and wondered why that's even possible:
>
> scala> var meep = Set(1)
> meep: scala.collection.immutable.Set[Int] = Set(1)
>
> scala> meep += 2
>
> scala> meep
> res3: scala.collection.immutable.Set[Int] = Set(1, 2)
>
> (Scala 2.8.1)
> Is there some kind of compiler magic involved? I'd be interested in
> knowing what's going on there in greater detail.
> I wasn't able to find that method in the scaladoc, either.

You do know magic does not exist, right?

Anyway, when an an expression of the form = is
encountered AND the statically known type of the variable does
not supply the operator = but _does_ supply AND its result
type is compatible with that of AND when is the name of a
mutable variable (one declared with "var"), then the compiler simulates
the = by computing and assigning the result to
.

Someone who knows where an implicit converstion applicable to the type
of supplies = precludes this "magic" will have to say so. Or
you can devise a test to determine whether it's so. I'm insufficiently
caffeinated right now (translation: I'm too lazy).

> Kind regards

Randall Schulz

Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: +=: Compiler magic?

while += exists as a method in collection.mutable.Set, it does _not_ exist in collection.immutable.Set. the compiler treats the call specially: if no corresponding method for a call ending in = is found, a x= b is retried as a = a x b, so in your case since meep is variable, you are re-assigning the result of meep + 2 to meep. this way you can exchange code from

val meep = collection.mutable.Set(1)
meep += 2 // += is a method

with

var meep = collection.immutable.Set(1)
meep += 2 // expands to meep = meep + 1

that is to say, you can often just change the first lines in both cases while the rest of the body remains unchanged.

best, -sciss-

Am 20.11.2010 um 14:41 schrieb Philipp Dörfler:

> Greetings,
>
> I've stumpled upon the method += of scala.collection.immutable.Set lately and wondered why that's even possible:
> scala> var meep = Set(1)
> meep: scala.collection.immutable.Set[Int] = Set(1)
>
>
> scala> meep += 2
>
> scala> meep
> res3: scala.collection.immutable.Set[Int] = Set(1, 2)
>
> (Scala 2.8.1)
> Is there some kind of compiler magic involved? I'd be interested in knowing what's going on there in greater detail.
> I wasn't able to find that method in the scaladoc, either.
>
> Kind regards

Philipp Dörfler
Joined: 2010-05-24,
User offline. Last seen 42 years 45 weeks ago.
Re: +=: Compiler magic?


2010/11/20 Randall R Schulz <rschulz [at] sonic [dot] net>
You do know magic does not exist, right?
Haha, good one!
 
Anyway, when an an expression of the form <name> <op>= <value> is
encountered AND the statically known type of the variable <name> does
not supply the operator <op>= but _does_ supply <op> AND its result
type is compatible with that of <name> AND when <name> is the name of a
mutable variable (one declared with "var"), then the compiler simulates
the <op>= by computing <name> <op> <value> and assigning the result to
<name>.
Which ultimately means that one can use this mechanism for one's own needs... That's awesome!
 
Someone who knows where an implicit converstion applicable to the type
of <name> supplies <op>= precludes this "magic" will have to say so. Or
you can devise a test to determine whether it's so. I'm insufficiently
caffeinated right now (translation: I'm too lazy).
That would have to be in scala.Predef (or it's parent class) then, wouldn't it?
A brief look of mine there didn't reveal any, so either I'm also insufficiently caffeinated or there is none.
 

Sciss wrote:
while += exists as a method in collection.mutable.Set, it does _not_ exist in collection.immutable.Set.
To avoid that mechanism of automagically^H^H^H^H^H^H^Htically rewriting that method's invocation... I see.

Thanks for the quick replies :) One never stops learning (especially when it comes to fancy scala features).

Kind regards
--
~ Philipp
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: +=: Compiler magic?

On Sat, Nov 20, 2010 at 04:19:43PM +0100, Philipp Dörfler wrote:
> > Someone who knows where an implicit converstion applicable to the type
> > of supplies = precludes this "magic" will have to say so. Or
> > you can devise a test to determine whether it's so. I'm insufficiently
> > caffeinated right now (translation: I'm too lazy).
> >
> That would have to be in scala.Predef (or it's parent class) then,
> wouldn't it?

It wouldn't have to be in predef. He means like this:

object Test {
var a: Set[Int] = Set()
implicit def foo(set: Set[Int]) = new {
def +=(x: Int) = { println("I'm an implicit conversion!") ; set + x }
}

def main(args: Array[String]): Unit = {
a = Set(1)
a += 2
println(a)
}
}

% scala29 Test
I'm an implicit conversion!
Set(1)

And the non-code answer is that the expansion from x += 1 to x = x + 1
is only performed if no other interpretation is valid.

Philipp Dörfler
Joined: 2010-05-24,
User offline. Last seen 42 years 45 weeks ago.
Re: +=: Compiler magic?

2010/11/20 Paul Phillips :
> It wouldn't have to be in predef. He means like this:
>
(snip)
>
> And the non-code answer is that the expansion from x += 1 to x = x + 1
> is only performed if no other interpretation is valid.

Oh, I see... I got the meaning of "preclude" wrong. I thought it'd
mean something like "allow", which is the very opposite. Silly me.
This gives Randall's answer a whole new meaning.

Sorry to have caused a bit of confusion and thanks for enlightening me.

Kind regards

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: +=: Compiler magic?
You do know magic does not exist, right?

How do you know that?  
Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: +=: Compiler magic?

On Monday November 22 2010, Naftoli Gugenheim wrote:
> > You do know magic does not exist, right?
>
> How do you know that?

It does not exist by definition.

RRS

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland