Сможет ли Scala заменить Perl?

Aug 10, 2008 19:20

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 (_/" +"/"")

it, scala

Previous post Next post
Up