Здравствуйте, matumba, Вы писали:
M>Помогите понять — это if такой неправильный или я что-то не догоняю?
Фигурные скобки лишние.
Учти что приоритеты будут такими:
def z = "smth" + if (1 < 2) "<"else (">" + if (2 < 3) "<"else">");
Здравствуйте, catbert, Вы писали:
C>Здравствуйте, YF, Вы писали:
YF>>... либо фигурные скобки {} убрать. YF>>Однако вопрос то остается, почему оно не компилится так, как есть?
C>баг
Это не баг. Это следствие того, что синтаксис языка построен на выражениях (expressions) и допустимы вот таки конструкции:
def c = { def a = 10; a } + { def b = 10; b }; // c == 30
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, matumba, Вы писали:
M>>Здравствуйте, YF, Вы писали:
YF>>>... либо фигурные скобки {} убрать.
M>>Фигурные стоят намеренно, чтобы выражение после else не прилепилось последущим плюсом к остальному.
H>Странная логика Фигурные скобки в данном случае не помогут, чтобы приоритеты были очевидны нужно целиком заключать if в круглые скобки.
Странное для немерлистов? Может быть. Однако, ПО ЛОГИКЕ всё сделано абсолютно верно — если IF возвращает любую из своих ветвей как выражение, я точно указываю фигурными скобками где у него кончается ветка else и где начинается сложение со следующим IF. Если такое очевидное выражение вызывает проблемы, это серьёзный повод подумать, правильно ли в немерле обрабатываются операторы-выражения.
Здравствуйте, matumba, Вы писали:
M>Странное для немерлистов? Может быть. Однако, ПО ЛОГИКЕ всё сделано абсолютно верно — если IF возвращает любую из своих ветвей как выражение, я точно указываю фигурными скобками где у него кончается ветка else и где начинается сложение со следующим IF. Если такое очевидное выражение вызывает проблемы, это серьёзный повод подумать, правильно ли в немерле обрабатываются операторы-выражения.
Ты не понял одной простой вещи. Фигурные скобки ничего не ограничивают, {"a"} + "b" вполне нормальное выражение и оно, по логике языка обязано вести себя точно так же как "a" + "b". Любые приседания с парсером, для нарушения этой логики будут вести к деградации логики в других случаях.
Ребят, транслирую с C# кое-какой код, в нём была тривиальная конструкция: строка складывалась с результатом двух "?:" операторов. Я это перевёл на немерлю:
def z = "smth" + if (1 < 2) "<"else {">"} + if (2 < 3) "<"else {">"};
// ^^^^^^^^^^^^^^^^^^^^^^^^^^ здесь ошибка "typing fails on finding the operator op_UnaryPlus(string-)"
Помогите понять — это if такой неправильный или я что-то не догоняю?
Здравствуйте, matumba, Вы писали:
M>Ребят, транслирую с C# кое-какой код, в нём была тривиальная конструкция: строка складывалась с результатом двух "?:" операторов. Я это перевёл на немерлю:
M>
M>def z = "smth" + if (1 < 2) "<"else {">"} + if (2 < 3) "<"else {">"};
M>// ^^^^^^^^^^^^^^^^^^^^^^^^^^ здесь ошибка "typing fails on finding the operator op_UnaryPlus(string-)"
M>
M>Помогите понять — это if такой неправильный или я что-то не догоняю?
Здравствуйте, matumba, Вы писали:
M>Здравствуйте, YF, Вы писали:
YF>>... либо фигурные скобки {} убрать.
M>Фигурные стоят намеренно, чтобы выражение после else не прилепилось последущим плюсом к остальному.
Странная логика Фигурные скобки в данном случае не помогут, чтобы приоритеты были очевидны нужно целиком заключать if в круглые скобки.
Здравствуйте, matumba, Вы писали:
H>>Странная логика Фигурные скобки в данном случае не помогут, чтобы приоритеты были очевидны нужно целиком заключать if в круглые скобки.
M>Странное для немерлистов? Может быть. Однако, ПО ЛОГИКЕ всё сделано абсолютно верно — если IF возвращает любую из своих ветвей как выражение, я точно указываю фигурными скобками где у него кончается ветка else и где начинается сложение со следующим IF. Если такое очевидное выражение вызывает проблемы, это серьёзный повод подумать, правильно ли в немерле обрабатываются операторы-выражения.
Операторы обрабатываются правильно (спецификации-то нету хе-хе). На деле тут банальная неоднозначность, и в какую сторону она бы не была решена, я готов поставить ползарплаты на то, что всегда найдется Матумба, которому не понравится выбранное решение. Твоя проблема решается заключением if-а в круглые скобки, кстати, аналогично разруливаются приоритеты и в C#, когда используются тернарные операторы. Более того, тернарный оператор ?: в разных языках имеет различную ассоциативность и в случаях его использования простановка круглых скобок — это правило хорошего тона. Я не вижу причины не следовать этому правилу и в Nemerle при использовании if внутри выражения.
Здравствуйте, YF, Вы писали:
C>>Скобки вокруг if поставить попробуйте...
YF>... либо фигурные скобки {} убрать. YF>Однако вопрос то остается, почему оно не компилится так, как есть?
У немерлового лексера, точнее у шага называемого PreParse, есть "странность". На шаге PreParse происходит свертка групп. Свертка осуществляется по следующему принципу. Идущие друг за другом токены объединяются в так называемую группу LooseGroup. Если встречается точка с запятой или открывающая скобка, то текущая LooseGroup закрывается и начинается другая группа. Скобки сворачиваются в отдельные группы.
Парсер работает уже с этими группами. Его логика приводит к тому что на фигурных скобках выражение должно завершаться. Отсюда и эта проблема. Тоже самое происходит с try ... fynally { ... } + ... и т.п.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, hardcase, Вы писали:
H>Операторы обрабатываются правильно (спецификации-то нету хе-хе). На деле тут банальная неоднозначность
На деле тут банальная недоработка парсера. Моё выражение однозначно — покажи его 100 прогерам и все 100 скажут, что я имел ввиду. И тернарные операторы тут не причём:
"a ? b : c" — он полностью "открытый", т.е. без скобок его просто невозможно поставить в сложное выражение. И смотри IF:
"if (cond) expr1 else expr2" — здесь expr2 может быть "закрыт" от последущих выражений фигурными скобками, которые однозначно выделяют ветку else.
Мне в принципе пофиг — я могу и 20 скобок поставить, но я ожидал, что if будет работать в соответствии со здравой интуицией. Ну а если не работает, то такие вещи надо указывать отдельно в документации (я нашёл if как замену "?:" на странице отличий от C#)
Здравствуйте, matumba, Вы писали:
M>На деле тут банальная недоработка парсера. Моё выражение однозначно — покажи его 100 прогерам и все 100 скажут, что я имел ввиду.
А, ну, да. Таким образом можно многое доказать. Тем более, что среди 100 "прогеров" точно не найдется достаточного количества людей понимающих в парсерах.
M>И тернарные операторы тут не причём: M>"a ? b : c" — он полностью "открытый", т.е. без скобок его просто невозможно поставить в сложное выражение.
Во как? А про приоритеты и ассоциативность ты слыхал?
Вот тебе пример на C#:
var c1 = true;
var c2 = true;
var x = c1 ? c2 ? "c" : "d" + "a" : "b";
Никаких проблем со сложным использованием.
M>И смотри IF: M>"if (cond) expr1 else expr2" — здесь expr2 может быть "закрыт" от последущих выражений фигурными скобками, которые однозначно выделяют ветку else.
Это ты сам для себя придумал. А если пойти и посмотреть как объявлен if в Nemerle, то станет очевидным, что в его синтаксисе никаких скобок нет:
M>Мне в принципе пофиг — я могу и 20 скобок поставить, но я ожидал, что if будет работать в соответствии со здравой интуицией. Ну а если не работает, то такие вещи надо указывать отдельно в документации (я нашёл if как замену "?:" на странице отличий от C#)
В ЯП поведение выражений определяется приоритетами. С } в немерле есть отдельные проблемы. Но к интуиции тут отсылать не надо. У тебя она одна, у других другая.
C# для тебя достаточно интуитивен? Если, да, то вот твое выражение преобразованное в C#:
var z = "smth" + (1 < 2) ? "<" : ">" + (2 < 3) ? "<" : ">";
^^^^^^^^^^^^^ error CS0029: Cannot implicitly convert type 'string' to 'bool'
и дело тут исключительно в приоритете и ассоциативности.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
А чё же не надо? В некоторых случаях может оказаться очень даже удобно. В твоем, например. Немного не привычно, но вряд ли кто-то не поймет написанного.
Я бы подобные вещи просто разнес на несколько выражений:
def a = if(1 < 2) "<"else">";
def b = if(2 < 3) "<"else">";
def z = "smth$a$b";
Что за задачу решаешь? Может для нее более удобные средства есть.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Что за задачу решаешь? Может для нее более удобные средства есть.
В данном случае это не очень важно, но если интересно — пишу "доставатель схемы БД". Нужно из класса-колонки получить её SQL описание. Соответственно, идёт проверка полей типа IsPK, IsNullable и т.п. и генерируется DDL. В оригинале было так:
Здравствуйте, matumba, Вы писали:
M>Здравствуйте, hardcase, Вы писали:
H>>Операторы обрабатываются правильно (спецификации-то нету хе-хе). На деле тут банальная неоднозначность
M>На деле тут банальная недоработка парсера. Моё выражение однозначно — покажи его 100 прогерам и все 100 скажут, что я имел ввиду.
def z = "smth" + if (1 < 2) "<"else {">"} + if (2 < 3) "<"else {">"};
Здесь ничего не ясно без поллитры. Я сам люблю покритиковать глупости в Немерле. Но тут глупость не в языке, извините.
Здравствуйте, matumba, Вы писали:
M>В данном случае это не очень важно, но если интересно — пишу "доставатель схемы БД". Нужно из класса-колонки получить её SQL описание. Соответственно, идёт проверка полей типа IsPK, IsNullable и т.п. и генерируется DDL. В оригинале было так:
Тогда очень советую посмотреть макрос StringTemplate. Он как раз для таких задач и был создан.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.