Re[5]: Что должен возвращать if?
От: gbear Россия  
Дата: 20.10.14 03:57
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>ИМХО, variant[Some[T], Nothing], или variant[T, void] это всё детали.

EP>Основной поинт в том, что и для if-без-else, и для if+else, и даже для if+else+if+else+... в качестве результата можно использовать один тип результата Variant<...>

При всем моем уважении, если это и детали, то это весьма важные детали.

Ход рассуждений примерно такой:
1. if-без-else — выражение;
2. Как любое выражение, оно может быть вычислено;
3. Результат этого вычисления может быть сохранен.

Но, с другой стороны, предикат может быть вычислен в false. И тут возможны варианты:
1. Условно, F#-way. Т.н. неявный else. Else есть всегда. Когда его мы его не наблюдаем — он таки есть и вычисляется в void;
2. Условно, erlang-way. Если предикат вычислился в false, результатом вычисления будет некое if-clause исключение.
3. То, что предлагаете вы. if-без-else вычисляется в монаду maybe.

Смысл всего этого, вообще говоря, избежать неоднозначности в вычислениях.

В F#-way неоднозначности просто нет. Альтернативная ветвь вычислений есть всегда. Просто иногда она не выражена явно.
В erlang-way, цепь вычислений прерывается специальным исключением.
В вашем случае, цепь потенциально неоднозначных вычислений "замыкается" на монаду maybe. И она дает возможность понять, что что-то "go wrong".

В вашем случае, важна именно полноценная монада maybe. Паллиатив вида variant[T, void] — не даст вам возможности поймать "go wrong".
И важен тут, не столько Nothing (который, вполне может быть заменен и на void), сколько Just. Т.е. если за-предикатное выражение вычисляется в T, то "нормальный" результат вычисления if-без-else будет Just[T], а не T.

Если теперь сравнить это с if-с-else, то видно следующее. Чтобы "в качестве результата можно использовать один тип результата" — в вашем случае — его придется вычислять в Just[T], а не в T. Что, вообще говоря, смысла лишено.

Даже если "обернуть" все это в variant — это мало что изменит . Типы A и Some[A] — это таки разные типы.
Можно потытаться "стереть границы" введя функторы, например... и вот тогда про "два синтаксиса" вообще никто вспоминать уж точно не будет

G>>Так же будут "проблемы" восприятия всяческих variant[A, A]. Даже если "упрощать" их до variant[A] — ничего, кроме дополнительного раздражения вывод таких типов вызвать не может.


EP>Для обобщённого кода это удобно.

EP>Для обычного — возможно да, автоматическое упрощение до A было бы удобней. Но это упрощение можно получить явным вызовом одного унарного оператора или функции, причём если считать что variant<A> всегда содержит значение типа A (то есть не Nothing), то такой вызов не будет давать никаких накладных расходов.
EP>Я думаю намного более неудобно, если в ветках получаются слабосвязанные A и B, и выводится какой-то крайне слабый общий тип вроде IPrintable (как это делается сейчас) — по сути много полезной информации о типах бесследно теряется.

Попытаюсь объяснить еще раз...

Смотрите, я выше высказался за разрешение неоднозначности при вычислении if-без-else. Действительно её можно снять вычисляя его в maybe. Проблема только в том, что это никакого отношения к вычислению if-с-else не имеет
Добиться "одинаковости" можно лишь вычислением и if-с-else тоже в maybe. Что весьма странно, согласитесь. Ведь никаких неоднозначностей при его вычмслении у нас нет. И никакие variant[A, B] и т.п. не дадут вам взаимозаменяемости, если хотите, между результатами вычислений if-с-else и if-без-else.

Вычисление if-с-else в variant, само по себе (без попытки добиться "симметрии") может иметь смысл. Но только в том случае, когда PM и использование variant уйдут на ступень выше, так сказать.
Какой смысл в данный момент получать из if (который, на самом деле PM) variant? Для его обработки все равно придется использовать PM. Если же мы можем выделить общий интерфейс (т.е. при дальнейшей обработки обойтись без PM), то и возвращать из if лучше именно этот интерфейс. Что, как я понимаю, сейчас и делается.

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

---
С уважением, Константин Сиваков
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.