Re[28]: Haskell нужен! (в Standard Chartered Bank)
От: Mamut Швеция http://dmitriid.com
Дата: 04.02.15 15:40
Оценка:
G>>
G>>public Order[*] read_order_from_db(OrderId id); // читаем уже правильный ордер, либо Order[New] либо Order[Processed]
G>>


G>А, пардон, я неправильно понял, что ты имеешь ввиду. Да, в таком случае придется извернуться и после чтения из базы прогнать ордер по состояниям снова.

G>Но все тоже возможно.

Зачем извращаться, и что это даст?


dmitriid.comGitHubLinkedIn
Re[28]: Haskell нужен! (в Standard Chartered Bank)
От: genre Россия  
Дата: 04.02.15 15:43
Оценка:
Здравствуйте, Mamut, Вы писали:

M>И? Дальше что?



M>
M>public Order[*] read_order_from_db(OrderId id);

M>// каким образом тут компилятор проверит, что за Order сюда идет?
M>// заказ же из базы читается
M>change_order_amount(Order, Amount)
M>


см. выше. придется догнать до нужного состояния снова. тут часть проверок действительно ляжет на рантайм.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[29]: Haskell нужен! (в Standard Chartered Bank)
От: genre Россия  
Дата: 04.02.15 15:49
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Зачем извращаться, и что это даст?


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

Какой процент ошибок так удастся поймать и стоит ли овчинка выделки видимо зависит от проекта.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[29]: Haskell нужен! (в Standard Chartered Bank)
От: Mamut Швеция http://dmitriid.com
Дата: 04.02.15 15:50
Оценка:
G>см. выше.

Да, уже заметил

G>придется догнать до нужного состояния снова. тут часть проверок действительно ляжет на рантайм.


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


dmitriid.comGitHubLinkedIn
Re[30]: Haskell нужен! (в Standard Chartered Bank)
От: Mamut Швеция http://dmitriid.com
Дата: 04.02.15 16:00
Оценка:
G>ну вот мы и вернулись к тому с чего начали

:D

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


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

G>Какой процент ошибок так удастся поймать и стоит ли овчинка выделки видимо зависит от проекта.


Как я уже говорил, есть далеко не одно исследование, которое говорит, что таких ошибок достаточно мало

Сейчас, естетсвенно, лень эти исследования искать (а гугл вообще двинулся мозгами и сейчас в нем невозможно что-либо найти)


dmitriid.comGitHubLinkedIn
Re[31]: Haskell нужен! (в Standard Chartered Bank)
От: genre Россия  
Дата: 04.02.15 16:07
Оценка: 17 (1) +1
Здравствуйте, Mamut, Вы писали:

M>Как я уже говорил, есть далеко не одно исследование, которое говорит, что таких ошибок достаточно мало


А я с этим и не спорил. Я тоже считаю, что количество пойманых таким образом ошибок компенсируется нечитабельностью кода.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[24]: Haskell нужен! (в Standard Chartered Bank)
От: AlexRK  
Дата: 04.02.15 16:51
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Это не ошибка в логике. Мы передаем черный ящик в API, который знает, как с этим ящиком работать. Где ошибка логики — неизвестно


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

ARK>>Согласно спецификации, change_order_amount обязан оперировать не с любыми Order, а только с их подмножеством, у которых Sent=true. Мы записываем в сигнатуру change_order_amount тип "UnsentOrder" (вместо любого Order) — и получаем в каких-то местах ошибку компиляции (вот в этих двух строчках в частности).

ARK>>И это правильно, потому что этот код некорректен. Чтобы он стал корректным, добавляем:
ARK>>
ARK>>  Order = read_order_from_db(OrderId);
ARK>>  if (Order.Sent = true)
ARK>>    change_order_amount(Order, Amount);
ARK>>

ARK>>и внезапно код теперь компилируется.

M>Во-первых, стоп. Выше ничего не изменилось. Тип Order как был, так и остался Order. Или оборачивание его в if(Order.Sent = true) автоматом превратило его в SentOrder?


Да, Order стал SentOrder после проверки. SentOrder — это такой "виртуальный" тип, который задается наложением ограничения на другой тип.
Пример такого подхода можно увидеть здесь: http://ceylon-lang.org/documentation/1.0/tour/types/
Проверка переменной в if или match "сужает" ее тип.

M>Во-вторых, ровно ноль разницы с API, которое имеет под капотом if Order.Sent/if Order.NotSent Более того, даже объемы тестов будут одинаковые. Причем при росте количества условий сам тип будет становиться мешаниной, а вызовы чего бы то ни было с этим типом будут ничем не отличаться от вызвовов без типов


Не-не, в API будет этот if в нескольких местах (а ведь он может быть и не таким простым). Мы можем заменить ифы просто нужным типом.
Соответственно, мы один раз сделали все необходимые проверки, а дальше у нас просто переменная нужного типа путешествует по системе, а компилятор следит, чтобы мы ее не засунули туда, куда не нужно.
Понятно, что в каких-то сценариях количество проверок будет одинаковое. А в каких-то одна проверка на входе и дальше 10 вызовов без проверок.

Насчет мешанины в типе — да, наверно это может быть. ИМХО, это значит, что мы где-то что-то сделали не так (засунули в тип слишком много ответственностей).

ARK>>У нас тут речь как раз о том, чтобы закладывать в программу больше семантики на уровне типов, тогда и дополнительных проверок будет больше.


M>Пока что я не убежден, от слова совсем. Разницы с API пока что ноль. Плюс проверки размазываются по всему коду: в одном месте что-то форсируется на уровне типов, в другом месте надо написать сто if'ов, чтобы впихнуть полученный объект в вызов.


Ну, тут плюс в том, что компилятор не даст сделать вызов, если нужных проверок не будет (т.е. ограничения на уровне типов влияют на обычный код) — это и есть та самая дополнительная корректность.
Другой вопрос, что все на типах запрограммировать все равно не удастся (на современном уровне технологий), поэтому будут и обычные проверки в коде тоже.
Re[25]: Haskell нужен! (в Standard Chartered Bank)
От: Mamut Швеция http://dmitriid.com
Дата: 04.02.15 17:16
Оценка:
ARK>Да, Order стал SentOrder после проверки. SentOrder — это такой "виртуальный" тип, который задается наложением ограничения на другой тип.
ARK>Пример такого подхода можно увидеть здесь: http://ceylon-lang.org/documentation/1.0/tour/types/
ARK>Проверка переменной в if или match "сужает" ее тип.

По ссылке не вижу ничего подобного. Более того, я вижу там банальное if typeof(Object) == что-то там Только присыпанное синтаксическим сахаром

M>>Во-вторых, ровно ноль разницы с API, которое имеет под капотом if Order.Sent/if Order.NotSent Более того, даже объемы тестов будут одинаковые. Причем при росте количества условий сам тип будет становиться мешаниной, а вызовы чего бы то ни было с этим типом будут ничем не отличаться от вызвовов без типов


ARK>Не-не, в API будет этот if в нескольких местах (а ведь он может быть и не таким простым).


Именно. if в нескольких местах, да еще не такой простой. Нафига козе баян?

ARK>Мы можем заменить ифы просто нужным типом.


Чтоа?

ARK>Соответственно, мы один раз сделали все необходимые проверки, а дальше у нас просто переменная нужного типа путешествует по системе, а компилятор следит, чтобы мы ее не засунули туда, куда не нужно.


Да-да. Следит, «нужного типа». Только вот незадача-то. Объект у нас одного типа — заказ.

И дальше над ним может идти очень длинная последовательность действий. Где в одном действии ему надо быть уже отосланным, в другом — неотосланным, в пятом — отосланным, но неоплаченным, в десятом — просто не иметь статуса "fraud". Как предлагаешь поступать? Писать стопятьсот типов на каждый чих и комбинацию, а потом стопятьсот if'ов, инициализаторов и кастований из одного в другое?

ARK>Понятно, что в каких-то сценариях количество проверок будет одинаковое. А в каких-то одна проверка на входе и дальше 10 вызовов без проверок.


Это, вообще-то, КО программирования. Валидность объекта проверяет первая функция, а дальше ненужных проверок делать не нужно.

ARK>Насчет мешанины в типе — да, наверно это может быть. ИМХО, это значит, что мы где-то что-то сделали не так (засунули в тип слишком много ответственностей).


Да нет никаких много ответсвенностей Просто заказ. Только заказ — это простая сущность только в синтетических примерах. На практике — это достаточно сложная сущность, от которой разным компонентам системы нужно очень много разных вещей.


ARK>>>У нас тут речь как раз о том, чтобы закладывать в программу больше семантики на уровне типов, тогда и дополнительных проверок будет больше.


M>>Пока что я не убежден, от слова совсем. Разницы с API пока что ноль. Плюс проверки размазываются по всему коду: в одном месте что-то форсируется на уровне типов, в другом месте надо написать сто if'ов, чтобы впихнуть полученный объект в вызов.


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


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

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


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


dmitriid.comGitHubLinkedIn
Re[26]: Haskell нужен! (в Standard Chartered Bank)
От: AlexRK  
Дата: 04.02.15 17:56
Оценка:
Здравствуйте, Mamut, Вы писали:

ARK>>Да, Order стал SentOrder после проверки. SentOrder — это такой "виртуальный" тип, который задается наложением ограничения на другой тип.

ARK>>Пример такого подхода можно увидеть здесь: http://ceylon-lang.org/documentation/1.0/tour/types/
ARK>>Проверка переменной в if или match "сужает" ее тип.

M>По ссылке не вижу ничего подобного. Более того, я вижу там банальное if typeof(Object) == что-то там Только присыпанное синтаксическим сахаром


Ну вот первый пример оттуда:
void printIfPrintable(Object obj) {
    if (is Printable obj) {
        obj.printObject();
    }
}


Тут "obj" внутри if стал уже другого типа (Printable, а извне if он просто Object) — причем без всяких кастов.

ARK>>Мы можем заменить ифы просто нужным типом.

M>Чтоа?

Я имею в виду что-то типа:
void Func1(MyObj obj)
{
  if (obj.Prop == 3 && ....  // тут много проверок
    Use(obj);
}

void Func2(MyObj obj)
{
  if (obj.Prop == 3 && obj.Prop2 == 4 && ....  // тут те же проверки, и еще пара других
    Use(obj);
}

MyObj obj = GetMyObj();
Func1(obj);
Func2(obj);


// предлагаемый вариант (псевдокод)

type MyCoolObj = MyObj where obj.Prop == 3 && ...   // тут все проверки

void Func1(MyCoolObj obj)
{
  Use(obj);  // проверок нет
}

void Func2(MyCoolObj obj)
{
  if (obj.Prop2 == 4 && ....  // тут только пара "лишних" проверок
    Use(obj);
}

MyObj obj = GetMyObj();
if (obj is MyCoolObj)    // все проверки в типе, тут ничего нет
{
  Func1(obj);
  Func2(obj);
}


Отличие второго варианта (проверки в типе + условие "if (obj is MyCoolObj)") от банальной проверки всего, чего нужно, сразу после "MyObj obj = GetMyObj();" — в том, что мы кодируем проверки в типе и дальше можем сразу, подставляя MyCoolObj, гарантировать, что в этом месте все проверки уже сделаны (компилятор проследил). Если мы будем работать с просто MyObj, то контроля со стороны компилятора не будет (хотя работать все будет и так, просто тестировать придется и этот момент тоже).

ARK>>Соответственно, мы один раз сделали все необходимые проверки, а дальше у нас просто переменная нужного типа путешествует по системе, а компилятор следит, чтобы мы ее не засунули туда, куда не нужно.

M>Да-да. Следит, «нужного типа». Только вот незадача-то. Объект у нас одного типа — заказ.

Не только, у нас есть просто заказ, есть отосланный заказ и неотосланный заказ. Это как предок и два потомка в ООП, только конверсия производится неявно — просто проверкой условий типа в if или match.

M>И дальше над ним может идти очень длинная последовательность действий. Где в одном действии ему надо быть уже отосланным, в другом — неотосланным, в пятом — отосланным, но неоплаченным, в десятом — просто не иметь статуса "fraud". Как предлагаешь поступать? Писать стопятьсот типов на каждый чих и комбинацию, а потом стопятьсот if'ов, инициализаторов и кастований из одного в другое?


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

ARK>>Понятно, что в каких-то сценариях количество проверок будет одинаковое. А в каких-то одна проверка на входе и дальше 10 вызовов без проверок.

M>Это, вообще-то, КО программирования. Валидность объекта проверяет первая функция, а дальше ненужных проверок делать не нужно.

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

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

Это в точности та проблема, которую могут смягчить типы. Поскольку язык С++ не позволяет кодировать в типах дополнительную информацию, в больших программах ставят как можно больше проверок, из страха, что кто-то где-то уберет лишнюю проверку и все обрушится. Потому что компилятор бессилен — с его точки зрения все корректно. Если же ЯП позволяет расширить типы дополнительной информацией, то на помощь приходит компилятор.

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

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

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

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

M>Тогда нафига козе баян? Ну и как это? Меня тут активно пытались убедить, что все прекрасно, и чуть ли ен все можно в типы запихнуть

Не, ну это явное преувеличение. Во всяком случае, я не знаю языков, которые позволяют _удобно_ записывать такие проверки.
Re[27]: Haskell нужен! (в Standard Chartered Bank)
От: Mamut Швеция http://dmitriid.com
Дата: 04.02.15 21:19
Оценка:
ARK>Если мы будем работать с просто MyObj, то контроля со стороны компилятора не будет (хотя работать все будет и так, просто тестировать придется и этот момент тоже).

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

ARK>Это в точности та проблема, которую могут смягчить типы. Поскольку язык С++ не позволяет кодировать в типах дополнительную информацию, в больших программах ставят как можно больше проверок, из страха, что кто-то где-то уберет лишнюю проверку и все обрушится. Потому что компилятор бессилен — с его точки зрения все корректно. Если же ЯП позволяет расширить типы дополнительной информацией, то на помощь приходит компилятор.


Но, как мы только что выяснили, это справедливо только для простых объектов в простых сценариях использования


dmitriid.comGitHubLinkedIn
Re[28]: Haskell нужен! (в Standard Chartered Bank)
От: artelk  
Дата: 04.02.15 21:24
Оценка:
Здравствуйте, Mamut, Вы писали:

M>
M>public Order[*] read_order_from_db(OrderId id);

M>// каким образом тут компилятор проверит, что за Order сюда идет?
M>// заказ же из базы читается
M>change_order_amount(Order, Amount)
M>


read_order_from_db :: OrderId -> Either NewOrder ProcessedOrder

И теперь для того, чтобы вызвать change_order_amount, требуется паттерн-матчинг для определения "подтипа".
Re[29]: Haskell нужен! (в Standard Chartered Bank)
От: Mamut Швеция http://dmitriid.com
Дата: 04.02.15 21:44
Оценка:
A>
A>read_order_from_db :: OrderId -> Either NewOrder ProcessedOrder
A>

A>И теперь для того, чтобы вызвать change_order_amount, требуется паттерн-матчинг для определения "подтипа".

Ну то есть компилятор нам все равно нам особо-то не помогает. В общем, не нужно ©

Потому что дальше все становится хуже, процитирую отсюда http://rsdn.ru/forum/philosophy/5944219
Автор: Mamut
Дата: 04.02.15

Только вот незадача-то. Объект у нас одного типа — заказ.

И дальше над ним может идти очень длинная последовательность действий. Где в одном действии ему надо быть уже отосланным, в другом — неотосланным, в пятом — отосланным, но неоплаченным, в десятом — просто не иметь статуса "fraud". Как предлагаешь поступать? Писать стопятьсот типов на каждый чих и комбинацию, а потом стопятьсот if'ов, инициализаторов и кастований из одного в другое?




dmitriid.comGitHubLinkedIn
Re[30]: Haskell нужен! (в Standard Chartered Bank)
От: artelk  
Дата: 04.02.15 22:54
Оценка:
Здравствуйте, Mamut, Вы писали:

A>>
A>>read_order_from_db :: OrderId -> Either NewOrder ProcessedOrder
A>>

A>>И теперь для того, чтобы вызвать change_order_amount, требуется паттерн-матчинг для определения "подтипа".

M>Ну то есть компилятор нам все равно нам особо-то не помогает. В общем, не нужно ©


Почему не помогает? Он же не дает передать в change_order_amount неопределенный Order.

M>Потому что дальше все становится хуже, процитирую отсюда http://rsdn.ru/forum/philosophy/5944219
Автор: Mamut
Дата: 04.02.15

M>

M>Только вот незадача-то. Объект у нас одного типа — заказ.

M>И дальше над ним может идти очень длинная последовательность действий. Где в одном действии ему надо быть уже отосланным, в другом — неотосланным, в пятом — отосланным, но неоплаченным, в десятом — просто не иметь статуса "fraud". Как предлагаешь поступать? Писать стопятьсот типов на каждый чих и комбинацию, а потом стопятьсот if'ов, инициализаторов и кастований из одного в другое?


M>)


Думаю, что выражать через типы имеет смысл только достаточно стабильную часть логики, т.к. изменение типов может быть болезненной процедурой и затрагивать кучу мест в проекте.
Ограничение "нельзя менять amount у processed order" выглядит стабильным.
Если amount меняется только в одном месте, то, наверно, смысла выражать это правило через типы нет.
Если таких мест 1024, то смысл появляется.

+= Еще один момент: некая функция принимает параметром Order, вызывает другую, та третью и далее по цепочке. Нам нужна гарантия, что эта некая функция не меняет amount, т.к. мы ее вызываем с processed order. Если тип параметра явно указать как ProcessedOrder, то такую гарантию нам даст компилятор, если нет — то остается только просматривать всю цепочку вызовов. Так что вышеуказанные "1024 мест" включают и такие случаи.
Отредактировано 04.02.2015 23:13 artelk . Предыдущая версия .
Re[30]: Haskell нужен! (в Standard Chartered Bank)
От: Mumitroller Беларусь  
Дата: 05.02.15 05:37
Оценка: +1
Здравствуйте, Mamut, Вы писали:

M>и чем больше у нас условий, тем больше проверок будет в рантайме с предсказуемым вопросом: а нафига козе баян?


Вроде как очевидно — компилятор не даст забыть проверить все необходимые условия при вызове. А при изменении логики ещё и потыкает во все места, где не сможет самостоятельно доказать выполнение необходимых условий. Как по мне, так это очень крутая фича, хотя, конечно, нужно пробовать в реальных условиях. Наверняка не обойдётся без подводных камней, которые существенно попортят всю малину.

Mumitroller.
... << RSDN@Home 1.2.0 alpha 5 rev. 56>>
Re[24]: Haskell нужен! (в Standard Chartered Bank)
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 05.02.15 06:54
Оценка:
Здравствуйте, Mamut, Вы писали:

DM>>В итоге компилятор хотя бы эту логику проверит статически


M>Каким образом, если заказ читается из базы данных? Подробнее в этом обсуждении: http://rsdn.ru/forum/philosophy/5943812
Автор: AlexRK
Дата: 04.02.15


А какая разница, БД там, файл на магнитном барабане или сигнальные костры? Это лишь деталь реализации модуля хранения данных.
Просто типы при записи в базу не должны теряться. Ты же не путаешь заказы с покупателями, хотя и те и другие хранятся в базе? Это разные типы. Вот и здесь тоже, заказы в разных состояниях будут разными типами. У них наверняка и набор полей может быть разный в зависимости от состояния. Скажем, дата отсылки имеет смысл для отосланного заказа, а способ оплаты — для оплаченного.

DM>>и не даст менять сумму когда не положено. Остальные правила проще описать данными.


M>Что значит «проще описать данными»?


Табличка с правилами вычисления максимального изменения суммы в зависимости от страны, например.
Re[31]: Haskell нужен! (в Standard Chartered Bank)
От: Mamut Швеция http://dmitriid.com
Дата: 05.02.15 08:42
Оценка:
A>Думаю, что выражать через типы имеет смысл только достаточно стабильную часть логики, т.к. изменение типов может быть болезненной процедурой и затрагивать кучу мест в проекте.

Ой, как это? Мне тут рядом говорили, что придется менять не в 1024 местах, а только в одном месте

A>Ограничение "нельзя менять amount у processed order" выглядит стабильным.


Увы, нет Начиная с "все спецификации ad-hoc" из оригинального сообщения и до последнего тикета, который таки позволяет увеличивать сумму заказа для pre-paid закаов согласно конфигурации магазина. И это связано с дополнительной логикой — что, если

A>+= Еще один момент: некая функция принимает параметром Order, вызывает другую, та третью и далее по цепочке. Нам нужна гарантия, что эта некая функция не меняет amount, т.к. мы ее вызываем с processed order. Если тип параметра явно указать как ProcessedOrder, то такую гарантию нам даст компилятор, если нет — то остается только просматривать всю цепочку вызовов. Так что вышеуказанные "1024 мест" включают и такие случаи.


Во-первых, совсем не факт, что нам нужна эта гарантия. Во-вторых, если Order — это черный ящик, и смена суммы происходит через order:set_amount, то внезапно все проверки тоже оказываются в одном месте В-третьих, увеличение суммы может зависить не только от того, запроцессился заказ или нет.

Лишь некоторые из условий:

— заказ не обработан, заказ не pre-paid, сумма повышена, risk chek пройден: повысили
— заказ не обработан, заказ не pre-paid, сумма повышена, risk chek не пройден: не повысили
— заказ обработан, заказ не pre-paid, сумма повышена, risk chek пройден: повысили
— заказ обработан, заказ не pre-paid, сумма повышена, risk chek не пройден: не повысили
...
...
...
и ко всему этому еще надо добавить проверку «а если order expired?», «а надо ли делать re-auth в банке?», «а надо ли...» ну и т.п. :D


dmitriid.comGitHubLinkedIn
Re[25]: Haskell нужен! (в Standard Chartered Bank)
От: Mamut Швеция http://dmitriid.com
Дата: 05.02.15 08:59
Оценка:
DM>Вот и здесь тоже, заказы в разных состояниях будут разными типами. У них наверняка и набор полей может быть разный в зависимости от состояния. Скажем, дата отсылки имеет смысл для отосланного заказа, а способ оплаты — для оплаченного.

/o\

Действительно. Давай сделаем тип UnprocessedNonPrePaidRiskClearedOrder, ProcessedNonPrePaidRiskClearedOrder, UnprocessedPrePaidRiskClearedOrder, ProcessedPrePaidRiskClearedOrder и еще два десякта таких же. Это же так удобно!




DM>>>и не даст менять сумму когда не положено. Остальные правила проще описать данными.


M>>Что значит «проще описать данными»?

DM>Табличка с правилами вычисления максимального изменения суммы в зависимости от страны, например.

Она есть. В конфигурации. В базе данных. Зависит от от страны и магазина


dmitriid.comGitHubLinkedIn
Re: Haskell нужен! (в Standard Chartered Bank)
От: zeeker  
Дата: 05.02.15 11:50
Оценка:
Здравствуйте, jazzer, Вы писали:

J>К вопросу о том, что хаскель не нужен и это инструмент для гиков-энтузиастов и никто его в продакшене в здравом уме использовать не будет


Тут давеча Майкрософт выложил свой Бонд (компетитор протобафа если кто не в курсе), так вот там кодогенерилка выполнена на хаскеле:
https://github.com/Microsoft/bond/tree/master/compiler

И, кстати да, она фактически занимается преобразованием DSL (IDL, .bond файлов) в C++ и C# code.
Re[26]: Haskell нужен! (в Standard Chartered Bank)
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 05.02.15 12:24
Оценка:
Здравствуйте, Mamut, Вы писали:

DM>>Вот и здесь тоже, заказы в разных состояниях будут разными типами. У них наверняка и набор полей может быть разный в зависимости от состояния. Скажем, дата отсылки имеет смысл для отосланного заказа, а способ оплаты — для оплаченного.


M>Действительно. Давай сделаем тип UnprocessedNonPrePaidRiskClearedOrder, ProcessedNonPrePaidRiskClearedOrder, UnprocessedPrePaidRiskClearedOrder, ProcessedPrePaidRiskClearedOrder и еще два десякта таких же. Это же так удобно!


Ну, если ты пишешь на Си или Го, то такая беда, да. В нормальных же языках полиморфизм позволит общие вещи описать лишь однажды, а разницу вынести, так что ненужного повторения много не будет.
Re[18]: Haskell нужен! (в Standard Chartered Bank)
От: Klapaucius  
Дата: 05.02.15 13:30
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Я привел простейший пример тут: http://rsdn.ru/forum/philosophy/5943418
Автор: Mamut
Дата: 04.02.15


M>Тут не нужны ни нетипизированная программа, ни тестовые данные. Потому что она в лоб решается так, как там описано:


Можно, например, определить функции проверки, обновлений, записывания не на одном и том же типе Order, а на разных типах различных стадий обработки Order.
updateOrder :: Int -> Order -> Maybe Done
updateOrder amount = check1 amount >=> check2 >=> update >=> writeOrder

check1 :: Int -> Order -> Maybe Checked1
check2 :: Checked1 -> Maybe Checked2
update :: Checked2 -> Maybe Updated
writeOrder :: Updated -> Maybe Done


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

K>>Т.е. ваш вопрос был о том, что будет если вы "забудете про 4-й пункт" на этапе спецификации?

M>Вопрос был. Как ты не смог его понять — это выше моего понимания.

Это не ответ на мой вопрос.

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


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

M>Извини, не верю. Учитывая, что ты даже не смог ни разу ответить на простой вопрос «как это все будет проверяться и дебажиться».


Если вы игнорируете ответ, это еще не значит, что вам никто не ответил.

M>[много текста про то, как магический тайпчек все отловит, невзирая на леность программиста, просто поскипано]


Ничего магического в тайпчеке нет, не выдумывайте.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.