LINUX.ORG.RU

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

> А если брать стандартную библиотеку - то у C++ она, как минимум, не беднее. Хешей там нету, правда - только упорядоченные ассоциативные контейнеры - но это и ни разу не "кучи байтов".

Только работать с ими карявенько. Отлистай вверьх, тамо с++ прого на полверсты, а лисповая аналог три строчки. Потому что сам йазыг приспособлен с кучками байтоф работать.

>> Если для большинства лисппрог новых типов строить безсмысленно, то на с/с++/питоне для более-менее сложной задачи с этого и приходицо начинать, изобретая лисапет сново и сново.

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

Дык, это вроде наоборот, пипл нащёт DSL догнать неможет, где не токо типы но и йазыг предметую облась отражает. Мне то чё объяснять? Если ты щитаеш обекты "типами, отражающими предметную область" дык, бугога, в лиспе их навалом можно наворотить _при_желании_ только как оказываецо не так уж чясто с ними луче.

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

> Ну вы блин демагогии развели из примитивного предложения написать 
> кастрированный клон adventure и A* pathfinder.

Да, друзья, вы тут предложений накидали уже на убийцу CS и WoW 
одновременно, а я то и TCP/IP предложил использовать чтобы не писать \
парсер вывода лабиринта.

Какие-то боты работающие на сервре, программирование AI на DSL, вы бы 
уж сразу предложили написать интерпритатор лиспа. На лиспе это 
сделать будет явно проще чем на всём остальном, кажется в первом 
сообщении сказано что достаточно 15 строк ;-)

Предложение такое:

1. Сервер при запуске принимает имя файла с картой такого вида:

##########
#  # $ # #
#$ #     .
#     #  #
##########

# - стена
$ - предмет
. - вход

2. Сервер понимает следующие комманды

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

perform_action() - выполняет действие. Возможные действия:
  north  - перейти на одну клетку на север
  west   - перейти на одну клетку на запад
  south  - перейти на одну клетку на юг
  east   - перейти на одну клетку на восток
  pickup - поднять предмет в текущей клетке
  drop   - бросить переносимый предмет в текущей клетке

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

3. Игра заканчивается если все предметы в мире лежат на клетке входа

4. Требуется написать:

  4.1. Сервер, процесс который при старте считывает карту мира и
    слушает какой-то порт по TCP/IP и обслуживает запросы приходящие
    по этому порту. Запуск: advserve world.dat 7766
 
  4.2. Клиента для человека, который цепляется к серверу,
    считвает состояние мира, отображает эту информация, ждёт ввода
    комманды и передаёт её серверу. Вывод идёт в stdout, т.е. просто
    старое состояние уползает вверх, на его место вылазит новое.

    Пример вывода:
      
    ##########
    #  # $ # #
    #$ #    @.
    #     #  #
    ########## 
    Game is in progress
    You carry an item
    Here lies 1 item(s)
    > [место для ввода комманды]
    
    @ - персонаж, если на одной клетке находится персонаж и что-то
    ещё, то отображается персонаж:

    ##########
    #  #   # #
    #  #     @
    #     #  #
    ########## 
    You won!
    Your hand are empty
    Here lies 3 item(s)
    > [место для ввода комманды]

    ##########
    #  #$  # #
    #$ #   @ .
    #    $#  #
    ########## 
    You won!
    Your hand are empty
    Here lies 0 item(s)
    > [место для ввода комманды]

    Пример запуска: hclient 127.0.0.1 7766

  4.3. Клиента робота, который должен выиграть игру. В процессе игры
    на экране отображается состояние мира как для человеческого
    клиента, только нет приглашения для ввода комманды

    Пример запуска:  roboclient 127.0.0.1 7766

5. Сравнивается краткость, компактность и концептуальность :-)
  исходных текстов всез трёх программ.

Вот такое предлоджение.

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

yyk, ну как эта задача достаточно большая чтобы макры проявили себя
во всей красе?

Ну кто-нибудь из лисперов берётся? А то получится что я напишу, а мне
потом скажут: "не, мы не написали, но если бы написали, то получилось
бы в 3, нет в 10 раз короче".

В принципе, приветствуются решения на Haskell OCaml и hq9+

На С++ можно и не писать, лично мне и так понятно что получится,
получится примерно то-же самое что и на питоне, но с учётом 
ограничений статической типизации.

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

>вовсе нет, с чево бы? При желании можно но луче не надо

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

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

> Только работать с ими карявенько. Отлистай вверьх, тамо с++ прого
> на полверсты, а лисповая аналог три строчки. Потому что сам йазыг 
> приспособлен с кучками байтоф работать.

Bugmaker, ты врёшь.

Программа c файлами без БД:

язык    не пустрых строк   непробельных символов
------------------------------------------------
Lisp       12                      434
Python     17                      420
С++        41                      863

Программа с БД, кстати, ты слил её написать, написал её таки eugene_kosenko

язык    не пустрых строк   непробельных символов
------------------------------------------------
Lisp       58                      1519
Python     52                      1612
Python(*)  52                      1408

Python (*) это версия где написано "from sqlalchemy import *"
вместо import sqlalchemy, что ближе к лисповой семантике импорта,
насколько я понимаю.

Имхо, главный размер это количество непробельных символов, т.к.
в C++ очень много строк вида "}"

На простой программе (без БД), лисп слил питону, и выиграл у C++
всего в два раза, но C++ и не претендует на
сверхкомпактность и абстракции высокого уровня.

На более сложной программе лисп слил питону и по строкам и по
символам.

На shootout-e лисп сливает С/C++ по скорости и питону по компактности.

И где здесь радикальное преимущество лиспа над "недоязыгами", о
котором ты все уши прожужжал?

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

> А зачем тут DSL ?

Дык я о том же. Нафиг тут DSL? Просто тут уже начались разговоры о DSL об AI о космических кораблях бороздящих просторы большого театра, короче о том чтобы свести эту задачу к трёпу и ничего не писать :-)

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

> На более сложной программе лисп слил питону и по строкам и по символам.

Сделайте в Лисп-программе поправку на новичка. Кроме того, там одна функция -- лишняя, плюс две строки на включение трассировки и комментарий к ним. Так что, если это учесть, то получится паритет.

Кроме того, я совершенно не ожидал, что проги будут мерять по числу символов и строк. Я бы тогда некоторые вещи записал еще компактнее, а имена сделал бы еще короче. Как говорится, нет предела совершенству.

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

>Дык я о том же. Нафиг тут DSL? Просто тут уже начались разговоры о >DSL об AI о космических кораблях бороздящих просторы большого >театра, короче о том чтобы свести эту задачу к трёпу и ничего не >писать :-)

Ну вообще-то метапрограммирование к созданию DSL не сводится. Насчет описанной задачи с закачиваемым ботом и всякими AI штуками, почему бы и нет ? Если это на Лиспе реализовать легче, то что тогда труднее ? Кодеки и драйверы ? Разница только в том, что алгоритм закачивается и работает прямо на сервере, клиентский бот не требуется, только клиент для просмотра текущего состояния и закачки ботов на сервер. А эта странная задача с каким-то человекочитаемым, но достаточно формальным языком малость скучновата. Прочем тут тогда разговоры о метапрограммировании и т.п. ?

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

> На более сложной программе лисп слил питону и по строкам и по символам.

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

Замеряем таким образом?

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

> Ну кто-нибудь из лисперов берётся?

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

В порядке уточнения: в одной клетке может лежать несколько предметов (см. п. 3)? Если может, то как это показывается на карте?

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

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

Собственно я тоже. Писал как пишу обычно. И имена у меня нормальные (metadata, filedb) и т.д.

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

Чего я в упор не вижу, так это этих загадочных абстракций высокого порядка, которых нет в других языках.

И bugmaker постоянно кричит что лисповый код в десятки раз компактнее, чего ну никак не наблюдается. Вот эти замеры строк и байтов в первую очередь для него.

Тут ему уже предлагали на спор померяться по компактности с Perl-oм, он не стал. Я бы поставил на Perl :-)

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

> В порядке уточнения: в одной клетке может лежать несколько предметов (см. п. 3)? Если может, то как это показывается на карте?

Может. Не покажется никак, в начальной карте каждый предмет лежит в своей клетке, человек догадается, а робот непосредственно прочитает из структуры мира с сервера.

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

> Насчет описанной задачи с закачиваемым ботом и всякими AI штуками, почему бы и нет ? Если это на Лиспе реализовать легче, то что тогда труднее ? Кодеки и драйверы ? Разница только в том, что алгоритм закачивается и работает прямо на сервере, клиентский бот не требуется, только клиент для просмотра текущего состояния и закачки ботов на сервер

Ради бога. Хоть WoW пиши. Я реально не могу и не хочу потратить на эту прогу всю жизнь.

То вариант что предлагаю я, можно написать за день. Я готов этот день потратить на написание такой проги.

Это явно уже не hello-world, так что если лисп настолько крут, докажите.

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

Я думаю что все кто может это реально написать, работают программистами, и у всех есть что писать на работе. И время у людей вобщем-то стоит денег.

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

> (а иначе довольно трудно вызвать финализатор, словив исключение уровней так на пять выше)

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

> Имеется ввиду, что между потерей последнего указателя на нечто и финализацией пройдет неопределенный промежуток времени.

Пишу по буквам: вызывайте финализатор явно _до_ потери указателя. Какое из слов непонятно? Если все слова понятны, то обратите особое внимание на подчеркивание.

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

Блин, какая религия запрещает создать объект-обертку вокруг дескриптора, который будет иметь специальный метод для закрытия файла. Вызывайте этот метод там, где у Вас на C++ полагается писать delete, а уничтожение пустой обертки оставьте сборщику мусора. Чем этот вариант не устраивает?

> Поэтому финализаторы в garbage-collected языках, имхо, абсолютно бесполезны

Кстати, еще вчера хотел добавить: ключ -no_gc при компиляции в Эйфеле никто не отменял. Ибо, как написано в самой документации, "This option is useful when one prefers to use another GC provided by an external library (such as the Boehm-Demers-Weiser conservative GC), or when no GC is needed". Как говорится, специально для Вас. Аналогично, сборщик мусора можно принудительно отключить на любом сколь угодно критическом участке программы и использовать явную деаллокацию. То же самое можно сделать в Питоне.

> привязывать к ним "счетно-конечные" ресурсы бесполезно по перечисленным выше причинам

Вообще говоря, может быть, перейдем от спора на уровне сферических коней к чему-то более конкретному? Опишите точнее ситуацию, где GC сосет (в частности, где требуется стековая дисциплина, крутые обработчики исключений и "счетно-конечные ресурсы"), а я попробую элегантно решить эту проблему на Эйфеле. Чтоб не флудить, можно поболтать на эту тему по почте. eugine dot kosenko at gmail dot com.

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

> Если я ничего не путаю, для ANTLR есть готовая грамматика SQL92.

Во-первых, для Эйфеля нет "родного" ANTLR. А сшивать их на уровне C -- занятие не для слабонервных. А во-вторых, ANTLR существенно проигрывает по скорости компиляции YACC. На объемах в 5-10 тысяч строк это хорошо заметно.

Говорю не от балды: пробовал ANTLR лет 5 назад, именно в этом контексте.

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

Гладко было на бумаге...

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

> Я готов этот день потратить на написание такой проги.

Лично для меня проблема в поведении робота. Если бы я знал алгоритм, то, может быть, тоже смог бы написать за день. Собственно, я бы сначала посмотрел на питонью реализацию, а потом попробовал бы собезьянничать на Лиспе. С учетом специфики.

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

> type inference для примитивных типов на макрах, с реализацией generic алгоритмов? Ню-ню. Это разве вообще возможно?

Можно компилятор, работающий с макрами и "с реализацией generic алгоритмов" научить нормально работать с типами ;)

> Там можно специализировать генерик на константу?

На константу в понимании лиспа? Да.

> Можно сказать "для пустых списков - так, для единичной длины - сяк, для более длинных - эдак"?

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

> А покажи, я, может, передумаю.

Не буду я тебе ничего показывать. Понадобится - сам найдёшь.

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

> Лично для меня проблема в поведении робота.

В детстве, когдя я шарахался по всяким олимпиадам, нас научили одному грязному трюку :-) Называется "волновой алгоритм" http://www.codenet.ru/progr/alg/way.php http://algolist.manual.ru/games/wavealg.php

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

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

> Чего я в упор не вижу, так это этих загадочных абстракций высокого порядка, которых нет в других языках.

И не увидите, если не погрузитесь в это. Обратите внимание на использование квадратных скобок для конструирования запросов. В Питоне для этого нужно использовать форматный вывод (что можно и в Лиспе), но это примерно в 1.5 раза длиннее и не так понятно. Считайте это неким мини-DSL в виде псевдо-SQL. Со стороны это кажется тривиальным (как и все в Лиспе), но когда пишешь -- серьезно помогает.

Кроме того, похоже, что у Питона намного больше спрятано "под коврик", чем у Лиспа.

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

> В детстве, когдя я шарахался по всяким олимпиадам, нас научили одному грязному трюку :-) Называется "волновой алгоритм"

Ну, метод "роты солдат" мы тоже на олимпиаде проходили :-). Я просто думал, что мне засчитают фол за такое использование -- ведь предполагается, что робот будет только один :-). Кроме того, я думал, что с тех пор придумали что-то более продвинутое.

Ну ладно, раз с алгоритмом определились, то можно и попытаться.

Еще вопрос: зачет личный или командный?

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

>Чего я в упор не вижу, так это этих загадочных абстракций высокого >порядка, которых нет в других языках.

А тут ножик Окама срабатывает, нафига в трех строках лишние сущности. Ну и потом сам Лисп на Лиспе и написан, поэтому многие абстракции (не такие уж высокие) просто не видны, так как выглядят естественно.

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

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

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

Если ваш код на питоне будет >200 строк - да :)

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

> На shootout-e лисп сливает С/C++ по скорости и питону по компактности.

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

Хотя лично я за такое выражение убил бы ;)

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

> Еще вопрос: зачет личный или командный?

Я думаю командный. Мы же не своими [CENSORED] меряемся, а у наших языков. :-)

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

> Чего я в упор не вижу, так это этих загадочных абстракций высокого порядка, которых нет в других языках.

На таком примере?.

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

> Думаю будет больше. Так ты участвуешь?

А правила ведения "эксперимента" и участия в нём? :)

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

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

> На примере перестановок, файлов, файлов с БД

Это больше похоже на примеры для соревнования имеющихся либ/функций языка. "Не катит" :)

> и на примере, куда tailgunner ссылку давал.

Каюсь, не смотрел.

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

> Только работать с ими карявенько. Отлистай вверьх, тамо с++ прого на полверсты, а лисповая аналог три строчки. Потому что сам йазыг приспособлен с кучками байтоф работать.

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

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

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

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

А в хелловорлдах-то конечно, преимущества C++ (или там Haskell) не видны.

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

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

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

Вот только "совершенством" программы - победители в Perl Golf назвать язык даже у меня не поворачивается.

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

> В Эйфеле обработка всех исключений жестко привязана к подпрограммам: это требование контрактного проектирования. Поэтому на пять уровней выше у Вас по любому уже не будет доступа к тем переменным, о которых Вы на этом уровне даже не догадываетесь. Либо финализируйте их явно на нижних уровнях, либо положитесь на GC. Как всегда, у Вас есть выбор.

Ой, блин. Это ж какой спагетти получается, наверное? Как с этим любители высоких строений (хехе ;) борются?

Это не издевка, правда - как? Мы тут выше обсуждали уже это в контексте "как правильно использовать goto".

> Пишу по буквам: вызывайте финализатор явно _до_ потери указателя. Какое из слов непонятно? Если все слова понятны, то обратите особое внимание на подчеркивание.

Это понятно - просто это ничем не лучше явного delete в C++.

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

> Вызывайте этот метод там, где у Вас на C++ полагается писать delete, а уничтожение пустой обертки оставьте сборщику мусора. Чем этот вариант не устраивает?

Явным вызовом delete. Например, если у меня функция делает return в нескольких местах - мне придетсь каждый раз писать рядом "delete filehandle;" - и если я забуду - то дескриптор утечет.

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

> Опишите точнее ситуацию, где GC сосет (в частности, где требуется стековая дисциплина, крутые обработчики исключений и "счетно-конечные ресурсы"), а я попробую элегантно решить эту проблему на Эйфеле.

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

На C++ у меня в подобном коде не будет ни одного delete, и, если мне позволено обрабатывать исключения выше, ни одного try/catch. Если не позволено - один-единственный try-block. И ни одного if-а - совершенно линейный понятный код.

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

> Не буду я тебе ничего показывать. Понадобится - сам найдёшь.

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

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

> Ой, блин. Это ж какой спагетти получается, наверное? Как с этим любители высоких строений (хехе ;) борются?

Борются при помощи вдумчивого чтения "Дисциплины программирования" и применения полученных знаний на практике.

> Это не издевка, правда - как? Мы тут выше обсуждали уже это в контексте "как правильно использовать goto".

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

> Это понятно - просто это ничем не лучше явного delete в C++.

Дыкть, я уже выше написал, что если для Вас явная деаллокация -- не исключение, а правило, то С++ -- это Ваш выбор.

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

Ну, есть еще понятие "expanded class", который аллоцируется прямо в стеке. Не знаю, как там с дисциплиной, но это тоже может помочь. Правда, у экспандедов есть определенные грабли в конкретных реализациях, например, в SmartEiffel при наследовании от COMPARABLE генерируется некомпилируемый C-код. Но я думаю, для Ваших целей можно обойтись без таких извращений.

> Явным вызовом delete. Например, если у меня функция делает return в нескольких местах - мне придетсь каждый раз писать рядом "delete filehandle;" - и если я забуду - то дескриптор утечет.

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

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

Ну, если есть задача промоделировать тот фрагмент кода, то попробую сделать. Правда, сразу предупреждаю, что освобождение будет написано явно. Я ж не знал, что Вам нужно "волшебным образом". Хотя, может быть, что вариант с экспандедами тоже прокатит.

> На C++ у меня в подобном коде не будет ни одного delete, и, если мне позволено обрабатывать исключения выше, ни одного try/catch. Если не позволено - один-единственный try-block. И ни одного if-а - совершенно линейный понятный код.

Ну, на Эйфеле тоже не будет ни одного if-а -- совершенно линейный понятный код. Более того, даже try-блока не будет -- достаточно только rescue -- аналог catch. Насчет delete -- посмотрю экспандеды, не получится -- посмотрю, что можно сделать стандартными средствами.

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

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

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

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

> Дык я уже нашел, даже два.

Искренне рад за Вас. Одного не пойму - что же Вы в этом топике потеряли? ;)

yyk ★★★★★
()

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

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

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

Я не предлагал для этого использовать гото (ну, в смысле предлагал - но только в plain C, где нет способов лучше).

> Во-первых, как я уже написал, в Эйфеле нет goto-подобных операторов, поэтому выход всегда осуществляется в одной точке.

Это хооршо, это правильно.

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

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

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

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

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

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

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

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

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

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

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

> Bugmaker, ты врёшь.

это твоя традиция и ты её не нарушаеш

> Программа c файлами без БД:

где же ты в лисповой 12 строк нащитал? Там всево 1 - на создание хеша 1 - на добавление файла 5 - на поиск по условиям. Скоко всево? Чё за хрень непортабельные символы?

> Программа с БД, кстати, ты слил её написать

некогда пока, потом понапишу

> На простой программе (без БД), лисп слил питону, и выиграл у C++ всего в два раза, но C++ и не претендует на сверхкомпактность и абстракции высокого уровня.

Бугога? это там где в питоне понадобилось два новых типа создавать?

> На более сложной программе лисп слил питону и по строкам и по символам.

это на какой?

> И где здесь радикальное преимущество лиспа над "недоязыгами", о котором ты все уши прожужжал?

Ну хто ш тебе виноват если ты не можеш отличить надобности в создании кучи новых типов от отсутствия таковой надобности?

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

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

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

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

> по количеству конструкций языка. У Питона это совпадает со строками

у питона совпадает не со строками а хрен знает с чем. Всякие . [] 1: коротки, но тем не менее это самостоятельные конструкции, они сильно усложняют и могут находиться в строке десятками.

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

> Чего я в упор не вижу, так это этих загадочных абстракций высокого порядка, которых нет в других языках.

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

> И bugmaker постоянно кричит что лисповый код в десятки раз компактнее, чего ну никак не наблюдается. Вот эти замеры строк и байтов в первую очередь для него.

Дык ты щитать если не умееш, хто те виноватый? Нащитал в файловой проге на лиспе вдвое больше строк чем там было :D

> Тут ему уже предлагали на спор померяться по компактности с Perl-oм, он не стал. Я бы поставил на Perl :-)

От задачи зависит. При достаточно большой можно было бы сотворить наречие у котокого все понятия по одному символу :D И на достаточно крупной и разнообразной перл таки слил бы :P только я нехочю тратить на это _столько_ своево времени. Тем более если уж народ собираецо сравнивать по длине прогу из перловых закорючек и нормально читаемую лисповую, и так очевидно чё бояцо проиграть.

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

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

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

anonymous
()

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

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

> Ну, чуть по-больше: посмотри в sbcl реализацию external-format для потоков и строк

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

Например: функции семейства OUTPUT-BYTES/<format> генерируются макросом, при этом в макрос передаются куски кода. Это стоит оформить как универсальный output-bytes, который вместо кусков кода принимает функции. А затем для генерации специализированного кода сделать что-то вроде.

(defun output-bytes/utf8 (stream string flush-p start end) (declare (inline output-bytes)) (output-bytes stream string flush-p start end (lambda ... кусок 1) (lambda ... кусок 2)...))

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

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

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

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

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