LINUX.ORG.RU

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

> Еще, блин, один раз: меня интересует _не_деаллокация_, а _финализация_. И не доверю я компилеру самому додумывать, когда мне файлики закрывать и мутексы анлочить.

Прости, недогнал. Эти случаи само собой особые. ИМО, ни один код не должен полагаться на финализацию из GC. Само собой такие вещи не для компилятора, но и расставлять повсюду нечто вроде .. } finally { SomeHelper.close(...); } это тоже не порядок. Правильно так: (with-mutex (lock) ...). Вот где блестят макросы.

Кстати, до недавнего времени (до 2.5) в Питоне не было адекватных языковых механизмов для удобной борьбы с такими сущностями.

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

>+1, маразм конешно. Однако как ещё мерить?

Посчитать примененные конструкции языка. Только в CL это сделать можно автоматизированно, так как программа на LISP -- это синтаксическое дерево. По нему можно пробежать относительно несложным алгоритмом и посчитать. А вот в случае с Питоном и др. это сделать непросто. Можно, но непросто. На небольших программах проще вручную посчитать. Вопрос, какие конструкции учитывать, обсуждаем. А то непонятно как-то: объявления переменных в (let ...) принято записывать в столбик. А в Си кто-то предпочитает int a, b, c; Вот и получается, что в LISP больше строчек. А по символам тоже глупо, так как многобуквенность идентификаторов -- вопрос личных предпочтений.

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

> Еще, блин, один раз: меня интересует _не_деаллокация_, а
> _финализация_. И не доверю я компилеру самому додумывать, когда мне
> файлики закрывать и мутексы анлочить.

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

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++ оговаривает порядок вызова деструкторов
при выходе из области видимости? Мне кажется, это может зависеть от
реализации компилятора и методов оптимизации кода. Или не?

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

>Ну вот. Опять. Что за программу не возьми, так она в них не нуждается.

А тебя не очень огорчает факт, что, например, объекты в большинстве программ не нужны совсем? Ну вот так и тут.

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

> Посчитать примененные конструкции языка.

Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.

По-моему, справедливо. Или не?

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

> А это можно сделать, если дескриптор не существует вне подпрограммы? Т.е. подпрограмма в духе save_text_to_file(text, filename)

Не, таки низзя, сам только что попробовал :-(.

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

Дыкть, он так и замышлялся: как язык, где твой товарищ не даст прострелить тебе ногу :-).

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

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

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

> Пилять, я ее писал сам.

ну кто же на твоё авторство претендует? пешы ешо

> Она семантически точно такая же, как лисповая, только strongly typed.

и вдесятеро длиннее

> Давай ты в лисповый вариант везде добавишь аннотации типов

зачем оне там?

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

я невижу проблемы с этим, но так и быть, добавлю проверку. Чё она должна делать, игнорить одинаковое или генерить ашыпку?

> сделаешь так, чтобы "неправильный" (в смысле, не являющийся кортежем "число, строка") идентификатор нельзя было использовать как ключ в хеше

...и ваще чёбы всё перестало работать

> - и тогда мы поглядим, чья программа короче.

и работает :D

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

>> в лиспе их навалом можно наворотить _при_желании_ только как оказываецо не так уж чясто с ними луче.

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

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

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

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

Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)

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

Слишком упрощенный алгоритм. Может привести к неверным результатам. Например, просто 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++ нетривиален.

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

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

IMO, такие вещи лучше всего организовывать как процедуру/метод/функцию куда передается блок кода, и которая гарантирует взятие мутекся до выполнения и освобождение (в том числе и при пролете исключения) после. Так позволяют делать все функциональные языки + все наследники smalltalk'а (Ruby в том числе) и даже Java (в лице анонимных классов).

Плюсовое решение с деструкторами тоже валидное, но оно привязано к деаллокации, что не так же здорово. Кстати, AFAIR плюсы гарантируют порядок вызова деструкторов.

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

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

>> Ну вот. Опять. Что за программу не возьми, так она в них не нуждается.

> Просто все нужные для нее макры уже есть в стандарте или либах.

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

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

>> Посчитать примененные конструкции языка.

> Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.

> По-моему, справедливо. Или не?

ИМХО кривовато. потомушто и в питоне и в с++ в строке может быть дофига лишних ссущностей таких как индексы, обращения к чьленам класса итд. а в лиспе оне все выглядят как (ыыы ...). Всётаки луче переводить в хумансовое наречие 1:1 и так сравнивать.

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

На самом деле, надо взять для C/C++ грамматику в BNF и распарсить программу, подсчитав количество expressions по результатам работы парсера. Это есть самый правильный способ.

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

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

Да, спасибо. Ничего так, читабельненько.

> Кстати, а разве стандарт C++ оговаривает порядок вызова деструкторов при выходе из области видимости? Мне кажется, это может зависеть от реализации компилятора и методов оптимизации кода. Или не?

В порядке, обратном аллокации - стек ведь.

http://www.research.att.com/~bs/glossary.html#Gorder-of-destruction

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

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

Brainfuck ?

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

>Пилять, я ее писал сам. Она семантически точно такая же, как >лисповая, только strongly typed. То, что некоторые не умеют за >деревьями увидеть леса - это их проблемы. И я не думаю, что у меня >на ее написание ушло сильно больше времени, чем у тебя на лисповую -> просто потому, что его вообще ушло мало, минут так 7 (в основном -> на чтение sgi.com/tech/stl).

Почему многие думают, что сильная типизация и шаблоны С++ такая уж благодать. Вот буквально сегодня разбирался с программой на С++, в которой одна только нормальная лямбда и замыкания заменили (1 строка) бы 17 строчный заголовок к С++ному шаблонному классу, которые делает то же самое, причем объявлен не по месту, а черт знает где. Когда программа становится больше, то эти шаблоны растут как на дрожжах не смотря на всякие изыски в метапрограммировании и автоматическом выводе шаблонов. В итоге по этому коду ходишь как по минному полю и внести хоть какое-то значительное изменение уже не представляется возможным.

А какой на это дежурный ответ у фанатов С++ ? Правильно: "Заранее все надо было продумывать и правильно проектировать!". Если код надо менять, а он уже задубел в шаблонах и куче всяческих вспомогательных типов, то это оказывается мир вокруг неправильный, меняется так быстро, что правильно спроектировать сразу никогда не получается.

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

Надо заметить, что вывод типов по Хиндли-Милнеру в Haskell и OCaml и подходы применяемые в этих языках вместо шаблонов (модули, классы типов и т.п.) является значительным улучшением по сравнению с плюсовыми заморочками.

Я изучал Haskell и OCaml - многое мне там понравилось, но все равно в итоге вернулся в Лисп. Почему ? Да потому что в то время как в других языках все делается только в рамках поддерживаемых парадигм и подходов: например С++ старается рядить все в одежды ООП, на каждую трехкопеечную функцию сооружаются классы, методы и т.д.; Haskell - чисто функциональный и никуда от этого не денешься, задачу все равно надо впихивать в то что предлагает ФП; OCaml поддерживает и ФП, и императивщину и ООП в одном флаконе, но это все что он предлагает, правда для большего есть некий замысловатый препроцессор, но это уже сравнимо по сложности с шаблонами в С++.

Лисп просто получается наименьшим общим делителем: ФП можно, императивщина - пожалуйста, ООП - какой угодно, простецкий встроенный Пролог - ~150 строк и готов, встроенный SQL - пожалуйста, встроенный constraint programming - милости просим, к тому же интегрировано с CLOS; надо инфиксные выражения - вот они. Может быть Лисп не так уж хорош во всех этих областях, как какой-то отдельный язык, но он как хамелеон быстро принимает все формы и затраты на коммуникацию столь разных языков/подходов практически отсутствуют в отличие от всяких .NET

Потом от компиляции и обновления программы на ходу без остановки откажется только законченный аскет. Юзер сможет перенастроить программу так что ее авторы не узнают ;-) сгенерить исполняемое изображение и без всякого там скриптинга тормозного. Так что это не наезд на другие языки, а просто реальное взвешивание возможностей. Вы будете правы, если скажете, что многие из этих возможностей реально не используются, а некоторые еще полноценно не реализованы. Не факт, что эпоха конвейерного подхода к созданию ПО продлится долго, сейчас всякие ограничения в языке и защита от дурака считается более полезной, чем какая-то там гибкость, трудно найти достаточно творческих личностей, но я думаю что на новом витке спираль вернется к творческому подходу и всякие там Java полетят в помойку истории.

Спасибо за внимание ;-)

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

> На самом деле, надо взять для C/C++ грамматику в BNF и распарсить программу, подсчитав количество expressions по результатам работы парсера. Это есть самый правильный способ.

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

Общая (информационная) длина -- количество лексем (с повторениями) в программе. Определяет абсолютную длину программы.

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

Лексическая насыщенность -- отношение числа разных (неповторяющихся) смысловых лексем (идентификаторов, чисел, строк, символов и т.п.) к лексическому размеру. Определяет объем полезной информации, дополнительная величина определяет степень "синтаксической засахаренности".

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

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

Хотел сегодня наваять мерялку в рамках освоения cl-lexer, но не сложилось. Если кто сделает раньше субботы, будет здорово. Появится у меня время до субботы -- постараюсь написать раньше.

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

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

> Brainfuck ?

Не, APL/J, конечно же. Там средняя длина ключевого слова около 2. Я уже писал про поиск простых чисел в 17 символов и модель ядра OS/360 в 120. Но читать это практически невозможно -- язык с очень низкой энтропией.

А вообще, если брать по абсолютной длине, то *ML, скорее всего, выиграют у Лиспа -- там не нужны скобочки :-). Правда, читать их тоже сложнее, чем Лисп.

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

> Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)

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

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

> Только на ЛОРе вокруг фразы о языке, крутость которого есть миф, может возникнуть спор на 30 с лишком страниц. :-/

[:]|||||||||||||||||||||||||||||||||||||||||||||||||||[:]

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

>> Это достаточно хорошё видно если описать алгоритм человечьим языком, т.е. фактически выразить алгоритмы наиболее высокоуровневым. Но пипл на такое не ведёцо ;)

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

Выразить - возможно, но описать буквально то чё делает прого всево одново хватит. Я выше по треду подобное делал ужо пару раз.

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

> человечьим языком

Кстати, навеяло:

LISP: Вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который...

Форт: Hога простреливать себе вы.

HyperTalk: Поместите первую пулю пистолета в ступню левой ноги вас. Сообщите результат.

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

APL: Вы простреливаете себе ногу, затем тратите весь день на то, чтобы представить себе, как это сделать с меньшим количеством символов.

java: тип "пуля" не соответствует типу "нога"

Delphi: вы лезете в гугль в поисках TGun и TLeg

C#: Вы находите System.Human.Gun и System.Human.Leg в поставке .НЕТ, выстреливаете, но пуля не долетает, будучи уничтоженной сборщиком мусора

Python: <не реализовано>

:-)))

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

с++: вы стреляеете себе в ногу и вам отрывает все, что ниже шеи

C++: Вы случайно создаете дюжину экземпляров объекта "вы" и всем им простреливаете ногу. Срочная медицинская помощь оказывается невозможной, так как вы не можете разобраться, где настоящие объекты, а где - те, которые только указывают на них и говорят: "А вот - я!".

BrainF**k : вы пытаетесь прострелить себе ногу, но в место етого запутываетесь в мега коде и простреливаете себе голову

Malbolge: для того, чтобы прострелить ногу на этом языке, вам надо написать программу на другом языке, генерирующую код на malbolge. При запуске последствия непредсказуемы, т.к. ничего сложнее hello world на malbolge не тестировалось

Eiffel: <видел, но уже не найду где>

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

Можно взять что-то типа CL-YACC, вбить BNF C++ (http://www.nongnu.org/hcb/) . По этим делам сгенерируется парсер, который выдаст результат в виде нормального синтаксического дерева, идентичного программе C++. А далее надо будет договориться, что будем считать и пробежаться по дереву.

Вот совершенно короткий мануал по CL-YACC с примерчиком:

http://www.pps.jussieu.fr/~jch/software/cl-yacc/cl-yacc.html

Аналогично этому примеру из программы на С++ можно получить синтаксическое дерево.

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

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

>Однако работа по вбиванию грамматики 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.

К сожалению, грамматики для С я у него не нашел в репозитории. То есть он где-то для себя написал, но не выложил. Можно выпросить. Тогда будет иметься готовый парсер. В результате задача сведется к сравнению двух синтаксических деревьев, исключив все ненужное: длины идентификаторов, количество строчек.

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

> Python: <не реализовано>

4.2 :-)

Пистолет и ногу можно было скачать с незапамятных времён, а начиная с 2.5 идёт в стандартной поставке (ctypes)

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

> Кстати, до недавнего времени (до 2.5) в Питоне не было адекватных языковых механизмов для удобной борьбы с такими сущностями.

Гмм, ну with это конечно хорошо, но по-моему во всех питонах время вызова деструктора было вполне детерминировано, правила те-же что и в C++ для объектов на стеке, это возможно из-за reference-counting GC, который конечно не труъ GC как в Ruby, но зато работает в предсказуемые моменты :-)

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

Достала эта байка о том, что в Питоне нет труъ GC! Он там есть и включен по умолчанию, в этом легко убедиться, сделав import gc; gc.isenabled(). Другое дело, что большинство объектов удаляется при подсчёте ссылок, ну так и в Руби емнип то же самое.

ero-sennin ★★
()
Ответ на: комментарий от Zubok

> Можно взять что-то типа CL-YACC, вбить BNF C++

Горе в том, что yacc органически не переваривает труъ BNF, поэтому набор грамматики С++ может стать нетривиальной задачей. Особенно, если учесть, что грамматика С++ контекстно-зависима...

> Вот совершенно короткий мануал по CL-YACC с примерчиком:

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

eugine_kosenko ★★★
()
Ответ на: комментарий от ero-sennin

> http://docs.python.org/lib/module-gc.html

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

eugine_kosenko ★★★
()
Ответ на: комментарий от ero-sennin

А в Ruby разве есть подсчёт ссылок?

Я думал что там только GC, по крайней мере из чтения всякой инфы сложилось такое впечатление...

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

> LISP: Вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который держит пистолет, с помощью которого вы простреливаете себе отросток, который...

Visual Basic: Hа самом деле вы будете только выглядеть, как будто ваша нога прострелена. Однако в процессе реализации вы получите столько удовольствия, что подобные мелочи вас не озаботят.

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

>Горе в том, что yacc органически не переваривает труъ BNF, поэтому набор грамматики С++ может стать нетривиальной задачей. Особенно, если учесть, что грамматика С++ контекстно-зависима...

Вот за что я люблю LISP, так это за регулярность. :) Есть в C++ *очень* труднопроходимые моменты в парсинге. Не спорю. Задача сама по себе очень сложная. Однако результаты дали бы, на мой взгляд, представление о том, сколько выражений языка требуется для решения задачи.

P.S. Кстати распарсить Java полегче должно быть, чем C++, так как она контексно-независимая.

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

> Ну я и предлагаю: у питона это число непустых строк (при отсутствии трюков с записью в одну строку), у C/C++ -- количество ';' (обычные операторы), '{' (функции и анонимные блоки, при этом для одного оператора всегда писать блок) и '#' (аналог включения модулей), а у Лиспа -- количество '('.

Сам же сказал - в питоне можно загонять операции в одну строку. У С/С++ можно объявление переменных одного типа загнать под один ';'. Ну а в лиспе один loop сэкономит далеко не одну пару скобок ;)

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

> Это как раз пример того, как делать не стоит.

Дредложи свой вариант, только учти, что...

> Например: функции семейства OUTPUT-BYTES/<format> генерируются макросом...

и эти же макросы генерируют из тех-же кусков кода ещё с десяток функций...

> Это стоит оформить как универсальный output-bytes, который вместо кусков кода принимает функции.

Т.е. функций у тебя станет в два раза больше, а функционал останется?

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

Как код отлаживал автор - фиг его знает. Читабельность - субъективный фактор. А кода в твоём варианте стало бы на много больше. Если только не завернуть его в макры :) Но что мы тогда получим? ;)

yyk ★★★★★
()
Ответ на: комментарий от ero-sennin

> Достала эта байка о том, что в Питоне нет труъ 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 становится тормозом.

anonymous
()

Русские физики выбрали лиспъ?

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

>http://www.cduniverse.com/images.asp?pid=5845800&cart=412346358&style...

Не знал о таком. Круто. Там весь движок, оказывается, написан на Allegro CL.

Я где-то видел опрос какой-то, из которого следовало, что CL пока используют в основном для решения каких-то внутрикорпоративных задач, информация о которых не публикуется. Крупных публичных проектов пока не так много, если сравнивать с тем, что понаписано на C++. Вот, например, где-то недавно в comp.lang.lisp пробегала цитата из блога сотрудника Amazon о том, что они у себя внутри компании используют Lisp для чего-то. О таких вот проектах можно прочесть на franz.com. Там и Cadence есть, и AMD (генератор тестов для микропроцессоров).

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

> Не знал о таком. Круто. Там весь движок, оказывается, написан на Allegro CL.

Для PS2? Да ну?

Если спросить у гугля "jak II lisp", то находится

http://www.lemonodor.com/archives/000610.html

где написано, что "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-шных геймов.

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

>GOAL

А ты почитай на чем сам GOAL написан :)

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&#8217;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.

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

> А ты почитай на чем сам GOAL написан :)

Ну, ээ. А Allegro CL все равно когда-то был бутстраплен с Сей, поэтому я сейчас скажу, что эо все программа на диалекте Си.

На чем написан компилятор - дело десятое

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

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

>На чем написан компилятор - дело десятое

В данном случае совсем не десятое. А очень даже важное! При написании игр свойства самого 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.

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

>А Allegro CL все равно когда-то был бутстраплен с Сей

Совсем не обязательно.

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

>Ну, ээ. А Allegro CL все равно когда-то был бутстраплен с Сей, поэтому я сейчас скажу, что эо все программа на диалекте Си.

Совершенно неверное заключение. Никакой такой "среды Си" не существует. А GOAL, судя по описанию, не отдельный проект, который просто написан на CL. Он и есть CL, только (вставлю своей термин) "передиалекченый". REPL как был, так и остался, а конструкции языка доопределены до того диалекта, который и зовется GOAL. Плюс к тому, написан кросскомпилятор для PS2.

B gрирода bootstrap'а тут тоже не важна. Вот, например, Movitz -- реализация Common Lisp (далеко не полная пока), сделанная в виде готовой операционной системы с драйверами (на CL), и предоставляющая сразу REPL. Movitz целиком написан на Allegro CL и страпнутая прямо из него. Никаких там Си даже и нет. Исходный код доступен -- можно полюбопытсвовать, если интересно. Так что природа bootstrap'а может меняться от реализации к реализации.

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

> А GOAL, судя по описанию, не отдельный проект, который просто написан на CL. Он и есть CL, только (вставлю своей термин) "передиалекченый".

Нет. AFAIK Allegro не компилирует в машинный код MIPS (PS2, кажется, имеет именно такой набор инструкций). Очевидно, что GOAL это именно компилятор и в конечном бинарнике нету никаких следов Allegro CL.

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

>Нет. 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 была подсоединена как-то к хост-компьютеру и сразу же получала все инкрементальные изменения, как только они производились.

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

>Но если бы не было Allegro CL, а игра писалась на чем-то другом, то всей этой интересной системы проетирования просто бы не было. А был бы исходный код -> правка -> перекомпилирование.

Хотя. Тут можно сделать некоторое подобие инкрементального компилятора C++. Вроде такие существуют. Об ограничениях такого компилятора я сразу не возьмусь говорить. Мое предложение касается, скорее, стандартных классических средств.

P.S. Кстати сейчас GOAL, насколько я понял, прекратили использовать там :(

И вот почему (классическая слезная история):

http://lists.midnightryder.com/pipermail/sweng-gamedev-midnightryder.com/2005...

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