Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Baiker, Вы писали:
B>>B>>int Width = 7;// обычная переменная в outer scope
B>>var btn = new Button init B { // внимание! 'B' - это alias для создаваемого объекта (во внешнем scope это btn)
B>> .Width = Width + 50;// Button.Width = Width + 50 = 57
B>> .Invalidate();// такое MS не сделала даже за 20 лет!
B>> .Height = .Width + 1;// очевидно, что справа от = всё тот же контекст - взяли внутреннего мембера .Width
B>> .Children.Add(niceIcon);
B>> .Styles = new HTMLStyle init { // как и просили, вложенный init
B>> .CSS = "color: #" + .Color;// Button.Color взят извне, т.к. HTMLStyle его не содержит
B>> .File = 1;// error! Нет такого мембера ни у HTMLStyle, ни у Button, внешний scope не рассматривается
B>> .Length = B.Length - 7;// ага! Вот где alias нужен. Вот теперь это HTMLStyle.Length = Button(B).Length - 7
B>> };
B>>};
B>>
S>Вот видите — первый же заданный вопрос заставил вас менять синтаксис
И что в этом такого??

Я что, принёс вам готовые спеки что ли?? Глупый наезд на почве личной опупительности. НЕ НАДО на меня наезжать! Я ни вам, ни микрософту ничего не должен.
Изменил синтаксис — значит так надо, значит СТАЛО ЛУЧШЕ. Так или иначе, я предлагаю
улучшать компилятор, а не бодаться с луддитами и "исторически сложилось" факапами.
S> Теперь в init появился опциональный алиас. Причём теперь нужно не забыть его указать, иначе получится бяка.
Разумеется указать! Если он нужен. А на его нужность укажет компилятор в местах с неоднозначностями. В ЧЁМ ПРОБЛЕМА-ТО??

Я не понимаю этого агрессивного противостояния — нужно ПОМОГАТЬ МНЕ решить эту синтаксическую проблему (если она вообще есть), а не выделываться здесь "мы в микрософт все умные, а вы ничего не понимаете!".
S>Двигаемся дальше. Вот у вас в .Styles не было .Color, а вот он появился. Всё, поведение кода поменялось, без малейших подсказок со стороны компилятора. Удачной отладки.
Да, это проблема. Но не такая проблема, чтобы прям осбосраться и отменить фичу! Просто надо чутка подумать и решить, как ОБЯЗАТЕЛЬНО реализовать фичу, но предусмотреть этот сложный случай.
К примеру, сам компилятор проверит, что было использование одного объекта, а после введения члена появился другой. Ни бог весть какая проблема — БЫЛО БЫ ЖЕЛАНИЕ РЕШИТЬ.
S>Коммент про .File — а что, если бы у Button было такое свойство, то всё бы скомпилировалось?
Да. В чём проблема?
S>Двигаемся дальше. В чём у нас семантика этого init?
С самого начала поста объяснил, так сложно доходит?

СОКРАЩЕНИЕ КОДА.
S>1. Определён указанный выше алиас, если он есть
S>2. Разрешены только операторы присваивания и вызовы методов (причём не любых, см далее)
S>3. В аргументах методов и в выражениях операторов присваивания разрешены обращения к свойствам и методам через точку без object expression слева.
Да, всё верно.
S>Для начала нужно убедиться, что у нас нет проблем с п.3. Не будет ли конфликтов при разборе? Я пока вижу один нехороший сценарий: взаимодействие с тернарным оператором и null-checking member access. Выражения типа x > y ? .Inc() похожи и на x > (y?.Inc()), и на (x > y)?.Inc()). А теперь у нас ещё и добавляется прекрасная возможность (x > y) ? (.Inc()), то есть "Syntax error, : expected".
Решается обычным приоритетом операторов! На крайняк, НЕТ такого оператора "?␣." — есть "?.". Пробел значим. В любом случае, ЕСТЬ СКОБКИ и подсветка/подсказка. Навёл курсор на .Inc() — увидел, от кого взят мембер.
S>Способ поиска методов слева от =, справа от =, и просто при записи .Invalidate() будет отличаться?
Нет, он должен быть одинаков (как и ожидает программист, просто СОКРАЩАЯ КОД).
S> Я так понимаю, что для "справа от = " вы хотите, чтобы выполнялся поиск вверх во всех init-блоках, пока не найдется подходящий метод. Будет ли это работать также без =? То есть если я пишу btn init{.Styles init {.Invalidate()}}; — будет ли успешно вызываться btn.Invalidate()?
Разумеется! Я же привёл пример:
B>> .Invalidate();// такое MS не сделала даже за 20 лет!
Здесь нет никакого присвоения, просто ищем подходящий объект.
S>Рассматриваются ли extension-методы?
Тут я ещё не думал, но... почему бы и нет? У компилятора ВСЕГДА есть шанс сказать, когда у него неоднозначность! Скажем, если будет код:
var lst1 = new List<File>() init {
var lst2 = new List<File>() init {
.Sort();// чей сорт?
}
}
...выправляем его так:
var lst1 = new List<File>() init L {
var lst2 = new List<File>() init {
L.Sort();// ага, знаю чей!
}
}
S>Самое интересное тут вот в чём: как будем разруливать перегрузки методов? Вот у нас завелись два похожих метода: Button.Foo(int i), HtmlStyle.Foo(decimal d). Мы наблюдаем такое выражение: btn init{.Styles init {.Length = .Foo(42)}};. Какой из Foo будет вызван?
Согласен, тонкий И РЕДКИЙ случай — выкинем ambiguous. Что сложного-то?? Не надо пытаться сделать больше, чем позволено "тупой машине"! (иначе сделаешь только хуже)
Тут принцип построения фич простой: запиливаем фичу для большинства случаев (предварительно хорошенько рассмотрев все случаи). Если люди дадут фидбэк "вот у нас такой часто используемый код, а он лажает на вашем синтаксисе" — повторяем SDLC и допиливаем как надо (фича всё равно в АЛЬФА ТЕСТЕ!). И так до полной шлифовки.
S>Примерно к любому варианту, который вы выберете, я напишу контрпример, который работает "не так, как интуитивно ожидается".
Да ради бога! Чем больше контр-примеров, тем шире почва для обсуждения (а не отмазок НЕ ДЕЛАТЬ). Факт тот, что фичу МОЖНО и НУЖНО сделать. Я не глубокий спец именно в компиляторах, но я знаю, что если что-то делать — то оно сделается! А если в стиле Хлипперта придумывать "почему мы НЕ ХОТИМ это делать" — то ничего и не будет.
Пока что из обсуждения я не увидел НИ ЕДИНОГО аргумента "эту фичу принципиально нельзя сделать" — ВСЁ ВОЗМОЖНО, но постепенно. А вы сейчас своей ДЕМАГОГИЕЙ пытаетесь грубо говоря "закидать шапками". Так люди НЕ КООПЕРИРУТСЯ! Мыслить надо ДРУЖЕСКИ, а не сидеть как тухлый ёж и совать всем иголки.