SlideShare a Scribd company logo
1 of 55
Download to read offline
WHAT DOTTY FIXES
自己紹介
麻植泰輔 / Taisuke Oe
Twitter @OE_uia
最近
Septeni Original, Inc. 技術アドバイザー
エフ・コード 商品開発部顧問
ScalaMatsuri 座長
来年のScalaMatsuriは3日間! 3月16-18日です。
フルタイム職を辞めました
今日の話
What Dotty xes
Dottyが直した モノ
そもそもDOTTYって何?
Scala3系で採用される新コンパイラ
Martin Odersky教授の研究室で主に開発が進んでいる
最新versionは0.3-RC2
pre-alphaなので、変なバグはまだ色々あります
Scala 2.14 ~ 2.15系でmigrationするロードマップ(今の所)
DOTTYは何が嬉しいのか?
Union Type, Implicit Function Typeなどを始めとしたより柔軟で強固な型システム
scalacのバグ修正
scalacの一見理解し難い仕様や制約の修正 <= 今日はこれの話をします
Q. 以下の式の戻り値はなんでしょう
List(1).toSet()
A.
答え: false
scala> List(1).toSet()
<console>:12: warning: Adaptation of argument list by inserting () is deprecated:
signature: GenSetLike.apply(elem: A): Boolean
given arguments: <none>
after adaptation: GenSetLike((): Unit)
List(1).toSet()
^
res4: Boolean = false
なぜ?
解説
List(1).toSet()
は以下のように展開される
scala -Xprint:typer
List.apply[Int](1).toSet[AnyVal].apply(())
どこから apply(()) が来た?
どこから APPLY が来たのか?
toSetメソッドは、無引数でかつ 括弧なし で定義されている。
def toSet:Set[A]
括弧なしで定義された無引数メソッドは、toSet() のように括弧付きで呼び出すことはできない
=> apply メソッド呼び出しと解釈
自動的に補われる引数
Set の apply[A](a:A):Boolean メソッドは1引数関数
Scalaのauto-tupling(後述)により、無引数関数に引数が渡されなかった場合、引数として () を補われてしまう
今回は () を引数として補っても、コンパイルが通る
()はSet(1)に含まれないため、apply関数の戻り値として false が返った
DOTTYになれば改善される?
以下の2点について、Scala 2.12とDottyを比較
auto-tupling
無引数メソッド呼び出しへの括弧付与
SCALA 2.12のAUTO-TUPLING
関数の取りうる引数と、実際に渡した引数がマッチしなかった場合
渡した引数をTuple化してコンパイルできるかチェック
SCALA 2.12のAUTO-TUPLING
def f(ab:(A,B)) = ???
f(a,b) というメソッド呼び出しを f((a,b)) に変換する。
def g(a:A) = ???
g() というメソッド呼び出しを g(()) に変換する(!?)
※ ただし、auto-tuplingによる() の挿入はScala2.11以降はdeprecatedになっている
※ -Yno-adapted-args scalacオプション 無効化
※ -Ywarn-adapted-args scalacオプション 警告
DOTTYのAUTO-TUPLING
件のような () の挿入を行わない
関数のauto-tuplingを行う
例えばある関数オブジェクト
(x,y) => expr
がメソッドに渡されたとき、そのメソッドが一引数関数を要求している場合
{case (x,y) => expr}
に展開される
def f(a:Int,b:Int) = a + b
List(3,2,1).zipWithIndex.map(f)
SCALA 2.12における無引数メソッド呼び出しへの括弧付与
既存の(特にJavaの)ライブラリとの互換性と、統一アクセス原則を両立するため
引数無しメソッドを空の引数リスト付きで定義されていた場合
メソッド呼び出しをする際に括弧をつけなくても自動的に括弧が追加される。
def getName():String
というメソッドは、getName と書いても良い。但し
def toSet:Set[A]
上のように空の引数リスト無しで定義されていた場合、(空の引数リストとしての)括弧は付与されない
DOTTYにおける無引数メソッド呼び出しへの括弧付与
Dottyでは、Dotty外で定義された括弧なしの無引数メソッドのみ について、自動で括弧が付与される。
import java.util._
scala> new ArrayList[String]()
val res14: List[String] = []
scala> res14.size //コンパイル通る
前スライドの例は、コンパイルエラーとなる。
scala> def getName() = "name"
def getName(): String
scala> getName
-- Error: <console>:6:0 --------------------------------------------------------
6 |getName
|^^^^^^^
|missing arguments for method getName
ETA-EXPANSION
SCALA 2.12のETA-EXPANSION
eta-expansion: (Scalaにおいては)メソッドの関数オブジェクト化
以下の2つの方法でeta-expansionができる
1. FunctionN型の値が要求されているところにメソッドを渡す
2. メソッドに対し _ を明示的に呼び出す
def double(a:Int):Int = a * 2
List(1,2,3).map(double)
val doubleFunction:Int => Int = double
double _
DOTTYのETA-EXPANSION
eta-expansionのための _ は廃止される。
値が要求されるところに引数有りメソッドを渡すと、自動でeta-expansionされる。
def double(a:Int):Int = a * 2
//型注釈がなくてもコンパイルが通る
val doubleFunction = double
引数無しメソッドはeta-expansionを直接行う方法がなくなる。
def getName() = "name"
() => getName()
IMPLICITの型注釈
SCALA2.12 におけるIMPLICITの型注釈
暗黙の値に明示的に型注釈を書かない場合、 暗黙の値の探索に失敗してしまいコンパイルエラーとなる場合がある
//compile success
scala> :paste
object B {import A._ ; implicitly[Int]}
object A {implicit val a:Int = 1}
//COMPILE ERROR
scala> :paste
object B {import A._ ; implicitly[Int]}
object A {implicit val a = 1}
参考: Implicitには型注釈をつけましょう - OE_uia Tech Blog
DOTTYにおけるIMPLICITの注釈
Dottyでは、ローカルではない暗黙の値には型注釈が必須。つけないとコンパイルエラーになる。
scala> implicit val a = 1
-- Error: <console>:4:13 -------------------------------------------------------
4 |implicit val a = 1
|^^^^^^^^^^^^^^^^^^
|type of implicit definition needs to be given explicitly
//暗黙のローカル変数なら型注釈が不要
scala> def f = {implicit val a = 1;a}
def f: Int
型クラスの依存関係
型クラスとは
既存の型に対し、共通の振る舞いを後から定義する (アドホック多相を実現する)ためのデザインパターン
型クラス Semigroup
trait Semigroup[A]{
def append(a1:A,a2:A):A
}
object Semigroup{
implicit val intGroup:Semigroup[Int] = new Semigroup[Int]{
def append(a1:Int,a2:Int):Int = a1 + a2
}
}
object SemigroupSyntax{
def append[A](a1:A, a2:A)(implicit S:Semigroup[A]):A = S.append(a1,a2)
}
import SemigroupSyntax._
append(1,2) // 3
DEPENDENT METHOD TYPE
引数の型に依存して、メソッドのシグネチャ(のうち、多くの場合は戻り値の型)を変化させることができる
型クラス + DEPENDENT METHOD TYPEの例
Measurableという型クラスを使って、Dependent Method Typeを活用する例
trait Measurable[A]{
type Size
def sizeOf(a:A):Size
}
object Measurable{
implicit val intSize:Measurable[Int] = new Measurable[Int]{
type Size = Int
def sizeOf(i:Int):Int = i
}
implicit def seqSize[A]:Measurable[Seq[A]] = new Measurable[Seq[A]]{
type Size = Int
def sizeOf(s:Seq[A]):Int = s.size
}
}
object MeasurableSyntax{
def measure[A](a:A)(implicit M:Measurable[A]):M.Size = M.sizeOf(a)
}
import MeasurableSyntax._
measure(Seq(1,2,3)) // 3
measure(1) // 1
SCALA2.12で型クラスを組み合わせる
同じ引数リスト内の引数を参照できない
scala> def sumSizes[A](a1:A,a2:A)(implicit M:Measurable[A], S:Semigroup[M.Size]):
| S.append(M.measure(a1),M.measure(a2))
<console>:32: error: illegal dependent method type:
parameter may only be referenced in a subsequent parameter section
def sumSizes[A](a1:A,a2:A)(implicit M:Measurable[A], S:Semigroup[M.Size]):
^
SCALA2.12で型クラスを組み合わせる
AUXパターン
型メンバを型パラメーターへマッピングすることで、暗黙のパラメーターが持つ型パラメーター同士で依存させることができる
trait Measurable[A]{
type Size
def sizeOf(a:A):Size
}
//ここまで同じ
object Measurable{
type Aux[A0,B0] = Measurable[A0]{type Size = B0}
implicit val intAux:Measurable.Aux[Int,Int] = new Measurable[Int]{
type Size = Int
def sizeOf(i:Int):Int = i
}
}
def sumSizes[A,Size](a1:A,a2:A)(implicit M:Measurable.Aux[A,Size], S:Semigroup[Size
S.append(M.sizeOf(a1),M.sizeOf(a2))
DOTTYで型クラスを組み合わせる
Dottyでは、同じ引数リストの中でも依存関係を作れる
object SemigroupMeasurableSyntax {
def sumSizes[A](a1:A,a2:A)(implicit M:Measurable[A], S:Semigroup[M.Size]):M.Size
S.append(M.sizeOf(a1),M.sizeOf(a2))
}
詳細: AuxパターンをDottyで解決する
型クラスインスタンス
の再帰的導出
型クラスSHOW
trait Show[T] {
def apply(t: T): String
}
def show[T](t: T)(implicit s: Show[T]) = s(t)
再帰的なデータ構造に対する汎用的な型クラスインスタンス
導出
次のような再帰的データ構造に対する、Show 型クラスのインスタンスを導出したい
sealed trait List[+T]
case class Cons[T](hd: T, tl: List[T]) extends List[T]
sealed trait Nil extends List[Nothing]
case object Nil extends Nil
再帰的に導出することで解決できないか?
出典: Scala Exercise - Shapeless
基底の型クラスインスタンス
型クラスインスタンスを、要素型とNilに対し定義する。
object Show {
implicit def showInt: Show[Int] = new Show[Int] {
def apply(t: Int) = t.toString
}
implicit def showNil: Show[Nil] = new Show[Nil] {
def apply(t: Nil) = "Nil"
}
}
型クラスインスタンスの再帰的導出を試みる
List及びConsに対する型クラスインスタンスは、データ構造に沿って再帰的に、暗黙のパラメーターを展開し導出する
object Show{
implicit def showCons[T](implicit st: Show[T], sl: Show[List[T]]): Show[Cons[T]] =
def apply(t: Cons[T]) = s"Cons(${show(t.hd)(st)}, ${show(t.tl)(sl)})"
}
implicit def showList[T](implicit sc: Show[Cons[T]]): Show[List[T]] = new Show[
def apply(t: List[T]) = t match {
case n: Nil => show(n)
case c: Cons[T] => show(c)(sc)
}
}
}
型クラスインスタンスの再帰的導出に失敗
これまで定義したShowのインスタンス及び導出用の関数を駆使して、 要素数1のListの型クラスインスタンスの導出を試みる。
scala> val l: List[Int] = Cons(0, Nil)
l: List[Int] = Cons(0,Nil)
scala> show(l)
<console>:20: error: diverging implicit expansion for type Show[Cons[Int]]
starting with method showList in object Show
show(res0)
^
「showListからはじまる暗黙展開(implicit expansion)」が発散(diverging)した、とはどういうことか?
暗黙展開の発散とは?
scala> val l: List[Int] = Cons(0, Nil)
scala> show(l)
showメソッドは暗黙のパラメーターとしてShow[List[Int]]型の値(型クラスインスタンス)を要求する。
暗黙展開の発散とは?
すなわちコンパイル時に以下のように展開される。
scala> show(l){
//以下、コンパイル時に暗黙の引数として渡される値
/* 1 */ showList{
/* 2 */ showCons(
/* 3 */ showInt, showList{
/* 4 */ showCons(/* ... */)
})
}
}
1. showメソッドがListの型クラスインスタンスを要求する
2. Listの型クラスインスタンスを、Consの型クラスインスタンスから導出する
3. Consの型クラスインスタンスは、headに相当するIntの型クラスインスタンスと、tailに相当するListの型クラスインスタンスから導
出する
4. (先のtailに相当する)Listの型クラスインスタンスは、やはりConsの型クラスインスタンスから導出可能
ここで再び1のステップのようにListの型クラスインスタンスを要求するため、暗黙展開はループに陥る。
暗黙の展開が永遠に終わらない可能性を察知すると、コンパイラは先程のような「暗黙展開の発散」エラーを引き起こす。
本来LISTは有限の大きさのデータ型
型クラスインスタンスの展開を(暗黙により)コンパイル時に行うと、型情報のみから展開することになる。 そのため値に依存して
Nilで展開を終えることができない。
実行時に(値の情報を基に)展開する方法はないだろうか?
SCALA 2.12で暗黙展開の発散を防ぐ方法
Shapelessの Lazy 型コンストラクタは、型クラスインスタンスの展開の殆どを実行時に遅延させる。
Lazyを使うと、型クラスインスタンス導出の定義は以下のようになる。
implicit def showCons[T](implicit st: Show[T], sl: Lazy[Show[List[T]]]): Show[Cons
def apply(t: Cons[T]) = s"Cons(${show(t.hd)(st)}, ${show(t.tl)(sl.value)})"
}
implicit def showList[T](implicit sc: Lazy[Show[Cons[T]]]): Show[List[T]] = new
def apply(t: List[T]) = t match {
case n: Nil => show(n)
case c: Cons[T] => show(c)(sc.value)
}
}
SCALA 2.12で暗黙展開の発散を防ぐ方法
Lazyを使うことで暗黙展開の発散を防げる
scala> val l: List[Int] = Cons(1, Cons(2, Cons(3, Nil)))
scala> show(l)
res2: String = Cons(1, Cons(2, Cons(3, Nil)))
なぜLAZY型コンストラクタで暗黙展開の発散が防げるのか?
Lazyの役割は、大きく分けて2つ。
1. マクロにより、暗黙のパラメーターの展開を以下のように修正する
val l: List[Int] = Cons(0, Nil)
show(l){
//以下、暗黙の引数として渡される値
lazy val list:Show[List[Int]] = showList(Lazy(cons))
lazy val cons:Show[Cons[Int]] = showCons(showInt, Lazy(list))
list
}
同じ型に対する型クラスインスタンスがlazy valに束縛され使いまわされるようになる
なぜLAZY型コンストラクタで暗黙展開の発散が防げるのか?
1. 以下のようなデータ構造により、 Lazy.applyに渡された値(型クラスインスタンス)の評価を遅延する (※ 実際のコードより簡略
化しています)
trait Lazy[T]{val value:T}
object Lazy{
def apply[T](t: => T):Lazy[T] =
new Lazy[T]{
lazy val value = t
}
}
これにより、型クラスインスタンスの展開は (コンパイル時ではなく)実行時に行われるようになる。 (もし展開がループに陥る場合は
StackOverFlowを引き起こすことに注意)
lazy val list:Show[List[Int]] = showList(Lazy(cons))
LAZYによる型クラスインスタンスの実行時展開
val l:List[Int] = Cons(0,Nil)
show(l)
この show を、擬似的にインライン展開すると:
//Listの型クラスインスタンスへの委譲
showList.apply(Cons(0,Nil))
//Listの型クラスインスタンスから、Consの型クラスインスタンスへ委譲
showCons.apply(Cons(0,Nil))
//Consの型クラスインスタンスから、IntとListの型クラスインスタンスへ委譲
s"Cons(${showInt.apply(0)}, ${showList.apply(Nil)})"
//Listの型クラスインスタンスから、Nilの型クラスインスタンスへ委譲
s"Cons(${showInt.apply(0)}, ${showNil.apply(Nil)})"
発散せず、すべて基底の型クラスインスタンスに委譲できた。
要素数2以上のListでも、同様に展開できる。
DOTTYで暗黙展開の発散を防ぐ方法
implicit by-name parameterにより、暗黙展開の発散を防ぐ
ShapelessのLazyと異なりマクロを使わないが、型クラスインスタンスを内部でlazy valに束縛する点では同じ
現時点では、implicit by-name parameterとDependent Method Typeを(実装上の都合で)同時に使えない
implicit def showCons[T](implicit st: Show[T], sl: => Show[List[T]]): Show[Cons[
def apply(t: Cons[T]) = s"Cons(${show(t.hd)(st)}, ${show(t.tl)(sl)})"
}
implicit def showList[T](implicit sc: => Show[Cons[T]]): Show[List[T]] = new Show
def apply(t: List[T]) = t match {
case n: Nil => show(n)
case c: Cons[T] => show(c)(sc)
}
}
余談
[WIP] Implementation of byname implicits with recursive dictionaries. by milessabin · Pull Request #6050 · scala/scala
Scala 2.12 系でもimplicit by-name parameterが入るかも!(現在WIP)
上記に関連してDottyのissue上でも議論は続いており、今後Dottyのimplicit by-name parameterの実装が変わる可能性があ
りそう
ENUMERATION
SCALA 2.12のENUMERATION
拡張しにくい
Color.Value が汚い
object Color extends Enumeration{
val Red,Yellow,Green = Value
}
def show(color:Color.Value):Unit = color match{
case Color.Red => println("赤")
case Color.Yellow => println("黃")
case Color.Green => println("青")
}
SCALA2.12におけるENUMERATIONの代替: SEALEDによる直和型(SUM TYPE)
拡張は容易だが、冗長。
特に、enumerationの一覧などが欲しい場合など自前で実装しないといけない。
sealed trait Color{def name:String}
object Color{
case object Red extends Color{val name = "赤"}
case object Yellow extends Color{val name = "黃"}
case object Green extends Color{val name = "青"}
}
def show(color:Color):Unit = println(color.name)
DOTTYの新しいENUM
新しい enum キーワードが
最新の0.3.0-RC-2で使用可
Enumeration(列挙型)、Algebraic Data Type(代数的データ型)等を便利に書くための糖衣構文
sealed class、companion objectとそのメンバ、ないしは子クラスに展開される
実装された
ENUMを使ったENUMERATIONの例
enum Color{
case Red,Yellow,Green
}
... は以下に展開される
sealed abstract class Color extends scala.Enum
object Color {
private val $values = new scala.runtime.EnumValues[Color]
def enumValue: Map[Int, Color] = $values.fromInt
def enumValueNamed: Map[String, Color] = $values.fromName
def enumValues: Iterable[Color] = $values.values
def $new(tag: Int, name: String): Color = new Color {
def enumTag: Int = tag
override def toString: String = name
$values.register(this)
}
final val Red: Color = $new(0, "Red")
final val Yellow: Color = $new(1, "Yellow")
final val Green: Color = $new(2, "Green")
}
ENUM によるENUMERATIONは拡張も容易
enum Color(val name:String){
case Red extends Color("赤")
case Yellow extends Color("黃")
case Green extends Color("青")
}
def show(color:Color):Unit = println(color.name)
その他のDOTTYで直るSCALA2系の制約
lazy valによるdeadlock
抽象型メンバーのshadowing
traitのコンストラクタ引数
Function22制限
などなど
詳しくは を参照のことDotty Documentation
DOTTYへのMIGRATION
SCALAFIX
ScalaCenter主導で、scalametaを活用した というマイグレーションツールを鋭意開発中scala x
Rewrite tool to prepare Scala 2.12 code for Dotty.
Dottyへのmigrationだけではなく、様々なmigrationで使われるかも?
sbtのメジャーバージョンアップ
様々なScalaコンパイラfolk
ライブラリのメジャーバージョンアップ
最後に
Dottyはまだpre-alphaステージなので、詳細な実装などまだまだ大きく変わりえますが、
現段階でもScala2系の制約や問題があるのか、より深く理解する資料として優れています。
またDottyの先行実装をもとに、Scala2系へ何らかのbackportをされたものも少なくありません。
Dottyは勉強の題材として非常におもしろいので、ぜひお手元で遊んでみてください。

More Related Content

What's hot

Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lensNaoki Aoyama
 
Sns suite presentation
Sns suite presentationSns suite presentation
Sns suite presentationJason Namkung
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?Kenji Nakamura
 
Material
MaterialMaterial
Material_TUNE_
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行guest5f4320
 
実務者のためのかんたんScalaz
実務者のためのかんたんScalaz実務者のためのかんたんScalaz
実務者のためのかんたんScalazTomoharu ASAMI
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
Java8から始める関数型プログラミング
Java8から始める関数型プログラミングJava8から始める関数型プログラミング
Java8から始める関数型プログラミングstylefreeslide
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)x1 ichi
 

What's hot (19)

Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lens
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Sns suite presentation
Sns suite presentationSns suite presentation
Sns suite presentation
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?
 
Material
MaterialMaterial
Material
 
Phantom Type in Scala
Phantom Type in ScalaPhantom Type in Scala
Phantom Type in Scala
 
Thinking in Cats
Thinking in CatsThinking in Cats
Thinking in Cats
 
大人のお型付け
大人のお型付け大人のお型付け
大人のお型付け
 
Rpscala2011 0601
Rpscala2011 0601Rpscala2011 0601
Rpscala2011 0601
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
Pythonintro
PythonintroPythonintro
Pythonintro
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
実務者のためのかんたんScalaz
実務者のためのかんたんScalaz実務者のためのかんたんScalaz
実務者のためのかんたんScalaz
 
Scala with DDD
Scala with DDDScala with DDD
Scala with DDD
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
Actor&stm
Actor&stmActor&stm
Actor&stm
 
Java8から始める関数型プログラミング
Java8から始める関数型プログラミングJava8から始める関数型プログラミング
Java8から始める関数型プログラミング
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)
 

Similar to What Dotty fixes @ Scala関西サミット

(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミングOuka Yuka
 
Scalamacrosについて
ScalamacrosについてScalamacrosについて
Scalamacrosについてdekosuke
 
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)Shin-ya Koga
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!bitter_fox
 
初めてのHaskell (表)
初めてのHaskell (表)初めてのHaskell (表)
初めてのHaskell (表)karky7
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話bleis tift
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.specKent Ohashi
 
Live Coding で学ぶ C# 7
Live Coding で学ぶ C# 7Live Coding で学ぶ C# 7
Live Coding で学ぶ C# 7Takaaki Suzuki
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんかcch-robo
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座bleis tift
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & ListenersTaisuke Oe
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析mametter
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~Nobuhisa Koizumi
 

Similar to What Dotty fixes @ Scala関西サミット (20)

(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
 
Scalamacrosについて
ScalamacrosについてScalamacrosについて
Scalamacrosについて
 
Trait in scala
Trait in scalaTrait in scala
Trait in scala
 
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
 
Haskell超入門 Part.1
Haskell超入門 Part.1Haskell超入門 Part.1
Haskell超入門 Part.1
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
fanscala1 2 scalaの基本
fanscala1 2 scalaの基本fanscala1 2 scalaの基本
fanscala1 2 scalaの基本
 
More C++11
More C++11More C++11
More C++11
 
MP in Scala
MP in ScalaMP in Scala
MP in Scala
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!
 
初めてのHaskell (表)
初めてのHaskell (表)初めてのHaskell (表)
初めてのHaskell (表)
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.spec
 
Live Coding で学ぶ C# 7
Live Coding で学ぶ C# 7Live Coding で学ぶ C# 7
Live Coding で学ぶ C# 7
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんか
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & Listeners
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 

More from Taisuke Oe

プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」Taisuke Oe
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1Taisuke Oe
 
Monix Taskが便利だという話
Monix Taskが便利だという話Monix Taskが便利だという話
Monix Taskが便利だという話Taisuke Oe
 
How to get along with implicits
How to get along with implicits How to get along with implicits
How to get along with implicits Taisuke Oe
 
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Taisuke Oe
 
Real World Android Akka
Real World Android AkkaReal World Android Akka
Real World Android AkkaTaisuke Oe
 
Real world android akka
Real world android akkaReal world android akka
Real world android akkaTaisuke Oe
 
多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターンTaisuke Oe
 
Android BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsAndroid BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsTaisuke Oe
 
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~Taisuke Oe
 

More from Taisuke Oe (10)

プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
 
Monix Taskが便利だという話
Monix Taskが便利だという話Monix Taskが便利だという話
Monix Taskが便利だという話
 
How to get along with implicits
How to get along with implicits How to get along with implicits
How to get along with implicits
 
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Real World Android Akka - 日本語版
Real World Android Akka - 日本語版
 
Real World Android Akka
Real World Android AkkaReal World Android Akka
Real World Android Akka
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
 
多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン
 
Android BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsAndroid BLEのつらみを予防するTips
Android BLEのつらみを予防するTips
 
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
 

What Dotty fixes @ Scala関西サミット