в лаборатории профессора Мартина Одерски в EPFL – Федеральной Технической Школе Лозанны (Швейцария) ™ Мартин известен тем, что разработал Generics для Java и создал эталонную реализацию компилятора javac для Sun ™ При создании generics он был ограничен обратной совместимостью с предыдущими версиями ™ Scala создана с нуля и поэтому более целостна и Историческая справка
на каждом уровне абстракции должны использоваться одни и те же конструкции. Для этого Scala объединяет объектно- ориентированную и функциональную парадигмы, предоставляет механизмы создания составных типов и расширения уже существующих. При этом Scala – чисто объектно-ориентированный Scalable language
™ AnyVal – общий предок для всех примитивов ™ AnyRef – аналог Object ™ Null – экземпляр любого ссылочного типа ™ Nothing – экземпляр любого типа ™ Unit – аналог void (блок кода, не возвращающий значения)
с реализованными методами ™ Подмешивание trait к классу не означает, что класс является разновидностью базового (is-a), как это происходит при наследовании. Подмешивание означает, что класс получает дополнительный функционал ™ На основе trait’ов можно создавать составные типы ™ Traits позволяют лучше переиспользовать код без недостатков множественного наследования. Mixin Class Composition
philosophize() { Console.println("It ain't easy being "+ toString +"!") } } class Frog extends Animal with Philosophical { override def toString = "green" } val frog = new Frog(); frog.philosophize(); // It ain't easy being green! override – ключевое слово Точки с запятой в конце строк не обязательны
if (x) that else this def or(that: MyBool): MyBool = if (x) this else that def negate: MyBool = new MyBool(!x) def not(x: MyBool) = x negate; // здесь ; обязательно def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) } Перегрузка операторов ™ В названиях методов можно использовать почти все спецсимволы (+, -, !, =, <, >, *, @) ™ Каждый метод, принимающий один параметр может использоваться как инфиксный оператор, а без параметров как постфиксный:
этом совсем не обязательно везде указывать какие типы должны быть использованы ™ Мощная система вывода типов определяет большинство типов по использованию переменных: Вывод типов (Hindley-Milner) def foo(s: String) = s.length def bar(x, y) = foo(x) + y
этом совсем не обязательно везде указывать какие типы должны быть использованы ™ Мощная система вывода типов определяет большинство типов по использованию переменных: Вывод типов (Hindley-Milner) def foo(s: String) = s.length def bar(x, y) = foo(x) + y Int
этом совсем не обязательно везде указывать какие типы должны быть использованы ™ Мощная система вывода типов определяет большинство типов по использованию переменных: Вывод типов (Hindley-Milner) def foo(s: String) = s.length def bar(x, y) = foo(x) + y Int Int
этом совсем не обязательно везде указывать какие типы должны быть использованы ™ Мощная система вывода типов определяет большинство типов по использованию переменных: Вывод типов (Hindley-Milner) def foo(s: String) = s.length def bar(x, y) = foo(x) + y Int Int Int
этом совсем не обязательно везде указывать какие типы должны быть использованы ™ Мощная система вывода типов определяет большинство типов по использованию переменных: Вывод типов (Hindley-Milner) def foo(s: String) = s.length def bar(x, y) = foo(x) + y Int Int Int Int
производить вычисления с функциями? Замыкания (closures) def apply(list: List[Int], f: (Int => String)) = { for(item <- list) yield f(item) } val toStr: (Int => String) = (a => "str" + a.toString) Console.print(apply(List(1,2,3), toStr).mkString(", ")) // str1, str2, str3 ™ В Scala функции – объекты первого порядка – замыкания ™ Функции высшего порядка – функции над функциями
вышел на прогулку с учеником Антоном. Надеясь разговорить учителя, Антон спросил: «Учитель, слыхал я, что объекты — очень хорошая штука — правда ли это?» Кх Ан посмотрел на ученика с жалостью в глазах и ответил: «Глупый ученик! Объекты — всего лишь замыкания для бедных.» Пристыженный Антон простился с учителем и вернулся в свою комнату, горя желанием как можно скорее изучить замыкания. Он внимательно прочитал все статьи из серии «Lambda: The Ultimate», и родственные им статьи, и написал небольшой интерпретатор Scheme с объектно-ориентированной системой, основанной на замыканиях. Он многому научился, и с нетерпением ждал случая сообщить учителю о своих успехах. Во время следующей прогулки с Кх Аном, Антон, пытаясь произвести хорошее впечатление, сказал: «Учитель, я прилежно изучил этот вопрос, и понимаю теперь, что объекты — воистину замыкания для бедных». Кх Ан в ответ ударил Антона палкой и воскликнул: «Когда же ты чему-то научишься? Замыкания — это объекты для бедных!» В эту секунду Антон обрел просветление.
case "two" => 2 case y: Int => "scala.Int" } map.get(key) match { case Some(x) => "got " + x case None => "got nothing" } List(v1, v2) filter (_ %2 == 0) match { case List(value1, value2) => "a" case List(value) => "b" case _ => "c" } Благодаря набору типов нельзя забыть проверку на null!
множественных параметров из функции • for на стероидах • Анонимные классы и final • Seamless Big Integers • Управление ресурсами • Взаимодействие с Java
re, im; public Complex(int re, int im) { this.re = re; this.im = im; } public int getRe() { return re; } public void setRe(int re) { this.re = re; } public int getIm() { return im; } public void setIm(int im) { this.im = im; } } final Complex number = new Complex(1, 0); number.setIm(12);
List(1, 2, 3); b <- List("a", "b", "c") ) yield (a, b) Console.print(product) // List((1,a),(1,b),(1,c),(2,a),(2,b),(2,c),(3,a),(3,b),(3,c)) ™ Вложенные циклы можно объединить в одну конструкцию (например, для обработки произведений множеств) ™ Ключевое слово yield возвращает результат для итерации ™ Нет привычного for(…; …; …): for(int i = 0; i < n; i++) ~ for(i <- 0 to n)
result: Any = null Array(1,2,3,4,5,6,7,8,9,10).foreach({ x => sum += x; result = new Object() }) Console.println(sum) // 55 Console.println(result) // java.lang.Object@147c5fc Scala
factorial(n: BigInt): BigInt = if (n == 0) 1 else n * factorial(n-1) val f50 = factorial(50); println("50! = " + f50) val f49 = factorial(49); println("49! = " + f49) println("50!/49! = " + (f50 / f49)) } ™ Благодаря возможности перегружать операторы, работать с большими числами можно как с обычными примитивами:
"Hello, there!"; val arr: Array[Any] = new Array[Integer](1) arr(0) = "Hello, there!" error: type mismatch; found : Array[Integer] required: Array[Any] var arr: Array[Any] = new Array[Integer](1) Java Scala java.lang.ArrayStoreException: java.lang.String
val last = objects.last // Последний элемент val tail = objects.tail // Список без первого элемента val init = objects.init // Список без последнего элемента val distinctObjects = List(2,4,6,4,2).distinct // List(2, 4, 6) val partition = List(1,2,3,4,5).partition((n) => n%2 == 0) // (List(2, 4), List(1, 3, 5)) Console.println((0 to 10).count(_ % 2 == 0)) // 6 Array("a", "b", "c").foreach(Console.print) // abc
с существующими последовательными. Для их использования достаточно будет просто изменить реализацию ™ Параллельные коллекции будут балансировать нагрузку на ядра процессоров при выполнении операций ™ Выпуск 2.9 RC1 планируется в феврале 2011 ™ Полный рассказ о новых параллельных коллекциях: http://days2010.scala-lang.org/node/138/140 Параллельные коллекции
используются круглые скобки ™ <: вместо extends ™ >: вместо super ™ Вместо ? используется _ _ используется во многих местах от import до pattern matching Обозначения
этот тип. В Java такое возможно для обратной совместимости. В Scala это помогает избегать ошибок! ™ Параметризация методов типами идёт между именем метода и списком аргументов, а не перед типом возвращаемого значения ™ Классы параметризуются аналогично Java. Если у класса есть агрументы, то тип указывается перед ними (как при параметризации метода) Особенности параметризации
AnyVal] // val upperBound: UpperBoundClass[Any] = new UpperBoundClass[Any]() val lowerBound: LowerBoundClass[Any] = new LowerBoundClass[Any]() val upperBound2: UpperBoundClass[Int] = new UpperBoundClass[Int]() // val lowerBound2: LowerBoundClass[Int] = new LowerBoundClass[Int]() val lowerBound3: UpperBoundClass[AnyVal] = new UpperBoundClass[AnyVal]() val upperBound3: LowerBoundClass[AnyVal] = new LowerBoundClass[AnyVal]()
} Class Child extends Base { List get(List argument) throws RuntimeException } Class ChildsChild extends Child { ArrayList get(Object argument) throws NullPointerException } Изменение одного типа относительно изменения другого ковариантно контравариантно ковариантно
CovariantClass[Any] = new CovariantClass[Any]() val contravariant: ContravariantClass[Any] = new ContravariantClass[Any]() val covariant2: CovariantClass[Any] = new CovariantClass[Int]() //val contravariant2: ContravariantClass[Any] = new ContravariantClass[Int]() //val covariant3: CovariantClass[Int] = new CovariantClass[Any]() val contravariant3: ContravariantClass[Int] = new ContravariantClass[Any]() Any – супер-класс Int => ContravariantClass[Int] – супер-класс ContravariantClass[Any] Int – подкласс Any => CovariantClass[Int] – подкласс CovariantClass[Any]
act() { loop { react { case Ping => sender ! Pong case Stop => exit() } } } } Actor - основной объект Scala для параллельных вычислений. Actor представляет собой объект, который общается со внешним миром путём обмена сообщениями
{ case msg => self reply (msg + " World") } } RemoteNode.start("localhost", 9999) .register("hello-service", actorOf[HelloWorldActor]) // client code val actor = RemoteClient.actorFor("hello-service", "localhost", 9999) val result = actor !! "Hello" Actors могут быть использованы для реализации Comet, как обработчики Camel и для организации кластера
ci = City as "ci" val co = Country as "co" // Выбирает все русские города, возвращает Seq[City]: SELECT (ci.*) FROM (ci JOIN co) WHERE (co.code LIKE "ru") ORDER_BY (ci.name ASC) list // Выбирает страны с подходящими городами, возвращает Seq[(Country, City)]: SELECT (co.*, ci.*) FROM (co JOIN ci) list // Выбирает страны с количеством городов, возвращает Seq[(Country, Int)]: SELECT (co.*, COUNT(ci.id)) FROM (co JOIN ci) GROUP_BY (co.*) list
™ Возможно прямое взаимодействие с кодом на Java – Вызов кода на Java из Scala – И вызов кода на Scala из Java ™ Поддержка Scala есть в IntelliJ IDEA, Eclipse и NetBeans – IntelliJ IDEA 10.0.1 ловит некоторые ошибки только во время компиляции, а не во время набора кода, обещают исправить – IntelliJ IDEA умеет конвертировать код на Java в Scala ™ Для Scala есть библиотеки + есть возможность использовать все Java библиотеки Scala поддерживается
™ Novell ™ Sony ™ Siemens ™ Xerox ™ FourSquare ™ The Guardian ™ GridGain Крупные компании и стартапы используют Scala «We're using Scala for real work in a business critical situation and there is a lot of money at stake if we get it wrong. There are risks, but we have had no problems [with Scala]. For me, a developer working at the coal face, the productivity improvements are massive.» Lee Momtahan. Électricité de France Trading.