Scala overview
-
Upload
steve-min -
Category
Technology
-
view
105 -
download
3
description
Transcript of Scala overview
민형기
S-Core Cloud Computing Lab
Data Solution Part
2013. 2. 18.
1
Contents
I. Scala란?
II. Scala는 간결하다.
III. Scala는 객체지향 언어이다.
IV. Scala는 함수형 언어이다.
V. Scala는 동적 언어이다.
VI. Scala는 정적으로 타입화된 언어이다.
VII. Scala는 많은 좋은 기능이 있다.
VIII.Scala를 어떻게 공부하지?
2
Scala 란?
object Hello {
def main(args:Array[String]) {
println(“Hello, World”)
}
}
3
Scala 정의
Scala [skah-lah] = scalable language
The language is so named because it was designed to grow with the demands of its users.
-Programming In Scala, p39
The language is so named because it was designed to grow with the demands of its users.
-Programming In Scala, p39
Scala is a modern multi-paradigm programming language designed to express common programming patterns in a concise, elegant, and type-safe way.
-scala-lang.com
Scala is a modern multi-paradigm programming language designed to express common programming patterns in a concise, elegant, and type-safe way.
-scala-lang.com
4
Scala에 대한 의견들
If I were to pick a language to use on the JVM today other than Java, it would be Scala.
-James Gosling, creater of Java
If I were to pick a language to use on the JVM today other than Java, it would be Scala.
-James Gosling, creater of Java
Scala, it must be stated, is the current heir apparent to the Java throne. No other language on the JVM seems as capable of being a “replacement for Java” as Scala, and the momentum behind Scala is now uniquestionable.
- Charlies Nutter, JRuby lead
Scala, it must be stated, is the current heir apparent to the Java throne. No other language on the JVM seems as capable of being a “replacement for Java” as Scala, and the momentum behind Scala is now uniquestionable.
- Charlies Nutter, JRuby lead
My tip thought for the long term replacement of javac is Scala. I’m very impressed with it! I can honestly say if someone had shown me the Programming in Scala book […] back in 2003. I’d probably have never created Groovy.
-James Strachan, creator of Groovy
My tip thought for the long term replacement of javac is Scala. I’m very impressed with it! I can honestly say if someone had shown me the Programming in Scala book […] back in 2003. I’d probably have never created Groovy.
-James Strachan, creator of Groovy
http://www.adam-bien.com/roller/abien/entry/java_net_javaone_which_programming
http://macstrac.blogspot.com/2009/04/scala-as-long-term-replacement-for.html
http://blog.headius.com/2009/04/future-part-one.html
5
Scalability in Programming Language
어플리케이션이 사용자의 요구에 맞추기 위해 크기나 용량을 변경해도, 그 기능이 계속하여 잘 동작 할 수 있는 능력
-Terms
어플리케이션이 사용자의 요구에 맞추기 위해 크기나 용량을 변경해도, 그 기능이 계속하여 잘 동작 할 수 있는 능력
-Terms
문제 영역의 크기나 복잡도가 증가하여도 유사한 방법으로 문제 해결이 가능한 것. - 빌딩 블록의 수가 증가하면 추상화 / 축약 - 언어의 지원 / 라이브러리 / 프레임 워크
문제 영역의 크기나 복잡도가 증가하여도 유사한 방법으로 문제 해결이 가능한 것. - 빌딩 블록의 수가 증가하면 추상화 / 축약 - 언어의 지원 / 라이브러리 / 프레임 워크
6
언어 확장의 예시 – 분수 (Rational)
규칙: (a, b) 단, b != 0 (a, b) + (c, d) = (ad+bc, bd) (a, b) * (c, d) = (ac, bd)
규칙: (a, b) 단, b != 0 (a, b) + (c, d) = (ad+bc, bd) (a, b) * (c, d) = (ac, bd)
*기타 - Big Integer - Complex number - Vector - Matrix …
*기타 - Big Integer - Complex number - Vector - Matrix …
7
BigInteger vs. BigInt
public BigInteger factorial(BigInteger x) {
if ( x == BigInteger.ZERO )
return BigInteger.ONE;
else
return x.multiply(
factorial (x.subtract(BigInteger.ONE)));
}
def factorial(x: BigInt):BigInt =
if (x == 0) 1 else x * factorial(x-1)
Java
Scala
Integer와
유사하지 않음
출처: http://www.artima.com/scalazine/articles/scalable-language.html
8
Google Trends
출처: http://www.google.com/trends/explore#q=scala,%20clojure,%20groovy
9
Job Trends
출처: http://www.indeed.com/jobtrends?q=scala%2C+clojure%2C+groovy&l=
10
Scala Today
출처: http://www.slideshare.net/Odersky/devoxx
11
Scala Best Practices
출처: http://www.slideshare.net/mslinn/scala-adoption-by-enterprises
Twitter –Kestrel: queuing
–FlockDB(and Gizzard): social graph store
–Hawkwind: people search
–Hosebird: streaming API
–Scalding: MapReduce Wrapper (build on top of Cascading)
Guardian: Open Platform –2009.11: java + guice + guice servlets + apache solr
–2010.01: Integration tests with ScalaTest / maven scala plugin
–2010.03: scala + guice + guice servlets + apache solr
–2010.06: maven -> sbt
–2011.06: scala + lift + apache solr ( 5k loc -> 3.5k)
in Java 1.5: Pair p = new Pair<Integer, String>(1, "Scala");
in Scala: val p = new MyPair(1, "scala");
12
Scala 언어 가계도
Scala
Java
C
C++
Simula
Smalltalk
Prolog
Erlang Haskell
ML
Lisp
functional
programming syntax
objects
pattern
matching
Actors
13
Scala를 멀리서 보기
함수형
프로그래밍
객체 지향
프로그래밍
동적
프로그래밍
강화된 타입 시스템
JVM/.Net
※동적 프로그래밍: 스칼라는 엄밀히 말하자면 동적 언어는 아니지만, 동적 언어에서 제공하는 많은 특징을 가지고 있다.
(간결함(Concise), REPL, 고수준함수, Duck Typing 등)
14
Scala 특징 1/3
Scala는 함수형과 객체지향형의 성격을 다 가지고 있다. –Method를 포함한 모든 함수 (function)은 값(value)이다.
–모든 값(value)는 객체(object)이다.
Scala는 정적 타입시스템이다. –강력한 타입 추론 시스템: in Java 1.5: Pair p = new Pair<Integer, String>(1, "Scala");
in Scala: val p = new MyPair(1, "scala");
15
Scala 특징 2/3
가벼운 문법(lightweight syntax)
–Anonymous functions
–Higher-order functions
–Nested Functions
–Currying
ML-style의 Pattern Matching
XML과 통합
–Scala 프로그램에서 XML을 직접 쓸 수 있다.
–Scala 클래스 정의로 XML DTD로 변환할 수 있다.
정규식 패턴
DSLs
Concurrency via actors
16
Scala 특징 3/3 – Scala는 실용적이다.
Java를 대체해서 사용이 가능함
Java와 Scala를 혼합한 프로젝트가 가능
기존 Java 라이브러리를 활용가능
기존 Java 툴(Ant, Maven, Junit, etc…)을 활용가능
기존 IDE 환경을 지원 (Eclipse, NetBeans, IntelliJ)
17
Scala compared to Java
Scala adds Scala removes
+ a pure object system - static members
+ operator overloading - primitive Types
+ closures - break, continue
+ mixin composition with traits - special treatment of interfaces
+ existential types - wildcards
+ abstract types - raw types
+ pattern matching - enums
Modeled in libiaries:
assert, enums, properties, events, actors, using, queries, …
출처: http://www.slideshare.net/Odersky/fosdem-2009-1013261
18
Scala는 간결하다.
object Hello {
def main(args:Array[String]) {
println(“Hello, World”)
}
}
19
Type Interface
val sum = 1 + 2 + 3 >sum: Int = 6 val nums = List(1, 2, 3) >nums: List[Int] = List(1, 2, 3) val map = Map("abc" -> List(1,2,3)) >map: scala.collection.immutable.Map[java.lang.String,List[Int]] = Map(abc -> List(1, 2, 3))
20
Explicit Types
val sum: Int = 1 + 2 + 3 val nums: List[Int] = List(1, 2, 3) val map: Map[String, List[Int]] = ...
21
Higher Level
// Java – Check if string has uppercase character
boolean hasUpperCase = false;
for(int i = 0; i < name.length(); i++) {
if(Character.isUpperCase(name.charAt(i))) {
hasUpperCase = true;
break;
}
}
// Scala
val hasUpperCase = name.exists(_.isUpperCase)
22
Less Boilerplate
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
class Person(var name: String,
var age: Int)
Java
class Person(var name: String,
private var _age: Int){
def age = _age // Getter
def age_=(newAge:Int) { // Setter
_age = newAge
}
}
Scala
23
Variables and Values
// variable
var foo = "foo"
foo = "bar" // okay
// value
val bar = "bar"
bar = "foo" // nope
24
Scala는 객체지향 언어이다.
object Hello {
def main(args:Array[String]) {
println(“Hello, World”)
}
}
25
Class Hierarchy
출처: https://docs.google.com/document/pub?id=1kSNKKKwM8rjGhn9Gnw-6Q0VCImpwSRZ7_QzwNwXgMxM
26
Pure O.O.
// Every value is an object
1.toString
// Every operation is a method call
1 + 2 + 3 (1).+(2).+(3)
// Can omit . and ( )
"abc" charAt 1 "abc".charAt(1)
27
Classes
// Classes (and abstract classes) like Java
abstract class Language(val name:String) {
override def toString = name
}
// Example implementations
class Scala extends Language("Scala")
// Anonymous class
val scala = new Language("Scala") { /* empty */ }
28
Case Classes
case class Person(firstName: String = "Jamie", lastName: String = "Allen") val jamieDoe = Person(lastName = "Doe") // Person(Jamie,Doe) abstract class Tree case class Sum(l: Tree, r: Tree) extends Tree case class Var(n: String) extends Tree case class Const(v: Int) extends Tree … type Environment = String => Int def eval(t: Tree, env: Environment): Int = t match { case Sum(l, r) => eval(l, env) + eval(r, env) case Var(n) => env(n) case Const(v) => v }
Data Transfer Objects (DTOs) done right
By default, class arguments are immutable & public
Should never be extended
Provide equals(), copy(), hashCode() and toString() implementations
Don’t have to use new keyword to create instances
Named Parameters and Default arguments give us Builder pattern semantics
29
Traits
// Like interfaces in Java
trait Language {
val name:String
// But allow implementation
override def toString = name
}
30
Traits
trait JVM {
override def toString = super.toString+" runs on JVM" }
trait Static {
override def toString = super.toString+" is Static" }
// Traits are stackable
class Scala extends Language with JVM with Static {
val name = "Scala"
}
println(new Scala) "Scala runs on JVM is Static"
31
Objects
object Bootstrapper extends App { Person.createJamieAllen } object Person { def createJamieAllen = new Person("Jamie", "Allen") def createJamieDoe = new Person("Jamie", "Doe") val aConstantValue = "A constant value” } class Person(val firstName: String, val lastName: String)
Singletons within a JVM process No private constructor histrionics Companion Objects, used for factories and constants
32
Tuples
def getNameAndAge: Tuple2[String, Int] = { val name = “Steve” val age = 30 (name, age) } val (name, age) = getNameAndAge println(“Name: “+ name) // Name: Steve println(“Age: “ + age) // Age: 30 val scalet = (“Scalet”, 27, “Seoul”) // scalet: (String, Int, String) = (“Scalet”, 27, “Seoul”) println(“Address: “ + scalet._3) // Address: Seoul
Tuple is a generalization of that: a collection of two, three, four, and more values Tuple can hold objects with different types but they are also immutable
33
Scala는 함수형 언어이다.
object Hello {
def main(args:Array[String]) {
println(“Hello, World”)
}
}
34
g(f(X))
35
Characteristic Imperative Functional
Programmer focus How to perform tasks (algorithms) and how to track changes in state.
What information is desired and what transformations are required.
State Changes Important. Non-existent.
Order of execution Important. Low importance.
Primary flow control Loops, conditionals, and function (method) calls
Function calls, including recursion.
Primary manipulation unit Instances of structures or classes.
Functions as first-class objects and data collections.
Imperative Style vs. Functional Style
출처: http://msdn.microsoft.com/en-us/library/bb669144.aspx
36
Function Type + Function Literal
// Type
(Int, Int)=>Int
// Literal
(x:Int, y:Int) => x + y
37
First Class Functions
// Lightweight anonymous functions (x:Int, y:Int) => x + y // Calling the anonymous function val add = (x:Int, y:Int) => x + y val add : (Int, Int) => Int = (x:Int, y:Int) => x + y val add : (Int, Int) => Int = _ + _ val add = new Function2[Int, Int, Int] { def apply(x:Int, y:Int):Int = x + y } add(5,1) 6 add.apply(5,1) 6
Function name Argument List Function expression
어떤 함수가 다음 조건을 만족하면 일급 함수로 간주한다. 1. 변수나 데이터 구조안에 담을 수 있다. 2. 파라미터로 전달 할 수 있다. 3. 반환값(return value)으로 사용할 수 있다. 4. 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
어떤 함수가 다음 조건을 만족하면 일급 함수로 간주한다. 1. 변수나 데이터 구조안에 담을 수 있다. 2. 파라미터로 전달 할 수 있다. 3. 반환값(return value)으로 사용할 수 있다. 4. 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
출처: http://en.wikipedia.org/wiki/First-class_function
38
Closures
// plusFoo can reference any values/variables in scope
var foo = 1
val plusFoo = (x:Int) => x + foo
plusFoo(5) 6
// Changing foo changes the return value of plusFoo
foo = 5
plusFoo(5) 10
39
Pattern Matching
def what(any:Any) = any match {
case i:Int => "It's an Int"
case s:String => "It's a String"
case _ => "I don't know what it is"
}
what(123) "It's an Int"
what("hello") "It's a String"
what(false) "I don't know what it is"
40
Pattern Matching
val nums = List(1,2,3)
// Pattern matching to create 3 vals
val List(a,b,c) = nums
a 1
b 2
c 3
41
Immutable Types
// Immutable types by default
var nums = Set(1,2,3)
nums += 4 nums = nums.+(4)
// Mutable types available
import scala.collection.mutable._
val nums = Set(1,2,3)
nums += 4 nums.+=(4)
42
Referential Transparency
// Transparent val example1 = "jamie".reverse val example2 = example1.reverse println(example1 + example2) // eimajjamie // Opaque val example1 = new StringBuffer("Jamie").reverse val example2 = example1.reverse println(example1 append example2) // jamiejamie
An expression is transparent if it can be replaced by its VALUE without changing the behavior of the program
In math, all functions are referentially transparent
43
Scala Collections
val myMap = Map(1 -> "one", 2 -> "two", 3 -> "three") val mySet = Set(1, 4, 2, 8) val myList = List(1, 2, 8, 3, 3, 4) val myVector = Vector(1, 2, 3...)
You have the choice of mutable or immutable collection instances, immutable by default
Rich implementations, extremely flexible
44
Rich Collection Functionality
val numbers = 1 to 20 // Range(1, 2, 3, ... 20) numbers.head // Int = 1 numbers.tail // Range(2, 3, 4, ... 20) numbers.take(5) // Range(1, 2, 3, 4, 5) numbers.drop(5) // Range(6, 7, 8, ... 20)
There are many methods available to you in the Scala collections library
Spend 5 minutes every day going over the ScalaDoc for one collection class
45
scala.collection
46
scala.collection.immutable
47
scala.collection.mutable
48
Or Use Existing Java Collections
java.util
Apache Commons Collections
fastutil
Trove
Google Collections
scala.collection.JavaConversion available to convert to and from java.util Interfaces
49
Higher Order Functions
val plusOne = (x:Int) => x + 1
val nums = List(1,2,3)
// map takes a function: Int => T
nums.map(plusOne) List(2,3,4)
// Inline Anonymous
nums.map(x => x + 1) List(2,3,4)
// Short form
nums.map(_ + 1) List(2,3,4)
50
Higher Order Functions
val nums = List(1,2,3,4)
// A few more examples for List class
nums.exists(_ == 2) true
nums.find(_ == 2) Some(2)
nums.indexWhere(_ == 2) 1
nums.reduceLeft(_ + _) 10
nums.foldLeft(100)(_ + _) 110
nums.filter(_ % 2 == 0) List(2,4)
// Many more in collections library
flatMap, flatten, zip, fold, foldRight, reduce, reduceRight, groupBy
partition, slice, take, takeRight, takeWhile, drop, dropRight, dropWhile, splitAt
sortBy, sortWith, startsWith, endsWith, product, sum …
51
Higher Order Functions
// functions as parameters
def call(f: Int => Int) = f(1)
call(plusOne) 2
call(x => x + 1) 2
call(_ + 1) 2
52
Higher Order Functions
// functions as parameters
def each(xs: List[Int], fun: Int => Unit) {
if(!xs.isEmpty) {
fun(xs.head)
each(xs.tail, fun)
}
}
each(List(1,2,3), println)
1
2
3
53
Higher Order Functions
// More complex example with generics & pattern matching
@tailrec
def each[T](xs: List[T], fun: T => Unit): Unit = xs match {
case Nil =>
case head :: tail => fun(head); each(tail, fun)
}
each(List(1,2), println)
1
2
each(List("foo", "bar"), println)
foo
bar
class List[+A] … { def head: A def tail: List[A] … }
54
Parallel Collections
scala> 1 to 1000000 res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3,... scala> res0.par res1: s.c.parallel.immutable.ParRange = ParRange(1, 2, 3,... scala> res1 map(_ + 1) res2: s.c.parallel.immutable.ParSeq[Int] = ParVector(2, 3, 4,... scala> res2.seq res3: s.c.immutable.Range = Range(2, 3, 4,...
You can easily parallelize the application of a function literal to your collection by calling the par() method on a collection instance
Uses JSR166 under the covers to fork/join for you
Use the seq() method on the parallel collection to return to a non-parallel instance
55
Partial Functions
val sample = 1 to 10 val isEven: PartialFunction[Int, String] = { case x if x % 2 == 0 => x+" is even" } val isEven= new PartialFunction[Int, String] { override def apply(x:Int):String = x+" is even" override def isDefinedAt(x:Int):Boolean = x % 2 == 0 } // the method collect can use isDefinedAt to select which members to collect val evenNumbers = sample collect isEven > evenNumbers = Vector(2 is even, 4 is even, 6 is even, 8 is even, 10 is even) val isOdd: PartialFunction[Int, String] = { case x if x % 2 == 1 => x+" is odd" } // the method orElse allows chaining another partial function to handle // input outside the declared domain val numbers = sample map (isEven orElse isOdd) > numbers = Vector(1 is odd, 2 is even, 3 is odd, 4 is even, 5 is odd, 6 is even, 7 is odd, 8 is even, 9 is odd, 10 is even)
56
Currying
// multiple arguments def add(x:Int, y:Int) = x + y add(1, 2) // 3 add(7, 3) // 10 // after currying, single arguments def add(x:Int) = (y:Int) => x + y def add(x:Int)(y:Int) = x + y add(1)(2) // 3 add(7)(3) // 10
In computer science, currying, invented by Moses Schönfinkel and Gottlob Frege, is the technique of transforming a function that takes multiple arguments into a function that takes a single argument (the other arguments having been specified by the curry).
57
Partially Applied Functions
def justSum(a:Int,b:Int,c:Int) = a+b+c val partial1 = justSum _ val partial2 = justSum(1, _:Int, 8) def curriedSum(a:Int)(b:Int)(c:Int) = a+b+c println("Partial 1: "+partial1(5,6,7)) // Partial 1: 18 println("Partial 2: "+partial2(4)) // Partial 2: 13
58
Scala는 동적 언어이다.
(엄밀히 말하자면 동적 언어는 아니지만, 동적 언어에서 제공하는 많은 특징을 가지고 있다.)
object Hello {
def main(args:Array[String]) {
println(“Hello, World”)
}
}
59
Scriptable
// HelloWorld.scala
println("Hello World")
bash$ scala HelloWorld.scala
Hello World
bash$ scala -e 'println("Hello World")'
Hello World
60
Read-Eval-Print Loop
bash$ scala
Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.
scala> class Foo { def bar = "baz" }
defined class Foo
scala> val f = new Foo
f: Foo = Foo@51707653
scala> f.bar
res2: java.lang.String = baz
61
Structural Typing – Type safe Duck Typing
// Duck Typing (other language)
def test(o)
log o.getName # Let's hope this will work
end
// Type safe Duck Typing
def doTalk(any:{def talk:String}) {
println(any.talk)
}
class Duck { def talk = "Quack" }
class Dog { def talk = "Bark" }
doTalk(new Duck) "Quack"
doTalk(new Dog) "Bark"
출처: http://beust.com/weblog/2008/02/11/structural-typing-vs-duck-typing/
62
Implicit Conversions
// Extend existing classes in a type safe way
// Goal: Add isBlank method to String class
class RichString(s:String) {
def isBlank = null == s || "" == s.trim
}
implicit def toRichString(s:String) = new RichString(s)
// Our isBlank method is now available on Strings
" ".isBlank true
"foo".isBlank false
63
Implicit Conversions
// Does not type check
"abc".isBlank
// Search in-scope implicits defs that take a
// String & return a type with an isBlank method
implicit def toRichString(s:String):RichString
// Resulting code that type checks
new RichString("abc").isBlank
64
method_missing (Scala 2.9 Feature)
// Dynamic is a marker trait used by the compiler
class Foo extends Dynamic {
def typed[T] = error("not implemented")
def applyDynamic(name:String)(args:Any*) = {
println("called: "+name+"("+args.mkString(",")+")")
}
}
val f = new Foo
f.helloWorld called: helloWorld()
f.hello("world") called: hello(world)
f.bar(1,2,3) called: bar(1,2,3)
65
Scala는 정적으로 타입화된 언어이다.
object Hello {
def main(args:Array[String]) {
println(“Hello, World”)
}
}
66
Generic Classes
class Stack[T] {
var elems: List[T] = Nil
def push(x: T) { elems = x :: elems }
def top: T = elems.head
def pop() { elems = elems.tail }
}
object GenericsTest extends Application {
val stack = new Stack[Int]
stack.push(1)
stack.push('a')
println(stack.top) // 97
stack.pop()
println(stack.top) // 1
}
출처: http://www.scala-lang.org/node/113
67
Variances
class Animal
class Dog extends Animal
class Vector[+T] { … }
class Contravariant[-T] {…}
class Array[T] {…}
val aCovariantVector: Vector[Animal] = Vector.empty[Animal] // ok
val aCovariantVector: Vector[Animal] = Vector.empty[Dog] // ok
val aCovariantVector: Vector[Dog] = Vector.empty[Animal] // not ok
val contravariantClass: Contravariant[Animal] = new Contravariant[Animal] // ok
val contravariantClass: Contravariant[Dog] = new Contravariant[Animal] // ok
val contravariantClass: Contravariant[Animal] = new Contravariant[Dog] // not ok
val anInvariantArray: Array[Animal] = Array.empty[Animal] // ok
val anInvariantArray: Array[Animal] = Array.empty[Dog] // not ok
val anInvariantArray: Array[Dog] = Array.empty[Animal] // not ok
출처: http://www.scala-lang.org/node/129
구분 Scala Java Description
Covariant +T ? extends T Covariant subclassing. E.g., List[Tsub] is a subtype of List[T].
Contravariant -T ? super T Contravariant subclassing. E.g., X[Tsup] is a subtype of X[T].
Invariant T T Invariant subclassing. E.g., Can’t substitute Y[Tsup]or Y[Tsub] for Y[T].
68
Type Bounds (Upper, Lower)
object Array {
...
def apply[A <: AnyRef](xs: A*): Array[A] = { // A must be a subtype of AnyRef
val array = new Array[A](xs.length)
var i = 0
for (x <- xs.elements) { array(i) = x; i += 1 }
array
}
...
}
class List[+A] { // A is covariant, List[+A] is subtype of List[A]
...
def ::[B >: A](x : B) : List[B] = new scala.::(x, this) // B must be a supertype of A
...
}
val languages = List("Scala", "Java", "Ruby", "C#", "C++", "Python") // languages:List[String] = List(…)
val list = 3.14 :: languages // list:List[Any] = List (…)
println(list) // List(3.14, “Scala”, “Java”, “Ruby”, “C#”, “C++”, “Python”)
출처: http://www.scala-lang.org/node/136
구분 Scala Java Description
Upper Bounds A <: B A extends B A must be a subtype of B
Lower Bounds A >: B - A must be a supertype of B
69
Views
Implicit parameters and methods can also define implicit conversions called views.
The term view conveys the sense of having a view from one type (A) to another type (B).
A view is applied in two circumstances.
When a type A is used in a context where another type B is expected and there is a view in scope that can convert A to B.
When a non-existent member m of a type A is referenced, but there is an in-scope view that can convert A to a B that has the m member.
def m [A <% B](arglist): R = ...
def m [A](arglist)(implicit viewAB: A => B): R = ...
class Container[A <% Int] { def addIt(x: A) = 123 + x }
(new Container[String]).addIt("123") // ok, 246
(new Container[Int]).addIt(123) // ok, 246
(new Container[Float]).addIt(123.2F) // not ok
출처: http://www.scala-lang.org/node/130
구분 Scala Java Description
View Bounds A <% B - A can be converted to B using a view
70
Inner Classes
1. Use Companion Objects: object Graph for class Graph
2. Use Type Projection: Graph#Node is “a Node of any Graph”
출처: http://www.scala-lang.org/node/115, http://weblogs.java.net/blog/cayhorstmann/archive/2011/08/05/inner-classes-scala-and-java
class Graph { class Node { var connectedNodes: List[Node] = Nil def connectTo(node: Node) { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node :: connectedNodes } } } var nodes: List[Node] = Nil def newNode: Node = { val res = new Node nodes = res :: nodes res } } object IllegalGraphTest extends Application { val g: Graph = new Graph val n1: g.Node = g.newNode val n2: g.Node = g.newNode n1.connectTo(n2) // legal val h: Graph = new Graph val n3: h.Node = h.newNode n1.connectTo(n3) // illegal! }
class Graph { class Node { var connectedNodes: List[Node] = Nil def connectTo(node: Node) { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node :: connectedNodes } } } var nodes: List[Node] = Nil def newNode: Node = { val res = new Node nodes = res :: nodes res } } object IllegalGraphTest extends Application { val g: Graph = new Graph val n1: g.Node = g.newNode val n2: g.Node = g.newNode n1.connectTo(n2) // legal val h: Graph = new Graph val n3: h.Node = h.newNode n1.connectTo(n3) // illegal! }
object Graph { class Node { var connectedNodes: List[Node] = Nil def connectTo(node: Node) { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node :: connectedNodes } } } } class Graph { var nodes: List[Graph.Node] = Nil def newNode: Node = { val res = new Node nodes = res :: nodes res } }
object Graph { class Node { var connectedNodes: List[Node] = Nil def connectTo(node: Node) { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node :: connectedNodes } } } } class Graph { var nodes: List[Graph.Node] = Nil def newNode: Node = { val res = new Node nodes = res :: nodes res } }
class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil def connectTo(node: Graph#Node) { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node :: connectedNodes } } } … }
class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil def connectTo(node: Graph#Node) { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node :: connectedNodes } } } … }
Use Companion Objects
Use Type Projection
71
Abstract Types
abstract class Buffer[+T] {
val element: T
}
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] {
def length = element.length
}
object AbstractTypeTest2 extends Application {
def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] =
new SeqBuffer[Int, List[Int]] {
val element = List(e1, e2)
}
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length) // length = 2
println("content = " + buf.element) // content = List(7, 8)
}
출처: http://www.scala-lang.org/node/105
72
Explicitly Typed Self References
abstract class SubjectObserver {
type S <: Subject // S must be a subtype of Subject
type O <: Observer // O must be a subtype of Observer
trait Subject {
self: S => // #1. val self: SubjectObserver.this.S
private var observers = List[O]()
def addObserver(observer: O) = observers ::= observer
def notifyObservers = observers foreach (_.receiveUpdate(self)) // #2
}
trait Observer {
def receiveUpdate(subject: S)
}
}
- Comment #1 shows the self-type annotation, self: S =>. We can now use self as an alias for this, but whenever it appears, the type will be assumed to be S, not Subject.
- Comment #2 shows that we pass self instead of this to receiveUpdate.
출처: http://www.scala-lang.org/node/124
73
Polymorphic Methods
object PolyTest extends Application {
def dup[T](x: T, n: Int): List[T] =
if (n == 0) Nil
else x :: dup(x, n - 1)
println(dup[Int](3, 4)) // required parameters
println(dup("three", 3)) // not required to give actual type parameters explicitly
}
Method dup in object PolyTest is parameterized with type T and with the value parameters x: T and n: Int
출처: http://www.scala-lang.org/node/121
74
Scala는 많은 좋은 기능이 있다.
object Hello {
def main(args:Array[String]) {
println(“Hello, World”)
}
}
75
Default Parameter Values
def hello(foo:Int = 0, bar:Int = 0) {
println("foo: "+foo+" bar: "+bar)
}
hello() foo: 0 bar: 0
hello(1) foo: 1 bar: 0
hello(1,2) foo: 1 bar: 2
76
Named Parameters
def hello(foo:Int = 0, bar:Int = 0) {
println("foo: "+foo+" bar: "+bar)
}
hello(bar=6) foo: 0 bar: 6
hello(foo=7) foo: 7 bar: 0
hello(foo=8,bar=9) foo: 8 bar: 9
77
Everything Returns a Value
val a = if(true) "yes" else "no"
val b = try{
"foo"
} catch {
case _ => "error"
}
val c = {
println("hello")
"foo"
}
78
Lazy Definitions
// initialized on first access
lazy val foo = {
println("init")
"bar"
}
foo init
foo
foo
79
Nested Functions
// Can nest multiple levels of functions
def outer() {
var msg = "foo"
def one() {
def two() {
def three() {
println(msg)
}
three()
}
two()
}
one()
}
80
By-Name Parameters
// msg parameter automatically wrapped in closure
def log(doLog:Boolean, msg: => String) {
if(doLog) {
msg // evaluates msg
msg // evaluates msg again!
}
}
def foo:String = {
println("in foo"); "Foo"
}
log(true, foo+" Bar") // foo called twice
in foo
in foo
log(false, foo+" Bar") // foo never called
81
Many More Features
Annotations @foo def hello = "world"
Option
Actors
DSL
For Comprehensions for(i <- 1 to 5 if i % 2 == 0) yield i
Implicit Conversion
XML Literals val node = <hello>world</hello>
Reflections
Macros (2.10)
etc…
82
Scala를 어떻게 공부하지?
object Hello {
def main(args:Array[String]) {
println(“Hello, World”)
}
}
83
Scala 공부의 정석
84
Martin Ordersky 저자 강의
https://www.coursera.org/course/progfun
86
Scala-Lang.org
http://www.scala-lang.org/
87
Scala 공부관련 참고자료
스칼라 입문자료 – Scala API Reference – A Tour of Scala : 스칼라 공식 블로그에 올라온 스칼라 강좌 – Scala By Example : 마틴 오더스키가 작성한 100페이지짜리 스칼라 문서 – Scala School : 트위터가 작성한 스칼라 강좌 – Progammin in Scala 1st Edition : Programmin in Scala의 1st Edition은 온라인에서 무료로 볼
수 있음. – Effective Scala : 트위터의 Marius Eriksen가 만든 스칼라 강좌
스칼라 서적(영문) – Programming in Scala : 마틴 오더스키가 참여한 스칼라 서적. 강추!!, Scala 2.8 기준. – Programming Scala : 오렐리에서 나옴. 읽어본 사람 없어서 내용은 잘 모름. – Programming Scala : Pragmatic에서 나온 스칼라 서적. 읽어볼 만은 하지만 빠진 내용이 많아
서 많이 추천하지는 않음. – Scala in Depth : 매닝에서 나온 서적. 읽어본 사람이 없어서 내용은 잘 모름.
그외 참고 자료 – Style Guide for Scala : 스칼라 코드 작성에 대한 스타일가이드 발표자료 – Scala Puzzlers : 스칼라 문제를 풀어볼 수 있는 사이트 – Scala Cheat Sheet : 간단한 스칼라문법을 참고할 수 있는 치트시트 – S99 Scala Problems: 99 개의 스칼라 프로그래밍 학습 예제