Re[9]: Что должен возвращать if?
От: WolfHound  
Дата: 17.10.14 17:09
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Как я понял, ты говоришь что информация о типах там по сути не нужна.

Не нужна информация о том, в какой ветке, какой тип. И из какой ветки мы получили управление.

EP>Вопрос: почему бы просто тогда не возвращать void всегда, даже для if+else?

По тому, что нужно значение.

WH>>По тому, что идёт перевод в некий предопределённый вариантный тип.

EP>Почему в неопределённый-то? Он полностью зависит от того, что возвращают ветки if
Второе сообщение подряд, в котором я половину понять не могу.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Что должен возвращать if?
От: WolfHound  
Дата: 17.10.14 17:09
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>С другой стороны, в шарпе никакого общего типа не выводится, требуется точное совпадение. И этого, что характерно, в 99% случаев вполне достаточно. А оставшийся 1% легко фиксится явным кастингом одной из веток.

        | Not(Not(rule))                => optimize(Rule.And(r.Location, rule)) 
        | And(Not(rule))                => optimize(Rule.Not(r.Location, rule)) 
        | Not(And(rule))                => optimize(Rule.Not(r.Location, rule)) 
        | And(And(rule))                => optimize(Rule.And(r.Location, rule)) 
        | Not(rule)                     => Rule.Not(r.Location, optimize(rule)) 
        | And(rule)                     => Rule.And(r.Location, optimize(rule)) 
        | Capture(kind, rule)           => Rule.Capture(r.Location, kind, optimize(rule)) 
        | Scope(name, rule)             => Rule.Scope(r.Location, name, optimize(rule)) 
        | Chars(chars)                  => Rule.Fsm(r.Location, FSMBuilder.Seq(chars)) 
        | Cut as rule                   => rule 
        | Fsm as rule                   => rule

Rule.Not, Rule.And, Rule.Capture,... разные типы. Но все они потомки Rule.
В C# нет подобных языковых средств. Поэтому там никто так не пишет.
А в немерле есть. И в немерле нужно приведение к общему типу.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Что должен возвращать if?
От: Evgeny.Panasyuk Россия  
Дата: 17.10.14 18:01
Оценка:
Здравствуйте, WolfHound, Вы писали:

EP>>Как я понял, ты говоришь что информация о типах там по сути не нужна.

WH>Не нужна информация о том, в какой ветке, какой тип. И из какой ветки мы получили управление.

Почему не нужна?

EP>>Вопрос: почему бы просто тогда не возвращать void всегда, даже для if+else?

WH>По тому, что нужно значение.

И какой тип у этого значения?

WH>Второе сообщение подряд, в котором я половину понять не могу.


Псевдокод:
typeof
(
    if(condition)
        return A{};
    else
        return B{};
)
==
Variant<A, B>

Что в этом плохого?
Почему это хуже, чем вывод общей базы, которая может быть крайне "слабым" типом вроде IPrintable, а то и вовсе Object.
Re[11]: Что должен возвращать if?
От: WolfHound  
Дата: 17.10.14 18:21
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

WH>>Не нужна информация о том, в какой ветке, какой тип. И из какой ветки мы получили управление.

EP>Почему не нужна?
По тому, что мы уже обработали информацию о ветвлении внутри самого if.

WH>>По тому, что нужно значение.

EP>И какой тип у этого значения?
Тот, к которому приводятся типы обеих веток.

EP>Что в этом плохого?

То, что это не нужно.

EP>Почему это хуже, чем вывод общей базы,

Хотя бы по тому что для того чтобы получить данные из этого варианта тебе нужен ещё один точно такой же if.

EP>которая может быть крайне "слабым" типом вроде IPrintable, а то и вовсе Object.

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

Ради интереса можешь попробовать найти хоть один язык, который ведёт себя, так как вы тут хотите.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: Что должен возвращать if?
От: Evgeny.Panasyuk Россия  
Дата: 17.10.14 18:48
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>>>Не нужна информация о том, в какой ветке, какой тип. И из какой ветки мы получили управление.

EP>>Почему не нужна?
WH>По тому, что мы уже обработали информацию о ветвлении внутри самого if.

При вызове виртуального метода общего интерфейса (к которому привелись результаты веток) — точно также обрабатывается информация о ветвлении.
Не вижу здесь принципиальной разницы с Variant.

WH>>>По тому, что нужно значение.

EP>>И какой тип у этого значения?
WH>Тот, к которому приводятся типы обеих веток.

И получится в общем случае что-то очень близкое к Object'у

EP>>Что в этом плохого?

WH>То, что это не нужно.

Аргумент

EP>>Почему это хуже, чем вывод общей базы,

WH>Хотя бы по тому что для того чтобы получить данные из этого варианта тебе нужен ещё один точно такой же if.

Во-первых, как уже говорил выше — можно дать возможность получить из Variant'а значение общего типа (то есть текущее поведение).
Во-вторых, при вызове виртуального метода — также происходит индерекция (пусть и другого рода) как и при if.

EP>>которая может быть крайне "слабым" типом вроде IPrintable, а то и вовсе Object.

WH>В немерле Object не выводится. Там специальная закладка на этот счёт есть.

А с IPrintable (или подобным крайне "слабым") как быть?
То есть будут где-то иерархии пересекаться недалеко от Object'а — толку-то?
Re[8]: Что должен возвращать if?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 17.10.14 19:08
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>В C# нет подобных языковых средств.


Так и речь тут не про РМ, а про if. А то что if в немерле это сахар для РМ, это уже подробности реализации, которые в контексте разговора не очень интересны.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[13]: Что должен возвращать if?
От: Evgeny.Panasyuk Россия  
Дата: 17.10.14 19:12
Оценка: +1
WH>>>>Не нужна информация о том, в какой ветке, какой тип. И из какой ветки мы получили управление.
EP>>>Почему не нужна?
WH>>По тому, что мы уже обработали информацию о ветвлении внутри самого if.
EP>При вызове виртуального метода общего интерфейса (к которому привелись результаты веток) — точно также обрабатывается информация о ветвлении.
EP>Не вижу здесь принципиальной разницы с Variant.

Я даже больше скажу, теоретически вызов метода содержащегося внутри Variant может иметь абсолютно такой же синтаксис как и вызов виртуального метода:
Variant<Triangle, Rectangle> v = ...;
v.draw();


А вот такой синтаксис можно получить в C++ прям сейчас:
Variant<Triangle, Rectangle> v = ...;
use_concrete_type(v)
{
    v.draw();
};
Причём для всех вызовов внутри фигурных скобок не будет никакого dispatch, так как там у v один из конкретных типов — Triangle или Rectangle.
Dispatch будет только однократный, перед всеми вызовами (в отличии от виртуальных методов, где в общем случае для каждого вызова происходит индерекция).
Отредактировано 17.10.2014 19:13 Evgeny.Panasyuk . Предыдущая версия .
Re[7]: Что должен возвращать if?
От: kekekeks  
Дата: 18.10.14 10:16
Оценка: 51 (1)
Здравствуйте, AndrewVK, Вы писали:

AVK>С другой стороны, в шарпе никакого общего типа не выводится, требуется точное совпадение. И этого, что характерно, в 99% случаев вполне достаточно. А оставшийся 1% легко фиксится явным кастингом одной из веток.


https://roslyn.codeplex.com/discussions/569215
Re[12]: Что должен возвращать if?
От: jazzer Россия Skype: enerjazzer
Дата: 18.10.14 14:27
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Ради интереса можешь попробовать найти хоть один язык, который ведёт себя, так как вы тут хотите.


Ну вот Boost.Spirit 2 ведет себя именно так как раз, когда определяет тип атрибутов для разных грамматик.

т.е. для альтернативного парсера int_|double_ тип атрибута будет variant<int,double>
для опционального парсера -int_ тип атрибута будет optional<int>

подробнее здесь:
http://www.boost.org/doc/libs/1_56_0/libs/spirit/doc/html/spirit/qi/quick_reference/qi_parsers/operator.html
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Что должен возвращать if?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.10.14 01:47
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Эта ветка, кстати, отличная демонстрация того, что надо очертить некий Nemerle Base Level и долбить его детально и тщательно. Это большая работа, но ее надо делать обязательно, а не надеятся что каждый сам себе напишет свой if.


Он много лет как есть. Просто ты хочешь чтобы он был >= C#,а это не так. С when — это скорее недороботка в парсере тех времен. Но есть куда более концептуальные различия устранение которых может сделать язык хуже или другим.

Например, я на раз запомнил (прочтя в первой же статье), что нужно писать when. Ноя не раз нарывался на вот такую особенность:
when (true)
  42;
0

Как императивщик, я переводил этот код на Шара следующим образом:
if (true)
  return 42;
return 0;

Но это не верно, так как в Немерде выражение в конце функции не помещается в невидимый return, а вся функция рассматривается как дерево ветвления выражений. При этом незультат может быть получен только с "листьев". Таким образом, when посто теряет значение. Об этом говорит и warning, но человек из мира С# не понимает, что происходит.

Что уж говорить о мелких синтаксических фичах вроде mutable и описаниях массивов?

Тут уж нужно просто подумать и решить не проще ли сделать на потребу толпе полный супер–сет C#?

Собственно это была одна из
предпосылок для проекта Найтра. На ней создать два языка на одной базе будет парой пустяков.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Что должен возвращать if?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.10.14 13:37
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Он много лет как есть.

VD>С when — это скорее недороботка

Сам себе и противоречишь.

VD>Но есть куда более концептуальные различия устранение которых может сделать язык хуже или другим.


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

VD>Что уж говорить о мелких синтаксических фичах вроде mutable и описаниях массивов?


mutable как раз проблем не вызывает. А when — вызывает.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: Что должен возвращать if?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.10.14 21:43
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


Огласите весь список, пожалуйста. ©
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Что должен возвращать if?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.10.14 00:37
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Огласите весь список, пожалуйста. ©


Это отдельная немаленькая работа — понять что не так.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
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.

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

G>В вашем случае, важна именно полноценная монада maybe. Паллиатив вида variant[T, void] — не даст вам возможности поймать "go wrong".


Почему же не даст? void тут играет роль Nothing.

G>И важен тут, не столько Nothing (который, вполне может быть заменен и на void),


Да, именно.

G>сколько Just. Т.е. если за-предикатное выражение вычисляется в T, то "нормальный" результат вычисления if-без-else будет Just[T], а не T.


Да, и я не вижу в этом проблемы.

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


Почему же? Для обобщённого кода как раз и не лишено — вне зависимости от того, значения каких типов возвращают ветки if-else, всё выражение вычислится в Variant.
Для обычного, не обобщённого кода, да немного неудобно, но это обходится всего одним унарным оператором/унарной функцией, причём без потери производительности (Variant<T> всегда содержит внутри T, безусловно).
Тут главное не забывать, что if-с-else в общем случае возвращает Variant<T, U>, а не просто Variant<T>, который является всего лишь частным случаем.

G>Даже если "обернуть" все это в variant — это мало что изменит . Типы A и Some[A] — это таки разные типы.

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

В случае когда у нас Variant<T>, полноценный функторный fmap не нужен, точнее можно без него. Достаточно T unbox(Variant<T> x);, или короткого оператора.

G>Смотрите, я выше высказался за разрешение неоднозначности при вычислении if-без-else. Действительно её можно снять вычисляя его в maybe. Проблема только в том, что это никакого отношения к вычислению if-с-else не имеет


Maybe действительно не имеет отношения, а вот Varaint — вполне.

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


Почему же не дадут?

G>Вычисление if-с-else в variant, само по себе (без попытки добиться "симметрии") может иметь смысл. Но только в том случае, когда PM и использование variant уйдут на ступень выше, так сказать.


То есть основная проблема заключается в каких-то пробелах в Nemerle с Varaint'ом как таковым, а не в самой идеи if-else -> Variant?

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


Дело в том, что non-member функции также, грубо говоря, относятся к интерфейсу. Объектам необязательно иметь одинаковые-функции члены и общих предков, чтобы их можно было использовать с одинаковым синтаксисом.
Например на C++ можно вот так:
Variant<Widget, Gadget> x, y;
// ...
apply(x, y, [](auto &x, auto &y)
{
    draw(x);
    draw(y);
    collide(x, y);
});
Здесь нет PM, и нет общего предка, хотя оба объекта имеют одинаковый интерфейс с точки зрения этой полиморфной лямбды.

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


Это похоже по описанию на перегрузку функций в C++, там как раз и возможно разруливать ветви variant через перегрузку (а можно и через один шаблон функции, если интерфейс одинаков, как в примере выше).
Отредактировано 20.10.2014 13:52 Evgeny.Panasyuk . Предыдущая версия .
Re[6]: Что должен возвращать if?
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.10.14 21:24
Оценка:
Здравствуйте, AndrewVK, Вы писали:

VD>>Огласите весь список, пожалуйста. ©


AVK>Это отдельная немаленькая работа — понять что не так.


Раз так, то до ее окончания потрудись не делать заявлений. А то не понравилось тебе одно решение с when–ом и на этом основании делается вывод что есть "куча мелочей, которые мешают".

Я, вот, немерл уже 7 лет использую и реальных косяков особо не заметил. Историю с when можно счесть за косяк, ну там в описании массивов есть непоследовательность, выбор скобок для дженериков слабостью парсера объясняется. Но в остальном все решения имеют под собой конкретные обоснования. Да даже скобки для дженириков не прихоть авторов, а выбор в пользу меньшей неоднозначности. Без Нитры ее очень не просто было бы обойти. Нитра не ограничена LL(k), а немерловый парсер ограничен. Можно ли ругать авторов за этот выбор?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Что должен возвращать if?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.10.14 21:41
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Я, вот, немерл уже 7 лет использую и реальных косяков особо не заметил.

VD> Историю с when можно счесть за косяк, ну там в описании массивов есть непоследовательность, выбор скобок для дженериков слабостью парсера объясняется.

Опять сам себе противоречишь.
И мне пофигу, чем там оно объясняется. Косяки есть? Есть? Не фиксятся годами? Не фиксятся.

VD>Можно ли ругать авторов за этот выбор?


Я не ругаю авторов, я пытаюсь намекнуть почему у Немерле такое маленькое комьюнити.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[8]: Что должен возвращать if?
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.10.14 23:07
Оценка: -1
Здравствуйте, AndrewVK, Вы писали:

AVK>Опять сам себе противоречишь.


Я себе не противоречу. 3 (три) это никак не целая куча.
Запомнить их труда не представляет. Исправление таких "косяков" положения дел не изменит.

AVK>И мне пофигу, чем там оно объясняется. Косяки есть? Есть? Не фиксятся годами? Не фиксятся.


До тебя никто не говорил, что это косяк. В шарик 100500 подобных косяков. Но ты их выучил и принял как данное. А тут ты в бутылку полез. Да еще и про целую куче косяков речь завел.

AVK>Я не ругаю авторов, я пытаюсь намекнуть почему у Немерле такое маленькое комьюнити.


Думаю, ты ошибаешься с оценкой значимости этих проблем.

Если бы when был реальной проблемой, о нем бы уже 10 тем завели.

Повторюсь, что возможно для успешности проекта действительно разумно было бы сделать чистый (или не очень) суперсет шарпа. Дизайн немерла логичен и оправдан, просто ты хочешь видеть в нем суперсет шаопа, а это не так. И это дизайнерский выбор авторов. Как идиалист я с ним согласен. Как циник и скептик считаю, что при всей правильности дизайна он вредит популярности. Привычное люди ценят больше чем удобное. Да и оценить удобство можно тоько освоив язык, а именно этого и не случается.

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

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

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

На ее основе можно будет создать язык с несколькими синтаксисами и одним ядром.

Залудим и немерл, и шарп++. И пусть история рассудит какой синтаесис выбрать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Что должен возвращать if?
От: gbear Россия  
Дата: 20.10.14 23:50
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

G>>В вашем случае, важна именно полноценная монада maybe. Паллиатив вида variant[T, void] — не даст вам возможности поймать "go wrong".

G>>И важен тут, не столько Nothing (который, вполне может быть заменен и на void),
G>>сколько Just. Т.е. если за-предикатное выражение вычисляется в T, то "нормальный" результат вычисления if-без-else будет Just[T], а не T.

EP>Да, и я не вижу в этом проблемы.


А как вы собираетесь это потом использовать?! Повторюсь, смысл вычисления в maybe — возможность понять что "что-то пошло не так". Использование неявного приведения Just[T] к T (которое, кстати, вполне возможно) лишает нас этой возможности. Если нет неявного приведения, то "просто так" использовать результат вычисления if-без-else в тех же местах, где мы можем использовать результат вычисления if-с-else не получится.

Вот и вся проблема.

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


EP>Почему же? Для обобщённого кода как раз и не лишено — вне зависимости от того, значения каких типов возвращают ветки if-else, всё выражение вычислится в Variant.


Ну причем тут variant-то?! Речь идет о том, что нет смысла вычислять if-с-else в maybe.

EP>Для обычного, не обобщённого кода, да немного неудобно, но это обходится всего одним унарным оператором/унарной функцией, причём без потери производительности (Variant<T> всегда содержит внутри T, безусловно).

EP>Тут главное не забывать, что if-с-else в общем случае возвращает Variant<T, U>, а не просто Variant<T>, который является всего лишь частным случаем.

Уф. Если уж на то пошло, то обобщенный код — песня отдельная. Там можно и нормальный match использовать.

G>>Даже если "обернуть" все это в variant — это мало что изменит . Типы A и Some[A] — это таки разные типы.

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

EP>В случае когда у нас Variant<T>, полноценный функторный fmap не нужен, точнее можно без него. Достаточно T unbox(Variant<T> x);, или короткого оператора.


По-ходу, как-то я не ясно выразился. Я вам про одно — вычисление if-без-else в maybe, а вы мне про другое — вычисление if-c-else в variant

Ладно, поговорим за variant...

А зачем вам какой-то явный unbox для variant? Вполне можно обойтись и неявным приведением к. Но, дело-то не в этом.

Смотрите... вот получили мы какой-то variant[string, int, ?DateTime], условно. Пусть даже у него есть какой-то unbox. Нормально обработать его можно только через PM. Вы же, надеюсь, не собираетесь прогонять его через очередной if? Об этом и речь.

G>>Вычисление if-с-else в variant, само по себе (без попытки добиться "симметрии") может иметь смысл. Но только в том случае, когда PM и использование variant уйдут на ступень выше, так сказать.


EP>То есть основная проблема заключается в каких-то пробелах в Nemerle с Varaint'ом как таковым, а не в самой идеи if-else -> Variant?


Nemerle тут вообще не причем Недостаточно вычислить if в variant[A, B, C]. Нужно еще как-то "узнать", что конкретно этот variant сейчас в себе несет... A, B или C. Даже в варианте с явным unbox, его тип вам заранее не известен. И его нужно будет либо дополнительно проверять... либо двойную диспетчеризацию городить... либо я ещё не знаю что Но просто так (без PM) использовать не получится. Хоть в Nemerle, хоть еще где.

---
С уважением, Константин Сиваков
Re[9]: Что должен возвращать if?
От: DarkEld3r  
Дата: 21.10.14 08:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>2 или три языка поддерживающие главные концепции, но имеющие разный синтаксис.

VD>Залудим и немерл, и шарп++. И пусть история рассудит какой синтаесис выбрать.
Взгляд со стороны. Мне кажется, что многих людей (вероятно, не привыкших к написанию дсл) отпугнёт такое разнообразие. Может создаться впечатление, что вы распыляетесь и не можете сами определиться.

Или вот представим, что человек знает шарп, но услышал про ваш язык и заинтересовался. Изначально интерес может быть праздным — это нормально. Желательно на этом этапе увлечь. А у человека возникнет выбор — или брать "более знакомый" "шарп++" или немерле. Причём вы пишете на немерле, вот и думай, что выбирать или знакомый синтаксис или "реально используемый" диалект языка.

Если что, то это я по себе сужу. Разумеется, могу быть не обьективным. Тем не менее, на мой взгляд, лучше всё-таки сделать один немерле2.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.