LINUX.ORG.RU
Ответ на: комментарий от quasimoto

То есть рабочая система (ошибки динамики в рантайме ведь) должна таскать за собой IDE?

Может и не таскать.

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

Как контракты связаны со статической типизацией? Никак. Они в рантайме чекаются.

Я вообще на TI предпочитаю не полагаться, тогда и сообщения будут хорошими.

Ну да. Но в этом случае они и в динамике хорошие будут.

anonymous
()
Ответ на: комментарий от tailgunner

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

А как же сопроцессор и числа с плавающей точкой? Запихнуть в регистры сопроцессора можно любой набор битов, но не всякий набор битов является корректным числом с плавающей точкой. Процессор может и исключение вызвать :)

Harald ★★★★★
()
Ответ на: комментарий от anonymous

Кстати, проблема тайпинференса (и вообще распространения инфы по термам) весьма изящно решается при помощи свойств - в Racket у каждого синтаксического объекта (то есть терма) может быть произвольный набор свойств. Тогда мы можем ввести свойство type, которое будет содержать тип терма в боксе и ссылки на все термы, которые зависят от данного. Когда встречаем новый терм, то во время его эккспанда приписываем синтаксическому объекту общий тип и добавляем ссылку на терм во все подтермы, как только можем сузить тип - сужаем тип в боксе и запускаем тайпчек для всех зависимых термов. После экспанда последнего выражения у нас в свойстве каждого терма будет выведен его тип - ну или во время экспанда словим ошибку.

anonymous
()
Ответ на: комментарий от anonymous

Может и не таскать.

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

Как контракты связаны со статической типизацией?

В Racket же что-то делали на тему контрактов для compile-time. Я это имел в виду.

Они в рантайме чекаются.

assert(3), все дела.

quasimoto ★★★★
()
Ответ на: комментарий от Harald

А как же сопроцессор и числа с плавающей точкой? Запихнуть в регистры сопроцессора можно любой набор битов, но не всякий набор битов является корректным числом с плавающей точкой. Процессор может и исключение вызвать :)

Ну да, в рантайме. Поэтому машкод - динамика.

anonymous
()
Ответ на: комментарий от tailgunner

локальный вывод типов

Это просто тот же вывод для локальных биндингов (вроде присваиваний и let) или что-то ещё?

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

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

Ну да, как и в случае статики. Никакой разницы, то есть.

В Racket же что-то делали на тему контрактов для compile-time. Я это имел в виду.

Нет, там есть рантайм-контракты и есть typed/racket, причем функции из typed импортируются в untyped с контрактами, в которые преобразовывается тип.

assert(3), все дела.

На самом деле это все несколько сложнее. Напиши контракт для ФВП, например.

anonymous
()
Ответ на: комментарий от anonymous

И как же мне пропускает MOV AX, BX, если аргумент должен иметь тип reg32, а он reg16? Алсо - если я вместо регистра вообще участок памяти укажу? Как это в твоем типе отражено?

Обычная перегрузка же. Но вообще, тут используется слово untyped в отношении «conventional assembly language», но нужно ещё выяснить подходит ли этот conventional assembly language как язык машины или нет.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Обычная перегрузка же.

Перегрузка - это замечательно. Но она не отменяет того факта, что у указанных термов должны быть конкретные типы. Какие?

anonymous
()
Ответ на: комментарий от anonymous

Ну да, как и в случае статики. Никакой разницы, то есть.

В статике числа никак не попадают на места списков. Ещё раз, возьмём flatten - какой минимальный и максимальный типы? (list -> list) и (t -> t), (list <: t) и всё «хорошо». Только вот функция частичная - (flatten 1) «упадёт». В статике у flatten единственный тип (цвет) - (list -> list) и система типов гарантирует что весь control flow будет составлен по соответствующим правилам (только выходы и входы одинаковых цветов соединимы, это, конечно, без учёта полиморфизма, но пусть будет упрощённо). Причём в compile-time.

Вообще, с помощью системы типов можно гарантировать (в compile-time), что flatten принимает на вход именно вложенный список и возвращает именно плоский - даже тестов не нужно. Но это экзотика.

Напиши контракт для ФВП, например.

Не знаю, (assert (functionp ...))?

quasimoto ★★★★
()
Ответ на: комментарий от anonymous

Моя практика говорит то же самое для динамической типизации.

И как же она это делает? Вот положил ты не то в массив в одном месте, а облом случился в другом месте.

Делаю точно так же, только вместо тайпчека запускаю тесты. И в полуавтоматическом режиме правлю код. ЧЯДНТ?

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

А у меня тесты только функциональные. Они же регрессионные. И тестируют они только самый верхний уровень. Ибо внутри все проверяется типами.

прекрасно, какие типы у термов AX; MOV; MOV AX, BC?

AX - bits16

MOV AX, BC - read bits16, write bits16

Прекрансо, положи туда функцию. И покажи как это делается. Пример напиши.

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

То есть сперва создаем проблему (вводим систему типов и тайпинференс), а потом ее героически решаем?

Это не проблема. Это функциональное требование, которое стоит первым номером к данной системе. Ибо динамическая типизация ошибка природы. Я так считаю.

Но эта фича и без вывода типов полезна.

И, напоминаю, все описанное тобой эквивалентно банальному переписыванию функции expand руками.

Это твои фантазии. Я ничего не предлагал писать.

Вот именно. Макросистема берет все это на себя - ничего руками делать не нужно. А вот тебе придется все руками да внутри самописного expand'a.

Макросистема Н2 берёт. Для этого её и создаю. А вот макросистема лиспа нет. В лиспе нужно это руками делать.

И экспанд в Н2 вообще не нужен. Ибо все макросы можно типизировать до раскрытия.

А дальше у нас уже будет вся информация. И можно при помощи методики типа scrap your boilerplate но круче спокойно раскрываться методом что вижу то пою.

anonymous
()
Ответ на: комментарий от anonymous

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

Там препроцессор, который чисто синтаксически превращает mov r1,r2 в mov_reg_reg r1,r2, mov r1,(addr) в mov_reg_mem r1,addr и т.д.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Не знаю, (assert (functionp ...))?

Только нам ведь надо не гарантировать, что это функция, а гарантировать, что это функция с определенным типом, например int -> int -> int. Или даже A -> A -> A, где А - полиморфный параметр. Так что все не так просто :)

что flatten принимает на вход именно вложенный список и возвращает именно плоский

Это будет плохой flatten, т.к. ему можно будет подать на вход только список, вложенность которого известная на момент компиляции. А даже если известна - доказательство этого уровня вложенности будет неразрешимо :)

В статике числа никак не попадают на места списков.

Они попадают, только тайпчекер выводит в этом случае ошибку. В случае динамики ошибку выводит рантайм при запуске теста.

anonymous
()
Ответ на: комментарий от quasimoto

Там препроцессор, который чисто синтаксически превращает mov r1,r2 в mov_reg_reg r1,r2, mov r1,(addr) в mov_reg_mem r1,addr и т.д.

Как оно реализуется (полноценным чекером или препроцессором) неважно, вы указанным термам типы припишите. Если не можете - выходит, язык не статически типизированный, так ведь?

anonymous
()
Ответ на: комментарий от anonymous

вы указанным термам типы припишите

Тип MOV AX, BC уже назвали. Любой другой терм (аргументация «что если там регистр другого размера или память») это уже другой терм (синтаксически) с другим типом. Короче, построить систему типов ничего не мешает (выше есть ссылка на TAL). Если говорить именно про _ассемблер_ (то есть мнемоники) то я не представляю как его реализовать без хоть какой-то системы типов - чтобы генерировать опкоды нужно во время компиляции знать что мы делаем (читаем из регистра в регистр, пишем в память или вызываем прерывание).

quasimoto ★★★★
()
Ответ на: комментарий от anonymous

Да, действительно, в этом случае начинается веселье.

Про то, что мне нужно что-то писать это придумал ты.

Взаимодействовать куски кода будут прекрасно. Вся система типизации именно под этот сценарий и рассчитана.

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

Вот то, что у тебя это и есть гора кода. А я просто напишу что-то типа context.Get(moduleName).RuleNames.Contains(name). А все циклические зависимости разрулит типизатор. Так что у меня останется только логика. А ты на лиспе пишешь кучу говнокода на ровном месте.

я хуею, сколько не разговаривал с немерлеблядями, они ни грамма кода написать не могут, хоть как у них его не проси.

То-то я от тебя не видел ни буквы кода. А вообще твоя манера общения характерна для гопника из подворотни. Скажи все лисперы такие?

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

Понятно. Все компиляторы препроцессоры. Ну в такой постановке вопроса и Н2 и С++ и лисп это препроцессоры.

Да, любой компилятор является препроцессором. И он заведомо менее выразителен чем полноценная система метапрограммирования. То есть система метапрограммирования может сделать все, что может сделать компилятор, но не наоборот.

Как мы уже выяснили это пример так называемой лжи.

Все те проблемы, что ты нашел, основаны на твоих фантазиях. Но не на фактах.

anonymous
()
Ответ на: комментарий от anonymous

И как же она это делает? Вот положил ты не то в массив в одном месте, а облом случился в другом месте.

Так не надо писать код, в котором может такое произойти. Это верно и для статики и для динамики.

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

Тесты надо писать _в любом случае_. И для отлова ошибок типов достаточно, в сущности, одного единственного типа (то есть запустить код хотя бы раз). Если код корректно отработал - то вероятность ошибок типов КРАЙНЕ мала.

А у меня тесты только функциональные.

Так и у меня так. Зачем другие тесты нужны?

AX - bits16
MOV AX, BC - read bits16, write bits16

А у mov какой тип?

Заводим в типе типа переменную, в которую можно положить функцию и всё. Что никогда не заводил поле в объекте? Вот типы типов такие же объекты.

Прекрасно, как мне теперь сгенерировать код, частью которого будет эта функция? Это первый вопрос. Второй - то есть вот с макросистемой у меня все это делается автоматом, а тут мне руками надо будет пидорасить типы типов и чтото там кудато класть? Совсем не весело :(

Это не проблема. Это функциональное требование

Окей - это функциональное требования, которое создает кучу проблем, котоыре потом надо героически решать.

Это твои фантазии. Я ничего не предлагал писать.

То, что ты описал НЕ ДЕЛАЕТСЯ иначе как переписыванием expanda. В принципе не делается. Да, у тебя может не быть явно такой ф-и expand, но то что ты в итоге сделаешь будет совершенно эквивалентно этому переписыванию руками.

Макросистема Н2 берёт. Для этого её и создаю.

По твоим описаниям - она нихрена не создает, приходится руками лезть в типы и чтото там делать.

А вот макросистема лиспа нет. В лиспе нужно это руками делать.

Я описал конкретно как это делается в лиспе и как макросистема лиспа берет на себя ту самую чатсь работы, где ты лезешь руками внутри экспанда в тип и чтото там мудришь. Так что то что в лиспе не нужно это руками делать ДОКАЗАННЫЙ факт.

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

И экспанд в Н2 вообще не нужен.

Экспанд в н2 это тайпчек.

Ибо все макросы можно типизировать до раскрытия.

То, что типизация макросов - алгоритмически неразрешимая задача, немерлеблядь не смутило, лол.

Ее не смутило даже, что все гораздо хуже - во время типизации тебе надо будет, например, доказать непротиворечивость семантических правил (иначе тайпчек согласно этим правилам не даст гарантий корректности), которая может быть вполне эквивалентна непротиворечивости ZFC. Другими словами ты даже не сможешь написать алгоритм, который смог бы типизировать ОДИН КОНКРЕТНЫЙ НАБОР МАКРОСОВ. Про произвольные макросы и речи не идет, дружок.

anonymous
()
Ответ на: комментарий от quasimoto

Тип MOV AX, BC уже назвали.

Тип MOV не назвали :(

anonymous
()
Ответ на: комментарий от anonymous

Кстати, проблема тайпинференса (и вообще распространения инфы по термам) весьма изящно решается при помощи свойств - в Racket

Привет КО. Примерно так все типизаторы и работают. Вот только на практике всё намного сложнее, чем ты можешь себе представить.

А если не дай байт, появится перегрузка, то ваще полный песец наступает.

anonymous
()
Ответ на: комментарий от anonymous

Взаимодействовать куски кода будут прекрасно. Вся система типизации именно под этот сценарий и рассчитана.

У тебя нету никакой СИСТЕМЫ ТИПИЗАЦИИ, идиот. У тебя есть только мокрые фантазии и нулевой опыт работы с метапрограммированием.

Вот то, что у тебя это и есть гора кода. А я просто напишу что-то типа context.Get(moduleName).RuleNames.Contains(name). А все циклические зависимости разрулит типизатор

Нет, что-то типа такой строки напишу я. А тебе к ней еще типизатор надо будет дописать.

Так что у меня останется только логика.

И типизатор.

То-то я от тебя не видел ни буквы кода.

А ты не просил. От тебя же не только кода нет - вообще нихуя. «эта задача будет решена охуенным способом» - и кукареканье в ответ на вопрос об этом чудесном способе.

Ну в такой постановке вопроса и Н2 и С++ и лисп это препроцессоры.

Нет, лисп - мощнее. Потому что лисп-система кроме компилятора содержит еще и рантайм.

Как мы уже выяснили это пример так называемой лжи.

Замечательно, исполни препроцессором сгенерированную при помощи этого препроцессора программу. Макросистема такое умеет. Ну? Тебе ведь так легко докзаать что я лгу. Пару строк кода написать, буквально.

anonymous
()
Ответ на: комментарий от quasimoto

mov это лексема, она не составляет терма.

Ну у нас тогда должно быть какое-то семантическое правило для этой конструкции, так ведь? Какое?

anonymous
()
Ответ на: комментарий от quasimoto

Если на то пошло, то тут просто разные операции mov_,_ : reg x reg -> void; mov_,(_) : reg x mem -> void и т.п.

quasimoto ★★★★
()
Ответ на: комментарий от anonymous

Привет КО. Примерно так все типизаторы и работают.

Только обычно приходится писать руками, а тут 90% реализации уже есть «искаробки».

А если не дай байт, появится перегрузка, то ваще полный песец наступает.

Нет, никаких проблем с перегрузкой не возникает.

anonymous
()
Ответ на: комментарий от quasimoto

На стадии _лексического_ анализа уже известно, что mov r16, r32 это mov_reg16_reg32(r16, r32) и далее по списку.

С точки зрения семантики ЯП у нас нету никаких отдельных «лексических анализаторов». Есть грамматика языка (полная) есть семнатика (полная).

anonymous
()
Ответ на: комментарий от anonymous

Так не надо писать код, в котором может такое произойти. Это верно и для статики и для динамики.

Лол. В статике я это написать не смогу. Чем и пользуюсь. Изменил сигнатуру и айда по ошибкам скакать. А если я сделаю это в динамике? Мне придется молиться, что у меня тесты покрывают все что нужно. А если нет? При этом в статике у меня есть гарантия 100% покрытия кода типами.

Тесты надо писать _в любом случае_. И для отлова ошибок типов достаточно, в сущности, одного единственного типа (то есть запустить код хотя бы раз). Если код корректно отработал - то вероятность ошибок типов КРАЙНЕ мала.

У кого как. У меня типы очень подробные. Так что они много что ловят.

Так и у меня так. Зачем другие тесты нужны?

И как ты ими отловишь ошибку, которая случилась на глубине, ну скажем вызовов 10-20? Как ты поймешь, что надо искать именно там? Что не говори, а поиск ошибки по тесту намного дороже, чем по ошибкам компиляции. Ибо поиск по ошибкам компиляции вообще ничего не стоит.

Прекрасно, как мне теперь сгенерировать код, частью которого будет эта функция?

Там где мы генерим код достаем эту функцию и засовываем её куда надо. Твой КО.

Это первый вопрос. Второй - то есть вот с макросистемой у меня все это делается автоматом, а тут мне руками надо будет пидорасить типы типов и чтото там кудато класть? Совсем не весело :(

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

В Н2 эти действия будут требовать чуть больше букв. А может и не будут. Типизатор еще не до конца проработан. За то другие действия ты на лиспе до пенсии писать будешь. Ты сам писал, что если экспандить нужно не все то... В Н2 это просто из коробки будет работать. Ибо ему направление распространения информации не важно.

Окей - это функциональное требования, которое создает кучу проблем, котоыре потом надо героически решать.

Оно решает несравнимо больше проблем чем создает.

То, что ты описал НЕ ДЕЛАЕТСЯ иначе как переписыванием expanda. В принципе не делается. Да, у тебя может не быть явно такой ф-и expand, но то что ты в итоге сделаешь будет совершенно эквивалентно этому переписыванию руками.

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

А в коде будут написаны только данные и взаимодействия. Дай то. Сложи с этим. Положи туда.

А типизатор подождет пока то и это будут вычислены, после чего сложит и положит куда надо.

По твоим описаниям - она нихрена не создает, приходится руками лезть в типы и чтото там делать.

Опять твои фантазии. Ты бы вместо оскорблений на ровном месте спокойно спрашивал бы чего не ясно.

Я описал конкретно как это делается в лиспе и как макросистема лиспа берет на себя ту самую чатсь работы, где ты лезешь руками внутри экспанда в тип и чтото там мудришь. Так что то что в лиспе не нужно это руками делать ДОКАЗАННЫЙ факт.

И как в лиспе сделать циклический обмен данными между двумя узлами через десяток посредников? Что может макросистема лиспа предложить нам для этого? НИЧЕГО.

То, что типизация макросов - алгоритмически неразрешимая задача, немерлеблядь не смутило, лол.

Ну, точно с гопотой разговариваю. Наверное, пора заканчивать. Ничего интересного от тебя всё равно не узнаю.

Другими словами ты даже не сможешь написать алгоритм, который смог бы типизировать ОДИН КОНКРЕТНЫЙ НАБОР МАКРОСОВ. Про произвольные макросы и речи не идет, дружок.

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

anonymous
()
Ответ на: комментарий от anonymous

Только обычно приходится писать руками, а тут 90% реализации уже есть «искаробки».

Ну-ну.

Нет, никаких проблем с перегрузкой не возникает.

Под столом. Ты хоть раз типы в присутствии перегрузки выводил? По настоящему, а не для галочки.

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

anonymous
()
Ответ на: комментарий от anonymous

Ну это всё равно что выяснять «семантику» того бреда, что находится между /* и */. Ты просишь назвать «тип» синтаксической закорючки. Грамматику, пожалуйста:

u16 ::=
...
reg16 ::= ...
...
addr ::= ...

...

command ::=
  ...
  mov reg16, u16
  ...
  mov reg16, reg16
  ...
  mov reg16, (addr)
  ...
  mov (addr), reg16
  ...

семантические правила для команд - процедуры генерации опкодов, например:

void mov_r64_u64(R64 reg, U64 x)
{
    if (reg < r8) {
        emit_u8(0x48);
        if (x <= 0xFFFFFFFF) {
            emit_u8(0xc7);
            emit_u8(reg);
            emit_u32(x);
        } else {
            emit_u8(reg - 8);
            emit_u64(x);
        }
    } else {
        emit_u8(0x49);
        if (x <= 0xFFFFFFFF) {
            emit_u8(0xc7);
            emit_u8(get_u8(1, reg));
            emit_u32(x);
        } else {
            emit_u8(get_u8(1, reg) - 8);
            emit_u64(x);
        }
    }
}
quasimoto ★★★★
()
Ответ на: комментарий от anonymous

Лол. В статике я это написать не смогу.

Сможешь. Если не писать типы для ф-й то такое и будет.

У кого как. У меня типы очень подробные. Так что они много что ловят.

И все, что они ловят, ловит практически любой тест.

И как ты ими отловишь ошибку, которая случилась на глубине, ну скажем вызовов 10-20? Как ты поймешь, что надо искать именно там?

Так пиши контракты и не будет у тебя ошибок на такой глубине - дальше ф-и с контрактом ошибка не пройдет.

Ибо поиск по ошибкам компиляции вообще ничего не стоит.

Он стоит парсинг выблева тайпинференса и поиска места ошибки, которая может вообще где угодно - и тут даже стектрейса не будет.

Там где мы генерим код достаем эту функцию и засовываем её куда надо. Твой КО.

Каким образом засовываем мне хотелось бы узнать - весь хост-язык у нас не немерле, а ф-я - немерле, причем ф-я у нас существует только во время компиляции, а нам надо чтобы ОНА ЖЕ существовала в рантайме. Можешь привести пример? Это ведь всего две строчки.

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

Как мы выяснили автоматом у меня делается примерно 90% того, что делается руками у тебя.

В Н2 эти действия будут требовать чуть больше букв. А может и не будут. Типизатор еще не до конца проработан.

То есть ты вообще не знаешь, как это будет в немерле. Чего ты тогда говоришь с такой уверенностью? То, что вы хотите «сделать заебись» не значит того, что сделаете. Уже было множество попыток и все они упирались в фундаментальные проблемы.

За то другие действия ты на лиспе до пенсии писать будешь.

Другие - это какие?

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

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

Оно решает несравнимо больше проблем чем создает.

Что оно решает?

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

Угу, вот только логику распространения типизатор не знает. И ее тебе придется написать.

Опять твои фантазии. Ты бы вместо оскорблений на ровном месте спокойно спрашивал бы чего не ясно.

Да я уже заебался у тебя спрашивать, что не спрошу ты тупо игнорируешь.

И как в лиспе сделать циклический обмен данными между двумя узлами через десяток посредников?

КО намекает, что функция обмена данными между макросами не обязательно должна быть вызвана именно во время экспанда этого макроса. Как например в примере про инференс на синтаксических свойствах - экспанд инициирует цикл обновления типов у всех связанных термов, этот цикл в свою очередь может инициировать новый цикл и так далее до тех пор, пока типы не «устаканятся». То есть, условно говоря, когда вызван экспанд некоторой формы - это значит произошло что-то новое, то есть повилась какая-то новая информация. И дальше мы спокойно можем ее гонять туда-сюда сколько угодно и как угодно. попробуй придумать конкретный пример (что сделать) и я продемонстрирую.

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

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

anonymous
()
Ответ на: комментарий от anonymous

Вот в немерле самый мощный в мире вывод типов для языков с перегрузкой функций.

Это в чем выражается? Мне вот кажется, что в хаскеле инференс будет помощнее.

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

anonymous
()
Ответ на: комментарий от quasimoto

Ну это всё равно что выяснять «семантику» того бреда, что находится между /* и */. Ты просишь назвать «тип» синтаксической закорючки.

но у этой закорючки должно быть правило типизации, в соответствии с которым приписывается типа термам MOV A, B.

anonymous
()
Ответ на: комментарий от anonymous

MOV A, B.

A и B - undefined. В выражении mov ax,bx у mov тип r16 x r16 -> void, в выражении mov rax,rbx - r64 x r64 -> void. Нет такой вещи «MOV A, B». Ну или можешь считать, что у тебя есть сумма reg = r16 + r32 + r64, тогда mov_,_ : reg x reg -> void. Также u = u16 + u32 + u64 и mov_,$_ : reg x u -> void. Ну и mov_,(_) : reg x addr -> void; mov(_),_ : addr x reg -> void, mov_,(_)+_ : reg x addr x offset -> void и т.д.

quasimoto ★★★★
()
Ответ на: комментарий от anonymous

И как же мне пропускает MOV AX, BX, если аргумент должен иметь тип reg32, а он reg16?

О чем ты вообще?

Алсо - если я вместо регистра вообще участок памяти укажу? Как это в твоем типе отражено?

Что тебе непонятно в (reg32, word32) -> void ?

Хуевый какой-то ты тип выписал.

Для иллюстрации идеи - вполне нормально.

tailgunner ★★★★★
()
Ответ на: комментарий от Harald

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

А как же сопроцессор и числа с плавающей точкой?

Не понял проблемы. Результаты некоторых операций не определены. Результат деления на 0, например.

tailgunner ★★★★★
()
Ответ на: комментарий от quasimoto

Это просто тот же вывод для локальных биндингов (вроде присваиваний и let)

Да. Но, наверное, можно и немного обобщить - объявления типов делаются на границах модуля (все внешние интерфейсы снабжаются объявлениями типа, остальное выводится).

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Сможешь. Если не писать типы для ф-й то такое и будет.

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

Так пиши контракты и не будет у тебя ошибок на такой глубине - дальше ф-и с контрактом ошибка не пройдет.

Те типы это плохо, а контракты на каждый чих хорошо. Прэлэсно.

Он стоит парсинг выблева тайпинференса и поиска места ошибки, которая может вообще где угодно - и тут даже стектрейса не будет.

Я не помню когда вывод типов немерла промахивался. Ошибка показывается всегда там, где она есть.

Каким образом засовываем мне хотелось бы узнать - весь хост-язык у нас не немерле, а ф-я - немерле, причем ф-я у нас существует только во время компиляции,

Хост язык у нас манипулирует кодом на немерле. Так что и функцию немерла он может таскать, как ему захочется.

а нам надо чтобы ОНА ЖЕ существовала в рантайме. Можешь привести пример? Это ведь всего две строчки.

1)Этого в условии не было.

2)Зачем это надо? Засунул куда надо во время компиляции и пусть себе вызывается.

Как мы выяснили автоматом у меня делается примерно 90% того, что делается руками у тебя.

У тебя только в одном направлении данные автоматом распространяются. А у меня в любом.

То есть ты вообще не знаешь, как это будет в немерле. Чего ты тогда говоришь с такой уверенностью? То, что вы хотите «сделать заебись» не значит того, что сделаете. Уже было множество попыток и все они упирались в фундаментальные проблемы.

Года полтора-два назад орлы вроде тебя мне про парсер то же самое говорили. Но он уже работает. И сейчас обзаводится очень быстрым кодом разбора. Чтобы в ИДЕ мог работать без проблем.

Все основные алгоритмы уже придуманы. А вот синтаксис еще нет. Так что в реализуемости у меня сомнений нет. А вот как оно будет выглядеть, хрен его знает. Тут нужно много думать и смотреть на реализацию наиболее распространенных случаев. Ведь если я тебе сейчас выдам сырой синтаксис, где работа идет напрямую с вычислительной моделью, ты начнёшь кричать «Я же говорил что это говно!». А то, что в конечном продукте ничего подобного не останется, даже слушать не станешь.

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

Я знаю.

но с какой стати направление не важно? В макросах нельзя использовать сайд-эффекты? Какие еще ограничения?

С такой. Что касается сайдэффектов то это зависит, что под ними понимать. Если под ними понимать может ли макрос повлиять на другие макросы? Да, может.

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

Как я это добьюсь? Есть несколько вычислительных моделей, в том числе полных по Тьюрингу порядок вычисления в которых не влияет на результат. В чистом виде ни одна из них не подходит. Но вот если совместить...

anonymous
()
Ответ на: комментарий от anonymous

Что оно решает?

Ловит ошибки. Позволяет эффективно исполнять код. Позволяет сделать человеческую ИДЕ.

Угу, вот только логику распространения типизатор не знает. И ее тебе придется написать.

Что еще за логика распространения? Зависимостей достаточно. Написал a = b, теперь компилятор знает, что если в a или в b появились данные их нужно передать дальше. Вот и вся логика распространения.

Да я уже заебался у тебя спрашивать, что не спрошу ты тупо игнорируешь.

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

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

И как конкретно он будет это всё гонять? Императивно? Спасибо не надо. Я этого в немерле наелся по самые не могу. Без вычислительной модели, которая не зависит от порядка вычислений такие вещи делать просто нереально сложно. А уж взаимодействие таких процессов вообще тушите свет.

А тебя не смутило то, что в этих языках нету ни тьюринг-полной макросистемы,

За то полно языков с тьюринг полной системой типов. http://rsdn.ru/Forum/Message.aspx?mid=4605502&only=1

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

И что? Новые типы в С++ мы вводим. И ничего. Живы ещё.

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

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

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

anonymous
()
Ответ на: комментарий от anonymous

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

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

Те типы это плохо, а контракты на каждый чих хорошо.

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

Я не помню когда вывод типов немерла промахивался.

Не знаю на счет немерла. Тайпчекер хаскиля регулярно промахивается, например.

Хост язык у нас манипулирует кодом на немерле. Так что и функцию немерла он может таскать, как ему захочется.

Угу, я оговорился - перепутал хост-язык с целевым. И так, мы в немерле определили функцию, тепреь надо вставить ее в АСТ целевого языка. Как решается такая задача?

1)Этого в условии не было.

Как это не было? Было. Как можно вставить функцию, если ее не существует?

2)Зачем это надо? Засунул куда надо во время компиляции и пусть себе вызывается.

Куда надо - это куда? Короче, я прошу аналог такого кода:

(define-for-syntax (yoba x) x) ; определили функцию в компайлтайме

(define-syntax (yoba-macro stx) #,yoba) ;теперь при вызове (yoba-macro) на место этой формы будет подставлена функция yoba. Не определение ф-и и не ее имя - именно сама ф-я, сам этот объект.

У тебя только в одном направлении данные автоматом распространяются. А у меня в любом.

Только у тебя они в любом (да и вообще в каком-либо) направлении распространяются не автоматом, а после того, как ты напишешь чекер, в котором будет описана логика этого распространения. И так вот на каждый макрос, который передает данные тебе придется переписывать чекер.

Года полтора-два назад орлы вроде тебя мне про парсер то же самое говорили.

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

Все основные алгоритмы уже придуманы.

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

Ведь если я тебе сейчас выдам сырой синтаксис, где работа идет напрямую с вычислительной моделью, ты начнёшь кричать «Я же говорил что это говно!». А то, что в конечном продукте ничего подобного не останется, даже слушать не станешь.

Ну вот смотри - ты заранее сказал что это сырой синтаксис. Теперь можешь привести его пример. Я жду.

Я знаю.

И какая же?

С такой. Что касается сайдэффектов то это зависит, что под ними понимать.

Например - вывести на печать что-нибудь. Или добавить/убрать/изменить информацию в лексическом контексте.

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

Придется сильно ограничивать выразительность макросов тогда. «Сильно» - всмысле так, что макросы можно будет вообще убрать и заменить их обычной системой типов. Это какбе факт.

anonymous
()
Ответ на: комментарий от anonymous

Ловит ошибки. Позволяет эффективно исполнять код. Позволяет сделать человеческую ИДЕ.

Но ведь все это можно и без статики делать.

Что еще за логика распространения?

Какие данные куда идут, очевидно.

Ты не спрашиваешь.

Я выше задавал ряд конкретных вопросов. И повторял их. Причем не раз повторял. А потом заебался. Вот и все.

И как конкретно он будет это всё гонять? Императивно?

Конечно. Самый лучший способ.

Без вычислительной модели, которая не зависит от порядка вычислений такие вещи делать просто нереально сложно.

к сожалению такой модели (достаточно выразительной) не существует и существовать не может. те самые фундаментальные причины, да :(

За то полно языков с тьюринг полной системой типов.

И тайпчек в них алгоритмически незрешим. Что и требовалось доказать.

И что? Новые типы в С++ мы вводим. И ничего. Живы ещё.

При чем тут типы? Я говорю о семантических правилах. Итак, что тебе обязательно нужно, чтобы сделать тайпчек макрсоов не раскрывая их:

1. каждый макрос вводит вместе с синтаксисом семантическое правило для типизации

2. То есть ты должен проверить тело макроса на тот факт, что он действительно генерирует код в соответствии с этим правилом и в соответствии с ним же взаимодействует с контекстом. Поскольку код макроса тьюринг-полон, задача алгоритмически неразрешима, придется писать прувер и доказывать корректность макроса руками каждый раз.

3. Правила не должны быть противоречивы - иначе мы как в Qi сможем доказать компилятору, что в сложении числа со строкой нету ничего плохого. Естественно, задача опять алгоритмически неразрешима, по-этому для каждого правила (то есть с написанием каждого макроса заново доказывать надо будет) надо доказать руками тот факт, что правило не противоречит остальным. Причем при введении некоторых правил система может стать неразрешимой - непротиворечивость будет доказать нельзя даже руками. И мы этого даже не узнаем - будем просто пытаться доказать, пока не надоест.

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

anonymous
()
Ответ на: комментарий от anonymous

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

Бывают и такие. И что дальше? Нормальные люди даже на хаскеле сигнатуры публичным функциям пишут. Так что далеко такой массив не уйдет.

Не на каждый чих а в тех же местах, в которых ты писал бы типы.

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

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

У меня прямо противоположное мнение.

Ну и не стоит забывать, что эти самые контракты проверяются в рантайме. И жрут процессор. А если контракт проверяет, что массив отсортирован? А если массив длинный? А если в цикле. Ой.

При этом я знаю кучу систем типов, в том числе вполне практичные, которые могут это контролировать без затрат времени в рантайме.

Не знаю на счет немерла. Тайпчекер хаскиля регулярно промахивается, например.

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

anonymous
()
Ответ на: комментарий от anonymous

Угу, я оговорился - перепутал хост-язык с целевым. И так, мы в немерле определили функцию, тепреь надо вставить ее в АСТ целевого языка. Как решается такая задача?

Мы не можем вставить кусок Н2 в куда попало. Это просто не имеет смысл. Но мы при помощи Н2 можем собрать любой код на целевом языке и вставить его куда нужно. В чем проблема то?

теперь при вызове (yoba-macro) на место этой формы будет подставлена функция yoba. Не определение ф-и и не ее имя - именно сама ф-я, сам этот объект.

Зачем? Какую практическую задачу это решает?

Только у тебя они в любом (да и вообще в каком-либо) направлении распространяются не автоматом, а после того, как ты напишешь чекер, в котором будет описана логика этого распространения. И так вот на каждый макрос, который передает данные тебе придется переписывать чекер.

Это опять твои фантазии. Типизатор у меня будет модульным. Каждый модуль будет обрабатывать один узел АСТ или небольшую группу узлов. Описание типизатора для каждого узла будет маленьким. И уж точно не нужно будет ничего менять в описании типизации других узлов. Ты мой парсер то видел? А ты посмотри. Он во время разбора может загружать в грамматику новые правила. И все прекрасно работает. Ибо парсер у меня модульный. Неужели думаешь, что я с типизатором такое не повторю?

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

Парсеры они разные бывают. Написать рукопашный парсер калькулятора это действительно просто. Парсер лиспа еще проще.

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

anonymous
()
Ответ на: комментарий от anonymous

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

Это опять твои фантазии. Я решаю разрешимые задачи. А не то, что ты там себе нафантазировал.

Например - вывести на печать что-нибудь. Или добавить/убрать/изменить информацию в лексическом контексте.

На печать нет. Изменять данные в лексическом контексте да. Лексический контекст это просто частный случай любых других данных. Но сильно засыпанный сахаром.

Придется сильно ограничивать выразительность макросов тогда. «Сильно» - всмысле так, что макросы можно будет вообще убрать и заменить их обычной системой типов. Это какбе факт.

Да как угодно называй. Если система типов позволяет типизировать любой язык, который вообще можно типизировать то меня такая «ограниченность» более чем устраивает. Это покроет все мои потребности. И потребности моих единомышленников. А то, что оно не будет соответствовать представлению лисповодов о макросах, меня волнует меньше всего.

Но ведь все это можно и без статики делать.

Нельзя. Я еще ни одного примера не видел.

И как конкретно он будет это всё гонять? Императивно?

Конечно. Самый лучший способ.

Не работает. Сложность становится просто нереальной. Особенно если начинается взаимодействие.

к сожалению такой модели (достаточно выразительной) не существует и существовать не может. те самые фундаментальные причины, да :(

То-то я и их несколько знаю. В том числе очень выразительные.

И тайпчек в них алгоритмически незрешим. Что и требовалось доказать.

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

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

Не должен. Фокус вот в чем. При раскрытии макроса он сгенерирует еще кучу нетипизированных узлов. Их в любом случае нужно типизировать. Мы просто фиксируем те типы, что уже выведены и типизируем раскрытый код. Если нашли противоречие, то говорим что в макросе косяк. Всё!

В немерле всё то же самое. То, что сгенерировал макрос, проверяется после раскрытия. Сам макрос никто и не думал проверять. В лиспе вообще никаких проверок нет.

Ну а для тех макросов, которые не Тюринг полные (а таких будет много) можно будет потом анализ написать. Чтобы программистам ошибки показывал.

anonymous
()
Ответ на: комментарий от anonymous

Так что далеко такой массив не уйдет.

Почему не уйдет? С какой стати он не должен уйти? Программа же корректно типизируется.

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

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

У меня прямо противоположное мнение.

Ну значит твое мнение неверноЮ, раз оно противоречит общепризнанным фактам.

Ну и не стоит забывать, что эти самые контракты проверяются в рантайме. И жрут процессор. А если контракт проверяет, что массив отсортирован? А если массив длинный?

Если хочешь проверить - проверяй, да.

При этом я знаю кучу систем типов, в том числе вполне практичные, которые могут это контролировать без затрат времени в рантайме.

Ни одной практичной системы типов, которая бы контролировала «отсортированность массива» нет. Или приведи пруф такой системы.

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

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

anonymous
()
Ответ на: комментарий от anonymous

Мы не можем вставить кусок Н2 в куда попало. Это просто не имеет смысл. Но мы при помощи Н2 можем собрать любой код на целевом языке и вставить его куда нужно. В чем проблема то?

То есть создать объект и вставить его нельзя? Печально.

Зачем? Какую практическую задачу это решает?

Например, она может замыкаться на контекст компайл-тайма. То есть полная рефлексия искаробки.

Это опять твои фантазии. Типизатор у меня будет модульным. Каждый модуль будет обрабатывать один узел АСТ или небольшую группу узлов.

О чем и речь - логика распространения информации пишется руками, в каждом узле.

Описание типизатора для каждого узла будет маленьким.

Конечно-конечно.

И уж точно не нужно будет ничего менять в описании типизации других узлов.

Как это не будет? Ты же только что рассказывал как легко менять семантику одного узла (макроса) из другого, а тут, выходит, этого не будет?

Он во время разбора может загружать в грамматику новые правила.

Да бога ради, пусть загружает. Плох тот парсер, который этого не умеет.

Неужели думаешь, что я с типизатором такое не повторю?

Конечно, нет. Разного класса задачи.

Парсеры они разные бывают. Написать рукопашный парсер калькулятора это действительно просто.

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

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

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

anonymous
()
Ответ на: комментарий от anonymous

Это опять твои фантазии. Я решаю разрешимые задачи. А не то, что ты там себе нафантазировал.

Я ничего не фантазировал. Ты сказал, что у тебя чекер чекает макросы до их раскрытия - это алгоритмически неразрешимая задача. Это общеизвестный факт, все. Если ты имел ввиду чтото другое - надо было яснее выражаться.

На печать нет. Изменять данные в лексическом контексте да.

А в чем отличие? Давай такой пример, у меня есть два макроса: yoba1 и yoba2. Первый макрос помечает лексический контекст каким-то образом (ну например присваивает какой-то выделенной переменной определенное значение), второй макрос в зависимости от того помечен ли контекст (соответствует ли значение переменной нужному) раскрывается либо в А либо в Б. Теперь давай посмотрим - если сперва раскроется yoba1, а потом yoba2, то yoba2 раскроется в Б. Если сперва раскроется yoba2, а потом yoba1, то yoba2 раскроется в А. Ты же говоришь, что у тебя результат не зависит от порядка - можешь пояснить?

Да как угодно называй. Если система типов позволяет типизировать любой язык, который вообще можно типизировать то меня такая «ограниченность» более чем устраивает.

Алгоритмически неразрешимо, извини :(

Нельзя. Я еще ни одного примера не видел.

Да любой номральный динамический ЯП. Все есть.

Не работает. Сложность становится просто нереальной. Особенно если начинается взаимодействие.

Нет, никакой сложности. Наоборот - это наиболее удобный способ борьбы со сложностью.

То-то я и их несколько знаю. В том числе очень выразительные.

Пруфы?

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

Ну вот а тебе в твоих макросах для каждого использованного цикла придется доказывать, что он закончится. Дошло, нет, в чем проблема? Если ты не докажешь, что он закончится - ты не докажешь корректность семантического оправила. А если не докажешь корректность семнатическог оправила - вся типизация псу под хвост, потому что никто не помешает складывать строки с числами и ловить жопой дилду в рантайме.

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

То есть макросы не типизируются до экспанда. Типизируется уже раскрытый код. Так бы сразу и говорил (ранее ты утверждал обратное - что-де все типизируется до экспанда) - это существенно упрощает дело, но превращает написание макросов в АД И ПОГИБЕЛЬ, потому что ошибки типов вообще ничего общего с макрокодом иметь не будут. Только представь - у тебя макрос вводит новую переменную, которая эффективно скрыта, и тут опа - ошибка типа в этой переменной! Каким образом пользователь должен будет догадаться, что это за ошибка, если он даже не знает о том что макрос вводит эту переменную во время экспанда? Придется все ошибки типов перехватывать и формировать нормальные сообщения руками. Естественно, это все будет занимать в нцать раз больше кода, чем собственно логика макроса. Естественно, все кейзы все равно предусмотреть не удастся, и иногда пользователь будет налетать на заботливо расставленные макрописателем грабли. Ляпота.

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

Ты смешной такой. Даже примитивные схемовские syntax-rules - тьюринг-полные. Если они не тьюринг-полными будут - ну это вообще пиздец, на таких макросах просто тупо нихуя не сделаешь. Не забывай что макрос - по сути ф-я в компайлтайме (то есть аппликация), причем ФВП как буд-то «искаробки» (т.к. можешь собрать форму макровызова из аргументов) вместе с рекурсивным вызовом (можешь раскрыться в самого себя). Это уже сразу дает тьюринг-полноту.

anonymous
()
Ответ на: комментарий от anonymous

алгоритм парсинга сам по себе очень интересный

чем?

вообще планы у вас замечательные, но количество глаголов будущего времени вызывает серьёзные сомнения в том, что сделано будет хотя бы 10% от заявленного

jtootf ★★★★★
()
Ответ на: комментарий от anonymous

В Visual Studio Ultimate контракты статически чекаются.

anonymous
()
Ответ на: комментарий от anonymous

Почему не уйдет? С какой стати он не должен уйти? Программа же корректно типизируется.

Так не уходит же.

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

Моя многолетняя практика не соответствует твоим сказкам.

Ну значит твое мнение неверноЮ, раз оно противоречит общепризнанным фактам.

Общепризнанным среди кого?

Ни одной практичной системы типов, которая бы контролировала «отсортированность массива» нет. Или приведи пруф такой системы.

liquid types например. Вполне можно использовать на практике.

Ну так в немерле то их тоже нет -

Я тебя понял. Макросы есть только в лиспе. Все остальное не макросы.

anonymous
()
Ответ на: комментарий от anonymous

Например, она может замыкаться на контекст компайл-тайма. То есть полная рефлексия искаробки.

После чего весь компаилтайм закатывается на кристал размером в пару килобайт. Я же говорю твой лисп крайне ограничен.

О чем и речь - логика распространения информации пишется руками, в каждом узле.

Какая еще логика? Только прикладные вычисления. Все остальное сделает Н2.

Как это не будет? Ты же только что рассказывал как легко менять семантику одного узла (макроса) из другого, а тут, выходит, этого не будет?

Ты опять что-то нафантазировал. Я говорил про то, что информацию из одного узла в другой передать легко. И на основе этой информации узлы могут делать то, что им надо.

Да бога ради, пусть загружает. Плох тот парсер, который этого не умеет.

О да. Покажи, какой умеет и при этом показывает скорость на уровне хотя бы ANTLR.

Конечно, нет. Разного класса задачи.

Согласен. Провернуть такой фокус с типизатором будет проще.

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

Тебя послушать так их должно быть на каждом углу. А их нет. Почему?

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

Так это... генератор парсеров, который не тормозит и расширяется в рантайме в студию. Мы тут весь интернет перерыли. Нет таких.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.