1. Поглядел тут предложения МС для C# и в очередной раз порадовался с того как заботливо в МС относятся к запутыванию пользователей.
Назвать записи (record-ы) кортежами (tuple-ами), а алгебраические типы record-ами — это по нашему!
Люди близкие к телу дизайнеров языка, доведите, плиз, до ведома авторов C#, что они делают ерунду. Во всех языках то что они назвали record называется как угодно, но не record. В ML (где они и родились) — tagged union. В Немерле — это variant-ы. В Скале — это case classes. В F# — discriminated unions.
Причем в F#, ML и Scala есть и record, но означают они совсем другое.
Зато то что в C# решено назвать кортежами (tuple) во всех перечисленных выше языках называется record-ами.
2. Хочется заметить, что ключевое слово record (да и любое другое) в C#-ных аналогах вариантов вообще не нужно. Стинаксически они отлично отличимы по круглым скобками "первичного конструктора".
3. Кортежи C# (которые, как мы выяснили, являются по сути записями) дублируют функциональность анонимных типов. Будет довольно криво иметь в язык две похожих вещи. Я бы на месте авторов языка просто доработал напильником анонимные типы сделав из них полноценные записи (в человеческом смысле этого слова).
Что нужно сделать на мой взгляд:
1. Доработать синтаксис описания типов для анонимного типа. Например подойдет вариант { int a, string b }.
2. Допилить рантайм донтета так чтобы он поддерживал структурные типы, т.е. ввести типы считающиеся эквивалентными при совпадении всех их полей. В таких типах должно быть ничего кроме полей. Ну, разве что допустить автосвойства. Никакого кода быть не должно потому, что его очень сложно сравнивать структурно. Да и не нужен в них код. Рантайм должен незаметно для всех подменять тип из всех сборок на тип из одной из них или как-то еще обеспечить полную совместимость между ними.
4. Имеет смысл реализовать в языке и обычные котежи (с неименованными полями). Это должен быть обычный сахар над имеющимися типами System.Tuple<...>. Этот пункт не обязательный, но разумный и желательный. Все полноценные ФЯ поддерживают котежи.
Поддержка будет отлично сочетаться с добавлением паттерн-матчинга, так как кортежи в нем являются довольно важной составляющей (один из видов паттеров — это по сути и есть кортеж).
5. Предлагаю добавить дженерики с переменным числом параметров, по анологии с C++ поледних версий. Это уже мое личное пожелание выходящее за рамки того что обсуждается на гитхабе, но эта фича была бы очень и очень полезной (если ее удалось бы реализовать). Причем реализовывать ее нужно, в первую очередь, опять же в рантайме дотнета, так как дженерики — это рантайм-сущость.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Назвать записи (record-ы) кортежами (tuple-ами), а алгебраические типы record-ами — это по нашему!
А они сами до конца не определились с терминологией. Это не больше, чем предварительные наброски, которые относительно легко поменять.
Оно так и с шестым шарпом было, и с await в пятом. Кучу раз спецификацию и синтаксис меняли.
VD>Люди близкие к телу дизайнеров языка, доведите, плиз, до ведома авторов C#, что они делают ерунду. Во всех языках то что они назвали record называется как угодно, но не record. В ML (где они и родились) — tagged union. В Немерле — это variant-ы. В Скале — это case classes. В F# — discriminated unions.
Название фиговое конечно. Но не в названии проблема, там всё хуже: пока нет согласованного набора фич, которые в record надо впихнуть.
По уму рекорды надо пилить одновременно с primary ctor, PM, тюплами, операторами для PM и синтаксическим сахаром для immutable types. Ну и наконец разобраться с тюплами — они всё-таки нужны, или проще будет рекорды до ума довести. Если отказываться — надо возвращать declaration expressions.
Короче, пока до конца не понятно, во что рекорды в итоге превратятся, а ты уже им название требуешь придумать
И да, довести очень легко — в issues на гитхабе они активно общаются и отвечают.
VD> В F# — discriminated unions.
???
Мы точно про одно и то же говорим? record в шарпе — это просто сахар для immutable-типа, боль-менее актуальная спецификация тут. Или я отстал от жизни и они опять всё поменяли?
VD>2. Хочется заметить, что ключевое слово record (да и любое другое) в C#-ных аналогах вариантов вообще не нужно. Стинаксически они отлично отличимы по круглым скобками "первичного конструктора".
Не, record — это primary ctor + immutable + is_operator + equality operators. Всё вышеперечисленное можно и по отдельности использовать, так что отдельное ключевое слово нужно. Месяц назад обсуждалось, если надо — могу ссылку найти.
VD>3. Кортежи C# (которые, как мы выяснили, являются по сути записями) дублируют функциональность анонимных типов. Будет довольно криво иметь в язык две похожих вещи.
+ 100500 Только не две, а три. Рекорды в ту же степь на сегодня.
VD>2. Допилить рантайм донтета так чтобы он поддерживал структурные типы, т.е. ввести типы считающиеся эквивалентными при совпадении всех их полей.
Там куда больше надо сделать. Причём как я понял из очень обтекаемых комментариев, на CLR team надежды на этот и следующий релизы нет от слова совсем. То ли ресурсов у них нет, то ли совместимость превыше всего. Буду рад, если ошибаюсь, но пока так.
Кстати, что-то похожее есть уже, но только в K runtime и только для интерфейсов. Причём их по слухам (совсем слухам, без подтверждений) выпиливают.
VD>4. Имеет смысл реализовать в языке и обычные котежи (с неименованными полями). Это должен быть обычный сахар над имеющимися типами System.Tuple<...>. Этот пункт не обязательный, но разумный и желательный. Все полноценные ФЯ поддерживают котежи.
А они точно нужны, при наличии нормальных рекордов и сахара для разбора рекорда на отдельные переменные? Выставлять кортежи в public api... не нравится мне эта идея.
VD>5. Предлагаю добавить дженерики с переменным числом параметров, по анологии с C++ поледних версий.
А вот это принципе интересная мысль, но я пока не могу придумать ни одного разумного сценария использования. Можешь привести пример?
Здравствуйте, Sinix, Вы писали:
S>А вот это принципе интересная мысль, но я пока не могу придумать ни одного разумного сценария использования. Можешь привести пример?
Здравствуйте, hardcase, Вы писали:
S>>А вот это принципе интересная мысль, но я пока не могу придумать ни одного разумного сценария использования. Можешь привести пример? H>System.Tuple
Не, это уже к compile-time code generation. Ну, или к макросам/шаблонам c++.
Иначе толку от произвольного числа типов-аргументов нет. Ну объявишь их — дальше как использовать?
Здравствуйте, Sinix, Вы писали:
S>А они сами до конца не определились с терминологией. Это не больше, чем предварительные наброски, которые относительно легко поменять. S>Оно так и с шестым шарпом было, и с await в пятом. Кучу раз спецификацию и синтаксис меняли.
Ну, вот и надо до их ведома довести, что у них смешно получается.
S>По уму рекорды надо пилить одновременно с primary ctor, PM, тюплами, операторами для PM и синтаксическим сахаром для immutable types.
Дык, то что они все это в один релиз впихнули, как бэ, намекает на общность фич.
Я тебе больше скажу кортежи, записи и варианты (будем использовать немерловую терминологию) — это все алгебраические типы и для них есть общая теория на которой и созданы оные типы во всех озвученных мною языках. Так что делать их нужно вместо и по единым стандартам.
Далее, фичи вроде декомпозиции кортежей, оператора is, объявление переменных в кондишене if-а и т.п. — это все вариации на тему паттерн-матчинга. И он опять же тесно завязан на алгебраические типы.
S>Ну и наконец разобраться с тюплами — они всё-таки нужны, или проще будет рекорды до ума довести.
Они уже есть, только без синтаксиса. Сделать для них синтаксис не составит труда. В других языках они не мешают. Так что мое мнение — однозначно делать. Кроме того кортежи отлично подходят для описания сигнатур функций (в которых не важны имена). Любая функция может быть выражена в виде двух кортежей (синтаксис Немерла):
int * int -> bool * int
S>Если отказываться — надо возвращать declaration expressions.
Это что? Возможность вернуть значение из блока кода? Если — да, то это, как раз, фича совершенно независимая и очень нужная (особенно при генерации кода).
В Немерле она выглядит очень просто и элегантно. Любой блок может вернуть значение:
{ def a = 42; a * 2 }
Я бы и в Шарпе сделал так же. За одно исчезла бы необходимость в return-е во многих местах и не нужно было бы делать отдельных правил для лямбд с телами и без.
S>Короче, пока до конца не понятно, во что рекорды в итоге превратятся, а ты уже им название требуешь придумать
Совершенно понятно что они хотят сделать. Лично у меня это вопросов не вызвало. А вот то как они хотя это делать и как они это называют — это угар и стыд.
S>И да, довести очень легко — в issues на гитхабе они активно общаются и отвечают.
Там 100500 "знатоков" и "дезигнеров". Отсюда до них это скорее дойдет.
Ну, и в лом мне много по английски писать, а у них там русскоязычных хватает.
VD>> В F# — discriminated unions. S>??? S>Мы точно про одно и то же говорим?
Точно. Просто тебе нужно ознакомиться с теорией.
S>record в шарпе — это просто сахар для immutable-типа, боль-менее актуальная спецификация тут. Или я отстал от жизни и они опять всё поменяли?
immutab-ильность — это вопрос вторичный. Он возникает из свойств алгебраических типов (они используются как значения и их изменение приведет к странным эффектам).
Как я понимаю они ввели ключевое слово record для классов с первичным (primary) конструктором. У таких классов есть одна незаметное, на первый взгляд, особенность. Этот самый первичный конструктор проводит соответствие между параметрами этого самого конструктора и полями/свойствами класса. Это дает возможность выражать объект такого типа в виде конструктора. А это, в свою очередь, позволяет производить композицию (создание) и декомпозицию объектов с помощью паттерн-матчинга.
Это же свойство характерно для рекордов (классических, а не по МС), а так же для кортежей (опять же классических).
S>Не, record — это primary ctor + immutable + is_operator + equality operators.
is_operator + equality operators проистекают из наличия того самого первичного конструктора. Именно он описывает структуру. Тогда уж было бы логично вместо этого record использовать имеющееся ключевое слово readonly.
Довольно глупо не позволять использовать паттерн конструктор для типов у которых есть первичный конструктор, но не указано какое-то левое ключевое слово.
Если они рассматривают record именно так как говоришь ты, то это еще одна глупость.
S>Всё вышеперечисленное можно и по отдельности использовать, так что отдельное ключевое слово нужно. Месяц назад обсуждалось, если надо — могу ссылку найти.
Что это?
Как использовать отдельно immutable для всех полей типа?
Как использовать отдельно генерацию оператора is?
Как использовать отдельно автоматическое создание equality-операторов?
S>Только не две, а три. Рекорды в ту же степь на сегодня.
Не. Их "рекорды" — это аналоги case-классов скалы или вхождений вариантов немерла. Тут ты заблуждавшийся.
VD>>2. Допилить рантайм донтета так чтобы он поддерживал структурные типы, т.е. ввести типы считающиеся эквивалентными при совпадении всех их полей. S>Там куда больше надо сделать.
Ничего там большего делать не надо. Это все отбрехи.
S>Причём как я понял из очень обтекаемых комментариев, на CLR team надежды на этот и следующий релизы нет от слова совсем. То ли ресурсов у них нет, то ли совместимость превыше всего.
Эти уроды уже своими отмазками достали. Что они там вообще делают? На хрен выпускать тучу почти одинаковых ратаймов и посылать на хрент реализацию реально нужных фич? Не фига было декларировать платформу для разных языков, раз у них не хватает таланта и усидчивости для воспроизведения нужных для них фич. Мы не делаем поддержки рекородов (в классическом понимании) именно из-за отсутствия поддержки со стороны рантайма. Не хочется все костылями окружать.
S>Буду рад, если ошибаюсь, но пока так.
Я тоже.
S>Кстати, что-то похожее есть уже, но только в K runtime и только для интерфейсов. Причём их по слухам (совсем слухам, без подтверждений) выпиливают.
Это фигня для поддержки COM-а делалась. Она тут не подходит по указанным тобой причинам. Плюс это все левый хаки, а нужна нормальная поддержка структурных типов в дотнете. Тогда и Тайп Скрипт можно будет реализовать на базе дотнета.
Зато наличие этой фичи показывает, что когда начальство прикажет они могут сделать все.
А слова про том что "много чего..." — это отбрех. У них 10 лет было и они за эти 10 лет почти ничего не сделали. Если сравнить рантайм от дотнета 2.0 и от 4.5.1, то выясняется, что каких-то серьезных изменений между ними нет. Что они делали эти 10 лет?
S>А они точно нужны, при наличии нормальных рекордов и сахара для разбора рекорда на отдельные переменные? Выставлять кортежи в public api... не нравится мне эта идея.
Я уже говорил. Они уже есть. Нужно только синтаксис добавить. Причем для реализации не нужно менять фреймворк.
VD>>5. Предлагаю добавить дженерики с переменным числом параметров, по анологии с C++ поледних версий. S>А вот это принципе интересная мысль, но я пока не могу придумать ни одного разумного сценария использования. Можешь привести пример?
а рантайм уже создает конкретные специализации по необходимости.
ЗЫ
Ну, и до кучи надо ввести замену этому убогому delegate — функциональный тип. Это что-то вроде delegate, но без объявления и совместимы структурно. Тогда все эти убогие Actrion и Func вообще становятся ненужны, так как ссылку на функцию можно описать по месту (синтаксис немерла):
Foo(action : int * string -> void, func : int -> string);
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
S>> Кучу раз спецификацию и синтаксис меняли. VD>Ну, вот и надо до их ведома довести, что у них смешно получается.
Так c# 7 на сегодня не то что не альфа, только-только начинается отбор фич. Кто просил опенсорса и открытого процесса разработки — получайте
Или надо опять закрыть всё нафиг и выкатывать только прилизанные CTP?
S>>По уму рекорды надо пилить одновременно с primary ctor, PM, тюплами... VD>Дык, то что они все это в один релиз впихнули, как бэ, намекает на общность фич.
Это понятно. Но на сегодня каждая из фич обсуждается по отдельности, общей спецификации нет. Будем надеяться, объединят.
VD>... Так что делать их нужно вместо и по единым стандартам. VD>Далее, фичи вроде декомпозиции кортежей, оператора is, объявление переменных в кондишене if-а и т.п. — это все вариации на тему паттерн-матчинга.
Вот тут согласен целиком и полностью В таком изложении предложение очень разумно смотрится. Почти со всем остальным тож соглачен, поскипал, чтобы не плодить лишние цитаты
S>>Если отказываться — надо возвращать declaration expressions. VD>Это что? Возможность вернуть значение из блока кода?
Не, это
if (dict.TryGetValue(key, out var value)
{
// do smth with value
}
Мелочь, но в куче мест сводит необходимость тюплов к нулю.
VD>Там 100500 "знатоков" и "дезигнеров". Отсюда до них это скорее дойдет. VD>Ну, и в лом мне много по английски писать, а у них там русскоязычных хватает.
Так ты не с знатоками общайся, а с design team. Они вот тут перечислены.
VD>>> В F# — discriminated unions. S>>Мы точно про одно и то же говорим? VD>Точно. Просто тебе нужно ознакомиться с теорией.
С теорией всё более-менее ок. А вот ничего близкого к
type switchstate =
| On
| Off
| Adjustable of float
в шарпе на сегодня нет. Конечно, можно выразить ч/з наследование, но это всё-таки слегка не то.
VD>Как я понимаю они ввели ключевое слово record для классов с первичным (primary) конструктором. ... Это дает возможность выражать объект такого типа в виде конструктора. А это, в свою очередь, позволяет производить композицию (создание) и декомпозицию объектов с помощью паттерн-матчинга.
Ну да. Но нbкто не запрещает сделать тип с primary ctor но без is operator. Или использовать PM на любом типе дотнета. Эти фичи ортогональны. record просто позволяет получить типовую реализацию без лишнего кода.
VD>is_operator + equality operators проистекают из наличия того самого первичного конструктора.
Ну блин, это opt-in возможности. Можно добавлять, можно не добавлять. Без модификатора record такое поведение красиво не сделать.
S>>Только не две, а три. Рекорды в ту же степь на сегодня. VD>Не. Их "рекорды" — это аналоги case-классов скалы или вхождений вариантов немерла. Тут ты заблуждавшийся.
Что-то я не заметил. Как насчёт чего-нить вот такого
type switchstate =
| On
| Off
| Adjustable of float
на шарпе? Со всеми прелестями discriminated unions типа контроля со стороны компилятора "проверили все варианты".
Нету этого на сегодня. По крайней мере в публичных источниках.
S>>Причём как я понял из очень обтекаемых комментариев, на CLR team надежды на этот и следующий релизы нет от слова совсем. То ли ресурсов у них нет, то ли совместимость превыше всего. VD>Эти уроды уже своими отмазками достали. Что они там вообще делают?
Авральными темпами пилят поддержку всего, от дотнета в docker-контейнерах и до интеропа с android и objective-c кодом. Ага, обе платформы поддерживаются в win 10, на build пару часов назад сознались всё-таки. Занятые они, короче.
VD>Самые простые применения — это вместо 100500 Actrion<>, Func<> и Tuple<> заводит по одному типу: VD>а рантайм уже создает конкретные специализации по необходимости.
Ну а как equals и хэшкод для таких типов определять? Это надо или нормальные макросы впихивать, или не страдать фигнёй и один раз в жизни сгенерить однотипный код. Т.е. или макросы, или кодогенерацию в compile-time.
VD>Ну, и до кучи надо ввести замену этому убогому delegate — функциональный тип.
В другой жизни разве что. Слишком многое завязано.
S>if (dict.TryGetValue(key, out var value)
S>{
S> // do smth with value
S>}
S>
S>Мелочь, но в куче мест сводит необходимость тюплов к нулю.
Вот в F# методы out-параметрами интерпретируются как возвращающие кортеж. Если представить такую фичу в C#, то можно было бы писать следующим образом:
if ((true, var value) = dict.TryGetValue(key))
{
// do smth with value
}
а лучше:
if (var (true, value) = dict.TryGetValue(key))
{
// do smth with value
}
так как пихать var в каждую переменную в кортеже не очень разумно.
S>Так ты не с знатоками общайся, а с design team. Они вот тут перечислены.
Они меня среди "знатоков" просто не заметят. В общем, проверено. Это то место откуда информация доходит до кого надо .
S>С теорией всё более-менее ок. А вот ничего близкого к S>
S>type switchstate =
S> | On
S> | Off
S> | Adjustable of float
S>
S>в шарпе на сегодня нет. Конечно, можно выразить ч/з наследование, но это всё-таки слегка не то.
То, то. F#, просто еще несколько старомоден (унаследовал много от ML и далек от ОО-мира).
В Немерле это выглядит так:
variant SwitchState
{
| On
| Off
| Adjustable { Value : float; }
}
И переписывается в:
[Variant("SwitchState.On,SwitchState.Off,SwitchState.Adjustable")]
internal abstract class SwitchState
{
[ConstantVariantOption]
public class On : SwitchState
{
public static readonly SwitchState.On _N_constant_object;
public static SwitchState.On _N_constant_object_generator()
{
return SwitchState.On._N_constant_object;
}
static On()
{
SwitchState.On._N_constant_object = new SwitchState.On();
}
public override int _N_GetVariantCode()
{
return 0;
}
[RecordCtor]
private On()
{
}
}
[ConstantVariantOption]
public class Off : SwitchState
{
public static readonly SwitchState.Off _N_constant_object;
public static SwitchState.Off _N_constant_object_generator()
{
return SwitchState.Off._N_constant_object;
}
static Off()
{
SwitchState.Off._N_constant_object = new SwitchState.Off();
}
public override int _N_GetVariantCode()
{
return 1;
}
[RecordCtor]
private Off()
{
}
}
[VariantOption]
public class Adjustable : SwitchState
{
public readonly float Value;
public override int _N_GetVariantCode()
{
return 2;
}
[RecordCtor]
public Adjustable([MappedMember("Value")] float value)
{
this.Value = value;
}
}
public abstract override int _N_GetVariantCode();
public static int _N_GetVariantCodeSafe(SwitchState x)
{
return ((object)x != null) ? x._N_GetVariantCode() : -1;
}
public static int _N_GetVariantCodeObject(object x)
{
int arg_1E_0;
if (x is SwitchState)
{
SwitchState switchState = (SwitchState)x;
arg_1E_0 = switchState._N_GetVariantCode();
}
else
{
arg_1E_0 = -1;
}
return arg_1E_0;
}
}
Если абстрагироваться от оптимизаций, то это чистое наследование.
В Скале так вообще сделано так же как в шарпе планируется.
S>Ну да. Но нbкто не запрещает сделать тип с primary ctor но без is operator.
1. Зачем это нужно?
2. Я вообще не вижу смысла в этом операторе is. Точнее то не плохая фича для расширяемости ПМ, но по умолчанию ПМ должен работать и без наличия этого метода. В Немерле информация о связи между полями и параметрами конструктора записывается в атрибут Variant (видно в примере декомпилята).
S>Или использовать PM на любом типе дотнета. Эти фичи ортогональны. record просто позволяет получить типовую реализацию без лишнего кода.
Рекорд просто лишний. Очередная ошибка дизайна, на мой взгляд.
S>Ну блин, это opt-in возможности. Можно добавлять, можно не добавлять. Без модификатора record такое поведение красиво не сделать.
Возможности которые всегда полезны можно добавлять по умолчанию не думая. Если кому-то нужно вручную что-то реализовать, то они могут переопределить нужные методы врунчую.
Тебя ведь не смущает, что для объектов по молчанию работает GetHashCode и т.п.?
А для ПМ не нужно ничего из перечисленного выше. Только первичный конструктор. Да и тот, если хочется пользоваться более лаконичным паттерном конструктор. А для матчинга по свойствам/полям и сойдет любой класс.
S>Что-то я не заметил. Как насчёт чего-нить вот такого S>
S>type switchstate =
S> | On
S> | Off
S> | Adjustable of float
S>
S>на шарпе? Со всеми прелестями discriminated unions типа контроля со стороны компилятора "проверили все варианты".
См. выше. А для контроля полноты нужно иметь возможность предотвратить создание наследников. В Скале это называется sealed, но смысл отличается от шарповского.
sealed abstractclass LogMessage
case class StringMessage(message:String) extends LogMessage
case class ExceptionMessage(exception:Throwable) extends LogMessage
case class BothMessage(message:String, exception:Throwable) extends LogMessage
class Logger {
def debug(l:LogMessage) = log(10,l)
def info(l:LogMessage) = log(5,l)
def error(l:LogMessage) = log(1,l)
def log(level:Int, l:LogMessage):Unit = l match {
case StringMessage(msg) => println(msg)
case ExceptionMessage(exception:Error) => exception.printStackTrace
case ExceptionMessage(ex) => println(ex.toString)
}
}
S>Нету этого на сегодня. По крайней мере в публичных источниках.
Сегодня ничего нет. Мы же говорим о C# 7. Смотри на Немерл. Его в C# 5 пророчили многие, но он, похоже, C# и в десятой версии всех фичь не реализует.
S>Авральными темпами пилят поддержку всего, от дотнета в docker-контейнерах и до интеропа с android и objective-c кодом. Ага, обе платформы поддерживаются в win 10, на build пару часов назад сознались всё-таки. Занятые они, короче.
Ну, да. 10 лет это ведь так мало для МС.
S>Ну а как equals и хэшкод для таких типов определять? Это надо или нормальные макросы впихивать, или не страдать фигнёй и один раз в жизни сгенерить однотипный код. Т.е. или макросы, или кодогенерацию в compile-time.
Посмотри примеры на С++. Там конечно многе на метапрограммирование завязано, но кое-что можно и более простыми темпами.
Ну, и вы говорите об МП, как о чем-то плохом (ц)
МП — это очень даже хорошо. Когда-нибудь они и до этого дорастут. Но это уже будет C# 10, наверно.
VD>>Ну, и до кучи надо ввести замену этому убогому delegate — функциональный тип. S>В другой жизни разве что. Слишком многое завязано.
Это можно даже не меняя рантйм сделать. В Nemerle и F# такие типы есть.
Ну, да. У МС процесс озревания идет десятилетиями. Когда-нибудь и до этого дозреют. А жаль, так как такие типы нужны именно в рантайме, а не в отдельных языках.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, VladD2, Вы писали:
S>Авральными темпами пилят поддержку всего, от дотнета в docker-контейнерах и до интеропа с android и objective-c кодом. Ага, обе платформы поддерживаются в win 10, на build пару часов назад сознались всё-таки. Занятые они, короче.
Хорошо бы это все в постоянно виснущем моно увидеть. 2015 год на дворе а нужных вещей нет типа http://www.monodebugger.net/. Нет дампа стеков всех потоков (clrmd не пашет на моно). Есть дебаггеры но клиентам их не засунуть. Очень бы хотелось увидеть AOP (думал вместе с рослином сделают удобные атрибуты по перепахиванию кода в compile time без глубокого бурения с постшарпом но увы) для логов\синхронизаций\исключений. Так и не допилены многие async фичи типа поддержки в конструкторах\dispose-using\циклах\linq, более плотной интеграции с Rx. До сих пор Console.ReadLineAsync неблочащегося нет... Имхо товарищи с новыми фичами торопятся. Pattern matching с immutable подождет (так и не понимаю зачем оно нужно). Ну про свои предложения молчу
VD>Они меня среди "знатоков" просто не заметят. В общем, проверено. Это то место откуда информация доходит до кого надо .
Ну... ок. У меня опыт противоположный, пара предложений в принципе прошла. Но у меня задача попроще была, я не пытался им доказать, что они делают не то, так что спорить не буду
VD>То, то. F#, просто еще несколько старомоден (унаследовал много от ML и далек от ОО-мира). VD>В Немерле это выглядит так:
Так мы не про N и F# говорим. Проблема не в них, проблема в шарпе — нету там ничего похожего и планов не озвучено. По крайней мере пока.
VD>Если абстрагироваться от оптимизаций, то это чистое наследование.
Под капотом — да, а вот атрибут Variant и по хорошему валидацию от CLR надо бы добавить
S>>Ну да. Но нbкто не запрещает сделать тип с primary ctor но без is operator. VD>1. Зачем это нужно?
Коллекции, dto-классы и тд и тп. В общем берём любой mutable-тип, если хотим к нему primary ctor — это оно.
VD>2. Я вообще не вижу смысла в этом операторе is. Точнее то не плохая фича для расширяемости ПМ, но по умолчанию ПМ должен работать и без наличия этого метода.
Так и будет. Но вот это
if (point is (var x, var y)) // синтаксис по памяти пишу. По-моему, он не так выглядит.
{
// do smth with x & y
}
без is operator работать не будет.
VD>В Немерле информация о связи между полями и параметрами конструктора записывается в атрибут Variant (видно в примере декомпилята).
Ну а если Point внутри хранит x и y одним long-ом? Один фиг кастомный оператор нужен.
VD>Рекорд просто лишний. Очередная ошибка дизайна, на мой взгляд.
Ну, дождёмся финального дизайна — тогда и посмотрим. Как показывает опыт, если фишка не проходит по планке качества, её не стесняются выкинуть.
S>>Ну блин, это opt-in возможности. Можно добавлять, можно не добавлять. Без модификатора record такое поведение красиво не сделать. VD>Возможности которые всегда полезны можно добавлять по умолчанию не думая. Если кому-то нужно вручную что-то реализовать, то они могут переопределить нужные методы врунчую.
Ну а если нам нужен primary ctor, всё остальное не надо?
opt-out вообще не катит для языка, которому надо оставаться совместимым с кодом пятнадцатилетней давности. Иначе ещё через 10 лет получится тут opt-in, тут opt-out а тут рыбу заворачивали.
Даже для куда более полезных not null references режим not null по умолчанию добавлять не будут. Только opt-in, только хардкор.
VD>Сегодня ничего нет. Мы же говорим о C# 7. Смотри на Немерл. Его в C# 5 пророчили многие, но он, похоже, C# и в десятой версии всех фичь не реализует.
Ну так шарп и не немерл. Разные языки, разные ключевые сценарии. А если посмотреть на остальных мейнстримщиков — шарп так вообще цветёт и пахнет
VD>МП — это очень даже хорошо. Когда-нибудь они и до этого дорастут. Но это уже будет C# 10, наверно.
В виде макросов — не верю. Как я понимаю, ядро N2 на сегодня — это Nitra, так? И сама нитра превратилась в генератор dsl на стероидах. Не будут такую мегафишку протаскивать в язык, в котором от рождения макросов не было. Если не хватает шарпа лучше уж взять готовый язык и не мучаться.
А вот compile-time метагенерация скорее всего будет. Или в c#7 или в c#8.
Disclaimer: никакого инсайда, всё из публичных источников, так что может поменяться 100500 раз.
A>Хорошо бы это все в постоянно виснущем моно увидеть.
То, что в опенсорс ушло — перетаскивают. Оно не столько для mono надо, сколько для xamarin, те своих $999/year не упустят. Прицепом и в mono перейдёт.
A>2015 год на дворе а нужных вещей нет типа http://www.monodebugger.net/. Нет дампа стеков всех потоков (clrmd не пашет на моно). Есть дебаггеры но клиентам их не засунуть.
Тут не в курсе
A>Очень бы хотелось увидеть AOP
Предложение такое у них есть, но когда оно будет — неизвестно.
A>Так и не допилены многие async фичи типа поддержки в конструкторах\dispose-using\циклах\linq, более плотной интеграции с Rx.
using скорее всего будет, конструктора с await точно не будет, соотношение затраты/польза фиговое. Тем более что есть factory methods, незачем их переизобретать.
Поддержки await для rx/linq — тож пока нет. Не потому что не будет, просто никто proposal не накатал.
Здравствуйте, Sinix, Вы писали:
S>В виде макросов — не верю. Как я понимаю, ядро N2 на сегодня — это Nitra, так? И сама нитра превратилась в генератор dsl на стероидах. Не будут такую мегафишку протаскивать в язык, в котором от рождения макросов не было. Если не хватает шарпа лучше уж взять готовый язык и не мучаться.
S>А вот compile-time метагенерация скорее всего будет. Или в c#7 или в c#8.
Макросы и есть компайл-тайм генерация. Как только она появится — начнут думать в сторону ее упрощения. В итоге как раз в районе v9 появятся макроатрибуты, а в v10 квазицитирование. До расширения синтаксиса C# может и не дожить, но сами макросы и квазицитирование скорее всего успеет попробовать. Темпы развития радуют и вектор у него немерловый.
Здравствуйте, Ziaw, Вы писали:
S>>А вот compile-time метагенерация скорее всего будет. Или в c#7 или в c#8. Z>Макросы и есть компайл-тайм генерация. Как только она появится — начнут думать в сторону ее упрощения.
Тут слегка о другом речь, метапрограммирование на атрибутах и макросы/квазицитирование — это всё-таки разные штуки и покрывают они разный набор задач. Разница — как между AOP и DSL, лучше их обсуждать по отдельности.
С compile-time-реврайтерами никаких принципиальных проблем нет. Более того, с первых версий студии реврайтеры используются для кучи вещей — от кодогенераторов для настроек/ресурсов и до code contracts (начиная с vs 2010 конечно). Речь только о том, чтобы добавить публичное и поддерживаемое API для этой радости, что в принципе тож несложно. Для roslyn code fix нечто подобное уже сделано.
С _примититивным_ квазицитированием (только для избавления от генерации AST вручную) особых проблем тож нет,
var stubCode = SyntaxFactory.ParseExpression(@$"
public {typeName} {propertyName}
{
get { return {fieldName}; }
set
{
{fieldName} = value;
OnPropertyChanged(""{propertyName}"");
}
}")
— и вперёд
Конечно, назвать это полноценными макросами уровня N — сова лопнет, но для AOP-кодогенерации и этого за глаза достаточно.
А вот внедрять поддержку расширений синтаксиса аля всё тот же N — ну не лезет оно никак в шарп Другой язык получится. Точнее, тот же немерль, вид сбоку. Да и нафиг не нужно, по большому счёту.
Дисклаймер: разумеется, будут частные случаи, но как всегда, специализированный язык тут будет выигрывать с большим отрывом.
>До расширения синтаксиса C# может и не дожить, но сами макросы и квазицитирование скорее всего успеет попробовать. Темпы развития радуют и вектор у него немерловый.
Вектор не немерловый, ибо сценарии разные.
Вообще, это лучше не мне, а девелоперам шарпа высказывать. Я это уже сделал, есть желание поправить — присоединяйтесь.
Здравствуйте, Sinix, Вы писали:
S>Тут слегка о другом речь, метапрограммирование на атрибутах и макросы/квазицитирование — это всё-таки разные штуки и покрывают они разный набор задач. Разница — как между AOP и DSL, лучше их обсуждать по отдельности.
Это только так кажется. Макрос в данном случае это код, который генерирует другой код. Как только люди начнут генерировать код в заметных объемах, сразу поймут, что без квазицитат это делать не так приятно. А какой это будет код, AOP или транслятор DSL — уже не важно, для начала нужен сам инструмент.
S>С compile-time-реврайтерами никаких принципиальных проблем нет. Более того, с первых версий студии реврайтеры используются для кучи вещей — от кодогенераторов для настроек/ресурсов и до code contracts (начиная с vs 2010 конечно). Речь только о том, чтобы добавить публичное и поддерживаемое API для этой радости, что в принципе тож несложно. Для roslyn code fix нечто подобное уже сделано.
Ну да, эволюция идет. Я согласен, что все несложно и все будет. Просто не быстро.
S>С _примититивным_ квазицитированием (только для избавления от генерации AST вручную) особых проблем тож нет,
Генерация еще пол-беды. Вот когда люди помучаются с анализом AST без матчинга по квазицитатам, тогда станет понятно, что квазицитаты это офигеннейшая штука. Сейчас просто никто не понимает зачем она нужна, потому, что эти задачи люди перед собой сейчас не ставят. Это все уже было, с дженериками, лямбдами, варами, асинками, методами расширения и т.д. Аппетит приходил во время еды. Попытки обсуждать нужность фич до еды порождали гигантские и бесплодные холивары.
S>А вот внедрять поддержку расширений синтаксиса аля всё тот же N — ну не лезет оно никак в шарп Другой язык получится. Точнее, тот же немерль, вид сбоку. Да и нафиг не нужно, по большому счёту. S>Дисклаймер: разумеется, будут частные случаи, но как всегда, специализированный язык тут будет выигрывать с большим отрывом.
Да, про поддержку расширений синтаксиса я согласен, у шарпа есть шансы банально не дожить с такой скоростью.
S>Вектор не немерловый, ибо сценарии разные.
Давай его назовем параллельным вектором, он и правда не немерловый, но направлен практически идентично.
Здравствуйте, Ziaw, Вы писали:
S>>Тут слегка о другом речь, метапрограммирование на атрибутах и макросы/квазицитирование — это всё-таки разные штуки и покрывают они разный набор задач. Разница — как между AOP и DSL, лучше их обсуждать по отдельности.
Z>Это только так кажется. Макрос в данном случае это код, который генерирует другой код. Как только люди начнут генерировать код в заметных объемах, сразу поймут, что без квазицитат это делать не так приятно. А какой это будет код, AOP или транслятор DSL — уже не важно, для начала нужен сам инструмент.
Ну блин, если постараться, то всё можно натянуть на один знаменатель, но это спор ради спора получается
Смотри сам: сила макросов (тут мы говорим о нормальных макросах уровня N или хотя бы c++ templates) — в навороченности. Минимально заменяемая единица — лексема, макросы можно комбинировать, переиспользовать, они могут расширять язык произвольным образом и в пределе — вообще превратить язык в человекочитаемый dsl.
Напротив, AOP на атрибутах — дубовая, простая и надёжная вещь. Минимальная область для реврайтера — член типа (поле/метод/свойство и тд). Т.е. сразу отпадает куча нюансов типа корректного раскрытия макроса, порядка применения, возни с синтаксическими конструкциями и тд и тп. Т.е. чисто функционально AOP на атрибутах беднее. Но для тех задач, где используется AOP это абсолютно неважно.
Цель aop — бороться с кодом, который слишком туп, чтобы его стоило писать вручную. Примеры — от списка полей для бэкенда формы и до реализации INotifyPropertyChanged. Короче, это compile-time замена сниппетам студии и действиям решарпера. Ну не нужны тут расширение синтаксиса, лёгкость описания макросов из самого языка, возможность сделать свой for, etc.
Зато за счёт этой простоты мы получаем применение макросов в реалтайме (для рослина с его «живым» редактором это важно), отсутствие проблем с версионностью (вплоть до у каждой сборки — свои реврайтеры), никаких вирусных макросов (когда клиентский код тоже вынужден использовать макросы) и идеальный порог вхождения — он достаточно высок, чтобы отсеять новичков и достаточно низок, чтобы не отпугнуть экспериментаторов.
В общем разница как между дубовым switch и полноценным паттерн-матчингом. Сценарии использования разные
S>>С _примититивным_ квазицитированием (только для избавления от генерации AST вручную) особых проблем тож нет, Z>Генерация еще пол-беды. Вот когда люди помучаются с анализом AST без матчинга по квазицитатам, тогда станет понятно, что квазицитаты это офигеннейшая штука.
+ 100500. Одно но: для aop за глаза хватает того квазицитирования для бедных, что есть в рослине. Потому что там не требуется изменять произвольное AST, просто заменить пустышки готовой реализацией. Ну а если нужно что-то серьёзно большее, то надо смотреть на языки, в которых макросы есть с самого начала, а не вкорячены к (допустим) девятой версии
S>>Вектор не немерловый, ибо сценарии разные. Z>Давай его назовем параллельным вектором, он и правда не немерловый, но направлен практически идентично.
По-моему нет. Немерль вместе с нитрой сейчас всё больше напоминает эдакий всемогутор для генерации dsl. Т.е. в принципе возможно всё, ошибся в дизайне — твой косяк.
C#, напротив, очень прагматичный язык, иногда даже чересчур. Куча вещей была выброшена из реализации только потому, что эти фичи можно использовать неправильно или они не проходят по соотношению затраты-выигрыш. За примерами ходить далеко не надо, смотрим на шестой шарп и вздыхаем по primary ctors и declaration expressions.
Здравствуйте, Sinix, Вы писали:
S>Смотри сам: сила макросов (тут мы говорим о нормальных макросах уровня N или хотя бы c++ templates) — в навороченности.
Я говорю про другую силу: метапрограмирование, работа кода макросов с кодом программы. C++ templates, при всей навороченности, в этом плане ужасно бедны.
S>Напротив, AOP на атрибутах — дубовая, простая и надёжная вещь. Минимальная область для реврайтера — член типа (поле/метод/свойство и тд). Т.е. сразу отпадает куча нюансов типа корректного раскрытия макроса, порядка применения, возни с синтаксическими конструкциями и тд и тп. Т.е. чисто функционально AOP на атрибутах беднее. Но для тех задач, где используется AOP это абсолютно неважно.
В том то и дело, как только мы начнем потреблять метапрограммирование, оно моментально уйдет за пределы минимальной области, через год будет куча интересных библиотек, модифицирующих код разными способами, а через три оно станет привычным инструментом архитектора дотнетчика.
S>Цель aop — бороться с кодом, который слишком туп, чтобы его стоило писать вручную. Примеры — от списка полей для бэкенда формы и до реализации INotifyPropertyChanged. Короче, это compile-time замена сниппетам студии и действиям решарпера. Ну не нужны тут расширение синтаксиса, лёгкость описания макросов из самого языка, возможность сделать свой for, etc.
Расширение синтаксиса я пытаюсь оставить за скобками, рассматривая пока только то, что в Nemerle называется атрибутные макросы. Именно их я и вангую ко второй или третьей итерации рослина.
S>Зато за счёт этой простоты мы получаем применение макросов в реалтайме (для рослина с его «живым» редактором это важно), отсутствие проблем с версионностью (вплоть до у каждой сборки — свои реврайтеры), никаких вирусных макросов (когда клиентский код тоже вынужден использовать макросы) и идеальный порог вхождения — он достаточно высок, чтобы отсеять новичков и достаточно низок, чтобы не отпугнуть экспериментаторов.
Живой редактор nemerle вполне умеет применять макросы (даже синтаксические) в реалтайме. Это не проблема. Про вирусные макросы не понял, можно пример?
S>+ 100500. Одно но: для aop за глаза хватает того квазицитирования для бедных, что есть в рослине. Потому что там не требуется изменять произвольное AST, просто заменить пустышки готовой реализацией. Ну а если нужно что-то серьёзно большее, то надо смотреть на языки, в которых макросы есть с самого начала, а не вкорячены к (допустим) девятой версии
Это пока не видно, где, что потребуется. Конечно вначале придется довольствоваться тем, что дадут. AOP в принципе допускает произвольное изменение AST, а строгое ограничение вставкой вместо пустышек моментально обломает кучу AOP сценариев. Текущие сценарии это только замануха, лежащая на поверхности, реализовав их, остановиться уже не получится, там нет никакого берьера, все будет эволюционировать плавно.
S>По-моему нет. Немерль вместе с нитрой сейчас всё больше напоминает эдакий всемогутор для генерации dsl. Т.е. в принципе возможно всё, ошибся в дизайне — твой косяк.
Нитра это не немерль, а отдельный инструмент, который предназначен для создания ЯП. К немерлю она имеет отношение как идейный потомок и как средство для будущего переписывания компилятора (ну и то, что она пишется на смеси немерла с собой).
Сам же по себе немерль — такой же ЯП общего назначения как C# и F#. Я это говорю не для агитации за него (у него есть и серьезные недостатки), а для того, чтобы добавить понимания, никакого всемогутора нет. Более того, C# последовательно получает все интересные немерловые фичи и не сможет пройти мимо метапрограммирования. Потому, что рослин, если взлетит, жутко разожжет аппетит.
Здравствуйте, Ziaw, Вы писали:
Z>В том то и дело, как только мы начнем потреблять метапрограммирование, оно моментально уйдет за пределы минимальной области, через год будет куча интересных библиотек, модифицирующих код разными способами, а через три оно станет привычным инструментом архитектора дотнетчика.
Для aop — это безусловно так. Для макросов, которые расширяют синтаксис и/или требуют реврайта вызывающего кода — чойто я сомневаюсь.
С аор всё просто, с расширением языка сложно.
Во-первых, оно заразно — проникает в вызывающий код, примерно как с async-await — или не использовать, или использовать везде.
Во вторых, макросы видны по всему коду. Снова кривая аналогия, но это всё равно, что навешивать extension-метод на object — и не совсем очевидно, и контроль за распространением никакой. В принципе это можно решить явным включением макросов ч/з тот же юзинг, но тут лучше послушать немерлистов — у них опыт борьбы с такими вещами точно был.
В третьих, большинство попыток расширений языка из тех что я видел были вызваны NIH, а не реальной необходимостью. Почти всегда то же самое можно было решить изучением языка или исправлением косяков в дизайне.
Ну не умеют люди дизайнить даже api как правило, что уж тут о языке говорить Макросы с их лёгкостью добавления тут выглядят слишком большой пушкой.
Z>Расширение синтаксиса я пытаюсь оставить за скобками, рассматривая пока только то, что в Nemerle называется атрибутные макросы. Именно их я и вангую ко второй или третьей итерации рослина.
Тогда да, согласен целиком и полностью. Но это всё-таки полумеры получаются. Делаем кучу усилий для поддержки квазицитирования и изобретаем синтаксис для макросов, а на выходе получаем то, что наворачивается прям поверх текущего рослина без особых доработок.
Z>Живой редактор nemerle вполне умеет применять макросы (даже синтаксические) в реалтайме. Это не проблема. Про вирусные макросы не понял, можно пример?
Ну так это бонус в сторону N. В январе в обсуждении один из доводов против макросов везде был такой:
But if generated parts are themselves the result of language syntax — e.g. attributes in source code, then things quickly get messy from a tooling perspective. A keystroke in file A may cause different code to be generated into file B by some custom program, which in turn may change the meaning of A. Not a feedback loop we're eager to have to handle in real time at 20 ms keystroke speed!
Выглядит конечно как натягивание на ровном месте, но без дополнительной информации я склонен доверять разработчикам рослина. У них опыт побольше будет.
Про "вирусные" макросы — например, использование в public api аналога std::list. Но такие вещи легко можно отсечь запретом использования макросов в качестве c++ templates. А вот пример с самописными await для самописных тасков посложнее будет. В общем, как только метапрограммирование опускается до отдельных инструкций или вылазит за пределы сборки — начинаются проблемы.
S>>По-моему нет. Немерль вместе с нитрой сейчас всё больше напоминает эдакий всемогутор для генерации dsl. Т.е. в принципе возможно всё, ошибся в дизайне — твой косяк.
Z>Нитра это не немерль, а отдельный инструмент, который предназначен для создания ЯП. К немерлю она имеет отношение как идейный потомок и как средство для будущего переписывания компилятора (ну и то, что она пишется на смеси немерла с собой).
Угу, я про N2 и говорил, нитра кажется будет в нём из коробки. Интересно, что у них в итоге получится.
Z>Сам же по себе немерль — такой же ЯП общего назначения как C# и F#. Я это говорю не для агитации за него (у него есть и серьезные недостатки), а для того, чтобы добавить понимания, никакого всемогутора нет.
Да ладно. Возможность дёшево написать произвольный dsl и получить на выходе аналог roslyn ast здорово меняет картину. Навскидку — свои форматы скриптов, формулы аля excel, нормальный синтаксис для кучи xaml-подобных языков, биз-скрипты, аналог specflow и тд и тп.
Здравствуйте, Sinix, Вы писали:
S>Для aop — это безусловно так. Для макросов, которые расширяют синтаксис и/или требуют реврайта вызывающего кода — чойто я сомневаюсь.
Их не код вызывает, как и аспекты, они сбоку кода. Расширение синтаксиса C# дело настолько далекого будущего, что о нем говорить нет смысла.
S>С аор всё просто, с расширением языка сложно. S>Во-первых, оно заразно — проникает в вызывающий код, примерно как с async-await — или не использовать, или использовать везде. S>Во вторых, макросы видны по всему коду. Снова кривая аналогия, но это всё равно, что навешивать extension-метод на object — и не совсем очевидно, и контроль за распространением никакой. В принципе это можно решить явным включением макросов ч/з тот же юзинг, но тут лучше послушать немерлистов — у них опыт борьбы с такими вещами точно был. S>В третьих, большинство попыток расширений языка из тех что я видел были вызваны NIH, а не реальной необходимостью. Почти всегда то же самое можно было решить изучением языка или исправлением косяков в дизайне. S>Ну не умеют люди дизайнить даже api как правило, что уж тут о языке говорить Макросы с их лёгкостью добавления тут выглядят слишком большой пушкой.
Тем не менее люди относительно успешно дизайнят api и решают свои задачи. Если хочется обсудить именно расширение языка, давай сделаем отдельную ветку. Тема холиварная и задавит весь конструктив в данной ветке.
S>Тогда да, согласен целиком и полностью. Но это всё-таки полумеры получаются. Делаем кучу усилий для поддержки квазицитирования и изобретаем синтаксис для макросов, а на выходе получаем то, что наворачивается прям поверх текущего рослина без особых доработок.
Для атрибутных макросов не надо изобретать никакого синтаксиса. Им достаточно синтаксиса атрибутов. Именно потому, что легко наворачиваются поверх рослина они и появятся в ближайших его версиях.
S>Not a feedback loop we're eager to have to handle in real time at 20 ms keystroke speed! S>Выглядит конечно как натягивание на ровном месте, но без дополнительной информации я склонен доверять разработчикам рослина. У них опыт побольше будет.
Тут лучше Влад расскажет, afaik, немерле не укладывается в 20мс, делая типизацию проекта в фоне, но и без этого вполне IDE достаточно неплохо реагирует.
S>Про "вирусные" макросы — например, использование в public api аналога std::list. Но такие вещи легко можно отсечь запретом использования макросов в качестве c++ templates. А вот пример с самописными await для самописных тасков посложнее будет. В общем, как только метапрограммирование опускается до отдельных инструкций или вылазит за пределы сборки — начинаются проблемы.
Проблемы есть всегда, от любой фичи.
S>Угу, я про N2 и говорил, нитра кажется будет в нём из коробки. Интересно, что у них в итоге получится.
Нитра отдельный и самодостаточный проект, а до N2 еще слишком далеко, чтобы что-то обсуждать.
S>Да ладно. Возможность дёшево написать произвольный dsl и получить на выходе аналог roslyn ast здорово меняет картину. Навскидку — свои форматы скриптов, формулы аля excel, нормальный синтаксис для кучи xaml-подобных языков, биз-скрипты, аналог specflow и тд и тп.
Да, это все очень и очень круто. Но и без синтаксического расширения nemerle очень неплох. Если взять его приятные фичи, то большое количество фич шарпа появилось в nemerle раньше. Дженерики(?), лямбды, вывод типов (шарповский все еще отдыхает), ET как ранний прототип инструмента работы с AST, ко/контрвариантность. Осталось — интерполяция строк, ?., import static classes(в ближайших планах), туплы, АТД и паттерн матчинг (в планах), метапрограммирование (в зачаточном виде уже есть в рослине), иммутабельные переменные (вроде бы тоже мелькали в планах, но могу ошибаться), все есть выражение (не скоро, пока только в лямбдах, но очень хочется).
Нельзя сказать, что копируются фичи немерла, просто это естественный неспешный ход эволюции, который экспериментальный язык смог проделать гораздо быстрее. Я к тому, что МП неизбежно придет в нашу жизнь, несмотря на кажущуюся сложность. Оно не сложнее ООП или ФП и не является им альтернативой, а лишь дополняет их, как ООП и ФП органично дополняют друг друга (хотя можно обходиться чем-то одним).
S>В шарпе это очень вряд ли появится.
Согласен, в обозримом будущем синтаксис расширять мы не сможем. Но лет через 10 картина может измениться.
Здравствуйте, Ziaw, Вы писали:
Z>Тем не менее люди относительно успешно дизайнят api и решают свои задачи. Если хочется обсудить именно расширение языка, давай сделаем отдельную ветку. Тема холиварная и задавит весь конструктив в данной ветке.
Сделаем проще. Я целиком и полностью согласен с твоим ответом, так что пока закруглимся
Здравствуйте, Sinix, Вы писали:
S>Вектор не немерловый, ибо сценарии разные.
А, можно развить эту тему?
В чем разница? А, то у меня уже лет 7 стойкое ощущение, что люди упорно не хотят учиться на чужом опыте, а тупо годами собирают шишки лбами, чтобы найти те же самые решения самостоятельно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.