четверг, 25 февраля 2010 г.

Еще о Scala

Краткость - сестра таланта. А программист - ленивое существо :) За что мне понравилась Scala - так это за краткость. Вот если посмотреть на примере - надо посчитать норму вектора. Для тех, кто уже забыл, что это такое - корень из суммы квадратов всех его координат. Пускай вектор у нас представлен списком, каждый элемент которого - соответствующая координата. Ниже 2 реализации - на Java и на Scala:

Java

List<Double> vector = new ArrayList<Double>();
vector.add(-1.0);
vector.add(2.0);
vector.add(3.0);
Double norm = 0.0;
for (Double coord : vector) {
norm+=coord*coord;
}

norm = Math.pow(norm, 0.5);

Scala

val v = -1.0::2.0::3.0::Nil
val norm = Math.sqrt(
(0.0 /: v)((x, y) => x + y * y))

Разница в обьёмах набранных буков очевидна :) А результат один - корень из 14.

6 комментариев:

Sergey K. комментирует...

Уважаемый автор позволю себе с вами не согласится - пример очень уж притянут за уши. Да и читабельность кода на яве лучше :)

Представь, что эту абракадабру


val norm = Math.sqrt((0.0 /: v)((x: Double, y: Double) => x + y * y))


увидешь через годик-другой?)
Думаю, не сразу будет понятно, что за хня. Угу.

PS: А так забавный язык.. Понравился. Попробую на нём реализовать что-нибудь дико нужное

yno комментирует...

Хех, на самом деле этот пример весьма широко используется в программировании того, что называется intelligent web - collaborative filtering, recommendation engines, etc. Там с векторами работают только в путь Читабельность выше, да. Но и абракадабра это только для непосвященных :) На самом деле синтаксис языка формализован весьма неплохо и читается легко. Если знать язык конечно :)

Sergey K. комментирует...


Если знать язык конечно


)Поизучаю и тоже какую-нить абракадабру тебе запощу ))

Анонимный комментирует...

На Хаскеле это будет так:

norm = foldr (\x a -> a + x * x) 0.0
norm [-1, 2, 3]

Вот как в консоли ghci:

=====================
[vlm@nala:~/work/fprog.ru]> ghci
GHCi, version 6.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> let norm = sqrt . foldr (\x a -> a + x * x) 0.0
Prelude> norm [-1,2,3]
3.7416573867739413
Prelude>
=====================

yno комментирует...

Да, на хаскелле еще короче и яснее получается. Интересно, получится ли на scala без указания типов переписать?.. Попробую))

yno комментирует...

scala> val norm = Math.sqrt((0.0/:v)((x, y) => x + y*y))
norm: Double = 3.74165738677394

Таки можно. Type inference работает