Scala
Читаю книжку Одерского, до основной шизы еще не добрался, но такое ощущение, что в скале чрезмерно много синтаксического сахара. Типа "тут вы можете скобки опустить, а тут вместо скобок использовать фигурные скобки, а тут мы прямо в параметрах класса сделаем их полями, а в multiline string literal вы можете сделать отступ и stripMargin" и прочая и прочая в том же духе.
Основное из этого, видимо - function literals и вызов методов в стиле a methodName b, без точек и скобок, что делает код более лаконичным, одновременно позволяя при желании превратить код в нечитабельный ад.
Заодно по наводке
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
По-моему, это уже достаточно сложно, чтобы увлечь психов и стать новыми крестиками. Вот
xeno_by еще приделает макросы - и совсем хорошо станет.
Основное из этого, видимо - function literals и вызов методов в стиле a methodName b, без точек и скобок, что делает код более лаконичным, одновременно позволяя при желании превратить код в нечитабельный ад.
Заодно по наводке
Примеры там, конечно, знатный abuse возможностей языка и вычислений на типах, типа extraction-директив с HList в качестве параметра типа.
Clojure по сравнению с этим выглядит более простой и логичной, хотя я не уверен, можно ли сравнивать совершенно разные языки, общего у которых только функциональщина и иммутабельность иногда.
PS: Вот, к примеру:
https://github.com/spray/spray/blob/master/docs/documentation/spray-routing/code/docs/HttpServiceExamplesSpec.scala
В SimpleService HttpResponse реализован как html-код написанный прямо внутри скала-кода.
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
По-моему, это уже достаточно сложно, чтобы увлечь психов и стать новыми крестиками. Вот
no subject
no subject
no subject
мне в голову приходит только паттерн матчинг в аргументах функции, но а) это в некотором виде существует в виде structural typing б) синтаксический сахар и аналог без сахара в скале есть
no subject
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 страниц книги. И мнение меняется по мере изучения предмета.
no subject
в аргументах функции -- ну я бы не сказал что это настолько киллер фича что бы говорить что он сильно лучше (это, опять же, мое субьективное мнение).
Вот например сбалансированные строки на скале
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
}
пожалуй эрланг и вправду короче, но не так что бы сильно меньше
no subject
no subject
weight '(' = 1 weight ')' = -1 weight x = 0 balanced = check . scanl (+) 0 . map weight where check balances = all (>=0) balances && last balances == 0Не мог удержаться. ;)no subject
После скалы это выглядит как бальзам на душу.
no subject
программистскогообщества. ;)Это ещё и демонстрация, чем выгодна ленивость. В качестве бонуса. ;)
no subject
и вправду красиво и компактно
no subject
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)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(Anonymous) - 2012-11-15 04:46 (UTC) - Expand(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Мелочь, а приятно. ;)
no subject
no subject
no subject
no subject
no subject
Приведенный синтаксис это self-type annotation. Он позволяет указать зависимости данного трейта от других трейтов и классов. В книжке Мартина тоже про это будет.
no subject
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
no subject
(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"
no subject
no subject
можно вот тут поподробней?
no subject
def bar(x: A): A = {
...
bar(..)
}
....
}
Для bar надо всегда указывать типы формальных параметров, а если она рекурсивная, то и тип возвращаемого значения. А в цацкеле в let и where — не надо.
no subject
выше про это вроде бы было (но если что -- основная причина -- в хаскелле хиндли милнер)
это и вправду не обойти, увы
no subject