демагогия о типах
Nov. 27th, 2011 10:34 pmНе о каких-нибудь там особо хитрых; в принципе, чуть ли не двоичных значений хватает, чтобы продемонстрировать.
Начнём, конечно, с Джавы. В которой сплошь и рядом, у "плохих программистов" встречается такое:
и хорошим программистам это не нравится, и они говорят "делегейшен давай", или "смартенумы давай!"
Делегейшен, это когда каждый параметр слишком широкого диапазона типов должен вдруг знать, что вот этот вот практически незнакомый тип однажды возьмёт да и обратится к ним, и надо для этого иметь особую форму (сиречь, сигнатуру), чтоб не подвести свой класс, а сделать, что положено (а там хоть не рассветай).
Ну или енум использовать - но енум контента не имеет, это константа... тогда люди ещё как поступают: в класс вставляют этот самый енум, "тип инстанса нашего класса".
и это кошернее, чем было бы писать
В Скале же, на самом деле, не особо стесняются расписывать по классам, но на то есть другая причина:
Фактически эта конструкция в некотором смысле помещает исполяемый, специфический для класса параметра, код немножко в контекст этого класса (видны только параметры конструктора).
В Скале есть немножко тенденция некоторые классы объявить более равными, например
Так же и на Хаскеле - или мы матчим список, или
И вот это вот "перечисление случаев" меня как-то смущает; нельзя ли для этого дела пристроить что-то вроде
Это практически cps, continuation passing style. Как в Джаваскрипте, если вы ещё помните, что такое
Это было бы почти идеальное решение, да?
Не знаю, не знаю.
Начнём, конечно, с Джавы. В которой сплошь и рядом, у "плохих программистов" встречается такое:
if (message inscanceof CancellationMessage) { application.cancelnahren(); } else if (message instanceof EncouragementMessage) { galera.trabalha(); } // etc
и хорошим программистам это не нравится, и они говорят "делегейшен давай", или "смартенумы давай!"
Делегейшен, это когда каждый параметр слишком широкого диапазона типов должен вдруг знать, что вот этот вот практически незнакомый тип однажды возьмёт да и обратится к ним, и надо для этого иметь особую форму (сиречь, сигнатуру), чтоб не подвести свой класс, а сделать, что положено (а там хоть не рассветай).
Ну или енум использовать - но енум контента не имеет, это константа... тогда люди ещё как поступают: в класс вставляют этот самый енум, "тип инстанса нашего класса".
class Message { enum type { CANCEL, ENCOURAGE, DGAF} myType; .... } ... switch(message.type()) { case CANCEL: ... case ENCOURAGE: ... case DGAF: ... }
и это кошернее, чем было бы писать
classmc = message.getClass(); if (mc.equals(CancelMessage.class)) { ... } else if (....
В Скале же, на самом деле, не особо стесняются расписывать по классам, но на то есть другая причина:
unapply
, а ещё лучше сказать, линза (обратная сторона); с помощью её можно устраивать сравнение по образцу и, в зависимости от типа, выполнять какие-то действия с параметрами конструктора.message match { case CancelMessage(timeout: TimeInSeconds) => app.cancelato(timeout) case EncourageMessage(text: String) => galera.listen(text); galera.trabalha ... }
Фактически эта конструкция в некотором смысле помещает исполяемый, специфический для класса параметра, код немножко в контекст этого класса (видны только параметры конструктора).
В Скале есть немножко тенденция некоторые классы объявить более равными, например
Option[T]
, Either[Left,Right]
- для них как бы некошерно употреблять кейсы, а надо использовать функциональную функцию map
. В принципе, скальные библиотеки любят возвращать Option[T]
, и тут-то бы и применять map
, да штука в том, что в случае None
ничего ни к чему применяться не будет. Так что приходится расписывать кейс. И со списками, что характерно, кейс приходится писать: как правило, разбивая ситуацию на два случая - пустой список или голова с хвостом, неважно, пустым или нет.Так же и на Хаскеле - или мы матчим список, или
Maybe
, или data type.И вот это вот "перечисление случаев" меня как-то смущает; нельзя ли для этого дела пристроить что-то вроде
map
? Но блин, это ж надо передавать, вообще говоря, по специальному исполнителю на каждый отдельный жизненный случай. Как в Джаве любят писать - лисинеры, listeners
- они будут теперь здоровкаться на каждый чих.Это практически cps, continuation passing style. Как в Джаваскрипте, если вы ещё помните, что такое
xhr
, а не вызываете что-нибудь там вроде JQuery.doAjaxForMeHurry()
, то у вас как правило два-три таких слушателя: - пока читает, - когда закончили, - если ошибка. А могли бы написать (если б могли)reset { switch { case STILL_READING: ...; break case GOT_RESULT: ...; return case ERROR: ...; return } shift(k) { do { var resp = XHR.doPost(myStuff) k(resp) } } }
Это было бы почти идеальное решение, да?
Не знаю, не знаю.