Scala

Nov. 6th, 2012 04:15 am
metaclass: (Default)
[personal profile] metaclass
Читаю книжку Одерского, до основной шизы еще не добрался, но такое ощущение, что в скале чрезмерно много синтаксического сахара. Типа "тут вы можете скобки опустить, а тут вместо скобок использовать фигурные скобки, а тут мы прямо в параметрах класса сделаем их полями, а в 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 еще приделает макросы - и совсем хорошо станет.

Date: 2012-11-06 10:07 am (UTC)
From: [identity profile] sum-erman.livejournal.com
Сей пост чуть менее чем полностью передаёт мои ощущения от языка. Добавлю что паттерн матчинг в его нынешнем виде неудобен и многословен, а необходимость указывать типы во вложенных функциях это просто садизм :)

Date: 2012-11-06 10:16 am (UTC)
From: [identity profile] divine-assass1n.livejournal.com
я приятно удивился, что он там вобще есть, но конечно с эрланговским pattern matching ему не сравнится

Date: 2012-11-06 06:10 pm (UTC)
From: [identity profile] golikov konstantine (from livejournal.com)
А что в эрланговском паттерн матчинге есть, чего нет в скаловском?

мне в голову приходит только паттерн матчинг в аргументах функции, но а) это в некотором виде существует в виде structural typing б) синтаксический сахар и аналог без сахара в скале есть

Date: 2012-11-06 06:21 pm (UTC)
From: [identity profile] divine-assass1n.livejournal.com
Да, в аргументах функции, плюс, как тут рядом в треде уже развернули дискуссию на эту же тему "многабукаф".

Guards опять же.

Вот например решение простого задания из курса Мартина на coursera, первая неделя, на сбалансированные круглые скобки, только на эрланге:

-module (balance).

-export([balance/1]).

balance(CharList) -> balance(0, CharList).

balance(-1, _) -> false;
balance(0, []) -> true;
balance(_, []) -> false;
balance(Counter, [$(|T]) -> balance(Counter + 1, T);
balance(Counter, [$)|T]) -> balance(Counter - 1, T);
balance(Counter, [_|T]) -> balance(Counter, T).

imho, элегантно и очень читабельно.

Вообще, я не претендую ни на что больше чем субъективное мнение, мой скромный опыт в скале - это почти завершенный курс Мартина на coursera c его assignments и 150 страниц книги. И мнение меняется по мере изучения предмета.

Date: 2012-11-06 06:30 pm (UTC)
From: [identity profile] golikov konstantine (from livejournal.com)
Guards есть http://metaclass.livejournal.com/741714.html?thread=14887506#t14887506

в аргументах функции -- ну я бы не сказал что это настолько киллер фича что бы говорить что он сильно лучше (это, опять же, мое субьективное мнение).

Вот например сбалансированные строки на скале

def isBalanced(list: List[Char]) = {
@annotation.tailrec
def countBracets(string: List[Char], count: Int = 0): Int = {
string match {
case '('::tail => countBracets(tail, count+1)
case ')'::tail => countBracets(tail, count-1)
case x::tail => countBracets(tail, count) // just skip if not bracet
case Nil => count
}
}

if (countBracets(list) == 0) true else false
}

пожалуй эрланг и вправду короче, но не так что бы сильно меньше

Date: 2012-11-06 06:38 pm (UTC)
From: [identity profile] divine-assass1n.livejournal.com
Ну что я могу сказать? Мне скала нравится. Когда начинал, не ожидал, что понравится.

Date: 2012-11-06 09:13 pm (UTC)
From: [identity profile] thesz.livejournal.com
weight '(' = 1
weight ')' = -1
weight x = 0
balanced = check . scanl (+) 0 . map weight
    where
        check balances = all (>=0) balances && last balances == 0
Не мог удержаться. ;)

Date: 2012-11-06 09:22 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Ну вот зачем вы издеваетесь над людьми своим лаконичным хаскелем? :)
После скалы это выглядит как бальзам на душу.

Date: 2012-11-06 09:28 pm (UTC)
From: [identity profile] thesz.livejournal.com
Мне можно. Я уже давно потерян для программистского общества. ;)

Это ещё и демонстрация, чем выгодна ленивость. В качестве бонуса. ;)

Date: 2012-11-06 10:45 pm (UTC)
From: [identity profile] golikov konstantine (from livejournal.com)
плюсую
и вправду красиво и компактно

Date: 2012-11-06 11:19 pm (UTC)
From: [identity profile] andy legkiy (from livejournal.com)
Сравнивают конкретный пример с рекурсией, так надо обязательно выставить HOF. Будто их больше нигде нет.
def balanced(seq: Seq[Char]) = {
  val balances = seq.view.map {
    case '(' => 1
    case ')' => -1
    case _ => 0}.scanLeft(0)(_+_)
  balances.forall(_ >= 0) && (balances.last == 0)
}

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 08:23 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-07 08:37 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 08:52 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-07 09:00 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 09:33 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-07 09:46 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 10:01 am (UTC) - Expand

(no subject)

From: [identity profile] isorecursive.livejournal.com - Date: 2012-11-07 10:07 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 10:32 am (UTC) - Expand

(no subject)

From: [identity profile] isorecursive.livejournal.com - Date: 2012-11-07 10:45 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 11:22 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-07 12:36 pm (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 01:54 pm (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-07 12:38 pm (UTC) - Expand

(no subject)

From: [identity profile] isorecursive.livejournal.com - Date: 2012-11-07 01:05 pm (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 01:53 pm (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2012-11-07 02:12 pm (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 02:29 pm (UTC) - Expand

(no subject)

From: [identity profile] isorecursive.livejournal.com - Date: 2012-11-07 03:38 pm (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 04:09 pm (UTC) - Expand

(no subject)

From: [identity profile] isorecursive.livejournal.com - Date: 2012-11-07 06:32 pm (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 07:10 pm (UTC) - Expand

(no subject)

From: [identity profile] isorecursive.livejournal.com - Date: 2012-11-07 07:33 pm (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-07 07:47 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-09 04:20 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-09 09:25 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-10 09:37 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-10 10:45 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-11 12:57 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-11 01:23 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-11 03:10 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-11 10:04 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-11 03:31 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-11 10:18 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-12 05:47 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-12 06:27 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-12 08:55 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-12 09:00 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-12 11:46 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-12 07:25 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-13 02:23 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-13 04:19 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-14 03:46 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-14 08:21 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2012-11-15 04:46 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-15 10:21 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-15 12:21 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-15 08:44 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-16 02:12 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-16 08:31 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-16 09:54 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-16 11:00 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-16 11:36 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-16 01:08 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-16 01:45 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-16 05:47 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-17 03:41 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-17 04:05 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-17 07:18 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-17 06:01 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-18 04:03 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.livejournal.com - Date: 2012-11-18 11:11 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-25 12:53 pm (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-13 10:20 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-14 03:49 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-14 08:29 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-15 04:54 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-15 08:53 am (UTC) - Expand

(no subject)

From: [identity profile] berezovsky.livejournal.com - Date: 2012-11-15 09:16 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-15 10:54 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-15 12:01 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-11 03:38 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-11 01:29 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2012-11-11 03:01 am (UTC) - Expand

(no subject)

From: [identity profile] metaclass.livejournal.com - Date: 2012-11-07 10:34 am (UTC) - Expand

(no subject)

From: [identity profile] isorecursive.livejournal.com - Date: 2012-11-07 11:02 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-07 11:31 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-07 11:31 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-11 01:34 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-11 08:25 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-11 10:09 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-11 10:12 am (UTC) - Expand

(no subject)

From: [identity profile] thesz.livejournal.com - Date: 2012-11-11 11:04 am (UTC) - Expand

Date: 2012-11-06 09:30 pm (UTC)
From: [identity profile] thesz.livejournal.com
Кстати, у вас код пропустит строку ")(". Код на Эрланге и мой не пропустят.

Мелочь, а приятно. ;)

Date: 2012-11-06 11:02 am (UTC)
From: [identity profile] xeno-by.livejournal.com
Можете.пожалуйста пояснить что не так с паттерн матчингом?

Date: 2012-11-06 11:12 am (UTC)
From: [identity profile] sum-erman.livejournal.com
Очень многобуков по сравнению с haskell/erlang, нельзя заматчить например пару(X,X), нету охранных выражений или я просто пока не сталкивался (понять что за шаманство использовано в очередном скало-коде (буквально только что увидел this: Foo with Bar => посреди класса) это песня почище haskell :) )

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

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

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

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

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

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-06 01:07 pm (UTC) - Expand

(no subject)

From: [identity profile] sum-erman.livejournal.com - Date: 2012-11-06 01:24 pm (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-06 01:32 pm (UTC) - Expand

(no subject)

From: [identity profile] sum-erman.livejournal.com - Date: 2012-11-06 01:37 pm (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-06 01:45 pm (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-06 01:46 pm (UTC) - Expand

(no subject)

From: [identity profile] sum-erman.livejournal.com - Date: 2012-11-06 08:46 pm (UTC) - Expand

(no subject)

From: [identity profile] isorecursive.livejournal.com - Date: 2012-11-07 03:12 am (UTC) - Expand

(no subject)

From: [identity profile] xeno-by.livejournal.com - Date: 2012-11-06 01:43 pm (UTC) - Expand

(no subject)

From: [identity profile] sum-erman.livejournal.com - Date: 2012-11-06 09:09 pm (UTC) - Expand

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

Date: 2012-11-06 05:57 pm (UTC)
From: [identity profile] golikov konstantine (from livejournal.com)
"нельзя заматчить например пару(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 Date: 2012-11-06 06:12 pm (UTC)

Date: 2012-11-06 06:24 pm (UTC)
From: [identity profile] golikov konstantine (from livejournal.com)
"а необходимость указывать типы во вложенных функциях"
можно вот тут поподробней?

Date: 2012-11-06 07:21 pm (UTC)
From: [identity profile] sum-erman.livejournal.com
def foo(l: List[A]): Boolean = {
def bar(x: A): A = {
...
bar(..)
}
....
}

Для bar надо всегда указывать типы формальных параметров, а если она рекурсивная, то и тип возвращаемого значения. А в цацкеле в let и where — не надо.

Date: 2012-11-06 07:24 pm (UTC)
From: [identity profile] golikov konstantine (from livejournal.com)
ясно понятно, спасибо

выше про это вроде бы было (но если что -- основная причина -- в хаскелле хиндли милнер)

это и вправду не обойти, увы

Date: 2012-11-06 08:23 pm (UTC)
From: [identity profile] sum-erman.livejournal.com
Я понимаю (примерно) почему оно так как оно есть, но писать код от этого увы не проще и не удобнее :/

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 3rd, 2025 04:42 pm
Powered by Dreamwidth Studios