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++ поледних версий. Это уже мое личное пожелание выходящее за рамки того что обсуждается на гитхабе, но эта фича была бы очень и очень полезной (если ее удалось бы реализовать). Причем реализовывать ее нужно, в первую очередь, опять же в рантайме дотнета, так как дженерики — это рантайм-сущость.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>>Ну, и твои подозрения, что расширения синтаксиса это что-то сложное, страшное и опасное ничем не отличаются от подозрений оп поводу того, что "var" сделает код программ нечитабельным. S>Чтоб не спорить впустую — можешь привести реальный полезный пример расширения синтаксиса? S>Потому что для AOP я с ходу десяток примеров приведу, для расширения синтаксиса — только мелочёвка типа счётчика в foreach или foreach ... else. Ну несерьёзно это
1) readlock(ReaderWriterLock/Slim){} / writelock(ReaderWriterLock/Slim){}, их же для локов на async/await (реврайтер там уровня using)
2) .FirstOrDefault, .Distinct, и прочие — думаю имей C# расширения, появились бы в nuget'е через неделю после выхода linq, включая insert, update, delete
3) Razor — он же по сути своей расширение синтаксиса C# (если на него посмотреть как на C# в котором можно фигачить текст, а не как текст в котором можно фигачить C#), туда же весь .xaml — оформить как расширение синтаксиса в духе Razor, ибо xml не ах
4) interlocked-переменные (ты ей ++, а под капотом вызывается Interlocked.Increment, ты ей += а там .Add, и т.п.)
5) генераторы не как в C#, а как в EcmaScript 6, где можно var a = yield return b; — тогда связанные между собой конечные автоматы становятся проще
6) def или let для иммутабельных переменных, в противовес var который мутабельный
7) var d = new Dictionary<string name, DateTime dateOfBirth>() — и чтоб в этом Dictionary с этого момента никаких TKey и TValue, а мои name и dateOfBirth, и чтоб Intellisense понимал
8) Возможность объявлять произвольные операторы (по идее тут можно и без макросов расширения синтаксиса)
9) Встраивание кода на другом языке, например asm { и погнали на IL }
10) mixin-ы (тут не уверен, может можно выкрутиться на имеющемся синтаксисе)
11) Встроенный парсинг простых регулярок, например regex var {(?<a:int>\d+)\s*-\s*(?<b:decimal, auto>)\s*-\s*(?<c:double,auto>)} = str; — с раскраской и автокомплитом, произвольной закрывающей скобкой (определяется по открывающей, чтоб экранирование не надобилось в 90% случаев), кусочки json'а туда же
12) Макросы для оптимального разворачивания математических операций, сейчас люди мозги вывихивают чтоб две большие матрицы сложить "in place", ибо static operator + полагает что нужен новый объект
13) Свой new (из пула например), delete (в дебаге например ещё и заставляющий проверить GC что ссылок на объект нет и ассертящий если вдруг нашлось)
14) parallel for, parallel foreach и т.п. — там вообще все методы принимают лямбды, а ведь можно чисто и красиво
15) переписать linq to objects на макросах, так чтобы простые локальные случаи работали без потерь перфоманса (типа .Where().Sum(), .Any(), .First() и т.п)
16) Синтаксис для выноса контрактов в объявление метода, включая ссылки на контракты (например группа методов не должна нарушать один и тот же набор инвариантов).
17) Собственные контракты, например часто встречаются методы которые можно вызвать только когда лок уже взят. Хотелось бы повесить на них requires lock SyncRoot, и дальше чтоб компилятор позволял эти методы вызывать только из под lock(SyncRoot) или из методов которые ограничены таким же requires, нарушение ограничения — ошибка компиляции
18) Ключевые слова для функций захватывающих объект "для себя", например часто встречаются конструкторы принимающие массив, и они внутри себя делают Array.Copy потому что не знают, будет этот массив меняться внешним кодом, или нет. Был бы макрос например "Vector(captures double[] row) { this.row = row; }", и компилятор во внешнем коде делал "undefined" входному значению, или бил бы по пальцам за попытку туда писать, или же наоборот, при обнаружении попытки записи варнил а на вход передавал копию — тут уже возможны варианты. А то сейчас есть приложение которое 5% мемори траффика генерирует на такой вот фигне.
S>Я почему-то не рассматривал сценарии из разряда "исправь недоработки шарпа". Подозреваю, потому что при очень большом желании это можно сделать и сейчас — исходники открыты, автоматизировать сборку и подтягивание свежей версии компилятора тоже несложно. Ну и по хорошему, если уж чинить, то в самом репо — пулл-реквесты всё-таки принимают
И получить убер-компилятор полный конфликтов и велосипедов? Держать ветки компилятора рядом с ветками проекта? А потом ещё и мержить их время от времени? Макросы хороши тем что их захотел включил, захотел ручками вызвал по полному имени, захотел — командно-административно использование запретил.
S>С другой стороны, предложения типа "Свой new / delete" или "Ключевые слова для функций захватывающих объект "для себя"" в шарп точно не попадут, а в отдельных проектах точно будут полезны. S>В общем да, я точно был неправ с "сценариев для расширения синтаксиса нет" — эти штуки практически никак не покрываются через AOP на атрибутах и по сути покрывают отдельный набор сценариев — экспериментальные возможности, которые со временем попадут (или не попадут) в язык. Спасибо!
Дык я сам против того чтобы они все попали в один язык суть в том чтобы под задачу какие-то возможности были а какие-то нет. В C++ мы же не инклудим сразу весь буст включая экспериментальные ветки, и не плачем когда обнаруживаем что (гипотетически) дефайны Server 2012 DDK конфликтуют с дефайнами WinPhone SDK. Вот макросы дают такую фишку как "фичи нужные по месту", и кроме них собственно больше никто не даёт.
_>>12) Макросы для оптимального разворачивания математических операций, сейчас люди мозги вывихивают чтоб две большие матрицы сложить "in place", ибо static operator + полагает что нужен новый объект S>А можно пример, про что речь? Никто ж не запрещает сделать первый операнд каким-нибудь MutableMatrix и изменять его в операторе сложения.
Ну мы то сделали велосипед, но он внутри устроен сложно и иногда ведёт себя непредсказуемо (для математиков) по скорости. Например чистый MutableMatrix сломается на сценарии var C = A + B; var TA = A.Transpose(); var D = A; — если A изменится в операторе сложения, то результат Transpose будет уже не торт. Поэтому мы делаем операцию как будто она mutable, и в матрице храним её "rvalue" и "lvalue", чтоб в этом сценарии копирований не было, вовремя сбрасываем эти "?value", в зависимости от операций, и огребаем мемори траффик, но более терпимый чем в случае если новый объект создаётся на каждый + (да ещё и пониженный за счёт пула). Но из-за этих хитростей сам код библиотеки раздут и понятен только тем кто знает зачем оно, а нормальным людям кажется что всё переусложнено на ровном месте. На "макрооператорах", это было бы чище, проще и совсем без траффика. Другой вопрос что вроде в самом Nemerle макрооператоров тоже пока нету но можно выкрутиться используя обычные операторы и сделав объявление типа matrix синтаксическим макросом.
Здравствуйте, Sinix, Вы писали:
S>Опыт был, приходилось наблюдать проект с использованием самописных DSL и чего-то типа макросов на комментариях в коде. Про то, как эти "макросы" прикручены были не будем — там страх и боль Но нас сейчас не это интересует, один фиг с точки зрения пользователей разницы никакой.
Тогда у меня есть опыт пилотирования самолетов, так как я наблюдал как дети воздушного змея запускают.
S>Так вот, с DSL всё было оччень зашибись — поддерживалось, записывалось и читалось понятнее, чем в коде, тут полностью за. С "макросами" было столько проблем, что день когда их наконец выпилили был праздником у всей команды.
Прямо как в том анекдоте.
- Да, фигня этот ваш Карузо!
— А, где ты его слышал?
— Да, Васка, из четвертого подъезда, напел.
У нас в проекте 90% кода генерируется макросами. Полет нормальный.
S>1. Ошибка была в том, что "макросы" добавлялись по всему проекту целиком. Если кто-то добавлял макрос для своей локальной задачи — он рано или поздно использовался не по назначения кам-то ещё, при изменении макроса всё сыпалось. И хорошо ещё, если при компиляции.
Давай на конкретных примерах. Что за макросы? Как их использовали не по назначению? Какие последствия были?
S>2. Макросы в том виде, что были — были добавлены абсолютно зря (точнее, как я понял, они достались в наследство от какого-то легаси-проекта то ли на плюсах, то ли на простом C). В реальности не было ни одного случая, когда то же самое не решалось бы разметкой атрибутами и реврайтерами.
Мясорубки повара использовали совершенно зря. Нужно было только измельчить мясо.
А, что такое, по-твоему, макросы, как не "разметка и переписывание"? Что такое эти твои реврайтеры? И почему разметка макросами не есть ДСЛ (т.е. расширение или реинтерпретация) синтаксиса?
S>Зато примеров использования макросов просто потому, что можно — было выше крыши.
Значит тебе не составит труда озвучить хотя бы парочку.
S>Часть вещей, которая элементарно решалась средствами шарпа была сделана на макросах, в результате макросы регулярно расползались по соседним проектам.
Не вижу связи. Если что-то можно было без ущерба решить средствами шарпа, то не фига было использовать макросы. Это бесспорно. Но причем тут "расползались"?
Функции и классы у вас по проектам тоже расползаются? Если, да, то вызывает ли это те же проблемы?
Пока что похоже, что у вас там была какая-то кривая реализация не пойми чего, в которой ты мало что понимал и от которой у вас были проблемы. Но вместо того чтобы заподозрить в кривизне инструмент ты, совершенно не обоснованно, обобщил опыт его использование на все макрос-системы.
S>там были ещё проблемы, но по сравнению с первыми двумя они были совсем мелочью.
Описывай. Пока что я вижу только общие слова по отношению к опыту поверхностного наблюдения за не пойми чем. А у меня, вот, совершенно обратный опыт опровергающий твой. Так в чем проблема, в макросах как в подходе, или в кривом инструменте? У меня сомнений нет, что в инструменте.
VD>>Ну, и твои подозрения, что расширения синтаксиса это что-то сложное, страшное и опасное ничем не отличаются от подозрений оп поводу того, что "var" сделает код программ нечитабельным. S>Чтоб не спорить впустую — можешь привести реальный полезный пример расширения синтаксиса?
Вообще-то два из них ты описал в своем ответе. Если ты думаешь, что атрибуты по которым генерируется код — это не новый синтаксис, то ты глубоко ошибаешься. Но примеров может быть масса. Например, у нас, в Немерле, есть все о чем вы можете только мечтать последние 10 лет. Все это реализовано на базе макросов. База выражений Немерла микроскопична. Язык соедржит локаольные функции паттерн-матчинг, объявление переменных, именованные блоки (нечто вроде локального ретурна), просто блоки (в фигурных скобках) и набор базовых операторов ("+", "-", "*" и т.п.). Все остальное раелизовано на макросах. А реализовано в разы больше чем вы можете ждать от шарпа в ближайшие 10 лет. Даже банальный foreach — это макрос который поддерживает кучу дополнительных возможностей (от индексов элементов, до встроенного паттернматчинга). Практически любое улучшение языка (новые фичи) можно получать в виде библиотеки. При этом к ним применимы все фичи библиотек: распространение в виде отдельного бинарного модуля (сборки), возможность подключения этой сборки к нужным проектам (фичи будут доступны только в этих проектах), возможность использования фичи в конкретном файле проекта (синтаксические расширения открываются как и методы-расширения имен с помощью using-ов), возможность замены версий банальной сменой ссылки на сборку.
Linq и многое другое тоже реализованы макросами.
Короче, можешь взять C# 1.0 и C# 6.0. Большая часть фич C# 6.0 реализуется с помощью макросво Немерла. А Найтра позволит релизовывать 100% фич даже C# 7.0.
S>Потому что для AOP я с ходу десяток примеров приведу, для расширения синтаксиса — только мелочёвка типа счётчика в foreach или foreach ... else. Ну несерьёзно это
Ты придумал себе термин "AOP" и споришь о терминах. Твой AOP — это ни что иное как ограниченный пример макросов. Примеров на этот твой AOP я тебе тоже придумаю множество, но ежу понятно, что чем шире возможности, тем больше проблем можно решить.
Ну, и как я уже говорил, все это есть ни что иное как встраивание ДСЛ-ей. Просто ты думаешь, что если синтаксис твоего ДСЛ-я записан в виде атрибутов, то это уже как бы и не изменение языка, да и, вообще, не язык. А это не так. Ты придумываешь синтаксические расширения и укладываешь их синтаксис в синтаксис атрибутов. Какой-то класс задач решается этим. Но процентов 80% не решается. В прочем, у Шарп нет и не ясно появится ли даже куцая урезанная версия макросов реинтерпретирующих синтаксис.
Ты почему-то все упиравшийся в синтаксис (AVK, кстати, тоже) меж тем основная проблема макросов не в том поддерживают ли они синтаксис или нет, а в том как они позволяют перехватывать действия в компиляторе, какие они предоставляют средства для разбора добавляемых конструкций (не важно будут ли они выражены атрибутами или полноценным синтаксисом), и какие они предоставляют средства для генерации кода который будет реализовывать логику этих конструкций (по факту ДСЛ-ьных). Вот этого всего и не будет. Не будет точек входа в компилтяор. Не будет полноценных средств анализа не шарпного кода, не будет удобных средств генерации кода. Будут какие-нибудь внешние тулы с ручным разбором и и реинтерпретацией АСТ-а и ручной генерацией текста на базе строковой интерполяции снабженной кучей приседаний и удвоением всех фигурных скобок, так как они конфликтуют с синтаксисом тех самых "дыр" (об этом же авторы языка тоже не подумали). В итоге сложность реализации и поддержки достигнет уровня на котором орел вроде тебя скажет: "день когда их наконец выпилили был праздником у всей команды...".
S>Не, вот как раз насчёт DSL по делу — я всегда за. А вот попытка скрестить ужеежа и запихнуть расширения синтаксиса туда, где они особо не нужны — ничего кроме скептицизма не вызывает
Тогда тебе осталось понять, что твой АОП и атрибуты — это чистой воды расширение синтаксиса. То что он при этом совпадает с синтаксисом атрибутов не устраняет того факта, что это ДСЛ. Это очень похоже на то как некоторые реализуют свой язык в ХМЛ-е думая, что при этом у них будет стандартный синтаксис. Ничего подобного. Язык есть язык. У него будет совой надсинтаксис. Только с очень убогими базовыми элементами — тегами и атрибутами. Тагая же фигня и тут. Ты делаешь тот же ДСЛ, но загоняешь его синтаксис в подмножество атрибутов. Где-то это прокатывает, где-то — нет.
VD>>медленность этого процесса обусловлена медленностью эволюции сознания пользователей языка. Я только добавлю, что дело не только в пользователях, но и авторах. Эволюция их сознания так же тормозит процесс. S>"У любой сложной проблемы всегда есть простое неправильное объяснение"
Тут больше подходит другое высказывание: Любую сложную проблему можно заболтать. Тот кто хочет — ищет решение, кто не хочет — ищет отмазки почему проблему не надо решать.
S>Другой планеты у нас нет, поэтому или делаем то, что действительно полезно для _большинства_ пользователей, или фейлимся, или получаем очень классный, но очень узкоспециализированный язык. Других вариантов я что-то не видел
Вы просто не хотите разобраться в имеющейся альтернативе. Те кто разобрались этих глупостей не повторяют. И сказки про про классные решения не более чем самовнушение. По жизни большинство решений получается так себе. И живут только за счет отличной реализации тулига (IDE, фремворков), бржнда стоящей за ним компании и ее пиарщиков.
По факту же Немерл, как язык, на протяжении 10 лет во всем на голову превосходит Шарп. Но ты даже не удосужился с ним как следует разобраться. Зато рассказываешь нам о каких-то страшных проблемах макросов написанных кем-то на коленке.
Нет никакого другого пути. Нет никаких других ниш. Все что можно на Шарпе — можно и на Немерле, но намного удобнее. Реализовал бы его МС и отпиарил бы как следует, никто в здравом уме даже сравнивать его с Шарпом не стал бы. Но МС идет своим, эволюционным путем. Через 12 лет после появления Немерла в Шарпе начали появляься простенькие фичи из Немерла. Еще через 10 лет он доживет и до макров. Лично у меня в этом сомнения нет. Они, скорее всего, будут чуть другие (такие же как у других, но другие).
Ну, да надеюсь, что у нас все получится и мы сделаем Найтру на которой можно бдует в кратчайшие сроки реализовать не только улучшенный Немерл без детских болезней, но и упростить создание любых ДСЛ-ей настолько насколько это возможно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, 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);
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinix, Вы писали:
S>Тут слегка о другом речь, метапрограммирование на атрибутах и макросы/квазицитирование — это всё-таки разные штуки и покрывают они разный набор задач. Разница — как между AOP и DSL, лучше их обсуждать по отдельности.
Это только так кажется. Макрос в данном случае это код, который генерирует другой код. Как только люди начнут генерировать код в заметных объемах, сразу поймут, что без квазицитат это делать не так приятно. А какой это будет код, AOP или транслятор DSL — уже не важно, для начала нужен сам инструмент.
S>С compile-time-реврайтерами никаких принципиальных проблем нет. Более того, с первых версий студии реврайтеры используются для кучи вещей — от кодогенераторов для настроек/ресурсов и до code contracts (начиная с vs 2010 конечно). Речь только о том, чтобы добавить публичное и поддерживаемое API для этой радости, что в принципе тож несложно. Для roslyn code fix нечто подобное уже сделано.
Ну да, эволюция идет. Я согласен, что все несложно и все будет. Просто не быстро.
S>С _примититивным_ квазицитированием (только для избавления от генерации AST вручную) особых проблем тож нет,
Генерация еще пол-беды. Вот когда люди помучаются с анализом AST без матчинга по квазицитатам, тогда станет понятно, что квазицитаты это офигеннейшая штука. Сейчас просто никто не понимает зачем она нужна, потому, что эти задачи люди перед собой сейчас не ставят. Это все уже было, с дженериками, лямбдами, варами, асинками, методами расширения и т.д. Аппетит приходил во время еды. Попытки обсуждать нужность фич до еды порождали гигантские и бесплодные холивары.
S>А вот внедрять поддержку расширений синтаксиса аля всё тот же N — ну не лезет оно никак в шарп Другой язык получится. Точнее, тот же немерль, вид сбоку. Да и нафиг не нужно, по большому счёту. S>Дисклаймер: разумеется, будут частные случаи, но как всегда, специализированный язык тут будет выигрывать с большим отрывом.
Да, про поддержку расширений синтаксиса я согласен, у шарпа есть шансы банально не дожить с такой скоростью.
S>Вектор не немерловый, ибо сценарии разные.
Давай его назовем параллельным вектором, он и правда не немерловый, но направлен практически идентично.
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>Для 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>Смотри сам: сила макросов (тут мы говорим о нормальных макросах уровня 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# последовательно получает все интересные немерловые фичи и не сможет пройти мимо метапрограммирования. Потому, что рослин, если взлетит, жутко разожжет аппетит.
Здравствуйте, Sinix, Вы писали:
S>Для aop — это безусловно так. Для макросов, которые расширяют синтаксис и/или требуют реврайта вызывающего кода — чойто я сомневаюсь.
Поверь нашему опыту. В тебе говорят предубеждения причина которых отсутствие опыта.
АОП не более чем разновидность МП. Разновидность куцая и мало полезная. Даже ты подразумеваешь под АОП нечто вроде МП без синтаксических расширений. Но это тоже макросы. Просто урезанная версия. В Скалу сейчас встраиваются именно такие макросы. Причем там используется типизированный подход (когда компилятор сначала типизирует код, а потом уже позволяет макросам сгенерировать вместо него другой код.
Ну, и твои подозрения, что расширения синтаксиса это что-то сложное, страшное и опасное ничем не отличаются от подозрений оп поводу того, что "var" сделает код программ нечитабельным.
Дело в том что 100% МП — это в том или ином роде создание ДСЛ-ей. Ограничивая язык фиксированным синтаксисом мы вынуждаем авторов реинтерпретировать синтаксис. Это ни разу не делает получаемые ДСЛ более понятными. Наоборот, это делает код сложнее и отвращает людей от использования языка.
ЗЫ
Похоже Ziaw прав. Причем как в том, что Шарп неминуемо, но очень медленно дрейфует в сторону Немерла. Так и в том, что медленность этого процесса обусловлена медленностью эволюции сознания пользователей языка. Я только добавлю, что дело не только в пользователях, но и авторах. Эволюция их сознания так же тормозит процесс. Если бы они прошли этот путь быстрее, то проблему эволюции сознания пользователей можно было бы решить за счет пиара и евангелистов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinix, Вы писали:
S>Потому что для языковых конструкций нет изоляции как таковой, они или используются повсеместно, или не должны использоваться вообще.
В Nitra есть.
namespace Ns
{
using TypeAlias;// загрузили синтаксис для type type X = A.B;
}
type X = A.B;//А тут уже нельзя.
A>>Нужна возможность запускать собственный код в compile time с возможностью доступа к AST и его изменения. Только для шарпа — IL тут не при чем. S>Вот тут +100500.
Без возможности добавлять свой АСТ со своей типизацией получается довольно убого.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, hi_octane, Вы писали:
_>Дык я сам против того чтобы они все попали в один язык суть в том чтобы под задачу какие-то возможности были а какие-то нет. В C++ мы же не инклудим сразу весь буст включая экспериментальные ветки, и не плачем когда обнаруживаем что (гипотетически) дефайны Server 2012 DDK конфликтуют с дефайнами WinPhone SDK. Вот макросы дают такую фишку как "фичи нужные по месту", и кроме них собственно больше никто не даёт.
Твой пример, кстати, не такой уж и гипотетичный: CefDOMNode methods conflicting with windowsx.h. Забавнее всего смотрится предложение переименовать методы. А вы тут говорите — метапрограммирование, АОП...
Здравствуйте, VladD2, Вы писали:
VD>Как я понимаю они ввели ключевое слово record для классов с первичным (primary) конструктором. У таких классов есть одна незаметное, на первый взгляд, особенность. Этот самый первичный конструктор проводит соответствие между параметрами этого самого конструктора и полями/свойствами класса.
В текущем состоянии — не проводит, акцессоры свойств все равно нужно руками расписывать. Потому и убрали из 6 шарпа, вот как раз чтобы сущности не плодить.
А record — это из отдельной, независимой спеки, которую писали другие люди. Там как раз такое соответствие имеется, чтобы автоматично реализовывать оператор is. И именно по результатам изучения спеки ПК запостпонили.
Суть того что нужно сделать — объединить эти две вещи в единой спецификации. Пока такого публично я не видел, так что и говорить о какой либо терминологии и синтаксисе слишком рано.
S>>Причём как я понял из очень обтекаемых комментариев, на CLR team надежды на этот и следующий релизы нет от слова совсем. То ли ресурсов у них нет, то ли совместимость превыше всего. VD>Эти уроды уже своими отмазками достали. Что они там вообще делают?
Мелочь одну — переписали с нуля JIT.
VD>Ну, и до кучи надо ввести замену этому убогому delegate — функциональный тип.
Это, очевидно, практически невозможно из-за совместимости.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
A>1) Я не увидел чтобы над той же локализацией кто-то там особо думал.
Тем не менее, оно там есть, пусть и в виде набора "сделай сам". Делаешь свой метод вида
A> 2) Имея на подходе рослин (вот уже прям скоро), не видел там ни одного предложения подождать его сделать на макросах\AST чего угодно. Очень странно учитывая как они его позиционируют. Имхо они именно не знают про альтернативы, что грустно.
Ну блин, это только в сказках можно сказать ХАЧУ и в шарпе тут же появятся макросы. Изначально на этот релиз планы были только перетащить шарп и студию на рослин, без крупных добавлений. Это потом уже сроки поехали и появилось время на всякую мелочёвку.
А до метапрограммирования ещё копать и копать. Для начала неплохо бы определиться, какие именно макросы нужны. Будет ли достаточно простого AOP на атрибутах или клиенты хотят полноценный язык с dsl и гейшами.
Если первое — повезло, если последнее — приплыли, нужен подопытный кролик экспериментальный диалект наподобие Cω.
Если что-то посередине — тож невесело. Нужны юз-кейзы, нужно определить границы применимости макросов, удостовериться, что кодом покрываются реальные проблемы и что набор сценариев логически полный.
Затем по реальным примерам посмотреть, что придётся менять в пайплайне компиляции и какое API надо срочно допиливать, т.к. его придётся сделать публичным, т.е. заморозить. Дальше пишется спецификация и, пробная реализация, договариваемся с tooling team на поддержку всей этой прелести в IDE, пишем эталонные примеры, возможно, допиливаем clr и msbuild, не забываем про документацию и работу с общественностью и тыды и тыпы.
Про интеграцию с другими языками (дотнет шарпом вообще-то не заканчивается), работу с c# script/REPL (его активно пилят, к следующему релизу будет) и традиционно отстающий edit'n'continue я вообще молчу.
Короче, по затратам это штука где-то между await и linq будет. А вот насчёт выхлопа я не уверен. Мы встроили тебе язык в язык, чтобы ты мог программировать пока ты программируешь, ага.
Здравствуйте, hardcase, Вы писали:
S>>Чтоб не спорить впустую — можешь привести реальный полезный пример расширения синтаксиса?
H>LINQ по сути — расширение синтаксиса.
Если бы Это только вишенка на торте, снизу куча работы, навскидку:
+ expression trees (пилились местами с учётом будущего DLR) + компиляция + допиленный emit.
+ провайдеры ef/linq2sql, добавился вывод параметров для генериков и лямбд
+ кодогенерация для yield
+ linq for objects (тоже не совсем простая штука)
+ поддержка всей этой радости студией (по объёму работы было столько, что "живая" подсветка ошибок в итоге получилась почти нахаляву) и тыды и тп.
и без всего этого linq бесполезен целиком и полностью. Так что не, не катит за штуку, ради которой стоило бы тащить расширение синтаксиса в язык. Мы всё-таки на реальных пользователей, а не на компиляторописателей ориентируемся
H>Анонимные типы в Nemerle воспроизведены синтаксическим расширением.
Ну.. это классно конечно, но какой толк от этого в шарпе при наличии готовых анонимных типов?
В том-то и проблема, что для AOP есть безусловно понятные и полезные примеры. Для DSL — тоже. А для макросов всё заканчивается на пользе для авторов языка (тут всё бесспорно как бы) и на "ну... можно накрутить вот так, а ещё вот так". Причём для последнего ещё и выяснится, что сам товарищ предлагающий этот вариант не пробовал, т.е. ему он тоже не особо нужен
Это ни в коем случае не наезд, было бы реально интересно увидеть полезный на практике пример.
Здравствуйте, Sinix, Вы писали:
S>В том-то и проблема, что для AOP есть безусловно понятные и полезные примеры. Для DSL — тоже. А для макросов всё заканчивается на пользе для авторов языка (тут всё бесспорно как бы) и на "ну... можно накрутить вот так, а ещё вот так". Причём для последнего ещё и выяснится, что сам товарищ предлагающий этот вариант не пробовал, т.е. ему он тоже не особо нужен
S>Это ни в коем случае не наезд, было бы реально интересно увидеть полезный на практике пример.
Мне кажется, тут дело не в разделении dsl\макросы\aop. Нужна возможность запускать собственный код в compile time с возможностью доступа к AST и его изменения. Только для шарпа — IL тут не при чем. А уж макросы это будут, postsharp like before\onExit или атрибуты — вопрос второй. Макросы наверное отлаживать легче чем вручную. Они опять-таки не должны быть даже единого формата. Атрибутами указывать что вызвать, чего туда передавать и в каком порядке все это исполнять. Т.е. препроцессор шарпа на .net
Здравствуйте, Sinix, Вы писали:
S>Если бы Это только вишенка на торте, снизу куча работы, навскидку: S>+ expression trees (пилились местами с учётом будущего DLR) + компиляция + допиленный emit.
Компиляция ET в рантайме — библитечный код, к компилятору отношения не имеет. Лифтинг кода в ET — довольно простой процесс при наличии типизированного представления, в Nemerle есть такой макрос — превращает код в ET.
S>+ провайдеры ef/linq2sql, добавился вывод параметров для генериков и лямбд
Провайдеры — библиотечный код, к компилятору отношения не имеет. Вот вывод типов — уже задача посложнее и к компилятору имеет прямое отношение.
S>+ кодогенерация для yield
Было в C# 2.0
S>+ linq for objects (тоже не совсем простая штука)
Библиотека.
S>Ну.. это классно конечно, но какой толк от этого в шарпе при наличии готовых анонимных типов?
Это тебе в качестве примера того, чем вообще могут быть полезны синтаксические макросы.
Здравствуйте, Ziaw, Вы писали:
Z>Для начала им надо убедить себя. Сейчас прогресс идет как раз там, где все легко решается макросами. Я верю в то, что они тоже со временем придут к такому решению.
Хочется в это верить, но уж больно алогичное сопротивление оказывается даже продвинутыми пользователями (программистами). Что уж говорить о середнячках и тем кому все по фиг?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, 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++.
Иначе толку от произвольного числа типов-аргументов нет. Ну объявишь их — дальше как использовать?
Здравствуйте, 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 — функциональный тип.
В другой жизни разве что. Слишком многое завязано.
Здравствуйте, 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# может и не дожить, но сами макросы и квазицитирование скорее всего успеет попробовать. Темпы развития радуют и вектор у него немерловый.
Вектор не немерловый, ибо сценарии разные.
Вообще, это лучше не мне, а девелоперам шарпа высказывать. Я это уже сделал, есть желание поправить — присоединяйтесь.
Здравствуйте, 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.
Здравствуйте, 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>Вектор не немерловый, ибо сценарии разные.
А, можно развить эту тему?
В чем разница? А, то у меня уже лет 7 стойкое ощущение, что люди упорно не хотят учиться на чужом опыте, а тупо годами собирают шишки лбами, чтобы найти те же самые решения самостоятельно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
Z>>Темпы развития радуют VD>Издеваешься?
Да не сильно. Видя, какую бурную негативную реакцию провоцирует каждое нововведение (восторги тоже бурные, но я сейчас про батхерт), становится понятно, что быстрее не получится.
Здравствуйте, Ziaw, Вы писали:
Z>Да не сильно. Видя, какую бурную негативную реакцию провоцирует каждое нововведение (восторги тоже бурные, но я сейчас про батхерт), становится понятно, что быстрее не получится.
С их то баблом? Они зарядили бы 100500 евангелистов, которые бы за пол года убедили бы всех промайкросовтовских программистов, что МС совершил революцию в программировании...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>В чем разница? А, то у меня уже лет 7 стойкое ощущение, что люди упорно не хотят учиться на чужом опыте, а тупо годами собирают шишки лбами, чтобы найти те же самые решения самостоятельно.
У нас там недоразумение мелкое получилось.
Ziaw говорил про "в шарп добавляют фишки, которые 100 лет как в N", я — про "в шарпе не будет части фишек N из-за заточенности на мейнстрим и из-за того, что поздняк метаться". Разные вещи короче обсуждали
VD>Поверь нашему опыту. В тебе говорят предубеждения причина которых отсутствие опыта.
Опыт был, приходилось наблюдать проект с использованием самописных DSL и чего-то типа макросов на комментариях в коде. Про то, как эти "макросы" прикручены были не будем — там страх и боль Но нас сейчас не это интересует, один фиг с точки зрения пользователей разницы никакой.
Так вот, с DSL всё было оччень зашибись — поддерживалось, записывалось и читалось понятнее, чем в коде, тут полностью за. С "макросами" было столько проблем, что день когда их наконец выпилили был праздником у всей команды.
Проблемы были не технического характера, тем более что ошибиться с чем-то типа
/*@DTO@*/class A { public int B { get; set; } } // INotifyPropertyChanged + IEquatable + ещё какие-то свои интерфейсы
или с
void Do(string b, SomeType b)
{
/*@ValidateArgs@*/
// real code
}
было сложно. Засада была в другом:
1. Ошибка была в том, что "макросы" добавлялись по всему проекту целиком. Если кто-то добавлял макрос для своей локальной задачи — он рано или поздно использовался не по назначения кам-то ещё, при изменении макроса всё сыпалось. И хорошо ещё, если при компиляции.
2. Макросы в том виде, что были — были добавлены абсолютно зря (точнее, как я понял, они достались в наследство от какого-то легаси-проекта то ли на плюсах, то ли на простом C). В реальности не было ни одного случая, когда то же самое не решалось бы разметкой атрибутами и реврайтерами. Зато примеров использования макросов просто потому, что можно — было выше крыши. Часть вещей, которая элементарно решалась средствами шарпа была сделана на макросах, в результате макросы регулярно расползались по соседним проектам.
там были ещё проблемы, но по сравнению с первыми двумя они были совсем мелочью.
VD>Ну, и твои подозрения, что расширения синтаксиса это что-то сложное, страшное и опасное ничем не отличаются от подозрений оп поводу того, что "var" сделает код программ нечитабельным.
Чтоб не спорить впустую — можешь привести реальный полезный пример расширения синтаксиса?
Потому что для AOP я с ходу десяток примеров приведу, для расширения синтаксиса — только мелочёвка типа счётчика в foreach или foreach ... else. Ну несерьёзно это
VD>Дело в том что 100% МП — это в том или ином роде создание ДСЛ-ей. Ограничивая язык фиксированным синтаксисом мы вынуждаем авторов реинтерпретировать синтаксис. Это ни разу не делает получаемые ДСЛ более понятными. Наоборот, это делает код сложнее и отвращает людей от использования языка.
Не, вот как раз насчёт DSL по делу — я всегда за. А вот попытка скрестить ужеежа и запихнуть расширения синтаксиса туда, где они особо не нужны — ничего кроме скептицизма не вызывает
VD>медленность этого процесса обусловлена медленностью эволюции сознания пользователей языка. Я только добавлю, что дело не только в пользователях, но и авторах. Эволюция их сознания так же тормозит процесс.
"У любой сложной проблемы всегда есть простое неправильное объяснение"
Другой планеты у нас нет, поэтому или делаем то, что действительно полезно для _большинства_ пользователей, или фейлимся, или получаем очень классный, но очень узкоспециализированный язык. Других вариантов я что-то не видел
Здравствуйте, VladD2, Вы писали:
VD>ЗЫ
VD>Похоже Ziaw прав. Причем как в том, что Шарп неминуемо, но очень медленно дрейфует в сторону Немерла. Так и в том, что медленность этого процесса обусловлена медленностью эволюции сознания пользователей языка. Я только добавлю, что дело не только в пользователях, но и авторах. Эволюция их сознания так же тормозит процесс. Если бы они прошли этот путь быстрее, то проблему эволюции сознания пользователей можно было бы решить за счет пиара и евангелистов.
. И следовательно даже не ждут таких фич — иначе string interpolation от компилятора даже не стали бы обсуждать.
В отличие от любого мелкого проекта, в мейнстриме работает закон больших чисел вместе с законом Мёрфи. Т.е. вместо "чотам думать, очевидно же" неплохо бы предусмотреть правильный синтаксис, расширяемость и поддержку кучи сценариев использования от оптимизаций для простых случаев и вплоть до локализации строк . Ну, или пару десятков лет поддерживать код напичканный последствиями ваших неправильных решений. Других вариантов (эмиграцию к эльфам и розовым пони не предлагать) увы нет.
Ну а как всю эту радость реализовать — это уже дело десятое, если не сотое. Тем более что с точки зрения разработчиков шарпа тут нет никакой разницы есть макросы/нет макросов. Они и так имеют полный доступ ко всем этапам обработки AST.
. И следовательно даже не ждут таких фич — иначе string interpolation от компилятора даже не стали бы обсуждать.
S>В отличие от любого мелкого проекта, в мейнстриме работает закон больших чисел вместе с законом Мёрфи. Т.е. вместо "чотам думать, очевидно же" неплохо бы предусмотреть правильный синтаксис, расширяемость и поддержку кучи сценариев использования от оптимизаций для простых случаев и вплоть до локализации строк . Ну, или пару десятков лет поддерживать код напичканный последствиями ваших неправильных решений. Других вариантов (эмиграцию к эльфам и розовым пони не предлагать) увы нет.
S>Ну а как всю эту радость реализовать — это уже дело десятое, если не сотое. Тем более что с точки зрения разработчиков шарпа тут нет никакой разницы есть макросы/нет макросов. Они и так имеют полный доступ ко всем этапам обработки AST.
1) Я не увидел чтобы над той же локализацией кто-то там особо думал. Они о регулярных выражениях с \{} вещами вспомнили на середине. 2) Имея на подходе рослин (вот уже прям скоро), не видел там ни одного предложения подождать его сделать на макросах\AST чего угодно. Очень странно учитывая как они его позиционируют. Имхо они именно не знают про альтернативы, что грустно.
Здравствуйте, agat50, Вы писали:
S>>Это ни в коем случае не наезд, было бы реально интересно увидеть полезный на практике пример.
A>Мне кажется, тут дело не в разделении dsl\макросы\aop.
К сожалению, есть. Из реального опыта: пока кодогенерация живёт отдельно (неважно — dsl это, или обработка размеченных атрибутами типов/сборок) — всё отлично. Как только метапрограммирование пытаются прикрутить на уровень отдельных языковых конструкций или распространить за пределы одной сборки — начинается фигня.
Потому что для языковых конструкций нет изоляции как таковой, они или используются повсеместно, или не должны использоваться вообще. Не, изобрести новую общеупотребительную конструкцию шансы конечно есть, примерно как придумать полезный extension-метод для object. Одна проблема: затраты/выигрыщ по сравнению с метапрограммированием на атрибутах выглядят совсем уж непристойно
A>Нужна возможность запускать собственный код в compile time с возможностью доступа к AST и его изменения. Только для шарпа — IL тут не при чем.
Вот тут +100500.
Здравствуйте, AndrewVK, Вы писали:
AVK>Суть того что нужно сделать — объединить эти две вещи в единой спецификации. Пока такого публично я не видел, так что и говорить о какой либо терминологии и синтаксисе слишком рано.
Замечательно. Главное, чтобы они над этим задумались. Так что имеет смысл их подтолкнуть к размышлениям.
AVK>Мелочь одну — переписали с нуля JIT.
Для того чтобы поддержать структурные типы ничего переписывать не надо. Не придумывай. А делать это все равно надо, раз еще 13 лет назад они назвали дотнет мультиязыковой платформой. Тем более, что и самим это все понадобилось.
А, вообще, ты заводишь старую шарманку. В прошлые разы ты примерно так же объяснял отсутствие того, что к данному моменту уже добавили или уже решили добавить в 7-ке.
Уверен, что лет через дцать ты снова согласишься с МС, когда они все это реализуют.
Ну, и переписать все с нуля для них не такая уж огромная работа. Раз в 15 лет ее можно и проделать. Вон с компилятором шарпа решились ведь. А раньше ты сам мне рассказывал, что использовать единый код для языкового сервиса и компилятора невозможно и приводил кучу доводов по этому поводу. Тут будет так же.
VD>>Ну, и до кучи надо ввести замену этому убогому delegate — функциональный тип.
AVK>Это, очевидно, практически невозможно из-за совместимости.
Это очевидно только для тебя. И обосновать ты это не сможешь хотя бы потому, что данные типы уже существуют в двух дотнетных языках: Nemerle и F#.
Лично мне очевидно, что делегат может (и должен) быть конкретным, именованным воплощением функционального типа. И, что тип этот лучше перенести в рантайм дотнета, чтобы все языки использовали одно единое решение, а не городили бы свои реализации. Под копотом его вполне можно реализовать на основе те же делегатов.
Еще мне очевидно, что замыкания тоже должны поддерживаться рантаймом, а не переписываться в паттерны на основе объектов. Тогда рантайм сможет полноценно оптимизировать функциональный код и донтет станет полноценным мультиязыковым фрейворком, а не рантаймом для C#, как сейчас.
Пройдут годы и все это будет очевидно всем. Только те кто сейчас спорят будут делать вид, что им это было очевидно и раньше. Такова природа человека. Признать неверные решения очень сложно. Даже сложнее чем осознать их неверность.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, hi_octane, Вы писали:
_>Это сходу. А если начать думать...
Однако!
Я почему-то не рассматривал сценарии из разряда "исправь недоработки шарпа". Подозреваю, потому что при очень большом желании это можно сделать и сейчас — исходники открыты, автоматизировать сборку и подтягивание свежей версии компилятора тоже несложно. Ну и по хорошему, если уж чинить, то в самом репо — пулл-реквесты всё-таки принимают
С другой стороны, предложения типа "Свой new / delete" или "Ключевые слова для функций захватывающих объект "для себя"" в шарп точно не попадут, а в отдельных проектах точно будут полезны.
В общем да, я точно был неправ с "сценариев для расширения синтаксиса нет" — эти штуки практически никак не покрываются через AOP на атрибутах и по сути покрывают отдельный набор сценариев — экспериментальные возможности, которые со временем попадут (или не попадут) в язык. Спасибо!
_>12) Макросы для оптимального разворачивания математических операций, сейчас люди мозги вывихивают чтоб две большие матрицы сложить "in place", ибо static operator + полагает что нужен новый объект
А можно пример, про что речь? Никто ж не запрещает сделать первый операнд каким-нибудь MutableMatrix и изменять его в операторе сложения.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, agat50, Вы писали:
S>Потому что для языковых конструкций нет изоляции как таковой, они или используются повсеместно, или не должны использоваться вообще. Не, изобрести новую общеупотребительную конструкцию шансы конечно есть, примерно как придумать полезный extension-метод для object. Одна проблема: затраты/выигрыщ по сравнению с метапрограммированием на атрибутах выглядят совсем уж непристойно
Мне тоже не кажется правильным врубать какой-то синтаксис на весь проект\solution. Сделать аналог using namespace для каждого файла. И пусть там хоть brainfuck будет. Но это опять-таки требует какого-то уж слишком умного парсера шарпа, если мы туда все засовываем. Какие-то рамки нужны.
Здравствуйте, Sinix, Вы писали:
S>В отличие от любого мелкого проекта, в мейнстриме работает закон больших чисел вместе с законом Мёрфи. Т.е. вместо "чотам думать, очевидно же" неплохо бы предусмотреть правильный синтаксис, расширяемость и поддержку кучи сценариев использования от оптимизаций для простых случаев и вплоть до локализации строк . Ну, или пару десятков лет поддерживать код напичканный последствиями ваших неправильных решений. Других вариантов (эмиграцию к эльфам и розовым пони не предлагать) увы нет.
К счастью они есть. Реализуем эти самые строки на базе макросов и имеем возможность:
1. Развивать их как библиотеку не ожидая выхода новых версий компилятора.
2. Положить библиотеку на НюГет и позволить кому угодна в дава клика получить эту функциональсность.
3. Использовать фичу в тех проктах в которых хочется (как библиотеку).
4. Выпускать новые версии библиотеки.
5. Создавать альтернативные решения.
S>Ну а как всю эту радость реализовать — это уже дело десятое, если не сотое. Тем более что с точки зрения разработчиков шарпа тут нет никакой разницы есть макросы/нет макросов. Они и так имеют полный доступ ко всем этапам обработки AST.
Разница как раз принципиальная — прибить гвоздями к языку или положить ее в библиотеку. Да и одно дело выпиливать что-то разбирая АСТ вручную, а другое с использованием высокоуровневого АПИ.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, agat50, Вы писали:
A>1) Я не увидел чтобы над той же локализацией кто-то там особо думал. Они о регулярных выражениях с \{} вещами вспомнили на середине. 2) Имея на подходе рослин (вот уже прям скоро), не видел там ни одного предложения подождать его сделать на макросах\AST чего угодно. Очень странно учитывая как они его позиционируют. Имхо они именно не знают про альтернативы, что грустно.
Они все знают. Даже в предложениях фич начали открыто указывать Немерл среди прочего.
Просто у них нет реального опыта и они рассуждают как Sinix.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinix, Вы писали:
S>Ну блин, это только в сказках можно сказать ХАЧУ и в шарпе тут же появятся макросы.
+1
В жизни между ХОЧУ и началом обсуждения возможности их реализации проходит 12 лет!
S>Изначально на этот релиз планы были только перетащить шарп и студию на рослин, без крупных добавлений. Это потом уже сроки поехали и появилось время на всякую мелочёвку.
Все еще прозаичнее. Кое кто внутри эту тему попедалировал, пообщался с кое-кем извне и протащили ограниченную версию строковой интерполяции (попутно придумав новое название для нее).
S>А до метапрограммирования ещё копать и копать.
За 12 лет можно было накопать больше. Проблема в том, что никто и не копал. Примерно 10 лет назад Хейльсберг про макросы сказал — "Это слишком большая пушка.". Вот сейчас с переходом на Рослин и увеличением давления извне и изнутри начали рассматривать подобную возможность. Думаю, эта идея еще несколько лет по варится и в МС решатся на ее реализацию.
S>Для начала неплохо бы определиться, какие именно макросы нужны.
Для начал неплохо бы определиться делать или нет. Если делать, то начать прорабатывать идеи, советоваться с комьюинити.
S>Будет ли достаточно простого AOP на атрибутах или клиенты хотят полноценный язык с dsl и гейшами.
Будет. Сказку про кашу из топора слышал? Вот с этим так же будет. Так что пусть решаются на самый простой вариант.
В прочем, пусть тормозят. Нам же лучше будет.
S>Если первое — повезло, если последнее — приплыли, нужен подопытный кролик экспериментальный диалект наподобие Cω.
Выдумал что-то и сделал выводы.
Блин. Потрать две недели. Разберись с тем же Немерлом. Увидишь, что все твои страшилки не более чем выдумки. Иначе не стоит обсуждать устрицы с теми кто их ел. (ц)
S>Если что-то посередине — тож невесело. Нужны юз-кейзы, нужно определить границы применимости макросов, удостовериться, что кодом покрываются реальные проблемы и что набор сценариев логически полный.
Другими словами — нужен дизайн. Ну, это не виданное чудо в нашей области . Тем более, что они просто таки первопроходцы. Первому языку с макросами более 50 лет, а язык с макросами для платформы дотнет существует уже 12 лет. За это время такой сложный процесс как дизайн было невозможно сделать.
S>Про интеграцию с другими языками (дотнет шарпом вообще-то не заканчивается), работу с c# script/REPL (его активно пилят, к следующему релизу будет) и традиционно отстающий edit'n'continue я вообще молчу.
Если не натягивать сову на глобус, то проблем не будет. Все это с макрами никак не связано, так как макры работают во время компиляции.
S>Короче, по затратам это штука где-то между await и linq будет. А вот насчёт выхлопа я не уверен. Мы встроили тебе язык в язык, чтобы ты мог программировать пока ты программируешь, ага.
Выхлоп можно было сэкономить не хардкодя те самые await и linq. Их можно было бы в 10 раз быстрее сделать в виде макросв. Были бы библиотеками которые могли бы использовать те кому нужно и не ждать выхода новой версии языка.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>С их то баблом? Они зарядили бы 100500 евангелистов, которые бы за пол года убедили бы всех промайкросовтовских программистов, что МС совершил революцию в программировании...
Для начала им надо убедить себя. Сейчас прогресс идет как раз там, где все легко решается макросами. Я верю в то, что они тоже со временем придут к такому решению.
Здравствуйте, VladD2, Вы писали:
VD>По факту же Немерл, как язык, на протяжении 10 лет во всем на голову превосходит Шарп. Но ты даже не удосужился с ним как следует разобраться. Зато рассказываешь нам о каких-то страшных проблемах макросов написанных кем-то на коленке.
В общем чтоб не спорить — давай закруглимся. Тем более что со многим согласен, да и с "расширение синтаксиса не нужно" я точно был не прав — hi_octane выше привёл примеры из разряда фиг оспоришь
Здравствуйте, VladD2, Вы писали:
VD>Замечательно. Главное, чтобы они над этим задумались. Так что имеет смысл их подтолкнуть к размышлениям.
То что ПК отменили, причем на довольно позднем этапе, когда эти самые ПК были реализованы в компиляторе на довольно высоком уровне (и даже Решарпер их уже поддерживал), как раз и свидетельствует о том, что они задумались.
AVK>>Мелочь одну — переписали с нуля JIT. VD>Для того чтобы поддержать структурные типы ничего переписывать не надо.
Я этого и не утверждал. Ты, судя по всему, как обычно не вникаешь в то, что тебе пишут.
VD>>>Ну, и до кучи надо ввести замену этому убогому delegate — функциональный тип. AVK>>Это, очевидно, практически невозможно из-за совместимости. VD>Это очевидно только для тебя. И обосновать ты это не сможешь хотя бы потому, что данные типы уже существуют в двух дотнетных языках: Nemerle и F#.
Хреново, надо сказать, существуют.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>>>Мелочь одну — переписали с нуля JIT. VD>>Для того чтобы поддержать структурные типы ничего переписывать не надо.
AVK>Я этого и не утверждал. Ты, судя по всему, как обычно не вникаешь в то, что тебе пишут.
Значит ты влез в разговор не разобравшись в том о чем в нем идет речь. Мы говорили о том, что для поддержки записей (которые они называют кортежами) нужно реализовать поддержку структурных типов в рантайме. На что было заявлено, что у них нет времени.
VD>>Это очевидно только для тебя. И обосновать ты это не сможешь хотя бы потому, что данные типы уже существуют в двух дотнетных языках: Nemerle и F#.
AVK>Хреново, надо сказать, существуют.
Хреново? Расскажи нам в чем заключается эта хреновость. А еще лучше, не спорь о вкусе устриц с теми кто их ел.
Единственная "хреновость" — это не стандартность. Было бы значительно лучше, если тип поддерживался в рантайме. Тогда все языки были бы совместимы между собой.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
AVK>>Я этого и не утверждал. Ты, судя по всему, как обычно не вникаешь в то, что тебе пишут. VD>Значит ты влез в разговор не разобравшись в том о чем в нем идет речь.
Да нет, я то как раз разобрался. А ты не потрудился все таки в никнуть что и про что я писал. Прошлый раз итераций 5 понадобилось, чтобы ты наконец прочел исходное сообщение.
VD> Мы говорили о том, что для поддержки записей (которые они называют кортежами) нужно реализовать поддержку структурных типов в рантайме.
Я не на это отвечал. Потрудись таки прочесть собственную цитату, на которую был ответ.
AVK>>Хреново, надо сказать, существуют. VD>Хреново? Расскажи нам в чем заключается эта хреновость.
В плохой совместимости со стандартной библиотекой и необходимости перехода от делегатов к функциональному типу и обратно.
VD> А еще лучше, не спорь о вкусе устриц с теми кто их ел.
Не хами. Тут еще неизвестно, кто из нас и в каком количестве ел устриц. И по поводу обсуждения квалификации в правилах имеется соотв. пункт, который для тебя никто не отменял.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Я не на это отвечал.
Но мы то об этом говорили. Отмазки что они там что-то переписывают не катят. 13 лет прошло. И переписывая даже проще что-то добавить. Плюс назвать переписыванием с нуля конвертацию 32-битной версии в 64-битную могут только бравые парни из МС.
AVK>В плохой совместимости со стандартной библиотекой и необходимости перехода от делегатов к функциональному типу и обратно.
Ты детали давай. Где плохая совместимость. С чем. Примеры приведи.
VD>> А еще лучше, не спорь о вкусе устриц с теми кто их ел.
AVK>Не хами.
Я хамлю? Ты заявляешь полнешую чушь, а я хамлю? Может разберешься в вопросе или хотя бы подумаешь для начала.
AVK>Тут еще неизвестно, кто из нас и в каком количестве ел устриц.
Ну, да. Ну, да...
Ну, так потрудись аргументировать свои голословные заявления. Раз ты эксперт, в обсуждаемой области, тебе не составит это труда.
AVK>И по поводу обсуждения квалификации в правилах имеется соотв. пункт, который для тебя никто не отменял.
Тут обсуждать нечего. Лепишь заявления с важным видом, а обосновать их не можешь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
AVK>>Я не на это отвечал. VD>Но мы то об этом говорили.
Я процитировал твою фразу, на которую отвечал. А спор в стиле Сергинио, когда у тебя к4акие то свои образы в голове мне не интересен.
VD> Отмазки что они там что-то переписывают не катят.
Итак, ты опять не прочел на что я отвечал. Опять 5 итераций понадобится?
AVK>>В плохой совместимости со стандартной библиотекой и необходимости перехода от делегатов к функциональному типу и обратно. VD>Ты детали давай. Где плохая совместимость. С чем. Примеры приведи.
Делегатов с новым типом. Берем, к примеру, Enumerable, а там одни делегаты. Что в твоем новом дивном мире с ними делать предполагается?
AVK>>Не хами. VD>Я хамлю?
Да. И нарушаешь правила форума.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Делегатов с новым типом. Берем, к примеру, Enumerable, а там одни делегаты. Что в твоем новом дивном мире с ними делать предполагается?
С делегатами никаких проблем нет. Они являются подтипом функционального типа. Делегат совпадающий по сигнатуре с функциональном типом совместим с ним (может быть передан туда где ожидается функциональный тип). Под капотом функциональный тип может быть реализован через те же делегаты. Надо только ослабить некоторые проверки.
AVK>Да. И нарушаешь правила форума.
Факт отсутствия у тебя опыта, в конкретном вопросе, правилами не регулируются. Я же не говорю, что ты ламер? Я тебе указываю на то, что ты споришь о том в чем плохо разбираться. Причем споришь декларациями, не приводя никаких аргументов. Против такой демагогии невозможно возразить. Если бы ты попытался сформулировать свои претензии более конкретно, то и спорить бы не стал бы, скорее всего, так как понял бы, что никаких проблем введение более общего типа не вызовет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.