Здравствуйте, Evgeny.Panasyuk, Вы писали:
G>>2. Если выражение if содержит else, то оно вычисляется "нормально". Иначе, оно вычисляется в void. EP>А почему void, а не Maybe?
Эта ветка, кстати, отличная демонстрация того, что надо очертить некий Nemerle Base Level и долбить его детально и тщательно. Это большая работа, но ее надо делать обязательно, а не надеятся что каждый сам себе напишет свой if.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
EP>>А почему void, а не Maybe? AVK>Кстати да.
Думаю если if без else это Maybe, то по идее if+else это Variant (в таком случае есть некоторая симметрия: Maybe<T> это грубо говоря Variant<T, void>).
А сейчас видимо для if+else просто общий тип выводится?
Здравствуйте, AndrewVK, Вы писали:
EP>>Думаю если if без else это Maybe, то по идее if+else это Variant AVK>Думаю все таки Variant должен быть только если общий тип равен object.
Допустим два типа слишком слабо связанны, и общий тип представляет процентов 5% от их возможностей — думаю в таком случае лучше Variant.
В крайнем случае можно дать возможность получить из Varaint какой-то общий тип, с помощью отдельного явного вызова.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Допустим два типа слишком слабо связанны, и общий тип представляет процентов 5% от их возможностей — думаю в таком случае лучше Variant.
Ну значит хотя бы при полном совпадении не должен генерироваться variant.
EP>В крайнем случае можно дать возможность получить из Varaint какой-то общий тип, с помощью отдельного явного вызова.
Согласен.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
EP>>Допустим два типа слишком слабо связанны, и общий тип представляет процентов 5% от их возможностей — думаю в таком случае лучше Variant. AVK>Ну значит хотя бы при полном совпадении не должен генерироваться variant.
По-хорошему да, не хотелось бы делать Variant из одного типа, но это не должно ломать обобщённый код.
Например некая generic функция принимает два типа параметра, и делает if+else внутри. В общем случае типы результатов веток разные, а в некоторых частных — одинаковые. Код этой функции должен работать без изменений и там и там.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, gbear, Вы писали:
G>>2. Если выражение if содержит else, то оно вычисляется "нормально". Иначе, оно вычисляется в void.
EP>А почему void, а не Maybe?
Воот Совсем другой разговор.
Вообще говоря — принципиальной разницы во что вычилять if-без-else, в void или в option[T] — нет. Важно то, что if-с-else вычислит тоже самое выражение — гарантированно — в другой тип. А это — имхо, гооораздо... скажем так, станьше, чем "два синтаксиса для if"
Ну вот я и спрашиваю: зачем два _разных_ — по своей сути разных — выражения сводить к одному синтаксису?!
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Думаю если if без else это Maybe, то по идее if+else это Variant (в таком случае есть некоторая симметрия: Maybe<T> это грубо говоря Variant<T, void>). EP>А сейчас видимо для if+else просто общий тип выводится?
Для того, чтобы вычисление if+else в Variant имело смысл, его синтаксис должен позволять избегать вложенности. Иначе на выходе гипотетического:
Получим variant[string, variant[int, variant[decimal, option[T]]]]. Что несколько не удобно, имхо. Если идти по такому пути, то надо иметь возможноть получать какой-нибудь variant[string, int, decimal, option[T]]
Здравствуйте, AndrewVK, Вы писали:
EP>>Допустим два типа слишком слабо связанны, и общий тип представляет процентов 5% от их возможностей — думаю в таком случае лучше Variant. AVK>Ну значит хотя бы при полном совпадении не должен генерироваться variant. EP>>В крайнем случае можно дать возможность получить из Varaint какой-то общий тип, с помощью отдельного явного вызова. AVK>Согласен.
Вот да. if без else вычислять в Maybe, а if с else вычислять в Either. Тогда, всем пользователям C# будет привычно и удобно, не то что when.
Здравствуйте, gbear, Вы писали:
G>Вообще говоря — принципиальной разницы во что вычилять if-без-else, в void или в option[T] — нет. Важно то, что if-с-else вычислит тоже самое выражение — гарантированно — в другой тип. А это — имхо, гооораздо... скажем так, станьше, чем "два синтаксиса для if"
if+else может возвращать Variant<A, B>, а if-без-else — Variant<A> или Variant<A, void> (в зависимости от того как реализован Variant), что по сути является Maybe.
Получается достаточно симметрично.
G>Ну вот я и спрашиваю: зачем два _разных_ — по своей сути разных — выражения сводить к одному синтаксису?!
Здравствуйте, gbear, Вы писали:
G>Получим variant[string, variant[int, variant[decimal, option[T]]]]. Что несколько не удобно, имхо. Если идти по такому пути, то надо иметь возможноть получать какой-нибудь variant[string, int, decimal, option[T]]
Вижу несколько вариантов:
1. Автоматически делать flatten, но только при условии что это сломает обобщённый код.
2. Дать возможность делать явный flatten.
3. Сделать выражение не просто if else, а составное if else if else if else, то есть что-то типа специального keyword'а elseif (но думаю что его вводить не обязательно, а просто задавать составной синтаксис).
В этом случае те кому нужен плоский Variant — будут писать составное выражение, а если иерархический — то просто добавят скобки.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>if+else может возвращать Variant<A, B>, а if-без-else — Variant<A> или Variant<A, void> (в зависимости от того как реализован Variant), что по сути является Maybe. EP>Получается достаточно симметрично.
Скорее всего, я как-то Вас не так понял... но, имхо, не получится в этом случие "достаточно симметрично". Начиная с того, что variant[A] — будет вызывать только раздражение, а variant[A, void] — не является (хоть по сути, хоть еще как) Maybe.
void — в сабже — вполне себе нормальный тип. Вводя вычисление if-без-else в option[T] (так, как я понял, выглядит Maybe а сабже) — а это, "по сути", variant[Some[T], Nothing], а не variant[Some[T], void] — мы получаем возможность явно различать — было ли произведено вычисление выражения в if, или нет.
Вычисляя же его же в variant[T, void] вы такую возможность теряете (ведь T, вполне, может быть и void). И мне не понятно, чего полезного — по вашему — дает такое вычисление?
Даже если принять такое вычисление, то variant[A, B] и variant[A, void] — это таки разные типы (конечно, если B не void). Это мало что меняет.
Так же будут "проблемы" восприятия всяческих variant[A, A]. Даже если "упрощать" их до variant[A] — ничего, кроме дополнительного раздражения вывод таких типов вызвать не может.
Здравствуйте, gbear, Вы писали:
G>Скорее всего, я как-то Вас не так понял... но, имхо, не получится в этом случие "достаточно симметрично". Начиная с того, что variant[A] — будет вызывать только раздражение, а variant[A, void] — не является (хоть по сути, хоть еще как) Maybe. G>void — в сабже — вполне себе нормальный тип. Вводя вычисление if-без-else в option[T] (так, как я понял, выглядит Maybe а сабже) — а это, "по сути", variant[Some[T], Nothing], а не variant[Some[T], void] — мы получаем возможность явно различать — было ли произведено вычисление выражения в if, или нет. G>Вычисляя же его же в variant[T, void] вы такую возможность теряете (ведь T, вполне, может быть и void). И мне не понятно, чего полезного — по вашему — дает такое вычисление?
ИМХО, variant[Some[T], Nothing], или variant[T, void] это всё детали.
Основной поинт в том, что и для if-без-else, и для if+else, и даже для if+else+if+else+... в качестве результата можно использовать один тип результата Variant<...>
G>Так же будут "проблемы" восприятия всяческих variant[A, A]. Даже если "упрощать" их до variant[A] — ничего, кроме дополнительного раздражения вывод таких типов вызвать не может.
Для обобщённого кода это удобно.
Для обычного — возможно да, автоматическое упрощение до A было бы удобней. Но это упрощение можно получить явным вызовом одного унарного оператора или функции, причём если считать что variant<A> всегда содержит значение типа A (то есть не Nothing), то такой вызов не будет давать никаких накладных расходов.
Я думаю намного более неудобно, если в ветках получаются слабосвязанные A и B, и выводится какой-то крайне слабый общий тип вроде IPrintable (как это делается сейчас) — по сути много полезной информации о типах бесследно теряется.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Я думаю намного более неудобно, если в ветках получаются слабосвязанные A и B, и выводится какой-то крайне слабый общий тип вроде IPrintable (как это делается сейчас) — по сути много полезной информации о типах бесследно теряется.
По сути, она почти никогда не нужна.
А в тех редких случаях когда нужна того решения что вы предлагаете не достаточно.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
EP>>Я думаю намного более неудобно, если в ветках получаются слабосвязанные A и B, и выводится какой-то крайне слабый общий тип вроде IPrintable (как это делается сейчас) — по сути много полезной информации о типах бесследно теряется. WH>По сути, она почти никогда не нужна.
Если по сути не нужна, тогда действительно не понятно зачем when — был бы void во случаях (только из-за dangling else?)
WH>А в тех редких случаях когда нужна того решения что вы предлагаете не достаточно.
Здравствуйте, WolfHound, Вы писали:
WH>По сути, она почти никогда не нужна.
С другой стороны, в шарпе никакого общего типа не выводится, требуется точное совпадение. И этого, что характерно, в 99% случаев вполне достаточно. А оставшийся 1% легко фиксится явным кастингом одной из веток.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Если по сути не нужна, тогда действительно не понятно зачем when — был бы void во случаях (только из-за dangling else?)
Я не смог прочитать вопрос.
WH>>А в тех редких случаях когда нужна того решения что вы предлагаете не достаточно. EP>Почему?
По тому, что идёт перевод в некий предопределённый вариантный тип. https://github.com/rsdn/nemerle/blob/master/snippets/peg-parser/Nemerle.Peg.Macros/Optimizer/Optimizer.OptimizeRule.n
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
EP>>Если по сути не нужна, тогда действительно не понятно зачем when — был бы void во случаях (только из-за dangling else?) WH>Я не смог прочитать вопрос.
Как я понял, ты говоришь что информация о типах там по сути не нужна. Вопрос: почему бы просто тогда не возвращать void всегда, даже для if+else?
WH>>>А в тех редких случаях когда нужна того решения что вы предлагаете не достаточно. EP>>Почему? WH>По тому, что идёт перевод в некий предопределённый вариантный тип.
Почему в неопределённый-то? Он полностью зависит от того, что возвращают ветки if