Size: a a a

Compiler Development

2020 March 16

AT

Alexander Tchitchigin in Compiler Development
Михаил Бахтерев
А какой смысл писать result = a - b, если  и так написано substract a b = a - b? Ведь, чисто с технической точки зрения, мы просто увеличиваем корректность кода повторением одного и того же в двух разных местах. Но, ведь, нет никаких гарантий, что ошибка именно на уровне типов, а не на уровне термов. Во-вторых, тесты делают то же самое. И можно строго доказать, что не нужно проверять каждую функцию в программе, а достаточно проверять свойства на верхнем уровне, и тогда с высокой степенью вероятности substract будет вести себя, как -.

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

Я вот недавно фигачил в марафонском режиме математический код на Схеме (сам не знаю, как так получилось), задача про bigdata, и структуры данных там были не самые тривиальные. Ошибки в типах при этом были редким явлением и совсем примитивное тестирование их обнаруживало сразу же. Основные ошибки были в самих вычислениях, даже в самой математической модели. И если бы мне пришлось всякий раз менять систему доказательств (даже если принять, что я мог бы выразить всю нужную мне математику в типах), я бы и за год не справился бы с этой задачей. Это можно утверждать наверняка, потому что есть же пример Certigrad,  где для обоснования простого градиентного спуска потребовалась годовая работа института. Хотя, на бумажке это делается минут за 15.

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

Или нет? Что я не вижу, не замечаю и игнорирую?
Fortress? 😉
источник

FO

FORTRAN ONE LOVE in Compiler Development
Alexander Tchitchigin
Поскольку генерируется код, а не бинарник, изучать его всегда можно. Некоторым-то и бинарник не проблема. 😊
Другое дело, что этот код ничем человеческий не напоминает.
Ну... Мой код и код, выплюнутый генератором, не сильно отличаются :)

(И вот теперь думайте, то ли у меня генераторы хорошие, то ли я говнокодер :) )
источник

M

MaxGraey in Compiler Development
Alexander Tchitchigin
А вот этого нельзя - чекер не пропустит... Можно сделать ошибку в типах/спецификации, но вот в доказательстве - нельзя.
Я не про семантические офибки, а скорее логических, например не полностью ограничения, некорректные условия, ошибки / неточности в спецификации. Ну и все что можно отнести к категории математического софизма.
источник

МБ

Михаил Бахтерев in Compiler Development
Alexander Tchitchigin
Fortress? 😉
Не знаю :( В том-то и проблема.
источник

МБ

Михаил Бахтерев in Compiler Development
У Fortress, мне кажется, проблема в том, что вот такое: y = 3 x sin x cos 2 x log log x читать невозможно. Когда вместо x появятся всякие сложные, длинные имена, станет тяжеловато.
источник

AT

Alexander Tchitchigin in Compiler Development
MaxGraey
Я не про семантические офибки, а скорее логических, например не полностью ограничения, некорректные условия, ошибки / неточности в спецификации. Ну и все что можно отнести к категории математического софизма.
Всё-таки ошибки в спецификации и ошибки в доказательстве - две большие разницы. И пафос machine-checked доказательств в том, что компьютер не пропускает "софизмы" и прочий handwaving.
источник

M

MaxGraey in Compiler Development
Alexander Tchitchigin
Всё-таки ошибки в спецификации и ошибки в доказательстве - две большие разницы. И пафос machine-checked доказательств в том, что компьютер не пропускает "софизмы" и прочий handwaving.
Интерестно, убежет ли она от «ошибки Эйлера»?) Я про 1 == -1
1  =>  √1 => √(-1)*(-1) => √-1 * √-1 => i * i => -1

? =)
источник

МБ

Михаил Бахтерев in Compiler Development
Вот есть, например, известная задачка о яйцах Фаберже и высоте небоскрёба. Там через handwaving можно обосновать формулу в три строчки. Обоснование при этом строгое. А если расписывать всё через арифметику, получается около 500 строчек кода. При чём, всё равно, приходится сначала давать handwaving-аргумент, чтобы формулу сформулировать, а потом приходится доказывать.

При этом, машинное доказательство, ещё и потребует такого кода, который для больших параметров просто работать не будет. Памяти не хватит :(

Есть ли выход из этого тупика?
источник

AT

Alexander Tchitchigin in Compiler Development
MaxGraey
Интерестно, убежет ли она от «ошибки Эйлера»?) Я про 1 == -1
1  =>  √1 => √(-1)*(-1) => √-1 * √-1 => i * i => -1

? =)
Думаю, что да. Там одно из преобразований одностороннее, когда все должны быть двусторонними. Такое не пройдёт.
источник

p

polunin.ai in Compiler Development
MaxGraey
но ведь ошибки можно допустить и при написании самих пруфов;)
Значит у тебя код в 99% случаев не скомпилируется
источник

МБ

Михаил Бахтерев in Compiler Development
MaxGraey
Интерестно, убежет ли она от «ошибки Эйлера»?) Я про 1 == -1
1  =>  √1 => √(-1)*(-1) => √-1 * √-1 => i * i => -1

? =)
Убережёт. Будет в типе sqrt записано, что требуется x >= 0.
источник

p

polunin.ai in Compiler Development
FORTRAN ONE LOVE
А пачку условий, если левый и / или правый меньше 0?
Там все это есть
источник

M

MaxGraey in Compiler Development
Михаил Бахтерев
Убережёт. Будет в типе sqrt записано, что требуется x >= 0.
Это комплексные числа
источник

МБ

Михаил Бахтерев in Compiler Development
polunin.ai
Значит у тебя код в 99% случаев не скомпилируется
Вон Compcert компилируется, а ошибки в нём до сих пор находят.
источник

AK

Andrei Kurosh in Compiler Development
Михаил Бахтерев
Вон Compcert компилируется, а ошибки в нём до сих пор находят.
Ну так 99%, а не 100 :)
источник

МБ

Михаил Бахтерев in Compiler Development
MaxGraey
Это комплексные числа
Хм... 🤔
источник

M

MaxGraey in Compiler Development
Было бы намного интерестнее если бы через мат индукцию выводились тесты. То есть ты пишешь пару простых тестов а солверы и программный синтез уже выводит все остальные случаи основываясь на коде и этой парочке тестов. Получается неплохой баланс мне кажется
источник

МБ

Михаил Бахтерев in Compiler Development
Такое пытаются делать в mini kanren
источник

p

polunin.ai in Compiler Development
Михаил Бахтерев
А какой смысл писать result = a - b, если  и так написано substract a b = a - b? Ведь, чисто с технической точки зрения, мы просто увеличиваем корректность кода повторением одного и того же в двух разных местах. Но, ведь, нет никаких гарантий, что ошибка именно на уровне типов, а не на уровне термов. Во-вторых, тесты делают то же самое. И можно строго доказать, что не нужно проверять каждую функцию в программе, а достаточно проверять свойства на верхнем уровне, и тогда с высокой степенью вероятности substract будет вести себя, как -.

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

Я вот недавно фигачил в марафонском режиме математический код на Схеме (сам не знаю, как так получилось), задача про bigdata, и структуры данных там были не самые тривиальные. Ошибки в типах при этом были редким явлением и совсем примитивное тестирование их обнаруживало сразу же. Основные ошибки были в самих вычислениях, даже в самой математической модели. И если бы мне пришлось всякий раз менять систему доказательств (даже если принять, что я мог бы выразить всю нужную мне математику в типах), я бы и за год не справился бы с этой задачей. Это можно утверждать наверняка, потому что есть же пример Certigrad,  где для обоснования простого градиентного спуска потребовалась годовая работа института. Хотя, на бумажке это делается минут за 15.

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

Или нет? Что я не вижу, не замечаю и игнорирую?
>тесты делают то же самое
Нет, тесты подтверждают правильное поведение программы только на определенных входных данных. А здесь мы можем быть уверены что если теорема написана правильно, то программа будет работать на всех входных данных.
>А какой смысл писать ...
Перестраховка. Написал два раза, и можешь быть уверен что если программа скомпилировалось, то ты не поставил там по пьяни другой знак. Ну или ты совершил одинаковую ошибку в коде и пруве, но я не знаю кем нужно быть чтобы такое совершить.
>Чтобы я видел что здесь можно вызвать undefined
В нормальных языках с сильной системой типов нет undefined
>Недавно фигачил в марафонском режиме...
Можешь не использовать прувы. Но в таком случае практически всегда в программе будут баги, так как тесты не могут покрыть весь код и все возможные варианты данных.
источник

M

MaxGraey in Compiler Development
Михаил Бахтерев
Такое пытаются делать в mini kanren
Спасибо за наводку!
источник