О Scala для тех, кому мало Java, и не только
в рубрике Java, Технологии
Автор статьи: Олег Галако.
Олег около 10 лет программирует на Java, в прошлом году начал применять Scala в проектах, первым проектом был самодокументирующийся JSON/REST вебсервис; сейчас Олег работает над пробной версией нового web-интерфейса к большому сервису (~3500 java classes) на Scala + Vaadin.
Прогресс не стоит на месте, люди ищут новые решения, и на JVM появляется всё больше интересных языков. Но «ядро» JVM сообщества — народ суровый, привыкший к серьёзным стандартам, и с высокими требованиями. Поэтому большинство новых языков так и висят «на периферии».
От других языков на JVM Scala отличается действительно основательным подходом — над языком работает лаборатория мощнейшего европейского института EPFL во главе с профессором Мартином Одерски, который также известен как дизайнер системы generic-ов из Java 1.5. Конечно, это не сравнить по объёму поддержки с серьёзными коммерческими конторами в роде Sun или Microsoft, поэтому язык развивался медленно и «пошёл в дело» совсем недавно:

Что в нём интересного?
Прежде всего, привычный синтаксис и доступность багажа наработок Java и свободное смешивание с ним — можно спокойно в существующий Java-проект добавить несколько классов Scala и всё будет работать (у Scala есть расширения, недоступные из Java, но это обычно не сложно решить, в обратную сторону всё доступно на 100%).
Краткий и выразительный код
Начиная от простейших вариантов type inference и послаблений синтаксиса:
def toString = "a: " + a // method
val map = Map(1 -> “one”, 2 -> “two”) // map: Map[Int, String]
кортежей (они же tuples):
def error = ("Not found", 404) // method
val (msg, code) = error // msg == “Not found”, code == 404
и заканчивая функциональными коллекциями:
List(1, 2, 3, 4, 5).filter(_ % 2 == 1).map(_ * 2).mkString(",") // "2,6,10"
смешиванием trait-ов (как интерфейсы в Java, только с возможностью имплементации):
val handler = new DefaultHandler with Logging with AdminRoleRequired with TransactionSupport
расширением классов (в том числе примитивных типов) через неявные преобразования:
val date = today + 1.month + 5.days
и, конечно же, case class-ами:
case class Person(name: String, age: Int) // getters, equals, hashCode, toString and more
val p = Person(”Vasia”, 12)
Качественная смесь функционального и ОО подходов
Scala — первый язык «широкого профиля» со статической типизацией и продуманной (а где-то и подкреплённой диссертациями) смесью функционального и объектно-ориентированного подходов:
Не очевидно, но такой подход приятно удивляет на практике своей простотой и надёжностью — функциональное программирование приучает минимально использовать mutable state (не держать в голове, что у нас сейчас чему равно и как с этим жить) и делить программу на много мелких, хорошо читаемых и автоматически легко тестируемых методов, мощная типизация и traits позволяют чётко задать требования и избежать кучи мелких ошибок (если скомпилировалось — будет работать).
Спецификация Scala по объёму — меньше спецификации Java
Как недавно выразился один тип из Scala community, «в отличие от C++, Scala становится тем проще, чем дальше её изучаешь». Собственно это и есть основная цель языка, и даже заключено в его названии — SCAlable LАnguage. В спецификации даны только базовые вещи, но на основе них можно построить новые удобные конструкции, которые будут выглядеть как часть языка и могут использоваться для построения сложных промышленных систем. При этом за счёт послаблений синтаксиса (можно опускать много конструкций — скобки, возвращаемые типы и т.д.) язык получается удобным даже для простых скриптов (можно написать .scala файл без классов и выполнять его как скрипт).
Не только ценный мех
Кроме отмеченных выше «приятностей», есть именованные параметры и параметры по умолчанию:
def box(width: Int = 100, height: Int = 200) = ... // method
box(height = 300) // same as box(100, 300)
by-name параметры (вычисляются только при необходимости):
def debug(msg: => String) = if (debugEnabled) println(msg)
debug(”Debug message: ” + heavyMethod()) // heavyMethod вызовется только если debugEnabled
«ленивая» инициализация (оптимизированная и thread safe):
class Context { lazy val (user, password) = { /* heavy initialization */ } }
поддержка XML прямо в исходном коде:
def description = <div><h4>{label}</h4>{text}</div>
продвинутая система уровней доступа:
protected[package] val a // виден в пакете и наследникам
private[this] val b // виден только этому экземпляру этого класса
и, конечно, супер мощный pattern matching:
case class Address(city: String, street: String)
case class Person(name: String, age: Int, address: Address)
somePerson match {
case Person(”Vasia”, _, _) => … // name == “Vasia”, остальное - не важно
case Person(_, n, _) if n < 18 => … // age < 18
case Person(_, _, Address(_, “Абрикосовая”)) => … // только с улицы Абрикосовой
case _ => … // всё остальное
}
И многое другое
Очень сложно собрать всё интересное в одном посте. Его слишком много. Всего даже и не вспомнить за раз. Что ещё хочется добавить:
Первая версия Lift, популярного web framework-а для Scala вышла чуть больше года назад, а уже используется в таких серьёзных проектах как Foursquare и Novell Pulse
Прокомментировать
Вы должны быть авторизованы для комментирования.



