Scala - молодой язык программирования, вокруг которого сейчас много шума. Говорят, что он заменит Java,
akuklev про него
написал: "И я понял, что в мире наконец-то появился язык программирования, на котором мне не пративно писать.", Яндекс уже
приглашает на работу, на IBM DeveloperWorks даже есть
русская статья.
В нём есть и компилятор и
REPL. Его создатель,
Martin Odersky, также причастен к javac и generics. Scala отлично взаимодействует с Java (и имеет сравнимое быстродействие): можно в скале унаследовать класс явы, потом в яве - класс скалы, вызывать и перегружать методы друг друга и т.д. Не исключено, что в одной из будущих версий scalac сможет компилировать java-исходники как родные. А главное - это функциональный язык, с отложенными (lazy) вычислениями, без
continuations, с частичной
tail recursion, и вроде без eval. Типизация статическая, но компилятор в большинстве случаев типы угадывает, поэтому явно их можно не писать.
Позиционируется он как универсальный и масштабируемый, пригодный как для огромных приложений, так и для крохотных скриптов. Мне стало интересно, правда ли на нём можно (и удобно) писать простые скрипты, например для обработки строк (в чём силён перл)? Я попробовал написать аналог perl -e "while(<>){s/ +//g;print}" (или sed "s/ //g") - убирание всех пробелов.
Первая проблема: по нему нет нормальной документации. В
комплекте есть 3 PDF-а, есть
форум,
блоги, вроде даже вышла какая-то
книга. Но, например, scala при запуске скрипта ругается "Could not connect to compilation daemon.", понятно что compilation daemon - это fsc, но как их запустить и подружить? Приходится юзать scala -nocompdaemon, нагуглить решение сходу не удалось. (Add: была проблема с фаерволом)
Вторая: при чтении строк приходится обрабатывать EOFException, что уже небанально. В принципе можно написать
небольшой итератор:
object lines extends Iterator[String] {
var nextLine: String = null
var eof = false
private def readNext {
if (!eof && nextLine == null) try {
nextLine = readLine
} catch {
case e: java.io.EOFException => eof = true
}
}
def hasNext = if (eof) false else if (nextLine != null) true else { readNext; nextLine != null }
def next = { if (nextLine == null) readNext; val l = nextLine; nextLine = null; l }
}, откомпилировать и положить в CLASSPATH, но это не универсально: на другой машине его не будет, а в перле сразу всё есть. Хотя с ним убирание пробелов вполне компактно:
for(s <- lines) println(s.replaceAll(" +",""))
Хотя можно дописать
ещё чуть-чуть:
class re2 (s: String, p: String) {
def /(r: String) = s.replaceAll(p,r)
}
class re1(s: String) {
def /(p: String) = new re2(s,p)
}
implicit def s2r(s: String) = new re1(s)
def sed (f: String => String) = for (s <- lines) (f andThen println) (s), и скрипт сократится до красивого:
sed (_/" +"/"")