SlideShare a Scribd company logo
プログラミング言語 
Scala 
安田裕介
歴史 
2001: スイス連邦工科大学のMartin Odersky教授がScalaの開発 
に着手 
2003: Javaプラットフォーム上でリリース 
2006: Scala 2.0をリリース 
2011: ヨーロッパ研究議会から230万€の研究助成金を獲得 
OderskyらがScalaの商用サポートを行うTypesafe社を設立 
Typesafe社がGreylock Partnersから300万$の投資を獲得
Scalaの特徴 
• あらゆる規模に対応するスケーラブルな言語 
• オブジェクト指向言語 
• 関数型言語 
• 静的型付け言語 
多彩な表現力をもつマルチパラダイム言語だ
Scalaの特徴 
そして何よりも強調したいのが、 
プログラマーとともに成長する言語 
プログラマーを成長させる言語
ScalaはREPLをもっている 
• この発表で出てくる 
コードはREPLで確認 
可能 
• シェルを立ち上げて 
scalaコマンドをたた 
こう
1.Scalaは 
オブジェクト指向言語 
• Scalaは徹底した純粋オブジェクト指向言語 
• すべてのメソッド、フィールドはオブジェクトに属 
している 
• あらゆる型の値はオブジェクトである
ScalaのHello World! 
println("Hello World!") 
ScalaのHello World!は非常に短い 
• セミコロン推論 
• printlnはPredefオブジェクトのメンバー 
• Predefオブジェクトはあらかじめimportされる 
• Javaのように静的mainメソッドをもつクラスを作る必要はない
Scalaではすべてのメソッド、 
フィールドはオブジェクトに属する 
• Scalaはクラスがメソッドやフィールドなどのメンバーをもつことを認め 
ていない。 
• Scalaではメソッドやフィールドはすべてオブジェクトに属する 
• Scalaではオブジェクトが主役となる 
• objectキーワードでシングルトンオブジェクトをダイレクトに生成できる 
object Singleton { 
val zero = 0 
def sum(x: Int, y: Int) = x + y 
}
あらゆる型の値は 
オブジェクトである 
Scalaではすべての値がオブジェクトだ 
プリミティブ型はないvoidはない。nullはあるがあまり使わない。 
scala> 1.toString 
res0: String = 1 
! 
scala> 1.0.toString 
res1: String = 1.0 
! 
scala> 'c'.toString 
res2: String = c 
! 
scala> true.toString 
res3: String = true 
! 
scala> "string".toString 
res4: String = string 
scala> val unit = (() => {})() 
unit: Unit = () 
! 
scala> val map = Map(1 -> "i", 2 -> "ii") 
map: scala.collection.immutable 
.Map[Int,String] = Map(1 -> i, 2 -> ii) 
! 
scala> val three = map.get(3) 
three: Option[String] = None 
すべてはAnyのサブクラスの値として表現される 
voidはUnit型の()オブジェクトに相当。 
NullクラスのnullオブジェクトよりもOption[Nothing] 
型のNoneオブジェクトの方をよく使う。
演算子は存在しない 
すべてはメソッドだ 
• 演算子は存在しない。あるのはメソッドのみ。 
• メソッド呼び出し形式と演算子形式を選択可能 
• あらゆる特殊記号を識別子として使用可能 
1 + 2 
1.+(2) ←この2つの式は等価 
REPLでTabを打ってみよう 
scala> 1. 
% + > >>> isInstanceOf toDouble toLong unary_+ 
| & - >= ^ toByte toFloat toShort unary_- * 
/ >> asInstanceOf toChar toInt toString unary_~ 
scala> val l = List(1) 
l: List[Int] = List(1) 
scala> l. 
++ /: :+ +: 
++: :: ::: :
トレイト 
トレイトとは?:機能の集合で、実装をもったインターフェースと思ってよい 
class Point(_x: Int = 0, _y: Int = 0) { 
def x = _x 
def y = _y 
def +(target: Point) = new Point(x + target.x, y + target.y) 
override def toString = s"(${x}, ${y})" 
} 
trait Landscape extends Point { 
override def x = super.y 
override def y = super.x 
} 
trait Retina extends Point { 
val ratio = 2 
override def x = super.x*ratio 
override def y = super.y*ratio 
def toNormal = new Point(super.x, super.y) 
} 
! 
class LRPoint extends Landscape with Retina 
new Point(3, 5) with Landscape with Retina 
//res0: Point with Landscape with Retina = (10, 6) 
実装を持っているので、インス 
タンス化時に直接ミックスイン 
することも可能 
クラスは複数のトレイトをミックスインできる
2.Scalaは関数型言語 
関数型言語は以下の2つの要素をもつ言語だ 
• イミュータビリティ(不変性) 
• 第一級オブジェクトとしての関数 
イミュータビリティはプログラムに安全性、拡張性をもたらし 
関数オブジェクトは柔軟性、簡潔性、表現力をもたらす
イミュータビリティ 
(不変性) 
• 変更不可能な変数宣言 
• イミュータブルなデータ型 
• パターンマッチ
変更不可能な変数宣言 
再代入不可能な変数宣言にはvalを使う 
scala> val abc = "abc" 
abc: String = abc 
! 
scala> abc = "cde" 
<console>: error: reassignment to val 
abc = "cde" 
^ 
再代入可能な変数宣言にはvarを使う 
scala> var abc = "abc" 
abc: String = abc 
! 
scala> abc = "cde" 
abc: String = cde
イミュータブルなデータ型 
Scalaでは不変なデータ型と可変なデータ型は区別されている。データ型はデフォルトで不変だ。 
不変なデータ型ではあらゆる操作を何回施しても値はもとのままである。 
scala> val m12 = Map("1" -> 1, "2" -> 2) 
m12: scala.collection.immutable.Map[String,Int] = Map(1 -> 1, 2 -> 2) 
scala> val m123 = m12 + ("3" -> 3) 
m123: scala.collection.immutable.Map[String,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3) 
scala> m123 
res0: scala.collection.immutable.Map[String,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3) 
scala> m12 == m123 
res1: Boolean = false 
Scalaは可変なデータ型を使う余地も残している 
scala> import scala.collection.mutable.Map 
import scala.collection.mutable.Map 
scala> val m12 = Map("1" -> 1, "2" -> 2) 
m12: scala.collection.mutable.Map[String,Int] = Map(2 -> 2, 1 -> 1) 
scala> val m123 = m12 += ("3" -> 3) 
m123: m12.type = Map(2 -> 2, 1 -> 1, 3 -> 3) 
scala> m12 
res2: scala.collection.mutable.Map[String,Int] = Map(2 -> 2, 1 -> 1, 3 -> 3) 
scala> m12 == m123 
res3: Boolean = true
パターンマッチ 
パターンマッチはパターンによって値と変数を束縛する。 
パターンマッチを使えば代入などの副作用やキャスト、nullかどうかなどの判定 
といった危険な処理を一切行わずにすむ。 
例)翼を含めた動物の足の数を合計する 
abstract class Animal { 
val legs: Int 
} 
class Dog extends Animal { 
val legs = 4 
} 
class Bird extends Animal { 
val legs = 2 
val wings = 2 
} 
val animals = List(new Dog, new Bird) 
//animals: List[Animal] = List(Dog@1e339ce8, Bird@4e8252d5) 
animals.map({ 
case bird: Bird => bird.legs + bird.wings 
case animal: Animal => animal.legs 
}).reduce(_ + _) 
//res0: Int = 8
第一級オブジェクトとしての関数 
第一級オブジェクトとは 
オブジェクトがもつべきあらゆる能力をもつオブジェクト 
•変数に代入することができる 
scala> val sum = (x: Int, y: Int) => x + y 
sum: (Int, Int) => Int = <function2> 
•関数の引数に渡すことができる 
scala> List(1,2,3).map(_ * 2) 
res0: List[Int] = List(2, 4, 6) 
•関数の返り値として返すことができる 
scala> def optioned[A, B](f: A => B) 
: Option[A] => Option[B] = _ map f 
optioned: [A, B](f: A => B)Option[A] => Option[B] 
•メンバーをもつ 
scala> ((x: Int) => x + 1).compose((x: Int) => x * 2) 
res1: Int => Int = <function1>
関数適用ができるオブジェクト 
オブジェクトは呼び出すものではないが、Scalaでは引数を適用で 
きる 
scala> :paste 
Entering paste mode (ctrl-D to finish) 
class Applicable(val s: String) 
! 
object Applicable { 
def apply(s: String) = new Applicable(s) 
} 
Exiting paste mode, now interpreting. 
defined class Applicable 
defined object Applicable 
! 
scala> Applicable("abc") 
res0: Applicable = Applicable@1cb285b 
コンパイラはオブジェクトへの引数の適用をapplyメソッド呼び出しに置き換える。 
ListやMapに引数を適用できるのは、それらがapplyメソッドを定義しているからだ。
値を返す制御構造 
if, for, whileのような制御構造はすべて式であり、値を返す。 
val result = if ("string" == new String("string")) “reasonable" 
else "unreasonable" 
result: String = reasonable 
for式はコンプリヘンション形式でフィルターをかけられる。 
yieldキーワードでコレクションを作ることができる。 
scala> for (i <- 1 until 9 if i % 2 == 0) yield i 
res0: scala.collection.immutable.IndexedSeq[Int] 
= Vector(2, 4, 6, 8)
match式 
switchに相当。パターンマッチにより値を抽出し、それを返す。 
abstract class Expr 
case class Var(name: String) extends Expr 
case class Number(num: Double) extends Expr 
case class UnOp(operator: String, arg: Expr) extends Expr 
case class BinOp(operator: String, left: Expr, right: Expr) extends 
Expr 
! 
val twoPlusZero = BinOp("+", Number(2), Number(0)) 
! 
def simplify(expr: Expr) = { 
expr match { 
case UnOp("-", UnOp("-", e)) => e 
case BinOp("+", e, Number(0)) => e 
case BinOp("*", e, Number(1)) => e 
case _ => expr 
} 
} 
! 
val number = simplify(twoPlusZero) 
number: Expr = Number(2.0) 
※コップ本に載っている例
caseクラス 
クラスとすべての引数の情報を再帰的に木構造にして内部に保 
持することで、再帰的なパターンマッチを可能にするクラス 
caseクラスは以下を自動定義する 
1.objectのapplyメソッドを定義val v = Var("x") 
val twoPlusZero = BinOp("+", Number(2), Number(0)) 
scala> twoPlusZero.toString 
res1: String = BinOp(+,Number(2.0),Number(0.0)) 
twoPlusZero.hashCode 
res2: Int = -571098259 
BinOp("+", Number(2), Number(0)) 
== BinOp("+", Number(2), Number(0)) 
res3: Boolean = true 
v.name 
//res0: String = x 
2.コンストラクタ引数にvalプレフィックスを付与 
3.toString, hashCode, equalsメソッドを定義
カリー化 
複数のパラメーターリストをもつ関数を定義できる 
カリー化によって関数を部分的に適用できる 
scala> def twice[T](arg: T)(op: (T) => T) = op(op(arg)) 
! 
twice(3)(x => x * x) 
res0: Int = 81 
! 
scala> val three = twice(3) _ 
three: (Int => Int) => Int = <function1> 
! 
scala> three(x => x * x) 
res1: Int = 81 
twice(3) {x => 
val square = x * x 
square + 1 
} 
res2: Int = 101 
()は{}に置き換え可能。 
このように書くとまるで独自の 
制御構造を作っているようだ
暗黙の型変換 
AndroidのsetOnClickListenerにFunctionオブジェクトを渡したい 
class MainActivity extends TypedActivity { 
override def onCreate(bundle: Bundle) { 
super.onCreate(bundle) 
setContentView(R.layout.main) 
val view = findView(TR.button) 
view.setOnClickListener(new View.OnClickListener { 
override def onClick(v: View) 
= Log.d("pressed", "button") 
}) 
} 
} 
※android-sdk-pluginテンプレートを使用 
暗黙の型変換を定義すれば関数オブジェクトを渡すことができる 
implicit def func2OnClick(f: () => _) = new OnClickListener { 
override def onClick(v: View) = f 
} 
! 
view.setOnClickListener(() => Log.d("pressed", "button"))
暗黙のパラメーター 
パラメーターリストが足りないまま関数が呼び出されたとき、足りな 
いパラメーターリストがimplicit宣言されていた場合、スコープ中の 
implicit宣言された値で関数を完成させる 
def maxList[T](elements: List[T])(implicit orderer: T => 
Ordered[T]): T = 
elements match { 
case List() => throw new IllegalArgumentException("empty 
list") 
case List(x) => x 
case x :: rest => val maxRest = maxList(rest)(orderer) 
if (orderer(x) > maxRest) x 
else maxRest 
} 
! 
scala> maxList(List(1,2,3,4,5)) 
res0: Int = 5 
※コップ本に載っている例 
ScalaライブラリはT=>Ordered[T]の暗黙の定義を提供しているので、 
Orderedトレイトを継承していないIntでもmaxListは使える
3.Scalaは 
静的型付け言語 
Scalaは厳格な型付けを行うが、開発者を難しい型シ 
ステムから解放するいくつかの仕組みをもっている 
• 型推論 
• ダックタイピング 
• ジェネリクスにおける変位指定のチェック
ダックタイピング 
ダックタイピングとは? 
アヒルのように鳴けばそれはアヒルであるという考えのもと、メンバー 
のシグニチャが同じであれば型が違っても互換性のある型とみなすこと 
def using[T <: {def close(): Unit}, S](obj: T)(operation: T => S) = { 
val result = operation(obj) 
obj.close() 
result 
} 
! 
import java.io.PrintWriter 
! 
using(new PrintWriter("date.txt")) { writer => 
writer.println(new java.util.Date) 
} 
※コップ本に載っている例 
ここではPrintWriterを渡しているが、セッションやソケットなど、close 
メソッドを持っているオブジェクトなら何でも渡せる
変位指定のチェック 
ジェネリックな型には変位という概念がある 
変位の種類は3つある。 Sのサブ型がTであるとき 
非変:Class[T]とClass[S]にサブ型関係はない 
共変:Class[T]はClass[S]のサブ型である 
反変:Class[T]はClass[S]のスーパー型である 
ここで共変な型Cell[+T]を定義する。しかしコンパイルを通らない。なぜだろうか? 
class Cell[+T](init: T) { 
private[this] var current = init 
def get = current 
def set(x: T) { current = x } 
} 
error: covariant type T occurs in contravariant position in type T of 
value x 
def set(x: T) { current = x } 
^ 
※コップ本に載っている例
変位指定のチェック 
さきほどのコードがコンパイルを通らないのは、以下のよ 
うな反例が書けるからである 
val c1 = new Cell[String]("abc") 
val c2: Cell[Any] = c1 
c2.set(1) 
val s: String = c1.get 
このコードは型に矛盾はない。しかし結果としてString型 
の変数にInt型の値を代入することを許している。もしこれ 
がコンパイルを通ると、実行時エラーの危険を生む。 
Scalaコンパイラは型パラメーターが現れるすべての場所を 
チェックし、危険があれば開発者に教えてくれる
さらにその先へ 
Scalaコレクション 
アクター 
アドホック多相性モナド 
並列コレクション 
パーサー・コンビネーター抽出子
まとめ 
• Scalaは非常に表現力が高く、言語そのものを拡張 
する感じで書ける 
• Scalaは様々なパラダイムを取り込んでおり、それ 
らを徐々に習得することで開発者は成長できる 
いつやるの?

More Related Content

PDF
Scala の関数型プログラミングを支える技術
PDF
What Dotty fixes @ Scala関西サミット
PDF
Scala with DDD
KEY
Actor&stm
PDF
今から始める Lens/Prism
PDF
AuxパターンをDottyで解決する
PPT
Pythonintro
PDF
Ekmett勉強会発表資料
Scala の関数型プログラミングを支える技術
What Dotty fixes @ Scala関西サミット
Scala with DDD
Actor&stm
今から始める Lens/Prism
AuxパターンをDottyで解決する
Pythonintro
Ekmett勉強会発表資料

What's hot (19)

PDF
たのしい高階関数
PDF
初心者講習会資料(Osaka.R#5)
PDF
BOF1-Scala02.pdf
PPTX
C# LINQ入門
PDF
Van laarhoven lens
PPTX
Chapter 6: Computing on the language (R Language Definition)
PDF
JastAdd & JastAddJ クリックチュートリアル
ODP
Ekmett勉強会発表資料
PDF
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
PPTX
Javaプログラミング入門【第7回】
PDF
関数プログラミング入門
PPT
言語処理系入門€5
PDF
Scalaで型クラス入門
PDF
初心者講習会資料(Osaka.r#6)
KEY
Clojure programming-chapter-2
PDF
たのしい関数型
PPTX
ゼロから始めるScala文法 (再)
PDF
Javaセキュアコーディングセミナー東京第1回演習の解説
PPTX
大人のお型付け
たのしい高階関数
初心者講習会資料(Osaka.R#5)
BOF1-Scala02.pdf
C# LINQ入門
Van laarhoven lens
Chapter 6: Computing on the language (R Language Definition)
JastAdd & JastAddJ クリックチュートリアル
Ekmett勉強会発表資料
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
Javaプログラミング入門【第7回】
関数プログラミング入門
言語処理系入門€5
Scalaで型クラス入門
初心者講習会資料(Osaka.r#6)
Clojure programming-chapter-2
たのしい関数型
ゼロから始めるScala文法 (再)
Javaセキュアコーディングセミナー東京第1回演習の解説
大人のお型付け
Ad

Viewers also liked (7)

PDF
CRDT in 15 minutes
PDF
Isomorphic web development with scala and scala.js
PPTX
Akka Clusterの耐障害設計
PDF
これからのJavaScriptー関数型プログラミングとECMAScript6
PDF
ECMAScript6による関数型プログラミング
PPTX
スケールするシステムにおけるエンティティの扱いと 分散ID生成
PPTX
Architecture of Falcon, a new chat messaging backend system build on Scala
CRDT in 15 minutes
Isomorphic web development with scala and scala.js
Akka Clusterの耐障害設計
これからのJavaScriptー関数型プログラミングとECMAScript6
ECMAScript6による関数型プログラミング
スケールするシステムにおけるエンティティの扱いと 分散ID生成
Architecture of Falcon, a new chat messaging backend system build on Scala
Ad

Similar to プログラミング言語Scala (20)

PDF
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
PDF
fanscala1 2 scalaの基本
PPTX
関数型言語&形式的手法セミナー(3)
PDF
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
PPT
Rpscala2011 0601
PDF
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 1 章
PDF
Introduction Xtend
PDF
BOF1-Scala02.pdf
PDF
BOF1-Scala02.pdf
PDF
ATN No.2 Scala事始め
PDF
初心者講習会資料(Osaka.R#7)
PPTX
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
PPTX
[機械学習]文章のクラス分類
PPTX
ゆるふわScalaコップ本読書会 第7章
PDF
map関数の内部実装から探るJVM言語のコレクション: Scala, Kotlin, Clojureコレクションの基本的な設計を理解しよう
PDF
F#入門 ~関数プログラミングとは何か~
PDF
15分でざっくり分かるScala入門
ODP
Haskell
PDF
第2回関数型言語勉強会 大阪
PDF
Pythonで始めるDropboxAPI
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
fanscala1 2 scalaの基本
関数型言語&形式的手法セミナー(3)
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
Rpscala2011 0601
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 1 章
Introduction Xtend
BOF1-Scala02.pdf
BOF1-Scala02.pdf
ATN No.2 Scala事始め
初心者講習会資料(Osaka.R#7)
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
[機械学習]文章のクラス分類
ゆるふわScalaコップ本読書会 第7章
map関数の内部実装から探るJVM言語のコレクション: Scala, Kotlin, Clojureコレクションの基本的な設計を理解しよう
F#入門 ~関数プログラミングとは何か~
15分でざっくり分かるScala入門
Haskell
第2回関数型言語勉強会 大阪
Pythonで始めるDropboxAPI

More from TanUkkii (9)

PDF
Distributed ID generator in ChatWork
PDF
Non-blocking IO to tame distributed systems ー How and why ChatWork uses async...
PPTX
JSON CRDT
PDF
WaveNet
PPTX
Akka HTTP
PDF
すべてのアクター プログラマーが知るべき 単一責務原則とは何か
PDF
ディープニューラルネット入門
PDF
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
PDF
Scalaによる型安全なエラーハンドリング
Distributed ID generator in ChatWork
Non-blocking IO to tame distributed systems ー How and why ChatWork uses async...
JSON CRDT
WaveNet
Akka HTTP
すべてのアクター プログラマーが知るべき 単一責務原則とは何か
ディープニューラルネット入門
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
Scalaによる型安全なエラーハンドリング

プログラミング言語Scala