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

dynamic-wind? Не, не слышал.

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

Говорю же инварианты разваляться. И ничего ты с эти не сделаешь.

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

JetBrains со своим MPS уже пытались выпендриться. И чем все закончилось? Пшиком и позорнейшим Kotlin-ом. Идете по их стопам?

Нет. Мы идем другим путем.

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

Какой прэлэсный переход на личности с оскорблениями. Слив засчитан.

Просто не пытайтесь выставить свое нелепое хобби как что-то значимое.

Я не представляю. Я делаю.

anonymous
()

и вообще - годный вброс, бро!

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

Хотя, Wolfhound, лучше б ты таки ширялся...

Какой шикарный слив. День прошёл не зря.

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

Ты даже не понял где проблема. Она не в том чтобы код переписать, а в том, чтобы сохранить инварианты. А это никаким CPS преобразованием не сделать. Ибо после того как детерминированная финализация закроет файл продолжение может вернуть управление в ту точку в который файл как бы еще открыт. И всё. Приехали. Инварианты программы нарушены. Пошло неопределенное поведение. Здравствуй худшая сторона С/С++.

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

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

А я и говорю про удобство. Максимум что могут динамисты это отжать десяток процентов кода. И то не всегда.

Замечательно. И за что я плачу эти 10% кода?

Он статически типизирован. Что может убрать динамическая типизация?

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

Хватит сказки рассказывать. Вывод типов выводит чуть менее чем все типы.

При чем тут вывод типов? Напиши мне аналог лисповой функции flatten на каком-нибудь хаскеле. Не можешь? Вот то-то и оно.

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

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

Это твоя вера.

Это не вера - это факт. Возьми любой более-менее сложный макрос и попробуй портировать его под статическую систему. Начнется жуткий турбоотсос. Это в том случае, если портировать вообще _можно_, а скорее всего будет нельзя - т.к. большинство возможностей макросистемы наличие типизации закрывает. Будешь лепить нелепые костыли и work-around'ы, да и с ними результат выйдет говном. В итоге переизобретешь динамику.

Да никто. Просто ты проделаешь на пару порядков больше работы чем на Н2.

Это уже зависит от качества библиотеки. На данный момент используя любой ЯП я выполню работу заведомо быстрее, чем на немерле2 (учитывая, что пока что нет никакого немерле2), т.к. любое конечное время заведомо меньше бесконечного времени. Я же вначале конкретно спросил - чем мне немерле2 поможет в парсинге и кодогенерации больше, чем хорошая библиотека для этих целей или препроцессор в рамках любого %langname%? Вместо того, чтобы ухватиться за эту возможность и расписать фичи немерле2, ты сказал «кукареку».

Ты даже не понял где проблема.

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

Ты просто не понимаешь и даже не пытаешься понять что такое Н2.

Так я спросил у тебя - чем он отличается от препроцессора (потмоу что по твоему описанию выше - ничем)? Ты ничего толкового не ответил. Пока что ВСЕ, что ты описал решается путем обычной библиотеки парсинга/кодогенерации. И никаких способов решения тех задач, которые решаются макросами, твой немерле не предоставляет. или предоставляет? Какие? Как мне сгенерировать макрос, который раскрывается в определение другого макроса, хотя бы? Локальные макросы как делать?

> Не волнуйся. Как работают макросы лиспа я знаю.

Сомнительно. Если бы это было так, то ты бы знал, что описанные возможности немерле2 покрывают ну максимум 10% возможностей продуманной макросистемы. естественно, ты, со стороны своего немерле-огрызка, о мощности выразительных средств макрсоов судить не в состоянии - парадокс блаба во всей красе.

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

Ну так нехер использовать сырой call/cc тогда в том случае.

Рад, что до тебя, наконец, дошло, что call/cc и детерминированная финализация не совместимы.

Это принципиально задача именно для ограниченных продолжений.

Другими словами резать продолжения. Что я изначально и сказал.

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

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

А он не будет восстанавливать объект. Рантайм просто не даст тебе прыгнуть внутрь некорректного контекста, вот и все.

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

Другими словами резать продолжения. Что я изначально и сказал.

Ты так говоришь, как будто урезанные продолжения под обёртками try-catch-finally и т. п. не могут жить параллельно с call/cc, который оставлен для желающих сделать «что-то эдакое».

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

call/cc это goto от функциональщины. Дай обезьянам try-catch-finally — 75% причин использовать goto отпадёт. Добавь named break/continue — прощай ещё 20%. Приправить сверху генераторами с их yield — ещё 4% уйдёт.

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

Другими словами резать продолжения.

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

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

Замечательно. И за что я плачу эти 10% кода?

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

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

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

А если мы говорим про предметно ориентированные системы типов, то там вообще не ясно с чем можно сражаться.

При чем тут вывод типов? Напиши мне аналог лисповой функции flatten на каком-нибудь хаскеле. Не можешь? Вот то-то и оно.

Это тот Flatten который список списков в список превращает? Так в немерле я его использую регулярно.

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

На счет надежности - никаких практических подтверждений этому нет.

Ага, конечно.

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

Хочешь сравнить с С++? Или хотя бы с немерле?

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

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

Как мне сгенерировать макрос, который раскрывается в определение другого макроса, хотя бы? Локальные макросы как делать?

Не нужно. У Н2 есть типизатор. Он в плане распространения информации является строгим надмножеством твоих хотелок.

Сомнительно. Если бы это было так, то ты бы знал, что описанные возможности немерле2 покрывают ну максимум 10% возможностей продуманной макросистемы. естественно, ты, со стороны своего немерле-огрызка, о мощности выразительных средств макрсоов судить не в состоянии - парадокс блаба во всей красе.

В том то и дело. Что я понимаю, как работает лисп. А ты не понимаешь что такое Н2.

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

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

Нужен один язык, который покрывает 80% задач и обладает средствами расширения, чтобы покрыть остальные 20%. Немерль1 был таким языком.

Неверно. Язык-то может и покрывать 80% задач - но только для своей платформы. А перенеси его, например, в embedded, на микроконтроллеры - и он и одного процента не покроет.

(пожимая плечами) Си довольно долго был языком тех самых 80% задач.

Так что языков нужно много и разных.

Языков нужно столько, сколько нужно, и не более %)

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

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

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

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

+1

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

За то, что компилятор поймает кучу ошибок.

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

И я не помню ни одного случая, чтобы после этого сломался хоть один тест.

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

Ни разу в жизни не сражался с тайпчекером.

Где мой flatten?

Это тот Flatten который список списков в список превращает?

Который превращает в список список списков _любой вложенности_.

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

Вот именно. Там вообще система типов не нужна - 90% инвариантов фиксируются синтаксисом и верно выбранным интерфейсом (это, кстати, гораздо более мощный метод гарантий надежности, чем любая система типов - вон тот же хаскель, вроде система типов мощная, а корректность того же IO держится на банальном скрытии конструктора IO, без помощи типов). Оставшиеся 10% - за счет работы с контекстом (чего ты в своем немерле сделать не сможешь - ведь доступа к рантайму нет).

Ага, конечно.

А есть? пруфы можно? Я сколько не видел исследований - везде разница между статической и динамической типизацией был незначима.

Хочешь сравнить с С++? Или хотя бы с немерле?

Зачем? Я с хаскелем сравнил. И вижу, что статика особого выигрыша не дает. Значит, дело не только и даже не столько в статике.

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

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

Не нужно. У Н2 есть типизатор. Он в плане распространения информации является строгим надмножеством твоих хотелок.

Наоборот - любая система типов является строгим подмножеством достаточно мощной системы метапрограммирования. Хорошо, более конкретно - вот у нас есть некоторый дсл, этот дсл выглядит примерно так (dsl settings body ...). body - это обычный код, причем в этом коде могут встречаться определенные специально для нашего дсл макросы (например macro1 и macro2), применение которых будет ошибкой вне этого дсл и ход раскрытия которых зависит от конкретно указанных settings. Причем мы, конечно же, можем определять макросы, которые будут раскрываться в эти макросы (то есть какой-нибудь macro3, раскрывающийся в код с использованием macro1/macro2). Как это сделать?

В том то и дело. Что я понимаю, как работает лисп.

Нет, не понимаешь.

А ты не понимаешь что такое Н2.

Я уже дважды спрашивал, спрошу в третий раз - в чем принципиальное отличие н2 от препроцессора и чем н2 лучше продуманной бибилотеки для парсинга/кодогенерации?

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

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

1)Обычно можно писать не весь компилятор, а расширить язык. Если конечно язык можно расширять. 2)У меня не было еще ни одного случая, чтобы рантам был бы хоть 10% от кода компилятора.

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

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

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

2)У меня не было еще ни одного случая, чтобы рантам был бы хоть 10% от кода компилятора.

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

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

Обычно можно писать не весь компилятор, а расширить язык.

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

Интересно. Можно пару примеров задач?

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

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

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

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

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

:)))) Под столом.

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

Нет. Ты увидишь диагностику хрен знает, где и хрен знает на что.

А мне статика точно говорит, где код изменить надо.

Где мой flatten?

Не знаю. Мой flatten прекрасно работает.

Который превращает в список список списков _любой вложенности_.

Ни разу желания не возникало. Но не трудно сделать и такую систему типов. Например С++ так может.

Вот именно. Там вообще система типов не нужна - 90% инвариантов фиксируются синтаксисом и

:))) Под столом.

верно выбранным интерфейсом

Интерфейсом чего?

Оставшиеся 10% - за счет работы с контекстом (чего ты в своем немерле сделать не сможешь - ведь доступа к рантайму нет).

Ты про что?

Зачем? Я с хаскелем сравнил. И вижу, что статика особого выигрыша не дает. Значит, дело не только и даже не столько в статике.

Разницу между необходимым и достаточным условием понимаешь?

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

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

Это называется резать продолжения. О чем я сразу и сказал. С чем тут спорить то?

Наоборот - любая система типов является строгим подмножеством достаточно мощной системы метапрограммирования.

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

Хорошо, более конкретно - вот у нас есть некоторый дсл, этот дсл выглядит примерно так (dsl settings body ...).

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

А теперь вопрос к тебе: Как мне передать информацию от вложенного макроса внешнему? А соседу?

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

А как делать это в случае с макросами? Внешний макрос то раскрылся. Да и сосед в зависимости от порядка раскрытия мог уже раскрыться. А если цикл? А если несколько?

Вот, например https://github.com/rampelstinskin/ParserGenerator/blob/7eabf20f45f1dc47525fcc...

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

Я уже дважды спрашивал, спрошу в третий раз - в чем принципиальное отличие н2 от препроцессора и чем н2 лучше продуманной бибилотеки для парсинга/кодогенерации?

Тем, что кода будет в десятки, раз меньше и работать будет в десятки раз быстрее. Про мелочи типа ИДЕ можно вообще не заикаться.

Я думал такие вещи для адепта метапрограммирования должны быть очевидны.

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

Нет. Ты увидишь диагностику хрен знает, где и хрен знает на что.
А мне статика точно говорит, где код изменить надо.

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

Без статической типизации быстрого кода быть не может.

Есть какие-то обоснования этого факта? То есть код на ассемблере (ЯП с динамической типизацией) вполне себе может быть быстрым. И это опроврегает твое мнение.

Это называется резать продолжения.

Нет, это не называется «резать продолжения». Где ты их тут режешь? Не хочешь - можешь барьеры не ставить.

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

В локальные макросы можно засунуть все. То есть вообще ВСЕ. Абсолютно все. В типы же произвольного рода информацию не засунешь ну ни как.

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

Пример приведи.

А теперь вопрос к тебе: Как мне передать информацию от вложенного макроса внешнему?

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

Тут CalcGrammar и IncGrammar ссылаются друг на друга. Они должны убедиться, что все правила есть. Должны получить их типы, чтобы сгенерировать типизированное АСТ.

Непонятно, в чем проблема. Раскрываем всю мета-информацию по месту вызова и делаем (syntax-local-lift-module-end-declaration form), где form - собственно та часть обоих «модулей», которая должна раскрываться, имея полную метаинформацию. Ну или если хочется - можно просто в санки обернуть и вызывать одну санку из другой.

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

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

А еще мои волосы на лобке станут длинными и шелковистыми. Вопрос заключался в том, ЗА СЧЕТ ЧЕГО кода будет меньше и работать будет в десятки раз быстрее? Чем н2 отличается от препроцессора? Конкретные отличия назови. То есть вот: «у нас в н2 есть следующая фича - делаешь так и эдак и получается от оно как! а с препроцессором это будет сделать трудно/невозможно!» - именно такого ответа я хотел. Он будет?

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

Точно так же как мы находим переменные.

А вообще все ясно - то есть просто переписываем функцию «expand» на какую-то самопальную - которая сама, чудесным образом, будет и переменные искать и информацию передовать и кофе наливать. Нет, спасибо, я не хочу писать реализацию экспанда для каждого макроса двухстрочника.Я лучше напишу макрос-двухстрочник и поеду на море отдыхать, а немерлеблядь пускай переизобретает лисп. Да, к слову, переопределять экспанд можно и в лиспе, причем давно - н2 опять в прососе.

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

А что, ассемблер-таки статически типизирован? И какие же там типы есть?

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

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

А что, ассемблер-таки статически типизирован?

Да.

И какие же там типы есть?

Байты и слова.

дело не в статической типизации, а в модели исполнения ЯП

Конечно. И при исполнении кода динамически типизированного языка код разбивается на статически типизированные участки, которые и компилируются в машкод («runtime specialization»). Почитай, например, о PyPy (но другие JIT'ы динамических языков работают похоже).

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

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

Который типизирован динамически, ага.

Байты и слова.

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

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

В случае ошибки в рантайме место и характер ошибки указываются более точно.

Дада, например, «1 is not NULL» + невменяемый стек вызовов - и ищи в тысячах кода где число попало на место списка. При этом в статике такое вообще невозможно.

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

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

Который типизирован динамически, ага.

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

Во-вторых - если в машкоде будет ошибка типов, то она произойдет в рантайме.

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

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

Дада, например, «1 is not NULL» + невменяемый стек вызовов - и ищи в тысячах кода где число попало на место списка.

Что это за бред? Мы о нормальных языках говорим, а не о говне, которое выблевывает вместо ошибки «1 is not NULL» + невменяемый стек вызовов.

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

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

Правильно. А почему? Да потому что в динамических программах ошибок типов не бывает - они все правильные с этой точки зрения. Потому что там тип один: T. Все его принимает и его же возвращает.

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

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

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

Что это за бред?

Реальная ситуация. Сейчас я нечто подобное вижу с node.js (а то что там весь рантайм держится на честном слове кооперативной многозадачности - вообще сказка) и единственный способ добиться вменяемой информации о состоянии системы - куча отладочной информации и тестов часто делающих то что должна делать система типов.

Мы о нормальных языках говорим, а не о говне, которое выблевывает вместо ошибки «1 is not NULL» + невменяемый стек вызовов.

Это SBCL себя так иногда ведёт :)

А как иначе? Динамика предполагает контракт ... T ... -> ... T ..., но код при этом сугубо частичен, то есть на аргументе типа T вызываются функции типа ... (a <: T) ... -> ... В сколько нибудь сложном control flow на это место рано или поздно попадает (b <: T) отличный от a и код уходит в исключение/рестарт - можно остановит нить и предъявить стек вызовов (который может быть большой) до места где b попало на место a, также озвучить типы a и b вместе с объектом b. Но почему это происходит ещё предстоит выяснить (то есть почему данные формируются так и программа работает так, что, например, числа попадают в ту часть control flow где должны быть списки). Система типов при этом это всегда нечто такое, что должно сделать поведение программы более _логичным_ (жестким и специфичным).

quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 1)
Ответ на: комментарий от anonymous

если в машкоде будет ошибка типов

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

Правильно.

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

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

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

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

Реальная ситуация. Сейчас я нечто подобное вижу с node.js (а то что там весь рантайм держится на честном слове кооперативной многозадачности - вообще сказка)

В js слабая типизация, о чем речь вообще?

Это SBCL себя так иногда ведёт :)

Да, я вкурсе.

А как иначе?

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

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

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

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

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

Ты другой анонимус?

Тот же.

А то совсем недавно было «ошибка типов в машкоде», а сейчас «правильно, в машкоде не бывает ошибок типа».

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

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

Именно так. Потому что ЯП, в котором один тип (не путать с «тип», тип - это в компайлтайме, «тип» - это в рантайме) - это и есть динамически типизированный ЯП. По определению. Вот в лиспе тоже один тип - лисп динамически типизирован.

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

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

Естественно.

Okay.

Статическая типизация — это когда компилятор может контролировать целостность типов

Статическая типизация - это когда типы известны в момент трансляции. Как раз случай ассемблера.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Статическая типизация - это когда типы известны в момент трансляции. Как раз случай ассемблера.

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

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

Хотя... это как посмотреть. Если считать переменные только числами разрядностью в слово, то всё окей.

Так что скорее правильно говорить не о динамичности самих машинных кодов, так как с такой точки зрения там всё действительно статично: когда есть только числа, то затруднительно присваивать что-то кроме чисел. Скорее... динамичность выстраиваемых абстракций. Ведь такая «последовательность чисел» и есть абстракцией с точки зрения машкодов.

Вот только во всяких хаскеллах эти абстракции являются типами и на них можно натравить чекалку, а в ассемблере фиг, всё «на соплях».

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

Как раз все наоборот - тебе статика укажет «блаблабла не могу вывести типы блаблабла» причем место, которое оно укажет, может быть вообще в другом конце программы

Моя практика говорит, что компилятор в 99% случаев указывает точное место. А ИДЕ позволяет перейти к ошибке за один клик.

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

Есть какие-то обоснования этого факта? То есть код на ассемблере (ЯП с динамической типизацией) вполне себе может быть быстрым. И это опроврегает твое мнение.

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

В локальные макросы можно засунуть все. То есть вообще ВСЕ. Абсолютно все. В типы же произвольного рода информацию не засунешь ну ни как.

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

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

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

Я периодически слушаю плач VladD2 на тему как всё страшно в типизаторе немерла. А все по тому, что поляки все написали руками.

Но если вдруг хочется - просто сделай expand внутренней формы.

Я так и думал. Это называется через зад автогеном. И особое веселье начентся если одни макросы надо экспандить, а другие нет. А если случился цикл. То всё. Приехали.

Непонятно, в чем проблема. Раскрываем всю мета-информацию по месту вызова и делаем (syntax-local-lift-module-end-declaration form), где form - собственно та часть обоих «модулей», которая должна раскрываться, имея полную метаинформацию. Ну или если хочется - можно просто в санки обернуть и вызывать одну санку из другой.

Примерно так я сейчас и делаю. Ибо нормального типизатора пока нет. Но это просто пиздец. Гора кода на ровном месте.

Теперь я хотел бы посмотреть на реализацию макроса syntax в н2

1)Это не макрос в твоем понимании этого слова. Н2 работает иначе.

2)Сейчас на 100% ясно как делать парсер. Типизатор еще не готов. Так что подожди. Но все заявленные фичи будут.

Вопрос заключался в том, ЗА СЧЕТ ЧЕГО кода будет меньше и работать будет в десятки раз быстрее?

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

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

Чем н2 отличается от препроцессора?

А что ты понимаешь под препроцессором? От Сишного препроцессора будет отличаться всем. Ну, то есть совсем ничего общего.

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

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

Вообще, блять, что такое статическая типизация в применении к машкоду? Какой тип у терма AX? А у терма MOV? А у терма MOV AX, BX? припиши-ка типы этим термам, будь добр.

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

Только вот беда: это называется сильная и слабая типизация. А не статическая-динамическая.

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

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

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

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

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

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

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

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

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

Есть компромисс - локальный вывод типов.

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

Моя практика говорит, что компилятор в 99% случаев указывает точное место. А ИДЕ позволяет перейти к ошибке за один клик.

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

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

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

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

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

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

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

Понятно. Раз лисп не может, значит это не нужно.

С чего ты взял что не может? В моем посте как раз прямо написано - может! Просто это затрудняет отладку в том числе. Если можно без этого обойтись - лучше обойтись. Если перед нами два решения и одно проще другого, а в остальном они равны - стоит выбрать более простое, не так ли? Коненчо, если более сложное решение имеет значимые профиты - то уже можно предпочесть его, с этим никто не спорит.

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

То есть сперва создаем проблему (вводим систему типов и тайпинференс), а потом ее героически решаем? Замечательно. Между тем я так и не увидел конкретного примера передачи произвольной информации между макросами в н2. И, напоминаю, все описанное тобой эквивалентно банальному переписыванию функции expand руками.

Более того перегрузки в общем случае создают варианты которые нужно перебирать с откатами. Делать это все руками полное самоубийство.

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

Я так и думал. Это называется через зад автогеном.

Где же через зад автогеном? Через зад автогеном - это ручное переписывание экспанда вмест оиспользование уже существующего и отлаженного алгоритма.

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

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

Да, действительно, в этом случае начинается веселье. В отличии от прошлых

задач (типа проброса информации о типах и т.п.) для которых _теоретически_

еще можно было сделать библиотеку обертку, в этом случае (когда одни

макросы надо раскрывать а другие нет) никакого другого способа решить

задачу кроме переписывания экспанда НЕТ даже в теории. Так что успехов тебе

в написании своей функции экспанда на каждый макрос. Еще интересно будет

посмотреть на то, как эти разные экспанды будут взаимодействовать между

собой при вызове одного макротрансформера, лол. Даже представить страшно,

на что обрекает себя наивная немерлеблядь. Сразу видно, что ничего сложнее

двустрочников она не писала и потому просто не представляет массив проблем,

который упадет на ее голову.

Примерно так я сейчас и делаю. Ибо нормального типизатора пока нет. Но

это просто пиздец. Гора кода на ровном месте.

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

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

макросистема. И тебе этого кода писать не надо. А с типизатором - надо.

По-меому, не писать код лучше, чем пистаь, сообенно если результат

одинаков.

1)Это не макрос в твоем понимании этого слова. Н2 работает иначе.

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

обмениваются между собой компайл-тайм информацией. Или не макросы а что у

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

кода написать не могут, хоть как у них его не проси. И вообще ничего

конкретного сказать не могут - только цитировать рекламные проспекты о том,

что с немерле мой хуй станет длиннее на 10 см.

2)Сейчас на 100% ясно как делать парсер. Типизатор еще не готов. Так что

подожди. Но все заявленные фичи будут.

Понятно, то есть кроме мокрых фантазий о том, как все будет заебись, нихуя

нет. Отлично просто. Неясно, о чем тогда вообще спор? Алсо, заявленные фичи

- это КАКИЕ? Я уже заебался у тебя спрашивать. Это четвертый раз (как

минимум), если что.

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

О каком мусоре речь?

Н2 сейчас для парсера (вот прямо сейчас пишу очень сильно

оптимизированный алгоритм разбора и в планах еще одна очень злая и куча

оптимизаций попроще), а потом и для всего остального будет генерировать

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

Почему? За счет чего?

Еще раз два ключевых вопроса:

1. за счет чего будет писаться меньше кода?

2. за счет чего будут сделаны йоба-потимизации (и почему они не сделаны в

библиотеках других ЯП)?

А что ты понимаешь под препроцессором?

Препроцессор - это такая хуйня, которая берет код, обрабатывает его каким-

либо образом и возвращает некоторый результат. Никаких ограничений на сам

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

нет.

А так с определенной натяжкой все компиляторы можно назвать

препроцессорами.

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

выразителен чем полноценная система метапрограммирования. То есть система

метапрограммирования может сделать все, что может сделать компилятор, но не

наоборот.

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

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

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