Skip to content

Instantly share code, notes, and snippets.

@kmizu
Created September 21, 2012 16:47
Show Gist options
  • Save kmizu/3762583 to your computer and use it in GitHub Desktop.
Save kmizu/3762583 to your computer and use it in GitHub Desktop.
Difference between 'Placeholder Syntax for Anonymous Functions' and 'Method Values'
[[syntax trees at end of parser]]// Scala source: Person1.scala
package <empty> {
object Main extends scala.ScalaObject {
def <init>() = {
super.<init>();
()
};
def main(argv: Array[String]): scala.Unit = {
val args = argv;
{
final class $anon extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
class Person1 extends scala.ScalaObject {
<paramaccessor> private[this] val name: String = _;
<paramaccessor> private[this] val y: Int = _;
def <init>(name: String)(y: Int) = {
super.<init>();
()
}
};
val f = ((x$1) => new Person1("foo")(x$1)); // expanded to anonymous function and not typed yet
println(f(100))
};
new $anon()
}
}
}
}
Main$$anon$1$Person1@39011f1d
[[syntax trees at end of parser]]// Scala source: Person2.scala
package <empty> {
object Main extends scala.ScalaObject {
def <init>() = {
super.<init>();
()
};
def main(argv: Array[String]): scala.Unit = {
val args = argv;
{
final class $anon extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
case class Person2 extends scala.ScalaObject with scala.Product with s
cala.Serializable {
<caseaccessor> <paramaccessor> val name: String = _;
<paramaccessor> private[this] val y: Int = _;
def <init>(name: String)(y: Int) = {
super.<init>();
()
}
};
val f = (Person2("foo"): (() => <empty>)); // not expanded to anonymous function yet
println(f(100))
};
new $anon()
}
}
}
}
Person2(foo)
[[syntax trees at end of typer]]// Scala source: Person1.scala
package <empty> {
final object Main extends java.lang.Object with ScalaObject {
def this(): object Main = {
Main.super.this();
()
};
def main(argv: Array[String]): Unit = {
val args: Array[String] = argv;
{
final class $anon extends scala.AnyRef {
def this(): anonymous class $anon = {
$anon.super.this();
()
};
class Person1 extends java.lang.Object with ScalaObject {
<paramaccessor> private[this] val name: String = _;
<paramaccessor> private[this] val y: Int = _;
def this(name: String)(y: Int): this.Person1 = {
Person1.super.this();
()
}
};
private[this] val f: Int => this.Person1 = ((x$1: Int) => new $anon.th
is.Person1("foo")(x$1)); // correctly typed
private <stable> <accessor> def f: Int => this.Person1 = $anon.this.f;
scala.this.Predef.println($anon.this.f.apply(100))
};
{
new $anon();
()
}
}
}
}
}
Main$$anon$1$Person1@7ca2da75
[[syntax trees at end of typer]]// Scala source: Person2.scala
package <empty> {
final object Main extends java.lang.Object with ScalaObject {
def this(): object Main = {
Main.super.this();
()
};
def main(argv: Array[String]): Unit = {
val args: Array[String] = argv;
{
final class $anon extends scala.AnyRef {
def this(): anonymous class $anon = {
$anon.super.this();
()
};
case class Person2 extends java.lang.Object with ScalaObject with Prod
uct with Serializable {
<caseaccessor> <paramaccessor> private[this] val name: String = _;
<stable> <caseaccessor> <accessor> <paramaccessor> def name: String
= Person2.this.name;
<paramaccessor> private[this] val y: Int = _;
def this(name: String)(y: Int): this.Person2 = {
Person2.super.this();
()
};
<synthetic> def copy(name: String = name)(y: Int = y): this.Person2
= new $anon.this.Person2(name)(y);
<synthetic> def copy$default$2(name: String): Int @scala.annotation.
unchecked.uncheckedVariance = Person2.this.y;
<synthetic> def copy$default$1: String @scala.annotation.unchecked.u
ncheckedVariance = Person2.this.name;
override def hashCode(): Int = ScalaRunTime.this._hashCode(Person2.t
his);
override def toString(): String = ScalaRunTime.this._toString(Person
2.this);
override def equals(x$1: Any): Boolean = Person2.this.eq(x$1.asInsta
nceOf[java.lang.Object]).||(x$1 match {
case (name: String)(y: Int)this.Person2((name$1 @ _)) if name$1.==
(name) => x$1.asInstanceOf[this.Person2].canEqual(Person2.this)
case _ => false
});
override def productPrefix: java.lang.String = "Person2";
override def productArity: Int = 1;
override def productElement(x$1: Int): Any = x$1 match {
case 0 => name
case _ => throw new java.lang.IndexOutOfBoundsException(x$1.toStri
ng())
};
override def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[this.Pe
rson2]()
};
final private <synthetic> object Person2 extends java.lang.Object with
ScalaObject with Serializable {
def this(): object this.Person2 = {
Person2.super.this();
()
};
final override def toString(): java.lang.String = "Person2";
case <synthetic> def unapply(x$0: this.Person2): Option[String] = if
(x$0.==(null))
scala.this.None
else
scala.Some.apply[String](x$0.name);
case <synthetic> def apply(name: String)(y: Int): this.Person2 = new
$anon.this.Person2(name)(y)
};
private[this] val f: Int => this.Person2 = {
((y: Int) => $anon.this.Person2.apply("foo")(y)) // expanded to anonymous function and correctly typed
};
private <stable> <accessor> def f: Int => this.Person2 = $anon.this.f;
scala.this.Predef.println($anon.this.f.apply(100))
};
{
new $anon();
()
}
}
}
}
}
Person2(foo)
class Person1(name: String)(y: Int)
val f = new Person1("foo")(_)
println(f(100))
case class Person2(name: String)(y: Int)
val f = Person2("foo") _
println(f(100))
@kmizu
Copy link
Author

kmizu commented Sep 21, 2012

Person2.scala (case class) に対して、Person2("foo") _

した場合と、

Person1.scala(普通のclass)に対して、new Pesron1("foo")(_)

の違いがわかるようにしてみました。

@kmizu
Copy link
Author

kmizu commented Sep 23, 2012

Person2("foo") _ and new Pesron1("foo")(_) have different meanings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment