LINUX.ORG.RU

lisp как препроцессор для C


0

0

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

Это не будет embedded lisp. Это не будет связка lisp-C по FFI или через IPC (хотя это возможно). Это не будет очередная виртуальная машина (хотя и это возможно). Это будет лисповая оболочка над С.

Будет иметься постоянно запущенная лисп-среда, своего рода "пчела-матка", которая будет генерировать C-код. С-код будет компилироваться обычным C-компилятором и потом исполняться отдельно.

Что мы возьмём от С? Всё. Результатом работы первой фазы компилятора будет обычный С-код.

Что мы возьмём от лиспа? Синтаксис. Синтаксис лиспа - это синтаксис деревьев из идентификаторов и констант. Кроме того, от лиспа мы возьмём статическое МП. Т.е., у нас будет не только c::defun (определение с-функции) и не только с::typedef. Но и defmacro, обычное лисповое defmacro, которое заменит #define. Также у нас будет лисповый класс c-type (который уже есть в разных реализациях лиспа в связи с FFI). Также у нас будет парсер сишных заголовочных файлов, чтобы мы могли "заинклюдить" сишный код в наш лисповый код. Такой парсер в разных реализациях лиспа тоже есть.

Зачем это нужно? Например, чтобы писать более удобно, чем на С, программы, которые обычно пишутся на С.

★★★★★

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

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

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

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

Тебе его генерить надо, а не анализировать.

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

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

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

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

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

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

> Почему ты к типам так прицепился? Типы в подобной задаче вообще нечасто нужны.

О_о

> Как пример - я генерил код на Си из Лиспа для реализации генетических алгоритмов.

генитические алгоритмы безусловно интересная тема, но эта тема называется: lisp как препроцессор для C

плюсы и минусы lisp в даном контексте

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

>Если Вы серьёзно возились с этим языком

к сожалению нет, серьёзно не возился. познакомился я с ним в процессе знакомства с проектом ОС Coyotos (EROS, бывший KeyCos), и пару раз встречал упоминания о нём как о низкоуровневом LISP'е. собственно его применимость для меня определяется тем, что EROS с его помощью таки написан. сожалею, что не могу помочь большим

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

> О_о

Нет уж, развернуто отвечай. Какие тут на хрен типы на уровне препроцессора?

> генитические алгоритмы безусловно интересная тема, но эта тема называется: lisp как препроцессор для C

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

> плюсы и минусы lisp в даном контексте

Простота работы со списками - главный плюс.

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

> Нет уж, развернуто отвечай. Какие тут на хрен типы на уровне препроцессора?

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

> Простота работы со списками - главный плюс.

ок

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

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

Это я не в теме? Хи хи. Смешно.

Шаблоны C++ пользщуются при раскрытии информацией о типах. Но это шаблоны C++, а тут - метапрограммирование. Исходный язык тут может какую угодно семантику иметь, в любом виде информация о типах может быть представлена, поскольку исходный язык - НЕ СИ. Этого ты и не понимаешь, и, не понимая, лопочешь что-то про типы, упоминание которых тут абсолютно неуместно.

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

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

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

Продемонстрирую, но не сегодня. И не с динамическим, а со статическим (анализ типа переменной, а не значения). Могу примерно сказать, как это делается.

Сопоставляем каждому С-типу свой CLOS-класс. Этот класс будет существовать только во время компиляции и будет основой для работы с типами.

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

int i,

то в дереве везде вместо неё будет подставлен экземпляр класса ctype:int со слотом "имя", равным "i".

определим

(defmethod c::print-to-stdout-code ((x ctype:int)) `(printf "%d\n" ,x))

(defmethod c::print-to-stdout-code ((x ctype:float)) `(printf "%d\n" ,x))

далее определяем макрос.

(defmacro c::print-to-stdout (x) (c::print-to-stdout-code x))

Далее можно просто писать:

(c:defun void foo () (let ((int x 1)) (double y 2)) (print-to-stdout x) (print-to-stdout y))))

вот, примерно так. На самом деле, всё не так уж просто в реализации. Я не говорю, что задача прямо уже решена. Была бы решена - и темы бы такой не было.

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

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

(cons 'vsl '(s nami))

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

jtootf, а какой примерно объём в строках этого EROSа? Языки с теоремами, по идее, должны страдать плохой масштабируемостью.

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

> какой примерно объём в строках этого EROSа?

EROS был на Си. На BitC пишется Coyotos, но он еще не закончен. Зная послужной список Шапиро, я думаю, что и Coyotos и не будет закончен :D

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

> Но это шаблоны C++, а тут - метапрограммирование.

А на C++ шаблонах тоже можно метапрограммированием заниматься ;).

Люди, вон, на ТеХе интерпретатор Васика написали...

Die-Hard ★★★★★
()
Ответ на: комментарий от vasily_pupkin

GCL вроде как славился своей тормознутостью и соответствием cltl1. Я неправ?

den73 ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

> А на C++ шаблонах тоже можно метапрограммированием заниматься ;).

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

> Люди, вон, на ТеХе интерпретатор Васика написали...

Дык. Тьюринг-полный, однако. Люди Форт на sed-е делают, это ещё круче.

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

> анонимусу про форт - форт это хороший язык, но он слишком низкоуровневый. К тому же он не быстр.

O_o Ты книжку-то почитай на досуге:

Таунсенд К., Фохт Д. "Проектирование и программная реализация экспертных систем на персональных ЭВМ": Пер. с англ./Предисл. Г.С. Осипова. - М.: Финансы и статистика, 1990. - 320 с: ил.

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

> Естественно. Можно делать особую шаблонную магию. Но это другой вид метапрограммирования, более сложный. Шаблоны анализируют и преобразуют исходник, а то, что люди обычно с лиспами и прочими макропроцессорами делают - это как компиляция - генерация целевого языка (си) из какого-то исходного, который совсем не си.

Не понял. Чем "исходник" отличается от "какого-то исходного"?

Вот классическое вычисление факториала на ЦеПП шаблонах -- что тут не так?(след. пост)

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

#include <iostream>

template<int N>
struct Factorial
{
 enum { value = N * Factorial<N-1>::value };
};

template<>
struct Factorial<1>
{
 enum { value = 1 };
};

int main()
{
 // Example use
 const int fact5 = Factorial<5>::value;
 std::cout << fact5;
 return 0;
}

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

> Не понял. Чем "исходник" отличается от "какого-то исходного"? 

 Языком.

> Вот классическое вычисление факториала на ЦеПП шаблонах -- что тут
> не так?(след. пост) 

 Всё там так, кроме того, что это C++ раскрывающийся в C++.

 А если задача стоит так, чтобы, например, конфигурационный файл
в виде:

node1 -> node2, node3.
node2 -> node3, node5.
node3 -> node3, node5.

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

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

- Я делаю особую, шаблонную магию.
- Не не не, Андрей Александреску, не не не!

anonymous
()

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

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

anonymous, который DSL-ит, а не хотите расшарить свой чемоданчик с инструментами?

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

> Давно не видел плюсов, но это просто ******!

По-моему в любом букваре по advanced c++ этот пример есть.

Кстати это иногда спрашивают на собеседованиях. Вот это точно ******.

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

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

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

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

Наверное!

Я не спец по метапрограммированию, просто к слову реплику вставил -- зря, "был не трезв"... :-)

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

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

(defmacro fact (n) ; макрос выполняется во время компиляции
                   ; и его результат подставляется вместо 
                   ; вызова макроса
  (the integer n)  ; проверим тип (тип проверяется в динамике
                   ; но сама эта динамика происходит в статике :) 
  (assert (>= n 0)) ; проверим область определения
  (labels ((f (n)   ; вводим локально функцию факториал, 
                    ; чтобы не засорять пространство имён
             (if (= n 0)             
                 1                   
                 (* n (f (- n 1))))  
             ))
    (f n)) ; вызываем факториал во время компиляции 
       ; итого вызов (fact n) вернёт значение факториала, 
       ; которое будет подставлено в компилируемый код
       ; вместо вызова (fact n)
       )  

(fact 5) ; пример обращения. 

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

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

Мне лень считать и я не стану утверждать, что определение макро-факториала на лиспе короче (хотя мне кажется, что оно всё же короче).

Но если смотреть на его использование в коде, то С++ требует 12 лексем, а лисп - 5.

Так вот, у нас на входе имеется задача для языка С. И есть два препроцессора на выбор - С++ с шаблонами и лисп с макросами. Что следует предпочесть, исходя только из объективных факторов (лаконичность кода, его прямота, быстрота обработки компилятором, надёжность полученного результата, простота поддержки)?

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

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

Лисп - 5 лексем С++ - 14 лексем. Я не считал вывод в стандарный поток, а считал только оператор, декларирующий константу и использование значения, состоящее только из одного слова fact5. Можно, кстати, посчитать и то, что нам пришлось придумать имя для fact5.

Возможно, что можно применить С++ - ный вариант как просто Factorial<5>::value, тогда разрыв в применении сильно сокращается, 6 лексем против 5. Я не настолько знаю С++, чтобы понять, не сломается ли от этого "шаблонная магия".

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

Можно проще:

(defun fact (x) (if (> x 1) (* x (fact (- x 1))) 1))

(defmacro fact! (x) (fact x))

В Common Lisp же главная его сила в том, что в определениях макр можно использовать любые функции и макры, определенные ранее. Именно это его отличает от других метаязыков, таких как C++ или Scheme.

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

Назови соответствующий раздел стандарта. Что там кроме syntax-rules?

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

В некоторых реализациях есть низкоуровневые макры типа define-macro (chicken, sisc) либо define-syntax с низкоуровневыми трансформерами (scheme48).

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

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

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

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

Согласно легенде, в своё время была построена Вавилонская башня и Бог, побоявшись могущества людей, сделал так, что люди стали говорить на разных языках. Конечно, разобщение происходило через мысли и стремления отдельных людей. Никто, конечно, не бросал громы с облаков и не кричал страшным голосом "а ну-ка быстро придумали себе разные языки!" Естественно, тогдашние люди были гораздо более знающи и мудры и могли заметить, тем не менее, что источник проблемы находится в небесах. Современные атеисты-сатанисты слишком горды, чтобы это понять и/или признать. А мне, человеку более смиренному и верующему, это признать куда как проще.

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

Обратите внимание, что в естественных языках ситуация не такая: существует рамочный язык, передающийся в Традиции данного народа, и существуют DSL, формируемые субкультурами и общепризнанные в рамках субкультуры. Разнообразие языков программирования несравнимо больше, чем разнообразие естественных языков. Соответственно, проект "анти-вавилон" в компьютерной индустрии действует гораздо более активно, чем в человеческом сообществе.

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

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

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

Наверное, на этом тему следует закрыть и продолжить разработку в привате, даже не open-source. Масштаб работы достаточно мал, её можно сделать в одно-два-три лица. С другой же стороны, следует, наоборот, провести эту работу открыто, чтобы проверить действие проекта "анти-вавилон" на себе. Надо подумать над этим.

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

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

Не было бы этой силы (хаоса), не было бы эволюции. Мутации рулят!

> не было единого полноценного языка программирования, а взамен этого было много ущербных

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

> Разнообразие языков программирования несравнимо больше, чем разнообразие естественных языков.

Это не совсем так, мягко говоря.

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

Признавайся - "За миллиард лет до конца света" перечитывал?

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

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

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

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

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

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

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

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

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

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

Если бы, допустим, CL не был кривым и включал в себя setjmp или call/cc, а Схема была бы подмножеством CL, то я бы это понял. А так - я разочарован.

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

Речь идёт о http://www.r6rs.org/formal-comments/ ? Спасибо, почитаю.

Ну и про макры в R6RS:

Each <keyword> is an identifier, and each <expression> is an expression that evaluates, at macro-expansion time, to a transformer. Transformers may be created by syntax-rules or identifier-syntax (see section 11.19) or by one of the other mechanisms described in library chapter on “syntax-case”. (C) R6RS, 11.18

Очень мило. Если бы они давали возможность задать любой трансформер, у которого на входе был бы не syntax-object (как в syntax-case), а произвольная форма (как в defmacro или explicit-renaming макрах s48), было бы другое дело. А так...

Это, кстати, Legioner-у тоже ответ :)

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

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

> Вообще, идея, что нужно в языке что-то изначально запретить, чтобы что-то сохранить - порочна.

Это древний флейм - bondage&discipline vs. полная свобода. На одном конце Haskell, на другом - Си и Форт.

> Работать с ним будет крайне неудобно, но на это есть МП.

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

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

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

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

> Из лона такого языка должны выходить в виде DSL все специализированные языки.

Подобные проекты тоже встречаются, см. http://lambda-the-ultimate.org/node/2895

> Философская идея использования лиспа в качестве препроцессора к С - привести все языки к общему знаменателю лиспа.

Ну так при этом подходе и от полной поддержки семантики Си никуда не денешься.

> Схема была бы лучше, но её изуродовали в плане макросов

Кстати, конкретно в твоей задаче макросы не нужны, поскольку целевой язык для твоих DSLей это не сам Лисп, а внешний Си. Так что вместо макр у тебя простой print будет.

> Если бы, допустим, CL не был кривым и включал в себя setjmp или call/cc

Кстати, лично я не уверен в универсальной полезности call/cc. Он слишком многого от языка требует. Делать CPS transform и "миниинтерпретатор" только ради возможности поддерки продолжений - как-то не радует.

> она слишком медленная

Не в последнюю очередь благодаря call/cc

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

Понял, спасибо. Меня смутил syntax-object. Смотрел невнимательно и не заметил что syntax<->datum поддерживают полноценную конверсию. В новом стандарте есть (в п.12.6 описания библиотеки).

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

> > Из лона такого языка должны выходить в виде DSL все специализированные языки.

> Подобные проекты тоже встречаются, см. http://lambda-the-ultimate.org/node/2895

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

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