4. small vs large language
1. Small language: short time to learn
2. Large language: more vocabulary to use
小さい言語は習うのが容易
大きい言語はより多くの語彙を使うことができる
5. primitive
• "A primitive is a word for which we can take it for
granted that we all know what it means."
プリミティブとは、それが何を意味するのか自明とできる言葉
6. language that can grow
1. APL: users cannot define symbols
2. LISP: user-defined words look like the primitives
APL は優れた言語だが、ユーザはシンボル演算子を定義不可
LISP はユーザ定義でプリミティブ的なものを作れる
7. language that can grow
1. Cathedral (one design) vs Bazaar (no one plan)
2. plan can change to meet the user
寺院設計は 1つの大計画、商店街は複数の計画を持つ
ユーザのニーズに応えて計画を変更することができる
14. Lightweight Language
1. Easy to learn and use
2. Widely-used languages are coming from industry
3. Perl, Python, Ruby, (Scheme)
http://ll1.ai.mit.edu/cfp.html
LL言語とは何だったのか。実用言語が産業側から来てるとい
うアカデミアにおける危機感。ライトなのは学びやすさ。
17. "The name Scala stands for scalable language.
The language is so named because it was
designed to grow with the demands of its users.
You can apply Scala to a wide range of
programming tasks, from writing small scripts to
building large systems."
'Programming in Scala', Odersky, Spoon, Venners
Scala という名前は「スケーラブルな言語」を意味する
ユーザーの求めに応じて成長していけるように設計されている
Scala: a scalable language
18. "Guy Steele noted in a talk on "growing a
language" that the same distinction can be
applied to language design. Scala is much more
like a bazaar than a cathedral, in the sense that it
is designed to be extended and adapted by the
people programming in it."
'Programming in Scala', Odersky, Spoon, Venners
Guy Steele は「言語を成長させる」という講演の中で
言語設計も「伽藍とバザール」が区別できると言っている
Scala: a scalable language
25. what is equality?
•substitution property
•for any a, b, and f(x): a == b ⇒ f(a) == f(b)
•equivalence relation
等価性とは代入原理を満たす同値関係の1つ
26. equivalence
• reflexive
• for any a (except NaN): a == a
• symmetric
• for any a, b: a == b ⇒ b == a
• transitive
• for any a, b, and c: a == b && b == c ⇒ a == c
同値関係は反射律、対称律、推移律
27. equivalent, but not equal
合同な図形は同値関係にあるが等しくは無い
these shapes are congruent
in some context they could be considered "same"
29. 1.if either operand is double, widen both to double
2.else if either operand is float, widen both to float
3.else if either operand is long, widen both to long
4.else widen both operands to int
numeric promotion in == operation
== 演算における数値昇格
double や long など広い方の型に拡張変換する
1 == 1.0
33. == in Scala
1. For value types, it uses numerical equality
2. For reference types, java.lang.Object#equals
that can be overridden
https://www.scala-lang.org/docu/files/ScalaOverview.pdf
値型は数値的等価性を用いる
参照型はオーバーライド可能な Object#equals を使う
34. eq in Scala
1. For reference types, use eq for reference
equality.
参照的等価性を使いたい場合は eq メソッドを使う
35. cooperative equality
協調的等価性 == の実装レベルでボックス型でも数値昇格を
エミュレート。さらっとボックス化するための仕組み。
scala> java.lang.Integer.valueOf(128) == java.lang.Long.valueOf(128L)
val res1: Boolean = true
scala> (128: Any).getClass
val res2: Class[_] = class java.lang.Integer
scala> (128: Any) == (128L: Any)
val res3: Boolean = true
scala> Set(128, 128L, "foo")
val res4: scala.collection.immutable.Set[Any] = Set(128, foo)
== emulates numeric promotion of boxed primitives
36. cooperative equality cont.
== は equal(...) と異なることに注意
hashCode() の代わりに ## というものが用意されている
scala> (128: Any) == (128L: Any)
val res3: Boolean = true
scala> (128: Any).equals(128L: Any)
val res5: Boolean = false
== is different from equals(...)
## is different from hashCode()
scala> (1.0: Any).hashCode()
val res6: Int = 1072693248
scala> (1.0: Any).##
val res7: Int = 1
41. Display warning on equals comparing non-
references #8120
Scala 2.13.4 から警告を出すようにしました
scala> def check[A](a1: A, a2: A): Boolean = a1.equals(a2)
^
warning: comparing values of types A and A using `equals` is
unsafe due to cooperative equality; use `==` instead
check: [A](a1: A, a2: A)Boolean
I implemented the warning
42. BCodeBodyBuilder
プリミティブ型の比較は Java 同様数値昇格が行われる
val tk = tpeTK(l).maxType(tpeTK(r))
genLoad(l, tk)
genLoad(r, tk)
genCJUMP(success, failure, op, tk, targetIfNoJump)
primitive type == is handled by genComparisonOp(...)
same numeric promotion as Java
43. BCodeBodyBuilder cont.
参照型の比較は、異なるボックス型の場合 BoxesRunTime
その他の場合は null 比較もしくは equals を用いる
reference type == is handled by genEqEqPrimitive(...)
1.if both sides are different boxed primitive types are
boxed floating point, use scala.runtime.BoxesRunTime.
2.if LHS is null literal, RHS eq null
3.if RHS is null literal, LHS eq null
4.if statically non-null (like "foo"), use Object#equals
5.otherwise, if (null eq this) null eq that
else this.equals(that)
44. universal equality
1. scala.Any (compiler fiction) defines == and
equals
2. since all values are a member of scala.Any, they
can be compared using ==
普遍的等価性
全ての値同士を == を用いて比較できる
45. unsound equality
絶対に真を返すことのできない式を書ける
これを不健全 (unsound) であると言う
scala> 1 == "1"
^
warning: comparing values of types Int and String using `==` will
always yield false
val res0: Boolean = false
scala> Option(1) == Option("1")
val res1: Boolean = false
== admits expressions that can never be true
46. unsound equality
Java の == は強い型付けを持っている
数値の取り扱いをナイスにする代わりに型安全性が犠牲に
scala> Option(1) == Option("1")
val res1: Boolean = false
Java has static and strongly-typed ==
java.util.Optional.of(1) == java.util.Optional.of("1");
| Error:
| incomparable types: java.util.Optional<java.lang.Integer> and
java.util.Optional<java.lang.String>
| java.util.Optional.of(1) == java.util.Optional.of("1");
| ^----------------------------------------------------^
scala> (128: Any) == (128L: Any)
val res3: Boolean = true
all for numeric niceness?
50. "Rethinking equality"
等価性の再考
現行の実装は長く見れば見るほど醜く見える
•"Now that 2.9 is almost out the door, we have the
luxury to think of what could come next. One thing I
would like to address is equality. The current
version did not age well; the longer one looks at it,
the uglier it gets. In particular it is a great
impediment for DSL design. Witness the recent
popularity of === as an alternative equality
operator."
https://groups.google.com/g/scala-internals/c/MhIR30mYt-M/m/MHD0VHhMqoQJ
56. cooperative equality is closed-world
scala> import spire.math._
scala> Complex(1.0, 0.0) == 1.0
1 | Complex(1.0, 0.0) == 1.0
|^^^^^^^^^^^^^^^^^^^^^^^^^
|Values of types spire.math.Complex[Double] and Double cannot be compared
with == or !=
協調的等価性は ## の実装で協調するため閉じた世界
そのためライブラリは参加できない
•requires ## implementations to be aware of
each other
•libraries like Spire cannot participate in this!
57. equality in Valhalla
Valhalla の値の等価性は置換意味論を用いる
参照値の等価性は == であるインラインオブジェクトの参照
•Valhalla is an experimental OpenJDK project to
develop value types
•"Two object references are equal if they are both
null, or are both references to the same identity
object, or are both references to inline objects that
are == to each other. This extends
the substitutability semantics of == to all values –
two values are == only if it is not possible to
distinguish between them in any way (excepting
the legacy behavior of NaN.)"
https://cr.openjdk.java.net/~briangoetz/valhalla/sov/02-object-model.html
58. equality in Valhalla
Java 的には数値昇格は == の前に起こっていることのなので
Valhalla 後も数値昇格はそのままっぽい
•numeric promotion
is likely to stay in
Java
https://twitter.com/eed3si9n/status/1317150368380428292
59. making Scala 3 growable
多元的等価性を導入するタイミングで協調的等価性を外すこと
ができれば Scala 3 をより成長させることができる
•let's remove cooperative equality under strict
equality mode
•let's restore == and equals(...)
final def == (that: Any): Boolean =
if (null eq this) null eq that
else this.equals(that)