Как стать автором
Обновить

Комментарии 51

Типизация (система типов) в конечном счёте нужна для единственной цели: формальной верификации корректности программ.

Спорное утверждение, особенно в части единственности. В мейнстримовых языках типизация (где она есть) или её аналоги, кроме возможности частичной формальной верификации, ещё обычно усиливает выразительность текста программы, облегчает её неформальный анализ и дальнейшую модификацию. По сути типизация служит инструментом создания DSL. Во многих задачах адекватные домену имена классов имеют большую ценность чем возможность формальной верификации.

ещё обычно усиливает выразительность текста программы, облегчает её неформальный анализ и дальнейшую модификацию.

Это всё следствие проявления верификации (в конечном счёте). Верификация происходит уже на этапе написания кода, и даже при чтении у нас в голове. Если понятия типизированы, семантика типов просто исключает вариации смысла понятия.


Подскажите, что вы имеете в виду под "усиливает выразительность"? Думаю как пример это могло быть Constraints on Type Parameters в generics?


По сути типизация служит инструментом создания DSL.

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


Во многих задачах адекватные домену имена классов имеют большую ценность чем возможность формальной верификации.

Полностью согласен. Хотя классы рано или поздно будут интерпретироваться как типы.

Это всё следствие проявления верификации (в конечном счёте).

В посте отсыл именно к формальной верификации. Грубо говоря, к ошибкам компайл- и рантайма, ошибкам машинного статанализа, ошибкам в тестах. Поэтому, как я понимаю, и предлагается вводить типизацию перед компиляцией. Так? Сначала почти всё реализуем, а потом введём типы, чтобы убедиться, что ошибок нет.


Я же считаю, что типизацию нужно проводить уже на этапе анализа задачи, этапе декомпозиции домена, при построении семантической модели.


Подскажите, что вы имеете в виду под "усиливает выразительность"?

Усиливает способность писателя кода передавать семантику кода читателю кода непосредственно через код. Относя, например, параметр метода к тому или иному типу(классу) в коде, мы передаём читателю кода не просто понятие домена, но и ссылку на его описание.


Мне кажется что тут вы как раз смешиваете понятия и типизированные понятия.

Не смешиваю. Просто в большинстве доменов большинство понятий являются естественно типизированными, если слово "естественно" вообще можно применять к интеллектуальной деятельности. Мозг человека склонен разбивать множества сущностей по категориям/типам/классам. Можно обойтись без типизации, моделируя домен, но зачем, если язык моделирования позволяет, а только редкие понятия доменов являются уникальными "типовещами в себе", существующие в одном экземпляре в рамках домена?


Да, бывает ошибочная типизация при моделировании, приводящая к ложному пониманию семантики, что в свою очередь приводит к функциональным ошибкам, как правило фатальным типа "это невозможно развивать, это нужно переписать с нуля". Может быть таких ошибок было бы меньше, если бы типизацию проводили как можно позже, но даже моя личная практика показывает, что такие ошибки разумная цена за плюсы, которая ранняя типизация даёт.

Поэтому, как я понимаю, и предлагается вводить типизацию перед компиляцией. Так? Сначала почти всё реализуем, а потом введём типы, чтобы убедиться, что ошибок нет.

Я предлагаю вводить типизацию постепенно. К этапу компиляции всё будет типизировано и конкретизировано, конечно. Количество информации будет не меньше, точнее говоря такое же.


Из определения типа (как множества допустимых значений (состояние) и операций над ними (поведение)) возникла идея вводить эти две составляющие раздельно. Объектная композиция основана на протоколе объектов, т.е. только поведение. Атрибуты (нетипизированые) определяют структуру объекта (понятия) но тоже без типов. Затем атрибуты объектов трактуются как состояние, контракт как поведение, там где нужно привязываются уже существующие (встроенные) типы, после этого можно проводить верификацию.


Мозг человека склонен разбивать множества сущностей по категориям/типам/классам.

Вот как раз классификация основана на атрибутах (признаках), и любая классификация указывает по какому признаку(признакам) она производится. Введение атрибутов позволяет определять классафикацию как таковую по каким-то атрибутам. Далее, для атрибутов можно определить допустимые значения (но не операции), и тогда классфикация приводит к классам с выбраной гранулярностью. Это я к тому, что жёсткая связь из определения типа домен+операции возможно и не требуется, копмоненты типа (домен и операции) можно вводить независимо друг от друга.


Вообще, я думаю что объектный подход обоснован не тем что человек как-то мыслит объектами, а именно атрибутированными понятиями, на которых и возможны классификации.

Вот вы написали уже много текста и ни одного примера. Возьмите какой-нибудь ToDo List или интернет-магазин, и напишите псевдокод, как вы это представляете. Тогда можно будет сравнивать.
Автор не может написать вам пример кода. Он же ясно сказал, что его «синтаксис, основанный на текстовых грамматиках» органичивает. Он вам может нарисовать пример кода. Наверное…

Преждевременная типизация хуже преждевременной эякуляции?)


Вообще, текст действительно не всегда самый оптимальный способ передачи смысла, просто он самый простой для генерации и чтения и способен передать большинство смыслов за счет прямой привязки к способу мышления — универсальней него только "сырое" представление мысли, которое пока выделять и передавать не научились. Это как с низкоуровневыми языками — описать через текст можно что угодно, другое дело что часто гораздо проще использовать более высокоуровневые вещи, те же картинки.

Любая парадигма должна

Вот прямо с этого и начнем. Вы не могли бы показать (общепринятое) определение парадигмы, где это указано?

Определение парадигмы (по-моему достаточное для темы) дано в самом начале поста, собственно вы и процетировали его начало. Я определил парадигму через её ключевые атрибуты и указал смысл этих атрибутов.


Вы ожидаете какое-то общепринятое определение, и которое будет совпадать с моим (точнее наоборот, моё должно совпадать с ним)? Википедийное определение заключается в том, что нет общепринятого и однозначного определения парадигмы. Но всё это и не требуется. Моё определение — это допущение, что если оно верно, то верны и следствия из него (при условии корректности вывода).


Например, покажите пожалуйста ложность/противоречивость моих выводов, тогда автоматом встанет вопрос о корректности изначальных допущений (в данном случае определение парадигмы) и/или логики вывода.

Например, покажите пожалуйста ложность/противоречивость моих выводов, тогда автоматом встанет вопрос о корректности изначальных допущений (в данном случае определение парадигмы) и/или логики вывода.

Да нет, все проще. Вы утверждаете, что "объектная парадигма неполноценна". В случае, если вы используете собственное определение парадигмы, это означает, что объектная парадигма не удовлетворяет вашему определению парадигмы — однако какое мне до этого дело? То, что ООП не удовлетворяет это определению — это не проблема ООП.

объектная парадигма не удовлетворяет вашему определению парадигмы

Т.е. вы имеет ввиду что всё-таки существует какое-то общепринятое определение? Которое определяет объектную парадигму и которому удовлетворяют ООП/ООЯП и которое не совпадает с моим определением? Общепринятого определения парадигме нет, отсюда следует простой вывод: какое-бы не было сущесвующее определение (и которое вы подразумеваете) — оно спорное и потенциально содержит изъяны, следовательно моё определение (теоретически) может быть более правильным.


То, что если вы не видите проблем, вовсе не означает их там действительно нет. Допустим, для вас существующие определения объектоной парадигмы и ООЯП вполне согласуются. Но без анализа содержательной части моего поста вы не можете утверждать что в ООП нет проблем — я как раз утверждаю что есть. Разработчики ООП/ООЯП могли ошибаться и текущее определения ошибочны. Я и пытаюсь в посте показать своё видение и какие следствия из него получаются.

Т.е. вы имеет ввиду что всё-таки существует какое-то общепринятое определение?

Ну да.


следовательно моё определение (теоретически) может быть более правильным

Как вы определяете правильность определения?


То, что если вы не видите проблем, вовсе не означает их там действительно нет.

Да нет, именно это это и обозначает. Вы ввели определение "сепулька — это ...", потом сказали "ООП/ООЯП — неполноценная сепулька, потму что..." — ну и что? Для меня в этом нет никакой проблемы, потому что мне совершенно все равно, являются ли ООП/ООЯП сепулькой.


в ООП нет проблем — я как раз утверждаю что есть

В ООП, очевидно, есть проблемы, потому что ни одной совершенной парадигмы программирования не существует. Просто эти проблемы — они не в несоответствии вашему определению.

Как вы определяете правильность определения?

Это зависит от определяемого понятия. В данном случае, для парадигмы — какого качества/удобства языки програмирования на ней построены. Такого количества критики как у ООЯП ещё надо поискать.


потому что мне совершенно все равно, являются ли ООП/ООЯП сепулькой.

В ООП, очевидно, есть проблемы, потому что ни одной совершенной парадигмы программирования не существует.

Пока вы не вникните в суть сепульки, как вы можете утверждать что проблемы ООП/ООЯП не в сепульке? Т.е. вы допускаете что ООП/ООЯП не без слабостей, при этом заранее уверены что не в сепульке дело?


И тем более, что суть не в соответсвии моему определению парадигмы, а в выводах которые из моих определений следуют. В контексте моих определений ООЯП имеют проблемы, в контексте общепринятых определений — не имеют. Но общепринятые определения под вопросом, мои могут оказаться как хуже так и лучше. Т.о. общепринятые определения не истина, а допущение (как и моё). Я не могу пока показать конечный вывод из моей "теории" в виде языка (IDE), чтобы можно было показать что постоеный язык (IDE) на моём определении лучше (или хуже) чем существующие ООЯП. Этот пост демонстрирует промежуточные выводы, и только в таком умозрительном виде, к сожалению.

В данном случае, для парадигмы — какого качества/удобства языки програмирования на ней построены. Такого количества критики как у ООЯП ещё надо поискать.

Ээээ, тут путаница, прямо вот несколько раз.


Начнем с парадигмы. С парадигмой, на самом деле, все просто: это "совокупность фундаментальных научных установок, представлений и терминов, принимаемая и разделяемая научным сообществом и объединяющая большинство его членов". Казалось бы, как на это определение может повлиять то, "какого качества на ней построен язык программирования"?


Ладно, может вы, на самом деле, про парадигму программирования? "это совокупность идей и понятий, определяющих стиль написания компьютерных программ (подход к программированию)." Тоже нет, на это определение качество языка программирования повлиять не может.


Таким образом, ваша метрика выглядит бесполезной для определения качества определения термина "парадигма".


Такого количества критики как у ООЯП ещё надо поискать.

Чего искать-то? Берете процедурные языки, и получаете все то же самое. Более того, если отнормировать по распространенности, то, я думаю, у вас по всем парадигмам будет более-менее одинаково. Так что тоже не показатель.


Пока вы не вникните в суть сепульки, как вы можете утверждать что проблемы ООП/ООЯП не в сепульке? Т.е. вы допускаете что ООП/ООЯП не без слабостей, при этом заранее уверены что не в сепульке дело?

Конечно. Потому что я утверждаю, что проблема ООП не в том, что ООП не сепулька. Я нигде не утверждаю, что проблема ООП не в сепульке.


в контексте общепринятых определений — [ООЯП проблем] не имеют

Приехали. А критика, на которую вы ссылаетесь выше, она в контексте каких определений существует? Или ее нет на самом деле?


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

Для того, чтобы об этом говорить, надо определить "лучше" и "хуже" для определений, а этого пока не наблюдается.


постоеный язык (IDE) на моём определении лучше (или хуже) чем существующие ООЯП

А что с того, что на вашем определении ваш язык лучше? Как это согласуется с моими задачами?

Таким образом, ваша метрика выглядит бесполезной для определения качества определения термина "парадигма".

Я имел в виду объектную парадигму, а не парадигму вообще. Как пример, покажите пожалуйста общепринятое определение объектной парадигмы? Как оно согласуется с приведёнными общими определениями парадигмы?


Приехали. А критика, на которую вы ссылаетесь выше, она в контексте каких определений существует? Или ее нет на самом деле?

Не, не приехали :) Эта часть фразы обозначает вашу позицию.


А что с того, что на вашем определении ваш язык лучше?

По идее он не на моём определнии лучше, и лучше не в абсолютном смысле. Он лучше тем что решает проблемы (некоторые) ООП/ООЯП (которые вы почему-то свели к несоответсвию определений).


Как это согласуется с моими задачами?

К вашим задачам это не имеет никакого отношения. ООП/ООЯП живут не одно десятилетие. В посте я высказал допущение (гипотизу), на основе которой получаются некоторые выводы. Насколько я понял, вы считаете что гипотиза не заслуживает даже постановки, не говоря уже о том чтобы разбирать её содержательную часть. Вы начали с разбора определений, хотя по-моему ими нужно заканчивать (а начинать с выводов). Суть поста: обсудить концепцию нового ЯП/IDE. Это не касается ваших задач, и не попытка модернизировать ООП/ООЯП, это просто мысли к размышлению.

Я имел в виду объектную парадигму, а не парадигму вообще.

Эм. Давайте подставим это в ваше изначальное высказывание: "Объектная парадигма в явном виде не определяет базовых механизмов. Любая объектная парадигма должна определять..". Получается фигня — сначала вы даете определение объектной парадигмы, а потом говорите, что она же ему не удовлетворяет.


Как пример, покажите пожалуйста общепринятое определение объектной парадигмы?

Я никогда не встречал этого термина. Или вы имеете в виду "объектно-ориентированную"?


Эта часть фразы обозначает вашу позицию.

То есть, согласно вашей позиции, критики ООП/ООЯП нет?


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

Вы поняли неправильно. Я считаю, что ваша гипотеза некорректно сформулирована, что не позволяет в дальнейшем ее обсуждать (не говоря уже о том, что нигде не указана, собственно формулировка гипотезы, дан просто набор утверждений, выдающихся за корректные).


Суть поста: обсудить концепцию нового ЯП/IDE

А зачем он тогда называется "проблемы ООЯП"?


а начинать с выводов

Эмм. А какие у вас выводы? Вот эти: "Обозначенные проблемы, на мой взгляд, являются причиной того, что ООЯП фундаментально противоречивы."? Ну так во-первых, оно решает непоставленный вопрос ("почему ООЯП фундаментально противоречивы"), а во-вторых, возвращает нас к "описанным проблемам"… которые являются проблемами только из-за неразрешенности вашей системы определений.


Вы постоянно возвращаетесь в своем посте вот к этому: "объектная композиция должна быть базовым и основным механизмом ООЯП, а не опциональным и второстепенным. " Но почему "должна"? Почему если это не так, у ООЯП — проблема? Почему то, что есть — не "объектная композиция"? Как следствие, все последующие выводы из этого постулата тоже не определены.

Или вы имеете в виду "объектно-ориентированную"?

Да, верно (для простоты одним словом: функиональная, процедурная, объектная).


Давайте для ясности проведём параллели. Во-первых, определение "парадигма программирования":


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


из моего поста: Любая парадигма должна определять: Примитив абстракции (...), Композиция примитивов (...), Агрегирующее отношение (...), Глобальное состояние (...)


Вы считаете эти два определения абсолютно безсвязными? Моё определение конкретизирует обтекаемое общепринятое определение (совокупность идей и понятий, определяющих стиль написания компьютерных программ), но никак не противоречит ему.


Во-вторых, определение "объекто-ориентированная парадигма". Какое определение считать общепринятым — чуть позже, главное что нужно показать как оно соответсвует общепринятому определению парадигмы программирования. В моём посте я показываю свой вариант опредения объекто-ориентированной парадигмы (но ещё и функциональной) и его соответсвие моему определению парадигмы программирования.


Теперь общепринятое определение "объекто-ориентированная парадигма": в варианте постулатов ООП или вариант Всё есть объект..., может что-то ещё? Что бы это нибыло, как оно соотносится с общепринятым определением парадигмы программирования?

Вы считаете эти два определения абсолютно безсвязными? Моё определение конкретизирует обтекаемое общепринятое определение (совокупность идей и понятий, определяющих стиль написания компьютерных программ), но никак не противоречит ему.

Вот только оно его сужает. Следовательно, могут быть парадигмы программирования, которые не удовлетворяют вашему определению.


Теперь общепринятое определение "объекто-ориентированная парадигма": в варианте постулатов ООП или вариант Всё есть объект..., может что-то ещё?

Ну да, вот возьмем Кеевское: "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things." Вот вам совокупность идей и понятий, организация вычислений и структурирование работы. Понятно, что это не формальное определение, потому что оно опирается на неформализованные термины, так мы его и взяли не из научной работы, а из переписки.

Вот только оно его сужает.

Бинго! Это и есть моя та самая гипотиза, что более конкретизированное и ограниченное определение приведёт к определённым результатам. Я описал её в виде "Потребуем, чтобы...", поэтому там "Каждая парадигма должна...".


Следовательно, могут быть парадигмы программирования, которые не удовлетворяют вашему определению.

Конечно, это очевидная мысль, и после моего определения парадигмы я показал что фунциональная парадигма удовлетворяет такому суженому определению. В черновиках статьи я и для процедурной парадигмы описал, но выкинул из-за объёма статьи.


Возвращаясь к сути поста: если допустить более сторогое (суженное) определение парадигмы (которому тем не менее удовлетворяет функциональная, но и процедурная тоже я считаю), из него вытекает некоторый смысл объектной парадигмы (я показал как на моём определени парадигмы должна выглядеть собственно объектная парадигма). Отсюда одно из следствий — ООП/ООЯП слабо поддерживают объектную композицию, и в новом языке/IDE её можно поддержать и получше.


Ну да, вот возьмем Кеевское:

Меня смущает то, что а) общее определение парадигмы довольно расплывчатое, б) определение А.Кея не формальное, и в) ООЯП на таком фундаменте могут интерпретировать ООП довольно в широком смысле, вплоть до потери специализации. Я считаю именно это и произошло на практике в ООЯП.


Опять же, я не против определений А.Кея или любых других. Вы, получается, поддерживаете определение А.Кея, и ООЯП в принципе с ним согласуются. Но меня не устраивает туманность и неоднозначность определений ООП, и то положение вещей что из себя предствляют ООЯП. Поэтому предлагаю пообсуждать альтернативные идеи.

Бинго! Это и есть моя та самая гипотиза, что более конкретизированное и ограниченное определение приведёт к определённым результатам.

… каким?


Я описал её в виде "Потребуем, чтобы...", поэтому там "Каждая парадигма должна...".

Понимаете ли, из "потребуем, чтобы" должно что-то следовать. У вас же из "потребуем, чтобы" вытекает только то, что ООЯП не попадает под ваши требования.


из него вытекает некоторый смысл объектной парадигмы

… который нужен зачем?


Отсюда одно из следствий — ООП/ООЯП слабо поддерживают объектную композицию

А что такое "объектная композиция", и зачем ее нужно поддерживать?


Поэтому предлагаю пообсуждать альтернативные идеи.

Которые не менее расплывчаты. Вы думаете, ваше определение формально? Нет. Смотрите:


Примитив абстракции – определяет стиль мышления парадигмы и является базовым элементом моделирования.

В ООП — объект (сообщение тоже есть объект)


Композиция примитивов – позволяет описывать (моделировать) системы произвольной сложности. Сама композиция также сама должна являться примитивом.

В ООП — объект, содержащий эксклюзивные ссылки на другие объекты, является их композицией.


Агрегирующее отношение – абстрактный механизм, который связывает примитивы в композиции. Точно такой же механизм проявляет примитив и во внешнем взаимодействии.

В ООП — ссылка от владельца на владеемый объект является аггрегирующим отношением.


Глобальное состояние – где (но не как!) будет локализовано абстрактное (наблюдаемое) состояние системы.

В ООП — глобальное состояние локализуется в локальном состоянии объектов.


Видите, ООП "объектов и сообщений" прекрасно удовлетворяет критериям вашей парадигмы.

idris — type, refine, define. В книге от автора языка про type driven development эти вещи на первых страницах объясняются. И без обид — гораздо более системно.
Причина добавления модификаторов методов async/wait в C# — видимо стало понятно, что жёсткая (синхронная) связь вызова метода и возвращаемого значения не соответствует практическим задачам.

Что? И это пишет человек, у которого в профиле значится «Разработчик .NET»! Модификатор async никак не влияет на тип возвращаемого методом значения, то есть к типизации не имеет вообще никакого отношения. А что касается языков моделирования (потому что большая часть тут описанного это как раз о моделировании, а не о реализации) — чем вам UML то не угодил? Не идеал, конечно, но свою задачу более-менее выполняет.
Модификатор async никак не влияет на тип возвращаемого методом значения, то есть к типизации не имеет вообще никакого отношения.

Модификатор async, разумеется, не имеет отношения к типу возвращаемого значения. Может я не верно выразился в том абзаце, но там речь о том что в C# методы классов и их вызовы — это конкретный тип реализации (вот какой тип имелся ввиду) абстрактной концепции протокола/контракта объекта. До появления async методы были синхронные, но практика показала что такое жёсткое поведение непрактично (хотя можно было использовать Task[T]). И добавили async/wait (которые под капотом реализованы через Task[T]).


чем вам UML то не угодил?

Именно тем что он язык моделирования. UML это на мой взгляд крайность в моделировании, ООЯП наоборот акцентируются на типах без объектной композиции. Идея в том чтобы сделать комбинированый вариант.

До появления async методы были синхронные

Конечно же, нет. APM был в .net начиная с первой версии.


(ну или наоборот, если вам угодно: методы синхронные до сих пор, ничего не изменилось)

APM был в .net начиная с первой версии.

APM который вы имеете ввиду — это не часть языка C#, я же говорю про сам язык. APM это паттерн, причём как в варианте Begin/End/IAsyncResult, так и в вариации Event-based Asynchronous Pattern, а затем и Task-based Asynchronous Pattern (TAP). Но сам язык C# формально сделал методы асинхронными с введением ключевых слов async/wait.

Но сам язык C# формально сделал методы асинхронными с введением ключевых слов async/wait.

Но нет же. async-метод возвращает управление синхронно в известный момент времени.


(более того, с точки зрения контракта вы вообще не знаете, async-метод или нет)

По-моему мы о понятиях на разных уровнях. Технически (это о чём говорите вы как я понял), конечно, async метод синхронно возвращает задачу, но собственно результат вызова придёт асинхронно (ещё и с возможной сменой потока, в зависимости от планировщика). Но это всё техническая сторона.


Я же говорю о грамматике языка, что async/wait это ключевые слова с конкретной семантикой, т.е. на уровне языка появились новые слова. Т.е. теперь на уровне языка есть синхронные и асинхронные методы. Моя мысль в том что на уровне объектной композиции вообще не нужно задавать тип реализации контракта.

Технически (это о чём говорите вы как я понял), конечно, async метод синхронно возвращает задачу, но собственно результат вызова придёт асинхронно (ещё и с возможной сменой потока, в зависимости от планировщика).

… и чем это отличается от APM? Технически BeginX вернется синхронно, но собственно результат вызова придет асинхронно.


Т.е. теперь на уровне языка есть синхронные и асинхронные методы.

… которые никак не видны в контракте. Правда, забавно?


По большому счету, нет никакой разницы с yield и генераторами — там тоже тип в контракте не меняется, а вот внутренняя реализация меняется.

А вы как будете расширять семантику своего нового языка? Или вы настолько уверенны в его полноте, что подобные вещи вам в голову не приходят?

По поводу добавления ключевых слов в язык — вот тут у Эрика Липперта очень толково изложено зачем ключевое слово async вообще притащили в язык. То есть, можно было без него, но это потенциально ломало работающий код и поэтому было принято такое решение. Оно не идеальное, но оно взвешенное и осознанное. А предложение не задавать типы в контракте — ну это тоже не новость. Языки с динамической типизацией тоже имеют свою нишу.
А вы как будете расширять семантику своего нового языка? Или вы настолько уверенны в его полноте, что подобные вещи вам в голову не приходят?

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


у Эрика Липперта очень толково изложено зачем ключевое слово async вообще притащили в язык. То есть, можно было без него, но это потенциально ломало работающий код и поэтому было принято такое решение.

А дело в том, что из-за текстовой грамматики и возникает эта проблема, которую решили довольно красиво я бы даже сказал. Вот пример из статьи:


var x = await + y;


При разборе как интерпретировать await — как идентификатор (тогда всё выражение это вызов бинарного оператора) или как точка разрыва и далее continuation (тогда выражение вызов асинхронного перегруженного оператора)? Решение: если у перегруженного оператора указан async — значит в данном выражении компилятор считает точка разрыва, иначе — бинарный оператор с агрументами await и y.


Если бы это была не текстовая грамматика, а некоторое дерево разбора типа AST, то проблема в принципе не возникает, т.к. await однозначно определён типом узла (т.е. это однозначно идентификатор т.к. legacy code). Чтобы извлечь смысл из плоского текста и приходится прибегать к решениям типа маркера async.

Если бы это была не текстовая грамматика, а некоторое дерево разбора типа AST

Можете показать результат, как в этом случае будет выглядеть ваш пример?

Можете показать результат, как в этом случае будет выглядеть ваш пример?

Выглядеть визуально он может точно также, тут суть в том IDE показывает не текст, а отформатированое поддерево. Т.е. текст можно всегда легко получить из дерева, а вот распарсить текст — тут не всякая контекстно-зависимая грамматика справится.


Вот интересная картина получается. IDE поддерживают вставку сниппетов, типа свойство get; private set; Т.е. человек заранее знает какой тип элемента кода ему нужен. Но IDE вставляет плоский текст и это знание теряется. Компилятор опять парсит текст чтобы понять какие там элементы указаны, свойства, методы и пр. Если бы после propg IDE вставляла узел дерева и показывала шаблон для указания setter and/or getter, возможно какие-то проблемы были бы просто исключены.

Если бы после propg IDE вставляла узел дерева и показывала шаблон для указания setter and/or getter, возможно какие-то проблемы были бы просто исключены.

Зато появилось бы ощутимое число других.

Зато появилось бы ощутимое число других.

Каких например?

Например, вам бы пришлось (а) придумывать формат хранения для этих "узлов дерева" (потому что если этого не делать, то вы просто оптимизировали задачу отображения, что неинтересно), и (б) связывать IDE с компилятором (по крайней мере, с его первой частью, которая отвечает за разбор).

(а) придумывать формат хранения для этих "узлов дерева" (потому что если этого не делать, то вы просто оптимизировали задачу отображения, что неинтересно)

Формат хранения может быть любой, начиная от XML и заканчивая бинарным оптимизированным. Причём хранить можно не дерево, а граф с семантическими связями уже.


(б) связывать IDE с компилятором (по крайней мере, с его первой частью, которая отвечает за разбор)

IDE и компилятор уже содержат парсер в том или ином виде ( подсветка синтаксиса и пр.). Что подавать на вход компилятору, текст или дерево/граф — это вопрос архитектуры IDE. Парсер как компонет может шариться IDE и компилятором, собственно Roslyn как раз про это.

Формат хранения может быть любой, начиная от XML и заканчивая бинарным оптимизированным. Причём хранить можно не дерево, а граф с семантическими связями уже.

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


Что подавать на вход компилятору, текст или дерево/граф — это вопрос архитектуры IDE.

А теперь, значит, представим себе ситуацию, что у вас компиляция выполняется не в IDE (потому что билд-сервер), и версии IDE и компилятора разошлись.

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

Этот специальный формат и есть "грамматика" языка. Либо вы описываете текстовую грамматику в виде какой-нить BNF нотации, либо описываете схему формата хранения дерева, которое абсолютно эквивалентно BNF нотации текстовой грамматики. Текстовые файлы с кодом на C# и Java различаются точно также как и, например, бинарные файлы с деревьями для C# и Java. Вы не можете подать на вход компилятору C# текстовый файл с кодом на Java по известной причине, с файлами дерева точно такая ситуация.


О какой куче проблем тогда речь?


А теперь, значит, представим себе ситуацию, что у вас компиляция выполняется не в IDE (потому что билд-сервер), и версии IDE и компилятора разошлись.

Это проблема не следствие идеи текст/дерево. Такая проблема возникнет и при разных версиях компилятора например IDE C# 7 и билд-сервер C# 5.

О какой куче проблем тогда речь?

Да о все той же — резкое сужение доступного инструментария.


Такая проблема возникнет и при разных версиях компилятора например IDE C# 7 и билд-сервер C# 5.

Вот только унифицировать компиляторы намного проще, чем унифицировать компиляторы и IDE. Что снова возвращает нас к проблеме инструментария.


Например, если у меня моя локальная IDE не умеет C# 7, и некорректно его парсит — я получу кривую подсветку, но пока я использую (локально же) правильный компилятор (который доставляется Nuget-пакетом), у меня будет собираться и работать.

Выглядеть визуально он может точно также, тут суть в том IDE показывает не текст, а отформатированое поддерево.

Так все-таки, вы можете ответить по существу? Вы привели пример с текстом. Как он хранится и отображается, понятно: "var x = await + y;". Что будет храниться в файле и отображаться на экране в том варианте, который предлагаете вы? Интересует не описание общими словами, а именно конкретные байты и пикселы. Хотя бы схематично.

Что будет храниться в файле и отображаться на экране в том варианте, который предлагаете вы? Интересует не описание общими словами, а именно конкретные байты и пикселы.

Вообще-то это и был ответ по существу. Может я не так понял акценты в вашем вопросе, но если байты и пикселы…


Вас действительно интересует именно как сериализуется такая структура данных как дерево? Может всё-таки акцент на дереве разбора, какие там типы узлов и пр.?


Дерево разбора первично, текст — это "побочный эффект", один из способов сериализации этого дерева. Вот поэтому дерево разбора можно представить (отрендерить) не только в виде текста.


Насчёт пикселей, если позволите тогда там ссылку на свой черновик. Это совсем черновой вариант, там нет полноты функционала, и уже очень многое в концепциях/дизайне поменялось на текущий момент, но если схематично вот так себе представляю визуально.

Вас действительно интересует именно как сериализуется такая структура данных как дерево?
Да. Потому что видите ли какое дело. Текст программы на языке X — это и есть один из вариантов сериализации дерева. Если вы будете хранить в XML или JSON, это тоже будет текстовая грамматика. Так что не в грамматике дело.

Насчёт пикселей, если позволите тогда там ссылку на свой черновик.
Спасибо, теперь более понятно. Текстом можно записать ровно то же самое.
Скрытый текст
object Alonzo.Polo.Process [Alonzo.Polo.Entity]
{
    Data Name: string;
    Data Status: Alonzo.Polo.ProcessStatus;
    Collaborator Kernel: Alonzo.Polo.Kernel;

    Message Stop
    Routine {
        StopProcess: this.Kernel
            Argument process this
    }

    Message Start
    Routine {
        StartProcess: this.Kernel
            Argument name this.Name
    }

    Message StartThread {
        priority: Alonzo.Polo.ThreadPriority
    }
    Routine {
        Variable thread: Alonzo.Polo.Thread
        Start: thread
            Argument priority

        this.Threads Operator add thread;

        // or
        Operator add
            this.Threads
            thread
    }

    Routine {
        Variable var1: string;
        Variable var2 = "This is a text.";
        Variable var3 = 1000 + 1900;
        Variable points = [[120,-35],[10,10],[-100,-3]];

        points -> point
            select Routine point.X -> x
                // or
                Routine {
                    point.X
                }
                ->x
            foreach Routine print x
        ;

        // This is a return statement

        return var2;
    }
}

Только это гораздо проще, чем накликивать мышкой блоки в IDE.
И отображать его можно точно так же, как у вас сделано HTML-кодом. Если бы кому-то было надо, давно бы уже сделали. Не делают, потому что неудобно.

По сути, единственное отличие, которое вы предлагаете, это хранить вот так.
Скрытый текст
Kind:Object Name:Alonzo.Polo.Process Tags:[Alonzo.Polo.Entity]
{
    Kind:Data Name:Name Type:string;
    Kind:Data Name:Status Type:Alonzo.Polo.ProcessStatus;
    Kind:Collaborator Name:Kernel Type:Alonzo.Polo.Kernel;
    
    Kind:Message Name:Stop
    Kind:Routine {
        Name:StopProcess: this.Kernel
            Kind:Argument Name:process Value:this
    }
    ...
}

А отображать без названий ключей. Это вполне может быть полезно в случаях типа новых ключевых слов. Только ни с ООП ни с типом грамматики это не связано.
Если вы будете хранить в XML или JSON, это тоже будет текстовая грамматика.

Дело не в самом тексте, а в том что дерево в XML/JSOM сериализуется как дерево, т.е. сохраняется вся информация о его узлах. В случае плоского текста утрачивается явная структура дерева, и её приходится восстанавливать прибегая к парсерам.


Текстом можно записать ровно то же самое.

Можно конечно, раз это эквивалентные представления. Я уже описывал ситуацию со сниппетами, где промежуточный этап с текстом просто не нужен. Моя идея это продолжение и развитие сниппетов.


Только это гораздо проще, чем накликивать мышкой блоки в IDE.

Это делается, конечно, не мышкой. Всё как обычно, как текст, только структурированый, или как сказать, шаблонированый. Вообще структурные (проекционные) редакторы (structured or projectional editors) уже существуют, мышкой там в принципе пользуются не больше чем в обычных IDE, например MPS от JetBrains.


По сути, единственное отличие, которое вы предлагаете, это хранить вот так.
А отображать без названий ключей. Это вполне может быть полезно в случаях типа новых ключевых слов. Только ни с ООП ни с типом грамматики это не связано.

Это от другой "фичи", черновик старый, поэтому оно действительно не связано с темой ветки.

т.е. сохраняется вся информация о его узлах

Вот я вас и попросил показать, какая информация там будет для примера с await. Так вы можете это сделать?


и её приходится восстанавливать прибегая к парсерам

Так XML или JSON тоже парсить надо. Как и любой другой формат. И даже скомпилированные бинарники при запуске парсятся загрузчиком программ.


где промежуточный этап с текстом просто не нужен

Ну как это не нужен? А название свойства? А надпись 'public'/'private'? То есть текст все-таки нужен. В чем тогда принципиальная разница, будет ли в файле четырехбайтовый int, обозначающий тип доступа, или шесть байт 'public'?

> Модификатор async никак не влияет на тип возвращаемого методом значения, то есть к типизации не имеет вообще никакого отношения.

Это если считать, что T и Task<T> это принципиально несовместимые сущности из разных вселенных. Но есть и другая трактовка — где это разные, но родственные типы, и где можно сложить T и Task<T> и получить новый Task<T>.
Собственно, построение через async или futures делает почти это (нет синтаксической прозрачности).
Это если считать, что T и Task это принципиально несовместимые сущности из разных вселенных.

Да нет, при чем тут это? Модификатор async не меняет тип с T на Task<T>.

Ещё раз прочитайте что конкретно из написаного у автора вызвало моё возмущение:

Причина добавления модификаторов методов async/wait в C# — видимо стало понятно, что жёсткая (синхронная) связь вызова метода и возвращаемого значения не соответствует практическим задачам.

Где тут про совместимость типов T и Task<T> говорится? Кто-то мешает вам вернуть Task<T> из метода, который не имеет модификатора async? Этот модификатор вообще только компилятору нужен. Вот тут Эрик Липперт очень толково рассказывает зачем это ключевое слово добавили в язык (если коротко — для того, чтобы добавление ключевого слова await не сломало старый код, то есть для обратной совместимости).

Там уже выше ответили, что этот модификатор не имеет никакого отношения к контракту, а описывает особенности реализации. То есть к типизации точно не относится.
Эх, «Потеряла я колечко, а в колечке 22 дивизии!»
Как должна примерно выглядеть объектная парадигма (по аналогии с функциональной):
Примитив абстракции: объект – агент, поддерживающий некоторый протокол взаимодействия. Протокол подразумевает правила и семантику взаимодействия для обеих сторон.

Примитив абстракции: интерфейсы — контракты взаимодействия агентов; классы — комбинация реализаций одного или нескольких интерфейсов; объекты — агенты экземпляры классов.
Агрегирующее отношение: передача сообщений. Сообщения являются объектами. Объект — получатель сообщения не обязан, в общем случае, уметь обрабатывать полученные сообщения.

Типизация — не преждевременная. Она происходит именно там, где должна происходить в выбранной парадигме. Вы подмешали async/await, но это не корректно. ООП не определяет протоколы взаимодействия объектов. ООП описывает лишь отправку сообщения от объекта к объекту. Формат сообщения — это уже отдельная история, которая лежит на уровне между языком и компилятором. К тому же, кроме async/await есть ещё и callback, и очередь сообщений, и signal/slot, и прочее прочее.
Ваше определение парадигмы сильно напоминает определение формальной системы, только другими словами.

Да, есть такое. Хотя до строгой формальности определение очевидно не дотягивает, по крайней мере задумывалось в том направлении.

«Не хочу писать, хочу клац-клац», так?)) Текст — это очень гибкая вещь. Написать можно все, что угодно. Нарисовать, например, производную уже сложнее.
Для «клац-клац» нужна не IDE, а набор написанных текстом подпрограмм.
Чем вам любая CMS не IDE c визуализацией? Модель? Модель. Подстраивается под нужды? Подстраивается. Вопрос мержа решен? Решен через блокировки. С текстом работаете? Нет.

Преждевременная типизация? Так не типизируйте, унаследуйте классы от от одного родителя, подцепите трейт и т.д. Создавайте слои абстракции, и ничто вам мешать не будет. Но чем ниже вы опускаетесь, тем более типизированным будет становиться ваш код.

Приведите пожалуйста примеры. Вообще непонятно, о чем вы рассуждаете. Проблемы проблемы проблемы… Пишите программы так, чтобы их было просто рефакторить, тогда и выработаются правильные абстракции.
Жесткий контракт, о котором вы писали, позволяет работать нескольким командам. А как он выражен, текстом или визуальной моделью, абсолютно неважно.

Вы программы для проектирования микросхем или сетей видели? Там прям объекты, протоколы, возможность симуляции работы. Почему это возможно? Из-за жесткой элементной базы, работающей на одном принципе. Предложите эти принципы, тогда и IDE будет проще простого построить. А до этого момента, различные люди будут создавать CMS разного рода, давая миру интерфейс управления определенной моделью.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории