LINUX.ORG.RU

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

 , , ,


1

4

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

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

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

★★★★★

Проверено: maxcom ()
Последнее исправление: Zhbert (всего исправлений: 3)

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

при этом, эта вторая строчка request.session(«datetime») = datetime может по легкому недогляду появиться только 1 раз — и все будет работать прекрасно, вот только время последней авторизации будет обновляться не всегда

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

подозреваю, там появиться вторая строчка request.session(«datetime») = datetime

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

Но позможно появиться implicit вида: (на самом деле чуть расширеней но так тоже будет работать)

implicit def session2richSession(session) = new { 
      def login(user) = { 
         session("user") = user
         session("logged-at") = new Date()
     }
     def loggedAt = session("logged-at").asInstanceOf[Date]
}

использование

session.login(user)

println(session.loggedAt)

либо появится

case class LoginInfo(user) {
     val loggedAt = new Date();
}

и пользоваться будут им

session("login-info") = LoginInfo(user)

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

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

>я четко написал, что комментировать код названиями функций не стоит, а ты *мне* пытаешься приписать такую мысль

тогда объясни зачем unckeckedLogin. Я думал чтобы откоментировать что понятие «залогинен» - это когда юзер в сессии.

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

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

чуток занимался, поэтому знаю, что он не настолько стереотипен, как ты говоришь (и поэтому, кстати, намного спокойнее отнесся к твоему коду, чем еао197)

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

> Когда их появится 2 будет отдельный метод чтобы избежать code duplication раз и гарантировать одинаковую логику.

ы!!!

так ты похоже сам не знаешь, что их (request.session(«user») = user) у тебя *уже* 2 штуки

вот и источник багов

прочти свой код внимательно

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

> Когда их появится 2 будет отдельный метод чтобы избежать code duplication раз и гарантировать одинаковую логику.

их уже 2 — конкретно на 13-й и на 20-й строках

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

>так ты похоже сам не знаешь, что их (request.session(«user») = user) у тебя *уже* 2 штуки

Я знаю. Я не вижу как

assign(session(«user»), user)

отличается от

uncheckedLogin(session, user)

что на хаскеле можно было бы переписать инфиксно:

session `uncheckedLogin` user

что сравнивая с

sesssion(«user») = user

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

То есть

sesssion(«user») = user

это по сути (то ессть практически фактически) :

гдето....
map = new HashMap()

map.put(«x», y)

я пока не вижу зачем мне каждый обычный put в мапу выносить функцией вида

def putx(map, y) = map.put(«x», y)

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

> что, стоит учить скалу?

Моё ИМХО, что учить надо Haskell. После него становится понятно, что, как и для чего в Скале. Хотя некоторые советуют начинать знакомство с функциональным программированием со Standard ML.

денег от этого у меня прибавиться?

Если это единственная мотивация, то нет, потому что не осилишь.

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

> их уже 2 — конкретно на 13-й и на 20-й строках

Две - я имел ввиду две одинаковые логично связанные строки в более чем одном месте. Когда в двух ветках матча будет код который должен быть одинаков и длиннее одной строки.

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

> что на хаскеле можно было бы переписать инфиксно: session `uncheckedLogin` user

ты еще мне про машинные инструкции расскажи

логин четко делиться на 2 части:

1. верификация данных о юзере

2. uncheckedLogin, который в твоем случае оказался assign(session(«user»), user), а в случае необходимости хранить данные о прошлом входе — еще потребуется добавить assign(session(«user»), date())

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

assign(session(«date»), date()) конечно же

и вообще я тебе это только что несколькими постами раньше написал

хочешь утопить свою ошибку в простынях разговоров?

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

>логин четко делиться на 2 части:

то есть на огромный кусок кода и одно присваивание. Вынос в uncheckedLogin - это переименование присваивания. Аргумент понятен если цель - самодокументирование. Но если цель не оно - зачем?

обрати внимание как называется сам метод - login. То есть присваивание - уже внутри метода с названием login. Характеристика «верифицированный неверифицированный логин» пока не существует. Зачем мне нужна функция неверифицированного логина? Появится нужда - изобрету.

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

> я пока не вижу зачем мне каждый обычный put в мапу выносить функцией вида

вот сценарий:

1. придет новый разраб или даже ты, чтобы добавить request.session(«datetime») = date()

2. найдет первый request.session(«user») = user

3. добавит около него request.session(«datetime») = date()

4. точно как ты несколькими постами раньше подумает (цитирую) «Когда их появится 2 будет отдельный метод чтобы избежать code duplication раз и гарантировать одинаковую логику»

5. т.к. метода нет, заключит, что code duplication нет и request.session(«user») = user единственен (хотя это будет скорее в подсознании, а не в виде логической мысли)

6. уйдет, оставив таким образом родившийся баг

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

>хочешь утопить свою ошибку в простынях разговоров?

Я не вижу тут ошибки.

Ответь на вопрос про вебсервер.

Вот эта строка:

httpParams.setIntParameter( CoreConnectionPNames.SO_TIMEOUT, 5000 )

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

Семантически и логически - это эквивалентный код с session(«user») = user.

Должен ли я такую строку сопровидить методом и горой документации зачем я загнал в параметры такой мегаштуки как httpserver именно 5000 и чего я вообще туда сунулся? На обяснения уйдет много деревьев распиленных на бумагу.

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

> Зачем мне нужна функция неверифицированного логина?

читай:

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

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

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

> httpParams.setIntParameter( CoreConnectionPNames.SO_TIMEOUT, 5000 )

Семантически и логически - это эквивалентный код с session(«user») = user.

не верю, так что задам вопросы

1. она *текстуально* тоже у тебя встречается 2 раза, как и session(«user») = user ?

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

> вот сценарий:

жизненно

но

2. найдет первый uncheckedLogin

3. добавит около него request.session(«datetime») = date()

получит то же самое. Менее жизненно - но вероятно.

второе - обозначает ли жизненность этого сценария что все подобные put в мапы нужно выделать в методы?

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

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

Предлагаю согласиться что это просто разница стиля.

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

>1. она *текстуально* тоже у тебя встречается 2 раза, как и session(«user») = user ?

Ну ты чтоле сомневаешься что есть куча место в сетевом коде где можно поставить SO_TIMEOUT?:)

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

>вполне возможно, на боевой системе надо иметь в запасе возможность залогинить кого угодно безо всяких консультаций с базой

ну я ответил - _если_ понадобиться иметь - я это сделаю. Зачем мне это делать когда это не надо иметь.

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

> найдет первый uncheckedLogin, добавит около него request.session(«datetime») = date(), получит то же самое. Менее жизненно - но вероятно

и че ты после этого сделаешь с *таким* программистом?

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

> Ну ты чтоле сомневаешься что есть куча место в сетевом коде где можно поставить SO_TIMEOUT?:)

а места, где можно сказать request.session(«user») = user, все сосредоточены в функции login, и количество их достаточно мало — более того, обычно их ровно 1 штука

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

вот к стати еще такой вопрос: предпочел бы ты вынести код в функцию если бы там было написано:

request.session.login(user)

а если

request.session <== user

а если

request.session.register('user, user).

А то у меня есть подозрение что это bite in the ass того что там просто «=».





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

>и че ты после этого сделаешь с *таким* программистом?

это вопрос отдельный:)

а места, где можно сказать request.session(«user») = user, все сосредоточены в функции login


это должен быть мой аргумент!!!:)

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

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

то ли дислексия, то ли выключенные мозги

я не люблю однострочники «локального применения», даже если они юзаются, как тут, в 2 местах

а концепция есть объективно

Есть вероятность что оно проживет в веках без изменений (в данном случае я это гарантирую).

это нетипично; стандартным является именно показ юзеру «last login was at ...»

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

> А то у меня есть подозрение что это bite in the ass того что там просто «=»

неправильное подозрение

аргументы — именно «ласт логин уаз» и возможность залогинить кого угодно при дисконнекте с базой

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

> найдет первый uncheckedLogin, добавит около него request.session(«datetime») = date(), получит то же самое. Менее жизненно - но вероятно

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

однако, тоже, обрати внимание, что среди явно лишних функций еао197 обнаружил также и эту, безусловно нужную

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

>я не люблю однострочники «локального применения», даже если они юзаются, как тут, в 2 местах

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

а концепция есть объективно


Там куча об́ъективно существующий концепций. Например обективно существующая концепция различных стратегий логина с которой расправляется if - хотя их можно заменить факторями паттернами обектами лукапом и вызовом метда - и заменить на что-то вроде:

AuthFactory.schema(user.authSchema).tryLogin(user)

Можно выдели довольно левый код

Runtime.getRuntime.exec......

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

Да мало ли.

Почему этого не сделано потому что:

a) этот код сейчас микроскопический
b) куда оно повернет влево, вправо или вверх в реальности - я не знаю.
c) для такого микрокода - мне облом напрягаться - хотя первое что получит рефакторингом по рогам - этот тот самый runtime.exec если мне придется что-то там увеличивать даже если не в самом runtime.exec - потому что он там не в тему на таких подробностях. Но он там потому что a).

А вообще я страшнейший перфекционист и фанат библиотекизирования и модульности - у меня в пятерочке основных проектов сейчас, штук 40 вынесенных библиотечныхы проектов со средним количеством модулей 5 штук каждый. То есть реально где-то ~200 абстрактных библитек повторно используемых (некоторые достаточно большие).

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

А я бы так написал:

val authResult = if( login == null || password == null ) Left((UNAUTHORIZED, "You should provide login and password"))
  else AccountsStorage.find(login) match {
    case None => Left((UNAUTHORIZED, "User not found"))
    case Some(user) if user.inactive => Left((UNAUTHORIZED, "Account is inactive"))
    case Some(user) if user.authScheme == "PETRIVKA" =>
      if( user.passwordMatches(password) ) Right(user)
      else Left((UNAUTHORIZED, "Authentication failed"))
    case Some(user) => AccessStorage.access.auth_configs.find(_.key == user.authScheme) match {
      case None => Left((FORBIDDEN, "Unknown authentication scheme: " + user.authScheme))
      case Some(scheme) =>
        log.debug("authenticating with " + scheme.command)
        val exec = Runtime.getRuntime.exec(scheme.command.replace("{login}", login).replace("{password}", password))
        if( exec.waitFor == 0 ) Right(user)
        else Left((UNAUTHORIZED, "Authentication within " + scheme.key + " failed"))
    }
    case _ => Left((UNAUTHORIZED, "Authentication failed"))
  }

authResult match {
  case Right(user) => request.session("user") = user
  case Left((code, message)) => respond(code, message)
}

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

это мне нравится значительно больше однострочника.

к стати надо уже научится изживать стринги - все никак не привыкну:
request.session('user) = user
""'!!!!


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

да, только s/Right/LoginSuccess/ s/Left/LoginFailure/

и не пойму, зачем там двойные скобки?

еще тут не решена задача залогинить кого угодно при дисконнекте с базой аутентификации

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

>да, только s/Right/LoginSuccess/ s/Left/LoginFailure/

Left/Right - это стандартный Either. ничего не нужно делать просто.

и не пойму, зачем там двойные скобки?


таплы

еще тут не решена задача залогинить кого угодно при дисконнекте с базой аутентификации


ну тут не решено много задач которые не нужно пока решать:)

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

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

потому что при твоем подходе это надо

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

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

переделаю по питекантропски

одновременно модифицирую либу сервисов со стрингов на символы в качестве ключей

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

> Left/Right - это стандартный Either

и если None от Some категорически отличается, то Left с Right элементарно перепутать

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

типичная недофункциональщина

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

>и если None от Some категорически отличается, то Left с Right элементарно перепутать

Есть еще статическая типизация

Тип authResult: Either[User,(Int,String)]

перепутай - и компилятор об этом расскажет.

r ★★★★★
()
Ответ на: комментарий от www_linux_org_ru
scala> val x:Either[Int,String] = if (true) Right("a") else if (false) Right(1) else Left(1)
<console>:5: error: type mismatch;
 found   : Int(1)
 required: String
       val x:Either[Int,String] = if (true) Right("a") else if (false) Right(1) else Left(1)
                                                                              ^

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

ОК, временно оставив за скобками все остальное, обсудим ваши претензии.

1. Cyclic dependency тут нет, respond никак не зависит от внутреннего класса. «In software engineering, a circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly.»

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

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

4. То же самое, что и предыдущий пункт (зачем два одинаковых пункта?). Кстати, для повторного использования годится далеко не любой код, а обычно только тот, который изначально создавался как библиотечный (что в данном случае не так).

5. Это опять дубликат - на этот раз пункта 2. Сказано же, что все методы там приватные. Нет никакой правильной последовательности вызовов.

6. И опять то же самое. Приватные во внутреннем классе методы, приватные. Это не концептуальная ошибка. Рассматривайте версию скалы.

7. В принципе, согласен, но опять же - нужны такие проверки или нет, зависит от (см. Макконнелла). В данном случае спорный вопрос.

8. Не согласен. На мой взгляд, сложностей он не породил, а наоборот - структурировал код. То, что кода вышло больше - не является показателем сложности. Напишите на Eiffel, еще больше кода будет. Но понятность - это другое.

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

Итого: 8 пунктов из 9 - мимо, в общем-то, уж извините.

Продолжать можно долго.

Не думаю. :) Разве что еще некоторые пункты скопировать в очередной раз.

Здесь код в 93 строки с 2мя классами и дюжтиной методов. Изщвините меня. Может доведем до абсурда количество методов или классов на которые не распространяются правила грамотного проектирования и можно писать всякое гавно?

Ну, до абсурда доводить не надо, конечно.

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

2 Rastafarra:

шикарный образцовый разнос. thanx.

Разберитесь сперва, что написано, а потом хвалите. :)

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

> Иллюстрации того, что исходный код функционально переусложнен, а так же того, что больше кода - не значит хуже.

моя имха: стало хуже. то, что было написано в 20-30 строк, помещалось на экране и хорошо (мной) воспринималось стало феноменально раздуто (за что собсно жабу и не любят), сомнительного качества (тут я согласен с r) и не читабельно (мной) ваще никак.

Разберитесь сперва, что написано, а потом хвалите.

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

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

> и если None от Some категорически отличается, то Left с Right элементарно перепутать

Класть в Right то, что «правильно», и в Left - то, что «неправильно» - распространённая идиома Хаскелля и Скалы. Тому, кто знает более одного значения слова right, перепутать будет сложно.

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

Кто это написал?

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

> Не правильно.

Не правильно вы понимаете.

Доказывай что неправильно.

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

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

была одна простая законченная функция, стала целая либа, невнятная, плохо написанная и плохо спроектированная.

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

жаба на коне

Я понимаю, что Scala-программистам это нелегко признавать, но таки да. По распространенности и восстребованности Java очень далеко впереди. И такой вот примитивный код на Java писать не сложнее, чем на Scala.

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

а что если твой пример переписать вот так: Группа разработчиков Scala получила грант Евросоюза (комментарий)

Я хочу подчеркнуть важную вещь, которую упустили здесь за кучей обоснованных (много мелких функций) и необоснованных (вроде проблем с переиспользованием кода) придирок. А именно: в исходном варианте было много частных случаев обработки пользователя — отсутствие пользователя в БД; присутствие но с флагом inactive; присутствие, но со схемой аутентификации PETRIVKA; присуствие со штатной схемой (которая еще может быть и не найдена). И, по сути, главная претензия к исходному коду, что все эти частные случаи были обработаны прямо «по месту» без попытки выделения на простые взаимно-подчиненные случаи:

есть пользователь в БД или нет;

установлен ли флаг inactive или нет;

используется ли схема PETRIVKA или нет;

известна ли нам схема аутентификации.

В твоем коде этих вариантов практически нет. Поэтому твой код не соответствует исходному.

А сам по себе он нормален. К нему бы я не придирался.

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

>1. Cyclic dependency тут нет, respond никак не зависит от внутреннего класса.

Если циклической зависимости нет значи один из дух модулей можно убрать что не повлияет на второй. Попробуй.

К тому же в скале все верно, т.е. это не концептуальный баг.


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

Его трудно поддерживать, он создает повышенную связность или что?


Он сознает ненужный инстанс обекта коотрый надо забирать GC, он генерирует вместо одного invokestatic, кучу кода по созданию инстанса объекта, заполнению полей, вызов виртуального метода. Представь что это код вызовется в цикле 10000 раз. Или представь что такого кода много. А потом «жаба тормозит».

Сказано же, что все методы там приватные.


Напомнило мне анекдот - "- Гоги докажи что этот треугольник равнобедренный. - Мамой клянусь!"

Компилятор в жабе иного мнения о недоступности этих методов.

Пункт 5 точно так же распространяется на вызовы изнутри самого класса. Даже если методы приватные. Они все равно _не должны_ позволять вызывать их неправильно. Код внутри класса - тоже код который нужно развивать кому-то. А не «написал однажды не трогай а то что нибудь поломается». В широко упоминавшемся тут «2ГБ» кода проекте - тоже надо все «помнить» в какой последовательности что можно вызывать чтобы не навернулось ничего?

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

Но понятность - это другое.


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

Тут он увидел гварды в матче и решил что это «нипанятно». Надо заменить классом ИмяКоторогоХренЗапомнишьХадлер с пятью методами handleХренЗапомнишь с понятными ifами внутри.

Когда «напанятную» базовую языковую конструкцию заменяют на «панятный» if - то про такого понимающего сразу все понятно.

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


Какие еще логические слои? Где ты там слои увидел? Клас называется «Обрабатывальщик», все методы называются «обработай». Он все методы так назвал - _все_ - ты только вдумайся в это. Мне страшно подумать что у него за названия в больших проектах.

Слои - подразумевают абстракцию. Что он от чего там абстрагировал? Как была мусорка смешанная с различными стратегиями автентикации - так он и перенес ее в другой класс всю. Как был неабстрагированный низкоуровневый exec - так он там и остался. У меня хотя бы причина так оставить есть - код маленький, незачем огород городить. У него причин таких нет - он с одной стороны начал его городить с другой стороны ничего не достиг с точки зрения абстракции - все осталось такой же свалкой - только кода стало в 3 раза больше.

Банда Четырех, Фаулер и Ларман готовы в могилу лечь и начать переворачиваться глядя на этот «рефакторинг».

То, что методы вышли небольшие - деталь реализации.


Я двадцатый раз повторю - любая программа - деталь реализации метода «main». Что это вы за фигню придумали - оправдывать говнокод тем что это детали реализации! Новое определение инкапсуляции появилось - «инкапсуляция - это код любой говняности с модификаторами private».

Однако, на мой взгляд, в качестве иллюстрации он вполне подходит


Ага - в качестве иллюстрации - как делать не нужно _никогда_.

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

К стати видел такую фишку?:)

scala> type |[A,B] = Either[A,B]
defined type alias $bar

scala> def f(x:Int):String|Int = if (x > 0) Left(x.toString) else Right(x) 
f: (x: Int)|[String,Int]
r ★★★★★
()
Ответ на: комментарий от r

Он сознает ненужный инстанс обекта коотрый надо забирать GC, он генерирует вместо одного invokestatic, кучу кода по созданию инстанса объекта, заполнению полей, вызов виртуального метода.

Надо полагать, что создание объектов Option[T], а так же лямбды для поиска схемы аутентификации в списке происходит абсолютно бесплатно. И GC они не нагружают.

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

И вообще, это как раз та задача, в которой быстродействие просто таки на первом месте.

Когда «напанятную» базовую языковую конструкцию заменяют на «панятный» if

Не выдавайте свое понимание моих претензий к вашему коду за истину. Вы привели пример, в котором, якобы, паттерн-матчинг обеспечивает большую защиту. Однако, в самом коде видно, что компилятор при обработке match в котором есть варианты с гуардами, не может проверить полноту матча. Поэтому вам пришлось делать case _. Ну и где же тогда обещанная защита? Как читатель вашего кода поймет, что вы перечислили в match-е действительно все нужные вам варианты? Тогда как if с бинарным делением возможных действий дает на это однозначный ответ.

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

В итоге часы дебаггинга, отвращение к своей работе потому что чудила который то написал решил что методы будут вызываться в неком particular order и толко из одного места, про которое только он знает, а на все остальное ему плевать.

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

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