metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-11-06 04:15 am
Entry tags:

Scala

Читаю книжку Одерского, до основной шизы еще не добрался, но такое ощущение, что в скале чрезмерно много синтаксического сахара. Типа "тут вы можете скобки опустить, а тут вместо скобок использовать фигурные скобки, а тут мы прямо в параметрах класса сделаем их полями, а в multiline string literal вы можете сделать отступ и stripMargin" и прочая и прочая в том же духе.
Основное из этого, видимо - function literals и вызов методов в стиле a methodName b, без точек и скобок, что делает код более лаконичным, одновременно позволяя при желании превратить код в нечитабельный ад.

Заодно по наводке [livejournal.com profile] jdevelop глянул на http://spray.io/ https://github.com/spray/spray/wiki
Примеры там, конечно, знатный abuse возможностей языка и вычислений на типах, типа extraction-директив с HList в качестве параметра типа.

Clojure по сравнению с этим выглядит более простой и логичной, хотя я не уверен, можно ли сравнивать совершенно разные языки, общего у которых только функциональщина и иммутабельность иногда.

PS: Вот, к примеру:
https://github.com/spray/spray/blob/master/docs/documentation/spray-routing/code/docs/HttpServiceExamplesSpec.scala

В SimpleService HttpResponse реализован как html-код написанный прямо внутри скала-кода. Сижу уже 30 минут ищу, где это преобразование реализовано и как. Т.е. не видя отдельных литералов и их типов (которые без загрузки всего оного кода с зависимостями в IDE/интерпретатор еще и не увидишь), с ходу догадаться, что происходит, достаточно сложно. XML literals, встроенные в язык и где-то implicit для конверсии.

PPS: implicit evidence:
http://jim-mcbeath.blogspot.com/2008/11/scala-type-infix-operators.html
http://stackoverflow.com/questions/3427345/what-do-and-mean-in-scala-2-8-and-where-are-they-documented

По-моему, это уже достаточно сложно, чтобы увлечь психов и стать новыми крестиками. Вот [livejournal.com profile] xeno_by еще приделает макросы - и совсем хорошо станет.

[identity profile] xeno-by.livejournal.com 2012-11-06 11:13 am (UTC)(link)
Касательно системы типов, мне кажется, подходит слово не "лучший", а "другой".

От тайп инференса пришлось отказаться (см. отличные примеры с обоснованием вот тут: http://groups.google.com/group/scala-language/msg/c26eb3bd7aa58817) ради смешивания ООП и ФП. В результате можно делать вот такие вещи: https://www.precog.com/blog-precog-2/entry/existential-types-ftw. Для меня неочевидно, что этот трейдофф проигрышный.

[identity profile] xeno-by.livejournal.com 2012-11-06 11:15 am (UTC)(link)
Охранные выражения есть. Пары матчить тоже можно. Или проблема была заматчить пару с одинаковыми первым или вторым элементом?

[identity profile] sum-erman.livejournal.com 2012-11-06 11:22 am (UTC)(link)
Где про них написано? Особенно чертовски удобно матчить пары в лямбдах { case (x,_) => ... } в итоге пишу негодное _._1 Да, с одинаковыми элементами. Кстати, пиведённый мной синтаксис это какой-то специальный для объявления типа this, или есть какой-то более общая идея?

[identity profile] xeno-by.livejournal.com 2012-11-06 11:42 am (UTC)(link)
Думаю, в книжке Одерского programming in scala, которая есть бесплатно в интернетах. Согласен, в лямбдах неудобно.

Приведенный синтаксис это self-type annotation. Он позволяет указать зависимости данного трейта от других трейтов и классов. В книжке Мартина тоже про это будет.

[identity profile] isorecursive.livejournal.com 2012-11-06 11:43 am (UTC)(link)
А я видел. Человек пытался воспроизвести на тайпклассах какие-то темплейт-трюки с перегрузками по аргументам и результату, и проверкой размерностей, для какой-то хитрой обобщённой матрично-векторной арифметики. Чем закончилось, не знаю, но товарищ был недоволен.
Мне в хаскеле от скалы хотелось бы хотя-бы имплициты (ни в коем случае не динамический скоупинг по имени, с которым их путают, как в уже присутствующем расширении implicit parameters!), но без конверсий - а только в качестве управляемого type-directed скоупинга, для того, чтобы не протаскивать постоянно конфигурации в монадах, для замены тайпклассов, и для удобного proof-carrying, если захочется что-нибудь такое в духе агды писать.

[identity profile] sum-erman.livejournal.com 2012-11-06 11:47 am (UTC)(link)
Это специальный синтаксис только для self-type annotation?

[identity profile] evil-invader.livejournal.com 2012-11-06 12:24 pm (UTC)(link)
>>"А можно подробнее про что именно впечатлило в джаве 8? Только лямбды или что-то еще?"

Лямбды и трейты. В джаве только нету паттернов.

Трейты в скале мне очень понравились. Особенно возможность к существующему классу примешать трейт и получить instance класса с примешанным трейтом. Ну и в целом что-то среднее между интерфейсами и множественным наследованием это очень ок.
Паттерны в скале я если честно не понял. Ну в смысле общую идею понял, но не успел вникнуть в нюансы. Не знаю на сколько они мне были бы полезны. Не успел пощупать и не уверен, что в ближайшее время доведется на практике использовать.

Конечно в джаве и десятая часть тех штук, что есть в скале, не будет реализовано в ближайшее время. Но если раньше я рассматривал скала, как замену джаве, то теперь я скорее думаю, что скала это своего рода стимулятор развития самой джавы.

[identity profile] metaclass.livejournal.com 2012-11-06 01:03 pm (UTC)(link)
Вот это Foo with Bar от входа воще хрен поймешь. И там много такого, надо книжку дочитать :)

[identity profile] xeno-by.livejournal.com 2012-11-06 01:05 pm (UTC)(link)
Так полноценных трейтов же в джаве восьмой нет.

[identity profile] xeno-by.livejournal.com 2012-11-06 01:07 pm (UTC)(link)
Специальный синтаксис, да. Можно написать ident => T1 with T2 ... with TN. Это будет означать, что трейт разрешено наследовать только тем, кто имплементит все Ti.

[identity profile] evil-invader.livejournal.com 2012-11-06 01:14 pm (UTC)(link)
ну хоть в каком-нибудь виде. Для начала хватит. Для меня самое главное это появление лямбд. Это уже значительно расширит возможности.

[identity profile] sum-erman.livejournal.com 2012-11-06 01:24 pm (UTC)(link)
Как всё сложно. Зачем так жить? :) Я там выше ещё спрашивал про зоопарк из object/class/trait и методов их композиции, есть чего почитать по сабжу просветляющего?

[identity profile] xeno-by.livejournal.com 2012-11-06 01:32 pm (UTC)(link)
Все это просто надо рассматривать в контексте кейк-паттерна, который включает в себя трейты, селф-тайпы и абстрактные тайп мемберы.

Описан паттерн в папере Scalable Component Abstractions. Вот тут еще есть пример, только мне сложно сказать как оно в качестве введения: https://www.precog.com/blog-precog-2/entry/existential-types-ftw.

После погружения в тему становится понятно, что сабжевые фичи взаимосвязаны и вместе предоставляют отличное средство для модуляризации программ. Мне кажется, это и есть сердце Скалы, ее едва ли не самая важная функциональность.

[identity profile] sum-erman.livejournal.com 2012-11-06 01:37 pm (UTC)(link)
Т.е. фактически в языке есть фича нужная чисто для имплементации "этого вашего" паттерна-который-торт, при том, что каррированные ф-ии + частичное применение сами по себе неплохо справляются с этой задачей. Я видимо недостаточно Enterprise парень чтобы понять всю сложность и необходимость всех этих вывертов с dependency injection

[identity profile] v-l-a-d.livejournal.com 2012-11-06 01:41 pm (UTC)(link)
>в скале чрезмерно много синтаксического сахара

ну если сравнивать с AST-дампом компилятора в виде S-выражений, то да, действительно много:)
а если с каким-нибудь хипсторуби - то вполне ок

[identity profile] xeno-by.livejournal.com 2012-11-06 01:43 pm (UTC)(link)
Про зоопарк.

trait = строительный материал, атомарная единица композиции. Сами по себе они инстациируются редко, хоть и есть соответствующая конструкция в языке.

class = можно сказать, молекула в плане "минимальная сущность, которая самодостаточно имеет смысл в программе". Если класс простой, то его так и пишут, не разбивая на трейты. Если сложный - разбивают на части и наследуются от них.

object = модуль. Как package, только first-class сущность, т.е. модули можно передавать в методы и возвращать из методов. Частый сценарий использования - напихать в object чего-нибудь (например, замиксить кучу трейтов) и потом сделать import someObj._, чтобы импортировать все напиханное.

[identity profile] xeno-by.livejournal.com 2012-11-06 01:45 pm (UTC)(link)
Dependency injection здесь сбоку припеку.

Кейк-паттерн это воплощение способа модуляризации программ, реализованного в Скале (см. паперу, которую я посоветовал выше). Модуляризация, на мой взгляд, полезна не только в энтерпрайзе.

[identity profile] sum-erman.livejournal.com 2012-11-06 01:45 pm (UTC)(link)
В хипсторуби — меньше

[identity profile] xeno-by.livejournal.com 2012-11-06 01:46 pm (UTC)(link)
Я не очень понимаю как взять два отдельных компонента и смешать их вместе при помощи частичного применения.

[identity profile] metaclass.livejournal.com 2012-11-06 02:22 pm (UTC)(link)
Вот к руби оно неоправданно близко :)

[identity profile] bydl0coder.livejournal.com 2012-11-06 02:25 pm (UTC)(link)
Все так, но самая главная сложность - сочетание ООП с функциональщиной, тут тебе и обычные классы, и алгебраические типы, и ленивость и хер знает что еще. В руби сахара тоже полно, но там он не мешает, очередной ОО-язык осваивается за неделю.

[identity profile] thesz.livejournal.com 2012-11-06 05:00 pm (UTC)(link)
Я внимательно прочитал ваши ссылки.

Честное слово, после чтения я пришёл к выводу, что я стал очень далёк от OO. Я даже не понимаю формулировки проблемы, которые могут привести к таким решениям, что уж говорить про сами решения.

Во второй (которая FTW) есть хотя бы список успехов. Но таким списком я бы гордился году в 2008, примерно. Сейчас это обычное дело в проекте на Хаскеле.

[identity profile] golikov konstantine (from livejournal.com) 2012-11-06 05:52 pm (UTC)(link)
Вообще Map(1 => 2, 3 => 4) не сработает

Map(1 -> 2, 3 -> 4)

"=>" это про другое

[identity profile] divine-assass1n.livejournal.com 2012-11-06 05:53 pm (UTC)(link)
ага. Именно это я и имел ввиду :)

[identity profile] golikov konstantine (from livejournal.com) 2012-11-06 05:57 pm (UTC)(link)
"нельзя заматчить например пару(X,X), нету охранных выражений"

(1,2) match {
case (a,b) if a > 0 =>
case other => ...
}

Кроме того можно матчить case class'ы, коллекции, да что угодно, у чего есть unapply:

Array(1,2,3) match {
case Array(a,b, _*) => "head: " + a + " second "+ b
}

Есть даже дизъюнкция аля

baz match {
case Foo | Bar => ...
}

И да, как и в эрланге есть destructuring assignment:

def foo = ("head", "tail")
val (a,b) = foo
// a == "head"; b == "tail"
Edited 2012-11-06 18:12 (UTC)

Page 2 of 7