LINUX.ORG.RU

Группа разработчиков Scala получила грант Евросоюза

 , , ,


1

4

Группа разработчиков языка Scala получила грант Евросоюза, выиграв конкурс языков для параллельного программирования. Разработчики получат в течение следующих 5 лет на развитие своего детища 2,3млн €.

Scala — язык программирования для платформы JVM, сочетающий возможности объектно-ориентированного и функционального программирования. Scala был разработан в лаборатории швейцарского ВУЗ’а EFPL.

>>> Подробности

★★★★★

Проверено: maxcom ()

Ответ на: комментарий от r

> То есть ты считаешь что граф с циклами?!

the number of linearly independent paths through the flow graph from an entry to an exit

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от AlexRK

>Это где? Я не заметил.

http://www.linux.org.ru/jump-message.jsp?msgid=5817442&cid=5853703

Да, восприятие.


Фантастика.

И пропорциональное количество дефектов в коде.


А вот тут ша. То что ты хочешь привести как причину я назову «корреляцией».


И опять же попрошу сравнивать сравнимые вещи - то есть реализации полностью. А не твою температуру на градуснике со средней температурой по больнице. И «бажность» приведенного кода на жабе - больше. Причины назывались много раз.

Могу только дать ссылку на википедию (выше), где написано про корреляцию цикломатической сложности и количества дефектов. :)


Количество дефектов в жабской программе возросло. Так что не попал:)

Ничего я никуда не натягиваю. Большая сложность - плохо. Маленькая - хорошо.


В таких утверждения надо писать дальше «где термином „сложность“ обозначается...., где термином „хорошо/плохо“ обозначачется». Иначе это бабки у подъезда за обсуждением ситуации на ближнем востоке.

r ★★★★★ ()
Ответ на: комментарий от AlexRK

> Сколько методов в системе - пофиг. :)

бред — тогда получается каждый отдельный иф надо оформлять в виде метода

на методы, в идеале, должны иметь возможность вызываться независимо, поэтому их число надо пытаться сокращать

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от r

хотя вот так оно работает:

object Hello2 {
    def main( args: Array[String] ) {
        println( Test.test() )
    }
}
class Test {
    private var x = 5;
}
object Test {
    def test() = (new Test).x
}

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

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от r

>http://www.linux.org.ru/jump-message.jsp?msgid=5817442&cid=5853703

А, это видел. Но это вовсе не то. Я просил другое.

А вот тут ша. То что ты хочешь привести как причину я назову «корреляцией».

Где я сказал про причину? Ну да, корреляция.

И опять же попрошу сравнивать сравнимые вещи - то есть реализации полностью.

Не вижу смысла. Число строк в жаба-коде тоже больше. Полезность таких показателей, как число строк или _суммарная_ сложность, считаю низкой (возможно, с оговорками).

И «бажность» приведенного кода на жабе - больше.

Насчет конкретно приведенного не знаю, но вообще идею разбивания на методы считаю правильной.

Количество дефектов в жабской программе возросло. Так что не попал:)

Хм. С чего это возросло?

В таких утверждения надо писать дальше «где термином „сложность“ обозначается...., где термином „хорошо/плохо“ обозначачется».

Сложность - имелся в виду обсуждаемый показатель (цикломатическая сложность).

Хорошо-плохо - речь о статистической корреляции сложности с числом дефектов. Больше сложность - больше дефектов, значит плохо.

Вам не надоело еще буквоедство? :)

AlexRK ()
Ответ на: комментарий от www_linux_org_ru

>бред — тогда получается каждый отдельный иф надо оформлять в виде метода

Не-не-не, Дэвид Блейн. Следует читать: «не в ущерб другим причинам создания методов». Причины мы уже обсуждали - формирование законченной абстракции и т.п.

Так и знал, что кто-нибудь прикопается к этой фразе. :)

AlexRK ()
Ответ на: комментарий от www_linux_org_ru

>the number of linearly independent paths through the flow graph from an entry to an exit

Я знал! Теперь тут тебе следует обратить внимание на слово _exit_ в единственном числе. А потом пойти по ссылкам и увидеть что

exit block - _block_(ед число) through which _all_ control flows leave the graph

В нашем случае таких блоков несколько.

Для нашего случая разработана другая формула - она там указана.

Но я соглашусь, что с точки зрения Basis Path Testing - это не имеет значения - количество вариантов выполнеия все равно по количеству выходов. Но это только в рамках BPT. Потому что, если смотреть с точки зрения графа - то дерево проще чем граф с циклами. И посколько не любой сингэкзит код можно свести к мультиэкзит без дублирования

def f(x) = {
if (x>0) result = 1
else result = 2

result = g(result)

return result
}

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

Но AlexRK вообще пытается натянуть CC на психологию, а не для BPT или графов - потому для него будем считать по мультиэкзит формуле:)

r ★★★★★ ()
Ответ на: комментарий от r

>Но AlexRK вообще пытается натянуть CC на психологию, а не для BPT или графов - потому для него будем считать по мультиэкзит формуле:)

Я, как большой знаток психологии, а также этики, могу вам сказать, что обсуждать человека в третьем лице некрасиво. :) Тем более подобным вашему барским тоном. :)

AlexRK ()
Ответ на: комментарий от www_linux_org_ru

>у тебя 2.8 есть? оно там запускается?

Я свой проверял.

Но в консольке работать не будет.

Если определение твоего Test находится в одном compilation unit - то object Test является companion для class Test, со всеми проистекающими компиляциями в один класс и ковырянием в потрошках. Внутри интерпретатора есть нюансы.



r ★★★★★ ()
Ответ на: комментарий от AlexRK

>Где я сказал про причину? Ну да, корреляция.

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

r ★★★★★ ()
Ответ на: комментарий от r

lmao

> >Итак, это все ваши аргументы (я бы вообще это к аргументан на отнёс)?

Ты привел ссылку на фаулера как на авторитета. Я показал что он не авторитет по указанной теме (ты ж не будешь спорить с этим?). Что тебе не нравится?

Поржал! Ты действительно непробиваем. Я спрашивал, почему ИМЕННО ТЫ считаешь, что Фаулер не прав в конкретном случае и какие же у тебя предложения исправить его возмжные «ошибки». Не знаешь, нет предложений - сглотни и напиши об этом.

А от тебя - одни тыкания авторитетами. Слушай, разве сложно прочитать и ответить на вопрос? Я вот в посте выше я спросил, будут ли у вас какие-либо аргументы. А вы всё авторитетами меряятесь, и ещё применяете паттерн «сперва добейся». Детсад

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

«Сперва добейся» во все поля. Раз ты у нас дипломированный специалист по «психологии восприятия» - потыкай нас в ошибки Фаулера и скажи же быдлу, как делать «правильно»

anonymous ()
Ответ на: комментарий от AlexRK

>Не вижу смысла.

То есть нет смысла сравнивать сравнимые вещи и есть смысл сравнивать несравнимые?

Хм. С чего это возросло?


Почитай мой длинный пост - там указываются кучи проблем с инвариантами коnорые вы пытались зашифровать за словом «private». Так что ша - вы не можете зашифровать за словом private все методы и одновременно говорить что оценивать надо не полной реализации. А то я перед логином поставлю слово приват - получу 0 - и все равно все будет работать:)

Сложность - имелся в виду обсуждаемый показатель (цикломатическая сложность).


Обсуждаемый показатель - количество ребер в графе которые надо убрать чтобы в графе не было циклов. Или по иному - количество execution paths.

Где там про впечатление производимое на психику?

Хорошо-плохо - речь о статистической корреляции сложности с числом дефектов.


О! Достижение - мы убрали психологию!

Теперь можно вернуться к параметру P согласно которому цикломатическая сложность отрефактореного кода - 9.

Вам не надоело еще буквоедство? :)


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



r ★★★★★ ()
Ответ на: комментарий от AlexRK

>. Причины мы уже обсуждали - формирование законченной абстракции и т.п.

Никакой абстракции там не сформировано. Сча опять пошлю общаться с Аристотелем:) Абстракции которые там могут быть я уже перечислял.

r ★★★★★ ()
Ответ на: комментарий от AlexRK

>Я, как большой знаток психологии, а также этики, могу вам сказать, что обсуждать человека в третьем лице некрасиво. :)

Я не обсуждаю а ссылаюсь. Ненене Девид Блейн:)

r ★★★★★ ()
Ответ на: комментарий от r

Если определение твоего Test находится в одном compilation unit - то object Test является companion для class Test, со всеми проистекающими компиляциями в один класс и ковырянием в потрошках.

$ cat r-test.scala 
object T extends Application {
    println(new T().x)
}

class T {
    private var x = 5;
}
$ scalac r-test.scala 
$ scala T
java.lang.NoSuchMethodException: T.main([Ljava.lang.String;)
$

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

www_linux_org_ru ★★★★★ ()
Ответ на: lmao от anonymous

> Я спрашивал, почему ИМЕННО ТЫ считаешь

Было бы шизофренией _именно мне_ обсуждать почему например именно www_linux_org_ru что-то считает. Поскольку я высказываю собственное мнение - мне кажется что вполне логично что его высказываю именно я, не?

Ы считаешь, что Фаулер не прав в конкретном случае


В каком конкретном случае? В _этом_? А что под каким-то ником тут скрывается Фаулер и он уже высказался?

Какие ваши конкретныё претензии?

К тому что я написал что фаулер не истина в последней инстанции? На его(и его колег) ошибки, которые совсем не являются простыми очепятками я показывал со ссылками.

У вас есть мнение что он истина в последней инстанции?

Я вот в посте выше я спросил, будут ли у вас какие-либо аргументы


Я их привел в развернутом ответе для eao197, ч2.

. А вы всё авторитетами меряятесь, и ещё применяете паттерн «сперва добейся».


Где? Где я просил кого-то чего-то добиваться?

Точно детсад.

«Сперва добейся» во все поля.


Ты точно знаешь значение этого термина?

Раз ты у нас дипломированный специалист по «психологии восприятия» - потыкай нас в ошибки Фаулера и скажи же быдлу, как делать «правильно»


Правильно - не приписывать Фаулеру утверждений, которых он не делал и скилов, которыми он не обладает.

r ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>как видим, еще и надежность у скалы низкая — настолько, что в тестовых примерах в нашей ветке, которых кот наплакал, уже начинаются ошибки

Ты почитай-то что за ошибка:)

В 2.7 были проблемы с Application. там надо обычный main написать. Твой код нормальный - просто в нем main нету - о чем и упомянула запускалка.




r ★★★★★ ()
Ответ на: комментарий от r

Ты почитай-то что за ошибка:)

давно уже и почитал...

В 2.7 были проблемы с Application. там надо обычный main написать.

... и обычный мейн написал, не совсем ведь тупой:

 
$ cat scala-static-strange-test.scala 
object Hello {
    def main( args: Array[String] ) {
        println(new Hello().x)
    }
}

class Hello {
    private var x = 5;
}
$ scalac scala-static-strange-test.scala 
$ scala Hello
java.lang.NoSuchMethodException: Hello.main([Ljava.lang.String;)
$
www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>... и обычный мейн написал, не совсем ведь тупой:

-version?

r ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>... и обычный мейн написал, не совсем ведь тупой:

def main( args: Array[String] ) {


def main( args: Array[String] ):Unit = {

r ★★★★★ ()
Ответ на: комментарий от r

> def main( args: Array[String] ):Unit = {

то же самое java.lang.NoSuchMethodException: Hello.main([Ljava.lang.String;)

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>то же самое java.lang.NoSuchMethodException: Hello.main([Ljava.lang.String;)

Тут проблема в сигнатуре какая-то. В смысле жаба не может найти единственно правильную сигнатуру метода.

javap натрави на Hello.class

должен быть метод:

public static final void main(java.lang.String[]);

r ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

в 2.7.x там была какая-то проблемка с тем что надо объявить майн именно так чтобы java его нашла - я не помню уже как именно - остальные варианты просто компилятся не в такой метод по сигнатуре как нужно жабе.

r ★★★★★ ()
Ответ на: комментарий от r

Предсказуемо. Слив защитан.

О как, ход конем. Хорошо развивается дискуссия. Вас тут уже просветили по поводу многих вещей. В ответ видны лишь доказательства бесконечности человеческой тупости. А попытка прервать этот порочный круг оказывается сливом.

Ладно, проверим глубину тупости еще немного :)

Можно пример когда гварды не зло с учетом пунктов 1 и 2?

Такой пример легко найти в исходниках компилятора Scala (файл src/scala/tools/nsc/Global.scala, метод coreClassesFirst):

for (file <- files) file.file.name match {
  case "ScalaObject.scala" if inScalaFolder(file) => scalaObject = Some(file)
  case "LowPriorityImplicits.scala" if inScalaFolder(file) => file +=: res
  case "StandardEmbeddings.scala" if inScalaFolder(file) => file +=: res
  case _ => res += file
}
В данном случае выполняется пункт 1, а пункт 2 не актуален. Тогда как гуарды способствуют выполнению пункта 1.

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

eao197 ★★★★★ ()
Ответ на: комментарий от r

Почитай мой длинный пост - там указываются кучи проблем с инвариантами коnорые вы пытались зашифровать за словом «private». Так что ша - вы не можете зашифровать за словом private все методы и одновременно говорить что оценивать надо не полной реализации. А то я перед логином поставлю слово приват - получу 0 - и все равно все будет работать:)

Баги — это очень очевидная вещь. Продемонстрируйте набор входных данных, на которых ваш login будет работать правильно, а мой не будет.

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

eao197 ★★★★★ ()
Ответ на: комментарий от r

А что под каким-то ником тут скрывается Фаулер и он уже высказался?

Объясните такую вещь: сначала вы сказали, что мой код можно раскритиковать по Фаулеру. Тем самым вы признали, что рекомендации Фаулера можно использовать для оценки кода. Потом вы сказали, что Фаулер не авторитет.

Так можно ли рекомендации Фаулера использовать для оценки кода или нет?

Принимается только односложный ответ «да» или «нет».

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

>В данном случае выполняется пункт 1, а пункт 2 не актуален.

Я тебе процитирую пункт 1:

Упрощение разбора сложных структур данных, вроде чего-то такого:

case [X, [a, b, _, c], D] => ...



Я так понимаю что простой стринг для тебя достаточно сложная структура, в то время как матчинг алгебраического типа Option - это невероятно просто.


r ★★★★★ ()
Ответ на: комментарий от eao197

> Баги — это очень очевидная вещь. Продемонстрируйте набор входных данных, на которых ваш login будет работать правильно, а мой не будет.

Точно. Но еще более очевидно что мы тут говорим о потенциальных багах. Где не будут работать твой полтергейст-хендлер из-за нарушения инвариантов я показывал.

Никакие потенциально возможные или невозможные будущие модификациями не рассматриваются


Метрические характеристики кода выясняются с точки зрения его будущего развития, а не чтобы в дневник оценку поставить.

А безбажно можно написать код любой степени мерзопакостности.

r ★★★★★ ()
Ответ на: комментарий от eao197

>Так можно ли рекомендации Фаулера использовать для оценки кода или нет?

Твоего - да.

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

r ★★★★★ ()
Ответ на: комментарий от r

Я так понимаю что простой стринг для тебя достаточно сложная структура, в то время как матчинг алгебраического типа Option - это невероятно просто.

Если хотите сложных структур, то загляните, скажем, в файлик tools/nsc/symtab/Types.scala — их есть там.

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

eao197 ★★★★★ ()
Ответ на: комментарий от r

Но еще более очевидно что мы тут говорим о потенциальных багах.

Нет бага, нет проблемы.

Где не будут работать твой полтергейст-хендлер из-за нарушения инвариантов я показывал.

В ваших умелых руках, однозначно, не будет. Это же вы предпочитаете повторное использование вида:

def mylogin(...) = {
  ...
  login(x, y, z)
}
И ваш код, совершенно очевидно, выдержит, скажем, такую ошибку:
def mylogin(...) = {
  ...
  login(x, y, z)
  ...
  login(a, b, c)
}

Метрические характеристики кода выясняются с точки зрения его будущего развития

Так именно это должны были подчеркнуть ваши первоначальные метрики?

eao197 ★★★★★ ()
Ответ на: комментарий от r

>Так можно ли рекомендации Фаулера использовать для оценки кода или нет?

Твоего - да

О! А вашего, следовательно, нет!?

Круче мосье только горы и яйца.

_Твоя_ проблема, что ты не читаешь то что тебе пишут, и не утруждаешь себя процессом размышления.

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

eao197 ★★★★★ ()
Ответ на: комментарий от r

> > Я спрашивал, почему ИМЕННО ТЫ считаешь

Было бы шизофренией _именно мне_ обсуждать почему например именно www_linux_org_ru что-то считает. Поскольку я высказываю собственное мнение - мне кажется что вполне логично что его высказываю именно я, не?

Феерично! (сорри за это клише).

Значит, вопрос:

Q: Почему так нельзя делать (речь про мелкие функции, которые могут вызываться только один раз, но с объясняющими названиями)

Ответ от эрчика:

A: Фаулер не использовал терминов из «психологии восприятия», поэтому он не знает, как нужно делать, поэтому это неправильно.

Дальше, ещё один вопрос:

Q: Что именно-то неправильно и как нужно делать?

A: Ты что, считаешь Фаулера авторитетом? Не нужно слепо следовать его рекомендациям.

и т.д., ещё куча таких итераций. Ты так ни разу и не ответил ни на один заданный тебе вопрос. Смешно :D

anonymous ()
Ответ на: комментарий от anonymous

>Ответ от эрчика:

Раз ты такой мастак придумывать мои ответы - может ты и на остальные свои вопросы мои ответы придумаешь?

Совет - лучше попробуй цитировать.

r ★★★★★ ()
Ответ на: комментарий от eao197

Если хотите сложных структур

Только не надо лохматить бабушку - ты отлично понял чего я хочу. Твои пункты говорят о том что матчинг надо использовать либо для сложных структур либо для проверки comprehensive'ности - это ты заявил.

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

в файлик tools/nsc/symtab/Types.scala — их есть там.

Там лежат алгебраические типы - точно такие же как Option! То есть Одерскому можно пользоваться алгебраическими типами - а мне нельзя? Или что ты тут заявить пытаешься?

вот 1 из файла который ты приводишь в пример:

    def findMember(name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean): Symbol = {
      val suspension = TypeVar.Suspension
      // if this type contains type variables, put them to sleep for a while -- don't just wipe them out by
      // replacing them by the corresponding type parameter, as that messes up (e.g.) type variables in type refinements
      // without this, the matchesType call would lead to type variables on both sides
      // of a subtyping/equality judgement, which can lead to recursive types being constructed.
      // See (t0851) for a situation where this happens.
      if (!this.isGround) {
        // PP: The foreach below was formerly expressed as:
        //   for(tv @ TypeVar(_, _) <- this) { suspension suspend tv }
        //
        // The tree checker failed this saying a TypeVar is required, but a (Type @unchecked) was found.
        // This is a consequence of using a pattern match and variable binding + ticket #1503, which
        // was addressed by weakening the type of bindings in pattern matches if they occur on the right.
        // So I'm not quite sure why this works at all, as the checker is right that it is mistyped.
        // For now I modified it as below, which achieves the same without error.
        //
        // make each type var in this type use its original type for comparisons instead of collecting constraints
        this foreach {
          case tv: TypeVar  => suspension suspend tv
          case _            => ()
        }
      }

      incCounter(findMemberCount)
      val start = startTimer(findMemberNanos)

      //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG
      var members: Scope = null
      var member: Symbol = NoSymbol
      var excluded = excludedFlags | DEFERRED
      var continue = true
      var self: Type = null
      var membertpe: Type = null
      while (continue) {
        continue = false
        val bcs0 = baseClasses
        var bcs = bcs0
        while (!bcs.isEmpty) {
          val decls = bcs.head.info.decls
          var entry =
            if (name == nme.ANYNAME) decls.elems else decls.lookupEntry(name)
          while (entry ne null) {
            val sym = entry.sym
            if (sym hasAllFlags requiredFlags) {
              val excl = sym.getFlag(excluded)
              if (excl == 0L && 
                  (// omit PRIVATE LOCALS unless selector class is contained in class owning the def.
                   (bcs eq bcs0) ||
                   !sym.isPrivateLocal ||
                   (bcs0.head.hasTransOwner(bcs.head)))) {
                if (name.isTypeName || stableOnly && sym.isStable) {
                  stopTimer(findMemberNanos, start)
                  suspension.resumeAll
                  return sym
                } else if (member == NoSymbol) {
                  member = sym
                } else if (members eq null) {
                  if (member.name != sym.name || 
                      !(member == sym ||
                        member.owner != sym.owner &&
                        !sym.isPrivate && {
                          if (self eq null) self = this.narrow
                          if (membertpe eq null) membertpe = self.memberType(member)
                          (membertpe matches self.memberType(sym))
                        })) {
                    members = new Scope(List(member, sym))
                  }
                } else {
                  var prevEntry = members.lookupEntry(sym.name)
                  while ((prevEntry ne null) &&
                         !(prevEntry.sym == sym ||
                           prevEntry.sym.owner != sym.owner &&
                           !sym.hasFlag(PRIVATE) && {
                             if (self eq null) self = this.narrow
                             self.memberType(prevEntry.sym) matches self.memberType(sym)
                           })) {
                    prevEntry = members lookupNextEntry prevEntry
                  }
                  if (prevEntry eq null) {
                    members enter sym
                  }
                }
              } else if (excl == DEFERRED.toLong) {
                continue = true
              }
            }
            entry = if (name == nme.ANYNAME) entry.next else decls lookupNextEntry entry
          } // while (entry ne null)
          // excluded = excluded | LOCAL
          bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail
        } // while (!bcs.isEmpty)
        excluded = excludedFlags
      } // while (continue)
      stopTimer(findMemberNanos, start)
      suspension.resumeAll
      if (members eq null) {
        if (member == NoSymbol) incCounter(noMemberCount)
        member
      } else {
        incCounter(multMemberCount)
        baseClasses.head.newOverloaded(this, members.toList)
      }
    }

А данный пример я привел, поскольку есть хорошее противопоставлению вашему коду:

И полное несоответствие твоему утверждению.

r ★★★★★ ()
Ответ на: комментарий от eao197

>Нет бага, нет проблемы.

Мне жалко ваших заказчиков.

Так именно это должны были подчеркнуть ваши первоначальные метрики?


Именно это. Или у вас там машину времени изобрели и вы научились писать код лучше в прошлом чтобы метрики получались лучше в настоящем?

r ★★★★★ ()
Ответ на: комментарий от eao197

>О! А вашего, следовательно, нет!?

Потрясающая логика!

Круче мосье только горы и яйца.


Круче мосье только мозги. Ты уже аслил объектный паттерн «стратегия» по гофофаулеру для языков с функциями высших порядков? Или рефакторинг encapsulate collection для языков с иммутабельными коллекциями? Encapsulate Downcast - для языков с параметрическим полиморфизмом или динамических языков? Encapsulate Field для языков с пропертями? Introduce Null Object/Replace Error Code with Exception для языков с Option/Maybe?...?

Попробуй воспользоваться мозгами - это не больно.


r ★★★★★ ()
Ответ на: комментарий от r

Твои пункты говорят о том что матчинг надо использовать либо для сложных структур либо для проверки comprehensive'ности - это ты заявил.

И вновь мимо, я этого не заявлял (и не мог заявить про «либо-либо», т.к. тогда исключаются как «и-и», так и «другие возможные преимущества»).

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

Там лежат алгебраические типы - точно такие же как Option! То есть Одерскому можно пользоваться алгебраическими типами - а мне нельзя? Или что ты тут заявить пытаешься?

Там полно примеров использования паттерн-матчинга с гуардами. Вы можете посмотреть на них, чтобы увидеть, в каких случаях гуарды не являются злом в сочетании с разборами сложных структур данных.

вот 1 из файла который ты приводишь в пример:

Вас что, нужно учить пользоваться grep-ом? Вот лишь небольшая выжимка:

bash-3.2$ grep "case\s.*if\s" Types.scala
        case TypeRef(pre, sym, args) if sym.isAliasType => tp.normalize
        case TypeRef(_, sym, _) if (sym == SingletonClass) =>
      case TypeRef(pre, sym, List()) if isRawIfWithoutArgs(sym) =>
        case TypeRef(prefix, sym, args) if (sym.isTypeParameter) =>
        case TypeRef(pre, sym, args) if !(pre eq NoPrefix) =>
        case SingleType(pre, sym) if !(pre eq NoPrefix) =>
      case (ExistentialType(_, res1), _) if alwaysMatchSimple =>
      case (_, ExistentialType(_, res2)) if alwaysMatchSimple =>

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

Поскольку с первого раза до вас не доходит, повторю еще раз:

поскольку есть хорошее противопоставлению вашему коду: несколько простых проверок, которые можно было бы записать и на if-ах. Но здесь матчинг уместен. В отличии от.

И, специально для знатока множества умных слов, расшифрую. Вы утверждали, что «банальный Option - делает программы намного более надежными в плане необработанных инвариантов». Вот упрощенная схема вашего кода:

AccountsStorage.find(login) match {
  case None => ...
  case Some(user) if user.inactive => ...
  case Some(user) if user.authScheme == "PETRIVKA" => ...
  case Some(user) => ...
  case _ => ...
}
Из-за наличия гуардов вам пришлось писать case _. Это ведет к тому, что если кто-то, случайно или намеренно, удалит case None, то компилятор вам не скажет больше, что один из значимых вариантов больше не обрабатывается.

Однако, если лишь слегка модифицировать ваш код:

AccountsStorage.find(login) match {
  case None => ...
  case Some(user) =>
    if user.inactive ...
    else if user.authScheme == "PETRIVKA" ...
    else ...
}
то преимущество контроля со стороны компилятора возвращается. Нельзя будет просто удалить обработку варианта None.

eao197 ★★★★★ ()
Ответ на: комментарий от r

>Так именно это должны были подчеркнуть ваши первоначальные метрики?

Именно это.

Могли бы вы объяснить популярно, как, например, такая метрика, как FuncLOC% что-то скажет о будущем развитии кода?

Или у вас там машину времени изобрели и вы научились писать код лучше в прошлом чтобы метрики получались лучше в настоящем?

Вопрос поражающий своей бредовостью.

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

Не нужно никакой машины времени.

eao197 ★★★★★ ()
Ответ на: комментарий от r

eao197>Так можно ли рекомендации Фаулера использовать для оценки кода или нет?

r>Твоего - да

eao197>О! А вашего, следовательно, нет!?

r>Потрясающая логика!

Простая логика. Положительный ответ был дан с органичениями => вне этих ограничений ответ отрицательный => раз в ограничениях указан только мой код, то для вашего кода ответ отрицательный.

eao197 ★★★★★ ()
Ответ на: комментарий от r

Ты уже аслил объектный паттерн «стратегия» по гофофаулеру для языков с функциями высших порядков? Или рефакторинг encapsulate collection для языков с иммутабельными коллекциями? Encapsulate Downcast - для языков с параметрическим полиморфизмом или динамических языков? Encapsulate Field для языков с пропертями? Introduce Null Object/Replace Error Code with Exception для языков с Option/Maybe?...?

Спасибо, поржал.

eao197 ★★★★★ ()
Ответ на: комментарий от r

> Совет - лучше попробуй цитировать.

Пробовал (и не раз), до тебя не дошло (ни на один мой вопрос ты так и не ответил). Я уже и так пересказывал, и этак, и даже упростил всё и сократил количество слов в вопросе, лелея надежду, что до тебя дойдёт. Но напрасно.

anonymous ()
Ответ на: комментарий от eao197

> Простая логика.

Не спорь с упёртыми людьми, которые не могут прочитать не то, что вопросы к ним, но и собственные ответы, данные день назад

anonymous ()
Ответ на: комментарий от anonymous

>Пробовал (и не раз), до тебя не дошло (ни на один мой вопрос ты так и не ответил).

Я не собираюсь отвечать на придуманное тобой мое мнение. Процитируй меня - тогда я отвечу. Я отвечаю за свои слова а не за твои впечатления.

r ★★★★★ ()
Ответ на: комментарий от eao197

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

В твоем коде которые тебя попросилил привести как иллюстрацию твоих высказываний оно тоже не использовалось. Ты совсем не читаешь чтоли что пишешь сам?

Там полно примеров использования паттерн-матчинга с гуардами.
case TypeRef(pre, sym, args) if sym.isAliasType =>
case Some(user) if user.inactive =>

Я смотрю разница принципиальна - да.

./src/scalap/scala/tools/scalap/Main.scala:      case Some(p) if (p.name != "<empty>") => {
./src/compiler/scala/tools/util/PathResolver.scala:      case Some(dir) if scalaHomeExists => join(ClassPath expandDir dir.path: _*)
./src/compiler/scala/tools/nsc/doc/html/page/Template.scala:        case Some(companion) if (isSelf && !isReduced) =>
./src/compiler/scala/tools/nsc/Interpreter.scala:        case Some(vname) if typeOf contains vname =>
./src/compiler/scala/tools/nsc/typechecker/Unapplies.scala:          case Some(xs) if xs.size > 1  => xs         // n > 1
./src/compiler/scala/tools/nsc/typechecker/Typers.scala:        case Some(c) if packageOK || !c.isPackageClass =>
./src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala:                case Some(entry) if !isScalaRaw && !isStatic(entry.jflags) =>
./src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala:          case Some(scalaSig) if (scalaSig.atp == definitions.ScalaSignatureAnnotation.tpe) =>
./src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala:          case Some(scalaSig) if (scalaSig.atp == definitions.ScalaLongSignatureAnnotation.tpe) =>
./src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala:          case Some(others) if ((others find { x => x._1 == LONG || x._1 == DOUBLE}) != None) =>
./src/compiler/scala/tools/nsc/transform/UnCurry.scala:        case Some(lastFormal) if isRepeatedParamType(lastFormal) =>
./src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala:        case Some(level) if level >= severity => true
./src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala:        case Some(pickle) if !jclass.getName().endsWith("$") =>
./src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala:                case Some(typ) if (typ.IsEnum) => {
./src/actors/scala/actors/scheduler/ThreadPoolConfig.scala:    case Some(i) if i > 0 => i
./src/actors/scala/actors/remote/TcpService.scala:        case Some(msgs) if msgs.length < TcpService.BufSize =>
./src/library/scala/math/PartiallyOrdered.scala:      case Some(x) if x < 0 => true
./src/library/scala/math/PartiallyOrdered.scala:      case Some(x) if x > 0 => true
./src/library/scala/math/PartiallyOrdered.scala:      case Some(x) if x <= 0 => true
./src/library/scala/math/PartiallyOrdered.scala:      case Some(x) if x >= 0 => true
./src/library/scala/xml/Xhtml.scala:      case Some(chr) if chr.toInt >= 128  => sb.append(chr)
./docs/examples/plugintemplate/src/plugintemplate/PluginProperties.scala:      case Some(p) if (p.getProperty(property) != null) =>

Я не вижу твоего открытого письма Одерскому чтобы рассказать как он был неправ!

Ты сморозин херню - я тебе дал шанс сделать вид что ты ничего не говорил - но нет тебе захотелось этот бред обсудить.

r ★★★★★ ()
Ответ на: комментарий от eao197

>Могли бы вы объяснить популярно, как, например, такая метрика, как FuncLOC% что-то скажет о будущем развитии кода?

Модифицировать программу в три строчки в общем случае легче чем программу в 23 строчки реализующую одну и ту же функцию - это что рокет саянс?

Вопрос поражающий своей бредовостью.


То есть ты как всегда просто не понял. Это бывает.

Ситуация, обычно, следующая:


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

Это к статим прямо подтверждает твои слова - что все проблемы с модификациями твоего кода - это проблемы модификатора а не твои.

Жесть. Ты почти сформулировал мотто говнокодера.

r ★★★★★ ()
Ответ на: комментарий от eao197

>Положительный ответ был дан с органичениями => вне этих ограничений ответ отрицательный => раз в ограничениях указан только мой код, то для вашего кода ответ отрицательный.


Столб с фонарем - не светофор.
Ты - не столб с фонарем.

Ты - светофор?

Мама родная - ты улицу перейти в состоянии без посторонней помощи?


r ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.