> Еще, блин, один раз: меня интересует _не_деаллокация_, а _финализация_. И не доверю я компилеру самому додумывать, когда мне файлики закрывать и мутексы анлочить.
Прости, недогнал. Эти случаи само собой особые. ИМО, ни один код не должен полагаться на финализацию из GC. Само собой такие вещи не для компилятора, но и расставлять повсюду нечто вроде .. } finally { SomeHelper.close(...); } это тоже не порядок. Правильно так: (with-mutex (lock) ...). Вот где блестят макросы.
Кстати, до недавнего времени (до 2.5) в Питоне не было адекватных языковых механизмов для удобной борьбы с такими сущностями.
Посчитать примененные конструкции языка. Только в CL это сделать можно автоматизированно, так как программа на LISP -- это синтаксическое дерево. По нему можно пробежать относительно несложным алгоритмом и посчитать. А вот в случае с Питоном и др. это сделать непросто. Можно, но непросто. На небольших программах проще вручную посчитать. Вопрос, какие конструкции учитывать, обсуждаем. А то непонятно как-то: объявления переменных в (let ...) принято записывать в столбик. А в Си кто-то предпочитает int a, b, c; Вот и получается, что в LISP больше строчек. А по символам тоже глупо, так как многобуквенность идентификаторов -- вопрос личных предпочтений.
> Еще, блин, один раз: меня интересует _не_деаллокация_, а
> _финализация_. И не доверю я компилеру самому додумывать, когда мне
> файлики закрывать и мутексы анлочить.
Не знаю, того ли анонимуса я цитирую, но вот как будет выглядеть
рассмотренный пример на Эйфеле:
class ROOT
inherit
EXCEPTIONS
creation
make
feature -- Root
make is
do
do_crytical
end
feature -- Implementation
do_crytical is
local
mutex_a: MUTEX
mutex_b: MUTEX
do
mutex_a.lock("A")
mutex_b.lock("B")
do_something
mutex_b.unlock
mutex_a.unlock
rescue
mutex_b.unlock
mutex_a.unlock
retry -- Until crytical section contract will be satisfied
end
do_something is
do
-- Doing something
end
end
expanded class MUTEX
inherit
EXCEPTIONS
feature -- Access
resource: STRING -- I.e., system lock information
is_locked: BOOLEAN is
do
Result := resource /= Void; -- I.e., resource is allocated
end
feature -- Setting
lock(p_resource: STRING) is
local
v_result: STRING
do
resource := p_resource -- I.e., real resource allocation
ensure
is_locked
rescue
retry -- Until finalization contract (is_locked) will be satisfied
end
unlock is
do
if not is_locked then
resource := Void -- I.e., system finalization
end
ensure
not is_locked
rescue
retry -- Until finalization contract (is_unlocked) will be satisfied
end
end
Да, решение более многословное, зато очевидно, когда заканчивается
критическая секция. Но раз уж зашла речь о "не доверяю компилеру
самому додумывать", то Эйфель как раз и заставляет прописать это явно.
Кстати, а разве стандарт C++ оговаривает порядок вызова деструкторов
при выходе из области видимости? Мне кажется, это может зависеть от
реализации компилятора и методов оптимизации кода. Или не?
Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.
> А это можно сделать, если дескриптор не существует вне подпрограммы? Т.е. подпрограмма в духе save_text_to_file(text, filename)
Не, таки низзя, сам только что попробовал :-(.
> Хотя он, скорее, для коллективной разработки оптимизированный получается, а не для выразительности
Дыкть, он так и замышлялся: как язык, где твой товарищ не даст прострелить тебе ногу :-).
> и применять его в одиночестве будет грустно, наверное...
Ну, для меня это самое оно. Бо каждый день у меня новая личность, и вспомнить, чего я хотел в этом куске кода вчера -- задача для меня почти неразрешимая :-)).
>> в лиспе их навалом можно наворотить _при_желании_ только как оказываецо не так уж чясто с ними луче.
> Можно. Нежелание это делать обычно отражает неумение (не в смысле неспособность, а отсутствие опыта) разрабатывать что-то большое и долгое, и большой командой.
это в основном верно для питонос++, асма, браинфака и других, где воротить всё одно _нужно_ и разница лиш в том оформить это как положено или итак сойдёт.
> Речь идет о количестве лишне-привлеченных сучностей. А это не всегда хорошо измеряется.
Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)
Слишком упрощенный алгоритм. Может привести к неверным результатам. Например, просто if:
if (x > 1) cout << "x is positive";
(if (> x 1) (format t "x is positive"))
В первом случае 1 очко, а во втором 3. Тоже самое касается множества других операторов В С++. Например в for (int n = 1; n > 0; n--) два знака ';'. Вот я и говорю, что подсчет количества конструкций языка в C/C++ нетривиален.
> Да, решение более многословное, зато очевидно, когда заканчивается критическая секция. Но раз уж зашла речь о "не доверяю компилеру самому додумывать", то Эйфель как раз и заставляет прописать это явно.
IMO, такие вещи лучше всего организовывать как процедуру/метод/функцию куда передается блок кода, и которая гарантирует взятие мутекся до выполнения и освобождение (в том числе и при пролете исключения) после. Так позволяют делать все функциональные языки + все наследники smalltalk'а (Ruby в том числе) и даже Java (в лице анонимных классов).
Плюсовое решение с деструкторами тоже валидное, но оно привязано к деаллокации, что не так же здорово. Кстати, AFAIR плюсы гарантируют порядок вызова деструкторов.
>>> В программе про робота показать макры не получится. Эта программа в них не нуждается.
>> Ну вот. Опять. Что за программу не возьми, так она в них не нуждается.
> Просто все нужные для нее макры уже есть в стандарте или либах.
вполне возможно использовать макры для трансляции наречия управления роботом в прогу по которой он будет ездить. Для этого лучше сделать соглашение о наречии, применяемом роботом ИМХО.
> Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.
> По-моему, справедливо. Или не?
ИМХО кривовато. потомушто и в питоне и в с++ в строке может быть дофига лишних ссущностей таких как индексы, обращения к чьленам класса итд. а в лиспе оне все выглядят как (ыыы ...). Всётаки луче переводить в хумансовое наречие 1:1 и так сравнивать.
На самом деле, надо взять для C/C++ грамматику в BNF и распарсить программу, подсчитав количество expressions по результатам работы парсера. Это есть самый правильный способ.
> Не знаю, того ли анонимуса я цитирую, но вот как будет выглядеть рассмотренный пример на Эйфеле:
Да, спасибо. Ничего так, читабельненько.
> Кстати, а разве стандарт C++ оговаривает порядок вызова деструкторов при выходе из области видимости? Мне кажется, это может зависеть от реализации компилятора и методов оптимизации кода. Или не?
>Поверь бывалому перлисту - я знаю язык, который всех порвет в >номинации "самая короткая программа, реализующая заданый алгоритм", >и это ни разу не лисп.
>Пилять, я ее писал сам. Она семантически точно такая же, как >лисповая, только strongly typed. То, что некоторые не умеют за >деревьями увидеть леса - это их проблемы. И я не думаю, что у меня >на ее написание ушло сильно больше времени, чем у тебя на лисповую -> просто потому, что его вообще ушло мало, минут так 7 (в основном -> на чтение sgi.com/tech/stl).
Почему многие думают, что сильная типизация и шаблоны С++ такая уж благодать. Вот буквально сегодня разбирался с программой на С++, в которой одна только нормальная лямбда и замыкания заменили (1 строка) бы 17 строчный заголовок к С++ному шаблонному классу, которые делает то же самое, причем объявлен не по месту, а черт знает где. Когда программа становится больше, то эти шаблоны растут как на дрожжах не смотря на всякие изыски в метапрограммировании и автоматическом выводе шаблонов. В итоге по этому коду ходишь как по минному полю и внести хоть какое-то значительное изменение уже не представляется возможным.
А какой на это дежурный ответ у фанатов С++ ? Правильно: "Заранее все надо было продумывать и правильно проектировать!". Если код надо менять, а он уже задубел в шаблонах и куче всяческих вспомогательных типов, то это оказывается мир вокруг неправильный, меняется так быстро, что правильно спроектировать сразу никогда не получается.
Потом типы в С++ как бы выводятся, но посмотреть, что получилось в результате вывода очень сложно. Вручную пишется куча левого кода, который к решаемой проблемме не имеет никакого отношения.
Надо заметить, что вывод типов по Хиндли-Милнеру в Haskell и OCaml и подходы применяемые в этих языках вместо шаблонов (модули, классы типов и т.п.) является значительным улучшением по сравнению с плюсовыми заморочками.
Я изучал Haskell и OCaml - многое мне там понравилось, но все равно в итоге вернулся в Лисп. Почему ? Да потому что в то время как в других языках все делается только в рамках поддерживаемых парадигм и подходов: например С++ старается рядить все в одежды ООП, на каждую трехкопеечную функцию сооружаются классы, методы и т.д.; Haskell - чисто функциональный и никуда от этого не денешься, задачу все равно надо впихивать в то что предлагает ФП; OCaml поддерживает и ФП, и императивщину и ООП в одном флаконе, но это все что он предлагает, правда для большего есть некий замысловатый препроцессор, но это уже сравнимо по сложности с шаблонами в С++.
Лисп просто получается наименьшим общим делителем: ФП можно, императивщина - пожалуйста, ООП - какой угодно, простецкий встроенный Пролог - ~150 строк и готов, встроенный SQL - пожалуйста, встроенный constraint programming - милости просим, к тому же интегрировано с CLOS; надо инфиксные выражения - вот они. Может быть Лисп не так уж хорош во всех этих областях, как какой-то отдельный язык, но он как хамелеон быстро принимает все формы и затраты на коммуникацию столь разных языков/подходов практически отсутствуют в отличие от всяких .NET
Потом от компиляции и обновления программы на ходу без остановки откажется только законченный аскет. Юзер сможет перенастроить программу так что ее авторы не узнают ;-) сгенерить исполняемое изображение и без всякого там скриптинга тормозного. Так что это не наезд на другие языки, а просто реальное взвешивание возможностей. Вы будете правы, если скажете, что многие из этих возможностей реально не используются, а некоторые еще полноценно не реализованы. Не факт, что эпоха конвейерного подхода к созданию ПО продлится долго, сейчас всякие ограничения в языке и защита от дурака считается более полезной, чем какая-то там гибкость, трудно найти достаточно творческих личностей, но я думаю что на новом витке спираль вернется к творческому подходу и всякие там Java полетят в помойку истории.
> На самом деле, надо взять для C/C++ грамматику в BNF и распарсить программу, подсчитав количество expressions по результатам работы парсера. Это есть самый правильный способ.
О! Пока добирался домой, придумал, похоже, самый наибольший общий знаменатель для всех языков, причем с достаточно простой реализацией. Достаточно посчитать число лексем в программе, после чего можно вычислить следующие характеристики:
Общая (информационная) длина -- количество лексем (с повторениями) в программе. Определяет абсолютную длину программы.
Лексический размер (тезаурус) -- количество разных (неповторяющихся) лексем. Этот параметр определяет приблизительное количество понятий, необходимых для понимания программы.
Лексическая насыщенность -- отношение числа разных (неповторяющихся) смысловых лексем (идентификаторов, чисел, строк, символов и т.п.) к лексическому размеру. Определяет объем полезной информации, дополнительная величина определяет степень "синтаксической засахаренности".
Общая (информационная) насыщенность -- отношение общего числа (с повторениями) смысловых лексем (идентификаторов, чисел, строк, символов и т.п.) к общей информационной длине. Похож на лексическую насыщенность, но дополнительно косвенно описывает "рутиность" кода, то есть, учитывается многократное использование понятий в тексте программы.
IMHO, получается достаточно объективно, так как не учитывается экономия "на спичках" (длина идентификаторов, ключевых слов, операторов) и различная сложность грамматических конструкций (у них может быть множество способов учета). Кроме того, не нужен сложный синтаксический анализатор, можно обойтись только лексическим.
Хотел сегодня наваять мерялку в рамках освоения cl-lexer, но не сложилось. Если кто сделает раньше субботы, будет здорово. Появится у меня время до субботы -- постараюсь написать раньше.
>> Поверь бывалому перлисту - я знаю язык, который всех порвет в номинации "самая короткая программа, реализующая заданый алгоритм", и это ни разу не лисп.
> Brainfuck ?
Не, APL/J, конечно же. Там средняя длина ключевого слова около 2. Я уже писал про поиск простых чисел в 17 символов и модель ядра OS/360 в 120. Но читать это практически невозможно -- язык с очень низкой энтропией.
А вообще, если брать по абсолютной длине, то *ML, скорее всего, выиграют у Лиспа -- там не нужны скобочки :-). Правда, читать их тоже сложнее, чем Лисп.
> Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)
Не ведется, потому что в человечьем языке одну и ту же мысль можно выразить десятком разных способов. И потом, на каком из человечьих языков предлагается записывать? А то ведь в истории есть курьез, когда исследовали перевод с человечьего языка на немецкий :-)).
>> Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)
> Не ведется, потому что в человечьем языке одну и ту же мысль можно выразить десятком разных способов. И потом, на каком из человечьих языков предлагается записывать? А то ведь в истории есть курьез, когда исследовали перевод с человечьего языка на немецкий :-)).
Выразить - возможно, но описать буквально то чё делает прого всево одново хватит. Я выше по треду подобное делал ужо пару раз.
LISP: Вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который...
Форт: Hога простреливать себе вы.
HyperTalk: Поместите первую пулю пистолета в ступню левой ноги вас. Сообщите результат.
Пролог: Вы сообщаете вашей программе, что вы хотите иметь простреленную ногу. Программа разрабатывает способ этого достичь, но синтаксис языка не позволяет объяснить этот способ вам.
APL: Вы простреливаете себе ногу, затем тратите весь день на то, чтобы представить себе, как это сделать с меньшим количеством символов.
java: тип "пуля" не соответствует типу "нога"
Delphi: вы лезете в гугль в поисках TGun и TLeg
C#: Вы находите System.Human.Gun и System.Human.Leg в поставке .НЕТ, выстреливаете, но пуля не долетает, будучи уничтоженной сборщиком мусора
с++: вы стреляеете себе в ногу и вам отрывает все, что ниже шеи
C++: Вы случайно создаете дюжину экземпляров объекта "вы" и всем им простреливаете ногу. Срочная медицинская помощь оказывается невозможной, так как вы не можете разобраться, где настоящие объекты, а где - те, которые только указывают на них и говорят: "А вот - я!".
BrainF**k : вы пытаетесь прострелить себе ногу, но в место етого запутываетесь в мега коде и простреливаете себе голову
Malbolge: для того, чтобы прострелить ногу на этом языке, вам надо написать программу на другом языке, генерирующую код на malbolge. При запуске последствия непредсказуемы, т.к. ничего сложнее hello world на malbolge не тестировалось
Можно взять что-то типа CL-YACC, вбить BNF C++ (http://www.nongnu.org/hcb/) . По этим делам сгенерируется парсер, который выдаст результат в виде нормального синтаксического дерева, идентичного программе C++. А далее надо будет договориться, что будем считать и пробежаться по дереву.
Вот совершенно короткий мануал по CL-YACC с примерчиком:
Аналогично этому примеру из программы на С++ можно получить синтаксическое дерево.
Однако работа по вбиванию грамматики C++ сама по себе может стать рутиной немалой. Да и грабельки могут по ходу появиться, так как все-таки язык навороченный по своему объему.
>Однако работа по вбиванию грамматики C++ сама по себе может стать рутиной немалой. Да и грабельки могут по ходу появиться, так как все-таки язык навороченный по своему объему.
Вот чего автор написал на сайте:
While CL-Yacc has undergone no systematic testing, I use it for compiling a grammar for a superset of "C" (over 400 productions) that routinely parses thousands of lines of "C" code.
К сожалению, грамматики для С я у него не нашел в репозитории. То есть он где-то для себя написал, но не выложил. Можно выпросить. Тогда будет иметься готовый парсер. В результате задача сведется к сравнению двух синтаксических деревьев, исключив все ненужное: длины идентификаторов, количество строчек.
> Кстати, до недавнего времени (до 2.5) в Питоне не было адекватных языковых механизмов для удобной борьбы с такими сущностями.
Гмм, ну with это конечно хорошо, но по-моему во всех питонах время вызова деструктора было вполне детерминировано, правила те-же что и в C++ для объектов на стеке, это возможно из-за reference-counting GC, который конечно не труъ GC как в Ruby, но зато работает в предсказуемые моменты :-)
Достала эта байка о том, что в Питоне нет труъ GC! Он там есть и включен по умолчанию, в этом легко убедиться, сделав import gc; gc.isenabled(). Другое дело, что большинство объектов удаляется при подсчёте ссылок, ну так и в Руби емнип то же самое.
Горе в том, что yacc органически не переваривает труъ BNF, поэтому набор грамматики С++ может стать нетривиальной задачей. Особенно, если учесть, что грамматика С++ контекстно-зависима...
> Вот совершенно короткий мануал по CL-YACC с примерчиком:
А вот что особенно убивает в Лиспе, так это периодическая лежка его информационных ресурсов. Еще в воскресенье эту доку пришлось выдирать из гуглевского кэша :-(.
Оно-то, конечно, написано хорошо. Да вот не работает так, как хотелось бы. Если взять ту же проблему с аллокацией диапазонов, форсирование сборки не помогает и в списке мусора их нету. И если бы дело ограничивалось только целыми...
> LISP: Вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который...
Visual Basic: Hа самом деле вы будете только выглядеть, как будто ваша нога прострелена. Однако в процессе реализации вы получите столько удовольствия, что подобные мелочи вас не озаботят.
>Горе в том, что yacc органически не переваривает труъ BNF, поэтому набор грамматики С++ может стать нетривиальной задачей. Особенно, если учесть, что грамматика С++ контекстно-зависима...
Вот за что я люблю LISP, так это за регулярность. :) Есть в C++ *очень* труднопроходимые моменты в парсинге. Не спорю. Задача сама по себе очень сложная. Однако результаты дали бы, на мой взгляд, представление о том, сколько выражений языка требуется для решения задачи.
P.S. Кстати распарсить Java полегче должно быть, чем C++, так как она контексно-независимая.
> Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.
Сам же сказал - в питоне можно загонять операции в одну строку. У С/С++ можно объявление переменных одного типа загнать под один ';'. Ну а в лиспе один loop сэкономит далеко не одну пару скобок ;)
> Например: функции семейства OUTPUT-BYTES/<format> генерируются макросом...
и эти же макросы генерируют из тех-же кусков кода ещё с десяток функций...
> Это стоит оформить как универсальный output-bytes, который вместо кусков кода принимает функции.
Т.е. функций у тебя станет в два раза больше, а функционал останется?
> Для достаточно нормального компилятора такого было-бы достаточно, чтобы получить такой-же по производительности код, но по сравнению с херовым аналогом шаблонов, у него была-бы выше читабельность и была-бы возможность нормально отлаживаться.
Как код отлаживал автор - фиг его знает. Читабельность - субъективный фактор. А кода в твоём варианте стало бы на много больше. Если только не завернуть его в макры :) Но что мы тогда получим? ;)
> Достала эта байка о том, что в Питоне нет труъ GC! Он там есть и включен по умолчанию, в этом легко убедиться, сделав import gc; gc.isenabled(). Другое дело, что большинство объектов удаляется при подсчёте ссылок, ну так и в Руби емнип то же самое.
Да в питоне есть GC. Тов. redvasily (*) (19.10.2006 9:41:34) имел в виду, что он (точнее CPyhton) в отличие от более классических реализаций GC имеет детерминированное время сборки объектов, а значит детерминированное время вызова деструкторов/финализаторов, из-за того что питоновский GC сочетает GC и reference-counting. Я не уверен так ли это, надо проверить.
В Ruby, в лиспах и практически во всех других реализациях языков с GC такого свойства нету. Т.к. reference counting, как считается, негативно влияет на производительность. Вероятно, для интерпретаторов это незначительный минус, но если в дело вступает JIT то reference counting становится тормозом.
Не знал о таком. Круто. Там весь движок, оказывается, написан на Allegro CL.
Я где-то видел опрос какой-то, из которого следовало, что CL пока используют в основном для решения каких-то внутрикорпоративных задач, информация о которых не публикуется. Крупных публичных проектов пока не так много, если сравнивать с тем, что понаписано на C++. Вот, например, где-то недавно в comp.lang.lisp пробегала цитата из блога сотрудника Amazon о том, что они у себя внутри компании используют Lisp для чего-то. О таких вот проектах можно прочесть на franz.com. Там и Cadence есть, и AMD (генератор тестов для микропроцессоров).
где написано, что "Of the 1.2 million lines of code, roughly 900,000 lines are written in GOAL. GOAL is a programming language based on LISP or rather Scheme".
Причем этот самый GOAL - это нечто, созданное этой же геймстудией специально для написания PS2-шных геймов.
Gavin used Allegro CL to create a programming language called "GOAL" (Game Oriented Assembly Lisp), which he designed specifically for the development of Naughty Dog’s games. Using this custom dialect whose compiler and development environment was written in Allegro CL, he and his team were able to produce hundreds of different game objects with sophisticated real-time behavior and animation, and more realistic graphics. "The behaviors are faster to develop, and more compact than an equivalent C program, allowing for rapid prototyping and experimentation." says Gavin.
В данном случае совсем не десятое. А очень даже важное! При написании игр свойства самого CL (а конкретнее -- инкрементальная компиляция) использовались на всю катушку:
Because the GOAL compiler itself runs in Allegro Common Lisp, the compiler knows a great deal about the state of the running program, including the symbol table. This allows a function to be edited, recompiled, uploaded, and inserted into a running game without having to restart. The process is similar to the "edit and continue" feature offered by some C++ compilers, but allows the programmer to replace arbitrary amounts of code (even up to entire object files), and does not interrupt the running game with the debugger. This feature was also used to implement the Jak and Daxter games' level-streaming.
>Ну, ээ. А Allegro CL все равно когда-то был бутстраплен с Сей, поэтому я сейчас скажу, что эо все программа на диалекте Си.
Совершенно неверное заключение. Никакой такой "среды Си" не существует. А GOAL, судя по описанию, не отдельный проект, который просто написан на CL. Он и есть CL, только (вставлю своей термин) "передиалекченый". REPL как был, так и остался, а конструкции языка доопределены до того диалекта, который и зовется GOAL. Плюс к тому, написан кросскомпилятор для PS2.
B gрирода bootstrap'а тут тоже не важна. Вот, например, Movitz -- реализация Common Lisp (далеко не полная пока), сделанная в виде готовой операционной системы с драйверами (на CL), и предоставляющая сразу REPL. Movitz целиком написан на Allegro CL и страпнутая прямо из него. Никаких там Си даже и нет. Исходный код доступен -- можно полюбопытсвовать, если интересно. Так что природа bootstrap'а может меняться от реализации к реализации.
> А GOAL, судя по описанию, не отдельный проект, который просто написан на CL. Он и есть CL, только (вставлю своей термин) "передиалекченый".
Нет. AFAIK Allegro не компилирует в машинный код MIPS (PS2, кажется, имеет именно такой набор инструкций). Очевидно, что GOAL это именно компилятор и в конечном бинарнике нету никаких следов Allegro CL.
>Нет. AFAIK Allegro не компилирует в машинный код MIPS (PS2, кажется, имеет именно такой набор инструкций). Очевидно, что GOAL это именно компилятор и в конечном бинарнике нету никаких следов Allegro CL.
Ну разумеется! Там даже нет Garbage Collector. И то, что GOAL работает на Allegro CL не говорит, что Allegro CL в бинарнике. И что там вообще LISP. Написали *кросскомпилятор*. Система написания и отладки игр сделана на Allegro. REPL из Allegro CL. IDE -- Emacs. Это, считай, система инкрементальной компиляции и отладки кода для другой платформы в не-LISP приложение. Но если бы не было Allegro CL, а игра писалась на чем-то другом, то всей этой интересной системы проетирования просто бы не было. А был бы исходный код -> правка -> перекомпилирование. Не было бы возможности заживо править игру. Здесь вся фишка в том, что вся парадигма инкрементальной компиляции автоматически перенеслась на бинарник PS2. Другими словами, ты программируешь на LISP, но в результате лепится не бинарный образ Allegro CL, а свой доморощенный бинарный образ, но так, что он тоже состоит из тех же кусочков, что и исходный код, т. е. он специально организован. А иначе не получилось бы инкрементального изменения этого бинарника. И, наверное, (точно не знаю, но предполагаю), Playstation2 была подсоединена как-то к хост-компьютеру и сразу же получала все инкрементальные изменения, как только они производились.
>Но если бы не было Allegro CL, а игра писалась на чем-то другом, то всей этой интересной системы проетирования просто бы не было. А был бы исходный код -> правка -> перекомпилирование.
Хотя. Тут можно сделать некоторое подобие инкрементального компилятора C++. Вроде такие существуют. Об ограничениях такого компилятора я сразу не возьмусь говорить. Мое предложение касается, скорее, стандартных классических средств.
P.S. Кстати сейчас GOAL, насколько я понял, прекратили использовать там :(