LINUX.ORG.RU

Homoiconic C

 homoiconicity,


3

2

Я тут упоролся и подумал, а что если бы у нас был ЯП уровня Си с гомоиконным синтаксисом в стиле Io или Julia. То есть — у нас есть интерпретатор гомоиконного языка, который работает как макропроцессор, и результат трансформаций исходного кода скармливается затем компилятору языка с Си-подобной семантикой. И у нас будет нормальный тьюринг-полный макроязык, который позволит бескостыльно расширять возможности ЯП неограниченно. Компилирующаяя же часть будет по сути обычным компилятором Си (просто читающим входные данные в неСишном синтаксисе).

Это ж кайф. Выражения типа regexp(«^[a-z][a-z0-9]») или format(«%s - %s (%d)», bla1, bla2, i) можно будет автоматически обрабатывать макропроцессором и отправлять компилятору оптимизированный вариант. Это значит, регулярка, например, будет скопилирована в конечный автомат при компиляции программы, а не при выполнении.

Вот эта вот странная задачка, на которой dr_jumba проверял лаконичность языков, записывалась бы как-то вот так:

sample_function := fn(a(iterable(T))) to(T) {
    a select(match(regexp(/^J[a-z]+/))) each_chunk(3) map(format_with("~1 and ~2 follow ~3")) join("\n")
}

Дискас.

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

Отлично, то что я понимаю программу на си, например, как описание _будущего_ процесса работы процессора, памяти, системных и библиотечных вызовов это pi = 4.

То есть тот факт что самолеты падать будут тебя не смущает?

«чистые тотальные функции» + «описания процессов» — другой возможный.

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

Ничего хорошего из этого не получится — при интерпретации типов как логических утверждений

Ну и не надо. Нам ехать, а не шашечки.

В таких случаях под ОДЗ алгоритма просто нужно понимать ровне те значения на которых он работает хорошо — эти UB и garbage нам не нужны.

Замечательно. Т.о. любая частичная ф-я становится тотальной (сужением ОДЗ). А алгоритм сервера остается алгоритмом - тотальная ф-я с пустым ОДЗ.

http://www.tiobe.com/content/paperinfo/tpci/images/history_paradigm_type syst...

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

Я не считаю блаблабла

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

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

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

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

То есть тот факт что самолеты падать будут тебя не смущает?

Меня просто удивляют твои ассоциации. Какие пи и самолёты вообще?

Что проще - писать программу, или писать программу, генерирующую программу?

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

А алгоритм сервера остается алгоритмом - тотальная ф-я с пустым ОДЗ.

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

Вообще прикольная будет новость — «сегодня состоялся такой-то выпуск алгоритма nginx» :) Вот то что в ngx_http_parse.c, например, это вполне алгоритмы, но не вся программа.

Так чем по-твоему объясняется взрывной рост популярности динамики в нулевых?

Если смотреть именно туда — линейный за пять лет, потом константа (и намёк на падение).

То, что в вебе алгоритмы простые - это не наблюдение, это твое _мнение_

Я не говорил что в вебе алгоритмы простые, я говорил про примитивное в вебе, про не примитивное судить не возьмусь — какая-то бизнес логика может быть даже в клиенте (статический ActionScript, динамический JS и что угодно динамическое или статическое компилируемое в JS), какая-то — на сервере (Groovy, JS в виде ноды, PHP, Python, Perl или статические C#, Java, Scala), за чем будут располагаться непосредственные бакенды делающие всю работу и «алгоритмы».

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

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

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

Меня просто удивляют твои ассоциации.

Какие ассоциации?

Какие пи

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

«программу, генерирующую программу» ты сам придумал.

Не надо врать. Это ты предложил вместо описания процесса (программы) делать описание описания процесса (программу, генерирующую программу).

Программа это и есть описание процесса а не сам процесс

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

За множество входных значений можно считать ядерные ресурсы — куда приходят оповещения, откуда происходит чтение и куда происходит запись.

Мост рухнет, самолет не взлетит, извини.

Но детерминированности, не пустого выхода и завершимости всё ещё нет — они есть у хендлеров.

А хендлеров у нас нет, они нам не важны. Речь именно о сервере самом - то есть лупе, который будет эти хендлеры обрабатывать.

Вообще прикольная будет новость — «сегодня состоялся такой-то выпуск алгоритма nginx»

Зачем?

Если смотреть именно туда — линейный за пять лет, потом константа

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

Я не говорил что в вебе алгоритмы простые, я говорил про примитивное в вебе

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

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

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

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

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

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

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

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

Какие ассоциации?

Вот:

Которую ты предложил во всех инженерных расчетах считать равной четырем

ты предложил вместо описания процесса (программы) делать описание описания процесса

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

Мост рухнет, самолет не взлетит, извини.

У тебя уже глюки начались, извини.

Речь именно о сервере самом - то есть лупе

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

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

А был ли мальчик? Ну удобно людям обвязку писать на скриптовых языках — отсюда и рост.

А не в вебе не бывает примитивного?

Почему именно примитивное в вебе — очень распространённая и доступная область, часто решения требуют исключительно написания бизнес логики вокруг готовых бакендов, тестирование = deploy — простые динамические языки находят своё применение.

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

Отсутствие чекера

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

Напомню, что до сих пор не было приведено _ни одного_ аргумента

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

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

У тебя уже глюки начались

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

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

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

Почему именно примитивное в вебе — очень распространённая и доступная область, часто решения требуют исключительно написания бизнес логики вокруг готовых бакендов, тестирование = deploy

Это верно для 99% индустрии программирования вообще, не только для веба. То есть веб не примитивнее всего остального.

экспериментальные наблюдения как-то противоречат действительности.

В чем именно противоречат? Я тебе конкретные противоречия твоей гипотезы назвал. Назови конкретные противоречия моей.

Несколько человек высказывались на тему времени жизни простой ошибки после запуска программы

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

Полезная величина - вероятность чекеру найти пропущенную при юнит-тестировании ошибку. И время жизни ошибки интересует нас лишь на столько, на сколько оно влияет на эту вероятность.

Другой аргумент про средства проектирования тоже был, ADT — sealed иерархии с разбором по типам

Паттерн-матчинг есть и в динамике.

модули в смысле ООП

ООП и модули тоже есть в динамике.

обобщённое программирование

Перекрывается макросами.

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

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

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

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

Одно — как раз твои (очень странные) ассоциации (то что из ложной предпосылки выводится всё что угодно, в том числе pi = 4, это bottom-elimination в логике высказываний, если ты забыл), а другого я не говорил — я говорил про описания процессов, всё как обычно, просто можно сваливать их в кучу, а можно разделять — описания чистых тотальных алгоритмов-функций отдельно, описания эффектов — отдельно, конкурентности и событий — тоже и т.д.

Мы же уже выяснили, что к определению википедии и кнута все подходит

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

В чем именно противоречат?

X используется, новые языки с X возникают, новые проекты на таких языках появляются, старые — развиваются, большинство тех самых бакендов (как и системное, прикладное и серверное ПО вообще) пишется на таких языках.

вероятность чекеру найти пропущенную при юнит-тестировании ошибку

Чекер это просто хорошо — как дополнительное средство к тестам. Зачем отказываться от дополнительных инструментов?

Паттерн-матчинг есть и в динамике.

А я говорю про закрытые ADT. Потом уже паттерн-матчинг с контролем за покрытием ветвей — паттерн-матчинг по всему что T такого контроля не даёт.

ООП и модули тоже есть в динамике.

За опусканием типов кто следит? За интерфейсами (вызываемый метод существует)?

Перекрывается макросами.

Это всё не то, статические контракты ты не проговоришь, либо запилишь ту же «статику на макросах».

Но ведь именно это ты и пытаешься доказать

Я ничего не пытаюсь доказать.

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

(то что из ложной предпосылки выводится всё что угодно, в том числе pi = 4, это bottom-elimination в логике высказываний, если ты забыл)

Именно об этом я и пытался тебе напомнить этими «ассоциациями».

У тебя раздвоение личности? Никто ничего не «выяснил» кроме тебя — алгоритм должен принимать опциональный (пустой или нет) вход, давать (не пустой) выход, состоять из конечного числа строго определённых шагов каждый из которых достаточно прост, эффективен и выполняется за конечное время в конечной памяти.

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

X используется, новые языки с X возникают, новые проекты на таких языках появляются, старые — развиваются, большинство тех самых бакендов (как и системное, прикладное и серверное ПО вообще) пишется на таких языках.

1. то, что ты написал не является синтаксически корректным утверждением вовсе (т.к. ты не указал квантор для х - всеобщности или существования?)

2. Даже если квантор и доставить - где противоречие то? Еще раз, противоречие заключается в том, что приводится пара утверждений с противоположной оценкой (X = не Y), из которых оценка одного заведомо известна (из наблюдений, например).

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

А я говорю про закрытые ADT.

Ну в динамике есть закрытые АТД.

Потом уже паттерн-матчинг с контролем за покрытием ветвей — паттерн-матчинг по всему что T такого контроля не даёт.

Но чем он лучше паттерн-матчинга без контроля за покрытием?

За опусканием типов кто следит?

Зачем кому-то следить за этим?

За интерфейсами (вызываемый метод существует)?

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

Это всё не то, статические контракты ты не проговоришь

А зачем их проверять? Что мне это даст?

Я ничего не пытаюсь доказать.

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

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

Именно об этом я и пытался тебе напомнить этими «ассоциациями»

Но ложная предпосылка P в том, что я что-то говорил про описания описаний (P1), а не в том что программы это описания процессов (P2). Если я сказал P1, то ассоциация P1 -> pi = 4 законна и ты прав (предполагая что P1 это абсурд, хотя ассоциация всё равно негодная и непонятно чем плохи описания описаний и в чём тут абсурд, но я об этом даже не хочу говорить), если твоя ассоциация это P2 -> pi = 4 про моё P2, то это плохо, так как P2 — хорошо, ты не прав :)

Даже если квантор и доставить - где противоречие то?

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

Это как раз _твое_ определение алгоритма, а не Кнута, не надо перевирать

А чем пять пунктов Кнута или

algorithm is an effective method expressed as a finite list[1] of well-defined instructions[2] for calculating a function.[3] Starting from an initial state and initial input (perhaps empty),[4] the instructions describe a computation that, when executed, will proceed through a finite [5] number of well-defined successive states, eventually producing «output»[6] and terminating at a final ending state.

от этого отличаются?

Ну в динамике есть закрытые АТД

То есть ты можешь вообразить, что твои int и string, например, это такой умозрительный вариант (or int string), хотя оно на самом деле T и никакого закрытого ADT нет. Повторю — «гарантий», «контроля» и «статических проверок» нет. Так что

Но чем он лучше паттерн-матчинга без контроля за покрытием?

Зачем кому-то следить за этим?

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

А зачем их проверять? Что мне это даст?

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

Вот я и не буду ничего доказывать.

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

Но ложная предпосылка P в том, что я что-то говорил про описания описаний (P1)

Твоя ложная посылка P была, напоминаю, в следующем: «пусть описание ~ процесс». Про то, что ты там что-то говорил или не говорил, никаких посылок не было.

Просто, как я понял, по-твоему X вообще не нужен — вот и доказывай сам.

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

от этого отличаются?

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

То есть ты можешь вообразить, что твои int и string, например, это такой умозрительный вариант (or int string), хотя оно на самом деле T и никакого закрытого ADT нет.

Повторю — «гарантий», «контроля» и «статических проверок» нет.

Ты с одного на другого прыгаешь. Закрытость АТД и гарантии блаблабла - это вещи ортогональные.

Вообще же у динамики ровно два ключевых преимущества над статикой:

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

2. Динамика дисциплинирует программиста (статика стимулирует программиста писать плохой код со слабо продуманной архитектурой).

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

пусть описание ~ процесс

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

Теория о ненужности статики как раз относится к таким.

Как и о ненужности динамики, так как никаких «теорий» тут нет, есть только это самое субъективное «блаблабла» в этом треде.

Тем, что там не требуется финитности

Как раз финитность там требуется — чёрным по белому (два раза встречается слово «finite» — про конечное число инструкций и конечное число состояний через которое проходит алгоритм, один раз «terminating», причём, «at a _final_ ending state». Кнут так и пишет про конечное количество шагов каждый из которых должен выполняться конечное время — очевидна же общая финитность).

А вообще вопрос в том что называть алгоритмом — частично вычислимое/рекурсивное или только тотально. Некоторые вообще определяют формальный алгоритм как МТ которые всегда halt.

Закрытость АТД и гарантии блаблабла - это вещи ортогональные.

data ABC = A Int | B String | C Int String — как будет? Или A, B, C <: ABC. Тут важно, чтобы новый case не появился в ABC и старые функции от этого не сломались и чтобы наследники ABC обязательно реализовывали функции интерфейса которые ABC декларирует — иначе они не будут его подтипами в строгом смысле (метод должен работать на супертипе, но не работает на его подтипе).

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