LINUX.ORG.RU

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

 , , ,


1

4

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

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

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

★★★★★

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

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

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

ах, так сравнивали работающий код со сферическим. отличное сравнение. сферический код слил. сферокод у вас имхо так себе...

По распространенности и восстребованности Java очень далеко впереди.

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

И такой вот примитивный код на Java писать не сложнее, чем на Scala.

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

вот только мы тут не об этом.

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

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

Абсолютно GC не нагружает ассемблер.

У тебя вместо лямбд - вообще троеточие в жабе.

Оправдать зачем там нужен именно экземпляр - ты не можешь.

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


Это к твоему сведению сервис в ембеддед сервере. Среднее время ответа этого сервера ~1мс. Для этого пришлось оптимизиорвать парсящую JSON либу - в основном пришлось выкинуть как раз создание кучи объектов, потому что при парсе банальной JSONовой разметки календаря на один год (~35Kb JSON) порождались десятки тысяч объектов. Если надо поднять календарь за 10 лет - то количество временных обектов уже достигает количества стрингов и hashentry в jvm.

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

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

Поэтому вам пришлось делать case _.


case _ остался от предидущей версии когда не было никаких схем автентикации и неактивных юзеров и выглядело оно как

match {
case Some =>
case _ =>
}

я просто забыл его убрать.

Ну и где же тогда обещанная защита?


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

Тогда как if с бинарным делением возможных действий дает на это однозначный ответ.


Как я и говорил - все понятно. Понятный if непонятный pattern matching.

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

>Что будет дальше?

Он возьмет и напишет этот метод. Если он не сможет его написать методом вызова старого метода

def mylogin = {
///specifics
login(x,y,z)
}

он отрефакторит его так чтобы было два метода без code duplcation.

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

Нет, не видел. Это, я так понял, сахар для типа с двумя параметрами.

def f(x: Int): String Either Int
Горы сахара в Скале иногда меня пугают. :)

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

Горы сахара в Скале иногда меня пугают. :)

Меня тоже:) Я когда начинал с ней разбираться ловил себя иногда на ощущениях «C++сности» :)

Даже гдето тред есть в рассылке по этому поводу - там кастовую систему скальных программистов изобретали - всякие там компилер девелоперы, лайбрари дизайнеры и т.д. и какой уровень знания скалы дял какой касты требуется:)

Это, я так понял, сахар для типа с двумя параметрами.

scala> def f(x: Int): String Either Int Either Int= Right(1) 
f: (x: Int)Either[Either[String,Int],Int]

:)

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

Это, я так понял, сахар для типа с двумя параметрами.

К стати я вот сейчас подумал - это наверное само собой получилось для

Int => Int

Значит «=>» это просто

type =>[A,B] = Function1[A,B]

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

Гы

scala> class X[A,B](a:A,b:B)
defined class X

scala> type @=>[A,B] = X[A,B]
defined type alias $at$eq$greater

scala> def f(x: Int @=> Int) = x
f: (x: @=>[Int,Int])@=>[Int,Int]

scala> implicit def a2x[A](a:A) = new { def @=>[B](b:B) = new X(a,b) }
a2x: [A](a: A)java.lang.Object{def @=>[B](b: B): X[A,B]}

scala> f(1 @=> 1)                                                     
res1: @=>[Int,Int] = X@532996d6

Я в восторге:)

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

Оправдать зачем там нужен именно экземпляр - ты не можешь.

У меня это русским языком написано — «Например, из моего кода видно, что изрядный объем занимают декларации методов handle* – за счет перечня параметров request, login, password и user. Поэтому я бы для обработки логина выделил бы специальный класс, в котором данные параметры были бы атрибутами.»

я просто забыл его убрать.

Отлично. В пример приводится код с мертвыми кусками.

там даже правильность входных данных не проверяется.

Извольте доказать, что в моей реализации login (включая весь взывающийся из него код) проверок валидности аргументов (то бишь login и password) меньше, чем у вас.

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

ах, так сравнивали работающий код со сферическим.

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

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

Не сложнее. Судя по вашим с r фрагментам, производить говнокод на Scala вам так же труда не составляет.

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

> У меня это русским языком написано

Жесть - ты нагенерил много текста потом увиде что его много - сделал его меньше таким способом??!! Чем дальше - тем интереснее!

А программирование там когда начнется?

проверок валидности аргументов (то бишь login и password)


Аргументы - это не логин и пассворд - это входные данные для каждого из существующих там методов. А методов там - завались.

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

Он возьмет и напишет этот метод. Если он не сможет его написать методом вызова старого метода

Ахринеть! С моим кодом такого сделать ну никак невозможно. Нужно, конечно же сразу дергать класс Handler!

он отрефакторит его так чтобы было два метода без code duplcation.

Как?

Точнее даже интересно другое: считаете ли вы свой код пригодным для повторного использования?

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

Аргументы - это не логин и пассворд - это входные данные для каждого из существующих там методов. А методов там - завались.

Если вы уж собираетесь идти на тотальный defensive programming, то позвольте спросить, откуда вы знаете, что:

AccessStorage.access != null?

user.authScheme != null?

scheme.command != null и можно безопасно вызывать replace?

Вдруг какой-нибудь другой программист взял и занулил что-то из этого в соседнем методе?

Все мои методы предназначены для очень ограниченного контекста, в рамках которого достаточно валидации login и password.

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

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

Убираю весь метод аутентификации вместе с внутренним классом - outer scope, в котором объявлен respond, ничего не замечает. Где зависимость-то? И в чем отличие от вашей функции? Или я чего-то не понимаю.

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

Давайте про это уж не будем. Оптимизация - это другой вопрос. Если код критичен по времени, то, возможно, его следует писать совсем иначе или вообще на другом ЯП. С точки зрения дизайна я ничего плохого в лишнем инстансе не вижу.

Пункт 5 точно так же распространяется на вызовы изнутри самого класса. Даже если методы приватные. Они все равно _не должны_ позволять вызывать их неправильно.

В общем случае это верно. Но иногда этим _можно_ пренебречь.

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

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

(Это я безотносительно паттерн-матчинга.)

Доводя до абсурда, можно создать язык, который будет понятен только Эйнштейну или Каспарову. Массовым он никогда не станет.

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

Какие еще логические слои? Где ты там слои увидел?

Ну как же. Авторизован/не авторизован, известен/неизвестен, активен/неактивен и т.п. Четкая последовательная цепочка с выбором на некоторых развилках. Или вам не нравится сам термин «слои»? Ну пусть будут не слои, а «точки принятия решений». :)

И что вы так бурно реагируете-то? С «говнокодом» Евгений наверное погорячился, но код ваш далеко не идеален все равно...

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

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

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

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

Хосспади, специально ведь сказал - «Это я безотносительно паттерн-матчинга». :)

Это о языковых конструкциях вообще, о том, что не все однозначно.

Не понимаю, с чем спорите (c)

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

>Нужно, конечно же сразу дергать класс Handler!

В моем случае он может звать любые методы как угодно - просто их там всего один. А в твоем он значит не может звать что угодно а только тот один? Разницу ощущаешь?

Как?


Искусство программирования.

считаете ли вы свой код пригодным для повторного использования?


Да. Или есть какие-то проблемы с вызовом функции логин? Типа такие как у тебя - те не звать там нельзя? Нету - зови не хочу. Параметры и инварианты четко специфицированы.

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

>Если вы уж собираетесь идти на тотальный defensive programming, то позвольте спросить, откуда вы знаете, что:

Thru the magic of «val» keyword!

Вдруг какой-нибудь другой программист взял и занулил что-то из этого в соседнем методе?


То он прочитает вот такой матюк от компилятора: error: reassignment to val

Все мои методы предназначены для очень ограниченного контекста, в рамках которого достаточно валидации login и password.


А - то есть в ограниченном контексте можно написать говнокод. Ну так какие проблемы - весь проект огранничено используется в контексте main.

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

Thru the magic of «val» keyword!

val в Scala не защищает от неиницализированных данных. Это вполне валидный код:

val s: String = null;

А - то есть в ограниченном контексте можно написать говнокод.

Ну вы же пишете, почему остальным нельзя?

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

> Где зависимость-то?

Два модуля там - это outer class - это модуль один и ...Handler - это модуль два. Ни один из них нельзя убрать без получения unknown identifier во втором.

Если код критичен по времени, то, возможно, его следует писать совсем иначе или вообще на другом ЯП.


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

Я с вас прямо поражаюсь.

Но иногда этим _можно_ пренебречь.


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

которая среднестатистическому программисту не очевидна.


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

А если он после университетов нихрена кроме «энтерпрайз-распространенной жабы» - не знает, и умеет писать только по туториалам на вебфреймворки - он не программист. Таких как он учат на курсах с лозунгами «поможем изучить C# и рубить бабло», а не в специальном учебном заведении - на него не стоило университету тратить время. И не надо оправдывать что так надо жить программистам, что это нормально. И уж тем более не надо думать что скала - это такой язык который должен вытеснить VB.

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

Четкая последовательная цепочка с выбором на некоторых развилках.


Это слои _абстракции_? Марш в школу читать аристотеля!

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

> Это вполне валидный код:

val s: String = null;


Ты заявил что паралельно это кто-то сделает. Ну сделай это параллельно.

А по засадам для того кто придет после тебя - да ты спец тут доказывать не надо.

Ну вы же пишете, почему остальным нельзя?


Ой ой ой? I'm hurt!

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

>И кстати, глядя на код login откуда следует, что user.authScheme, например, это val, а не var?

А зачем этому откуда-то следовать? Глядя на этот код вообще неизвесттно может это вообще метод - что ж по этому поводу - болеть душой?

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

А зачем этому откуда-то следовать? Глядя на этот код вообще неизвесттно может это вообще метод - что ж по этому поводу - болеть душой?

Я задал вам данный вопрос для иллюстрации простой мысли: когда вы пишете конкретный кусок кода вы делаете какие-то собственные допущения исходя из знания контекста, в котором будет работать данный кусок. В случае с AccountStorage и user.authScheme вы в чем-то уверены и исходя из этого не делаете проверок.

В своем вспомогательном классе я так же уверен в контексте, для которого класс предназначен. Поэтому я так же не делаю проверок, которые в данном контексте не нужны.

Однако, очевидно, что когда речь идет о вашем коде, то вы не делаете допущений, которые позволяете для моего кода. Вроде «а если кто-то где-то как-то».

Налицо повторение истории с сайд-эффектами, когда вы напрочь отказывались признавать их наличие.

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

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

Ты заявил что паралельно это кто-то сделает. Ну сделай это параллельно.

Да запросто — дайте мне доступ к коду и я переделаю инициализацию ваших объектов так, что мама родная не узнает.

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

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

>Два модуля там - это outer class - это модуль один и ...Handler - это модуль два.

Outer class - это класс, в котором объявлен respond и сам метод login? Т.е. этот класс сам же еще дергает login что ли в каком-то другом методе? Но это мутная придирка, ИМХО. Во-первых, внутренний класс существует исключительно в момент работы метода login - и является ненавистной вам «деталью реализации». Во-вторых, не думаю, что в данном случае вообще уместно говорить о циклической зависимости, если одним из модулей является внутренний класс другого.

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

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

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

Боюсь посеять в вас разочарование в людях, но среднестатистический программист сильно далек от вашего идеала. :)

И уж тем более не надо думать что скала - это такой язык который должен вытеснить VB.

Я как раз по этому поводу не питаю никаких иллюзий.

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

Главное не нагородить неподдерживаемой мути в процессе развития. :) А то вон у вас там уже сейчас жирный свитч стоит (а если число вариантов еще увеличится на парочку?), да констант нахардкожено.

Это слои _абстракции_? Марш в школу читать аристотеля!

Где вы в моем сообщении углядели слово «абстракция»? Марш выше по топику перечитывать исходное предложение.

Кстати, а что в школе сейчас из Аристотеля-то дают? :)

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

> И, по сути, главная претензия к исходному коду, что все эти частные случаи были обработаны прямо «по месту» без попытки выделения на простые взаимно-подчиненные случаи

если уж делать такие попытки, то ТОЧНО не разнося этот код по разным функциям

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

кстати, я еще напишу, почему комменты в виде названий функций — плохи

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

и если ты вынесешь этот код в функцию, тебе придется дублировать эти описания инвариантов — как в месте применения, так и в месте определения функции

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

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

это я попробовал сделать набросок кода в твоем стиле, и понял, что скала для этого плохо приспособлена

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

> Класть в Right то, что «правильно», и в Left - то, что «неправильно» - распространённая идиома Хаскелля и Скалы.

вот только для начала надо выяснить, что «правильно» и что «неправильно»

почему вдруг залогинить юзера правильно? для параноидального админа правильно — это конечно же не логинить

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

одна строчка (на псевдоскале) решила бы проблему:

type LoginResult(LoginSuccess, LoginFailure) = Either

а есть варианты и получше

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

> Ну пусть будут не слои, а «точки принятия решений». :)

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

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

>:5: error: type mismatch;

это было предсказуемо; а вот если у тебя оба Left[String] и Right[String] будут [String], то словить проблему будет весьма легко

строки же — вполне частый класс

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

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

Вы совершенно не правы. «Городить функции» можно по разным причинам, в том числе и по этой. Уж простите, опять на Макконнелла сошлюсь, раздел 7.1 «Разумные причины создания методов», далее со всеми остановками.

Да и вообще первый раз слышу про вашу теорию. :)

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

> Уж простите, опять на Макконнелла сошлюсь, раздел 7.1 «Разумные причины создания методов», далее со всеми остановками.

давай цитату, посмотрим, на что больше похожи эти причины — на слои абстракции или на «точки принятия решений»

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

Мне весь раздел процитировать, что ли? :) Там много всего. Например:

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

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

Купите книгу и почитайте, один из фундаментальных трудов в промышленном программировании. :)

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

> Мне весь раздел процитировать, что ли?

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

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

признаков, а не причин

признак может быть ложным

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

ОК, вот список причин по Макконнеллу:

Снижение сложности; формирование понятной промежуточной абстракции;

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

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

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

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

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

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

я на 95% согласен, что макконеловские причины есть хорошие причины создания функций (там по мелочам могут быть замечания)

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

насчет глубины вложенности структур управления есть случаи, когда в с++ выделение их части в отдельную функцию *не поможет* ничему из списка (или внесет превосходящий это отрицательный эффект); особенно это часто в численных методах — так что это признак хороший, но отнюдь не 100%

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

>но при этом путать слои абстракций и «Точки принятия решений»

И кто путает? Утверждается, что вынос части кода в отдельный метод вполне может быть оправдан, даже если это просто иф.

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

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

слой абстракции должен *изолировать* — т.е. например изолировать нас от такой возможности, что сетевой пакет может теряться — в результате мы можем писать функции так, будто сетевые пакеты не теряются (либо соединение рвется)

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

Я смотрю на них объективно со стороны, я, как код ревьювер беру отдельный, класс ....Handler и пишу его обективные характеристики:

1. он использует метод respond обявленный в outer scope, в то время как outer scope использует его - это cyclic dependency - антипаттерн.

Интересно, вот этот код из официальной документации по Java, вы точно также раскритикуете:

//An example of using an inner class.
public class MyClass extends Applet {
    ...
	someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
	    ...//Event listener implementation goes here...
        }
    }
}

Взято здесь General Information about Writing Event Listeners

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

Да я про абстракцию вообще ни слова не сказал. Посмотрите мою исходную цитату. Я не говорил и не имел в виду никаких абстракций. Возможно, выразился неудачно (сказал «логический слой»), не спорю.

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

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

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

r написал о том, еао197 не добавил новых логических слоев; я с r полностью согласен

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

* за одним исключениме — еао197 все же добавил логический слой в виде uncheckedLogin, который, правда, так обозвал я, а у него оно называлось setupSuccessfulAuthResult

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

>ты пытаешься в истинном высказывании заменить «логические слои» на «точки принятия решений», и в результате получить ложное утвреждение

Странное предложение. :) Смысл его от меня ускользнул.

Я ничего не пытаюсь. Нет такого аксиоматичного термина, как «логический слой». И нечего его сопоставлять с абстракцией. Этим словосочетанием я пытался выразить другое.

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

r написал о том, еао197 не добавил новых логических слоев

Не добавил - они там есть и так. Он их явно выделил.

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

вот только для начала надо выяснить, что «правильно» и что «неправильно»

почему вдруг залогинить юзера правильно? для параноидального админа правильно — это конечно же не логинить

Да Вы, батенька, зануда. :)

Я специально в кавычки взял, потому что знал, что ты прицепишься.

Хорошо, пускай будет success и falure.

Вот цитата из скаладоков:

The Either type is often used as an alternative to scala.Option where Left represents failure (by convention) and Right is akin to Some.

Вот из доки к Хаскеллу:

The Either type is sometimes used to represent a value which is either correct or an error; by convention, the Left constructor is used to hold an error value and the Right constructor is used to hold a correct value (mnemonic: «right» also means «correct»).

Короче говоря, соглашение общепринято и, по-моему, легко запоминается.

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

> Напиши мой код с комментариями.

и именно что *немного* отрефакторил

по-человечески все данные, полученные от пользователя, должны иметь тип Unverified[Something]; этот тип должен конвертироваться в Option[Something] и вот там-то юзаться паттерн матчинг

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

Значит «=>» это просто

type =>[A,B] = Function1[A,B]

Ну да, как и в Хаскелле:

Prelude> :info (->)
data (->) a b   -- Defined in GHC.Prim

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

я вот что по твоему коду не пойму

какого хрена в user.authScheme может оказаться неизвестная конфигу схема?

судя по коду, authScheme это все-таки строка? так может она еще и берется из юзерского инпута???

ну допустим не из юзерского, допустим это строка берется откуда-то из базы

тогда ее тоже надо верифицировать тогда, когда мы ее берем из базы и запихиваем в user.authScheme, а не тогда, когда ее пытаемся применять

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

т.е. user.authScheme должна быть особым типом данных а не строкой, возможно с неявной конвертацией в строку

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

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

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

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

>это было предсказуемо; а вот если у тебя оба Left[String] и Right[String] будут [String], то словить проблему будет весьма легко

Ну вообще-то Either придуман чтобы работать именно со значениями разных типов - например если функция возвращает String или List[String]. Применение его для одинаковых типов несколько нетипично:)

Определить свой класс вполне разумно. Просто если испльзуешь его часто - то переходишь на абстрактный Left|Right чтобы не писать по сути то же самое с другими именами.

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