LINUX.ORG.RU

CL standalone application.


1

0

Объясните пожалуйста как сделать standalone приложение в clojure и sbcl. Что оно из себя представляет и как согласуется с тем, что лисп заточен больше на интерпретатор.

★★

> лисп заточен больше на интерпретатор.

Это с каких пор?

Объясните пожалуйста как сделать standalone приложение в clojure и sbcl

Совсем standalone не получится, в бинарнике всё равно будет весь clozurecl или sbcl.

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

>Совсем standalone не получится, в бинарнике всё равно будет весь clozurecl или sbcl.
Можно поподробнее? Оно что таскает интерпретатор?

лисп заточен больше на интерпретатор.


Это с каких пор?

Не раз доводилось читать, что компиляция не очень подходит для лисп модели.

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

> Можно поподробнее? Оно что таскает интерпретатор?

Свободные реализацию в бинарник весь рантайм засовывают, коммерческие - нет.

Не раз доводилось читать, что компиляция не очень подходит для лисп модели.

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

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

>Свободные реализацию в бинарник весь рантайм засовывают, коммерческие - нет.
Ну рантайм это другое дело, главное чтобы не очень тормозило.

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

Да, но как откомпилировать в бинарь? Вот ищу как это сделать в clojure, но пока безуспешно.

Booster ★★
() автор топика

Clojure или Clozure cl?

Если последний, то у него в документации описано как создавать образ. Раздел «4.7 Saving Applications», функция ccl:save-application.

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

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

Кстати, у clisp образ получается меньше.

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

> Да, но как откомпилировать в бинарь?

Типичная ошибка. Компилятор это то, что транслирует исходный код в машинный, а не то, что создаёт бинарь, чувствуете разницу? ;)

Можете вы всё таки поясните, что именно хотите? Будет тогда проще объяснить...

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

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

Я вообще не в курсе какая модель компиляции у CL, и что можно сделать на выходе. Так что прошу помощи и как можно больше информации.

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

> Можно поподробнее? Оно что таскает интерпретатор?

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

Не раз доводилось читать, что компиляция не очень подходит для лисп модели.

Не читай больше такого бреда.

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

>Нет. Оно таскает полный дамп памяти. Common Lisp так устроен - бинарник генерится записыванием дампа памяти, в котором и сам компилятор остается, и весь уже скомпилированный код, и все созданные в памяти данные.
Фига себе, зачем так сложно? То есть он выплёвывает образ памяти который нужно будет промапить?

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

> Clisp тоже умеет компелировать?

Да, все реализации могут компилировть - ибо это в стандарте :) Просто он компилирует в байт-код.

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

У sbcl есть функция sb-ext:save-lisp-and-die, которая сохраняет текущий образ на диск, ей можно передать функцию, которая будет вызываться при запуске этого образа, которая таким образом становится аналогом функции main.

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

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

> в clojure - все просто

<оффтоп>

Я слышал вы используете clojure в своих разработках. Если не секрет, для чего?

</оффтоп>

anonymous
()

Я делаю так

sbcl --eval "(progn (push #p\"/home/andy/projects/PassStorage/\" asdf:*central-registry*) (asdf:oos 'asdf:load-op :pass-storage))" --eval "(sb-ext:save-lisp-and-die \"PassStorage\" :executable t :toplevel 'pass-storage::main-and-quit)"

или

 
ccl --eval "(progn (push #p\"/home/andy/projects/PassStorage/\" asdf:*central-registry*) (asdf:oos 'asdf:load-op :pass-storage))" --eval "(ccl:save-application \"PassStorage\" :prepend-kernel t :toplevel-function 'pass-storage::main-and-quit)"
k_andy ★★★
()
Ответ на: комментарий от Booster

> Фига себе, зачем так сложно?

Это проще, чем раздельная компиляция. И это лучше, потому как иначе инкрементальную компиляцию сделать нельзя.

То есть он выплёвывает образ памяти который нужно будет промапить?

Да. Такой образ и загружается быстрее, чем куча DLL-ок.

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

>У sbcl есть функция sb-ext:save-lisp-and-die,
То есть вызывать данную функцию из самой программы?

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

Меня интересует и байт код и возможность запуска без установленной лисп среды. Кстати, байт код как понимаю машинно зависим? То есть на других оs/cpu не запустится?

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

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

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

> То есть вызывать данную функцию из самой программы?

Из среды. Загрузить в образ нужный код и сохранить это на диск.

Важно понять, что любая программа на CL является живой и содержит в себе компилятор. При запуске SBLC в память загружается образ с диска, при выполнении всяких там defun и т.п. происходит модификация этого образа в памяти, в том числе модификация машинного кода. Функция sb-ext:save-lisp-and-die просто сохраняет текущее состояние образа на диск.

Меня интересует и байт код и возможность запуска без

установленной лисп среды.



При использовании sb-ext:save-lisp-and-die можно получить полностью независимый образ, который можно запускать и без SBCL.

Кстати, байт код как понимаю машинно зависим?


Я не знаю, что именно вы называете байт-кодом. Создаваемые .fasl файлы, таковым, вообще говоря, не являются.

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

Да, но как откомпилировать в бинарь?

Он и так компилирует в машкоды.

Welcome to Clozure Common Lisp Version 1.5-dev  (WindowsX8632)!
? (defun add (x y)
    (declare (type fixnum x y))
             (optimize (speed 3) (space 0) (safety 0) (debug 0)))
    (the fixnum (+ x y)))
ADD
?(add 5 6)
11
?(disassemble #'add)
;;; (defun add (x y) (declare (type fixnum x y) (optimize (speed 3) (space 0) (safety 0) (debug 0))) (th
  [0]     (recover-fn)
  [5]     (pushl (% ebp))
  [6]     (movl (% esp) (% ebp))
  [8]     (pushl (% arg_y))
  [9]     (pushl (% arg_z))

;;; (the fixnum (+ x y))
  [10]    (movl (@ -4 (% ebp)) (% arg_y))
  [13]    (movl (@ -8 (% ebp)) (% arg_z))
  [16]    (addl (% arg_y) (% arg_z))
  [18]    (leavel)
  [19]    (retl)
NIL
?
Дамп образа же делается так:
(ccl:save-application "helloworld" :prepend-kernel t
                      :toplevel-function (lambda ()
                                           (unwind-protect
                                             (write-line "Hello, world!")
                                             (ccl:quit))))
;получаем исполняемый файл размером 16 м.б.
;если не указывать :prepend-kernel, получится только "ядро", для работы которого нужно будет запускать рантайм (т.е. напр. "./wx86cl helloworld")
;если не указывать :toplevel-function, в новом процессе запустится REPL
В коммерческих реализациях есть механизм, который все неиспользуемые функции из дампа удаляет, поэтому размер оного меньше.

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

>При запуске SBLC в память загружается образ с диска, при выполнении всяких там defun и т.п. происходит модификация этого образа в памяти, в том числе модификация машинного кода.
Надеюсь это делается один раз? Ведь модификация кода это жёсткий оверхед.

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

>То есть вызывать данную функцию из самой программы?
В CL нет понятия «программа». Есть среда.

Кстати, байт код как понимаю машинно зависим? То есть на других оs/cpu не запустится?

SBCL и CCL, и, вообще, большинство реализаций CL компилируются в машинные коды. При чем тут байткод?
Байткод у clisp, и, да, он платформонезависим.

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

То есть обычная практика в СL это тащить с собой исходники и медленный старт? Как-то не здорово. Почему не сделать как в .Net, компилировать в платформонезависимый байт код, а на целевой докомпилять в целевой?

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

> Надеюсь это делается один раз? Ведь модификация кода

это жёсткий оверхед


Зависит от программиста, точнее от его кода.

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

> То есть обычная практика в СL это тащить с собой исходники и медленный старт? Как-то не здорово.

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

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

А зачем? Лучше сразу в целевой.

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

> Ведь модификация кода это жёсткий оверхед.

С чего вдруг?

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

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

> То есть обычная практика в СL это тащить с собой

исходники и медленный старт?


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

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

>Байт код удобней/быстрей исходников.

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

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

Байткод и JIT это тормозное говно.
Пригодное только для особо двинутых адептов кроссплатформенности(которая, кстати, миф).

Переносить код на CL, если исходники делиться жалко, можно либо уже вмонтированным в образ, либо c .fasl'ами.

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

> Байт код удобней/быстрей исходников.

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

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

> Байткод и JIT это тормозное говно.

Ни фига. LLVM совсем не тормозной. Промежуточное представление в GCC никаких тормозов не добавляет, а ведь тот же байткод по сути. Все Лиспы компилят через промежуточный типа как бы байткод. Ничего плохого в этом нет.

Я уж не говорю про всякие там AS/400.

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

>Фига себе компилятор в CL работает в рантайме?
Разницы между compile-time и run-time фактически нету. Вернее, все это перемешано.

Модель Java или .Net для CL разве не подошла-бы?

Нет.

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

>Байткод и JIT это тормозное говно.
Пригодное только для особо двинутых адептов кроссплатформенности(которая, кстати, миф).
В .Net по крайней мере компилируется только один раз, при запуске, далее JIT не работает, так что производительность не страдает. Понятно, что для нересурсоёмкого приложения пофик, хоть интерпретатор. Но например мейнстрим игры на Java это странный выбор.

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

> Фига себе компилятор в CL работает в рантайме?

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

Модель Java или .Net для CL разве не подошла-бы?

Нет. Потому что в CL есть инкрементальная компиляция. И в CL есть макры. А если попытаться подружить макры с раздельной компиляцией в стиле .NET или JVM, то получается кошмар вроде Nemerle или уродство вроде MBase.

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

>Нет.
Вернее, жаба это такое убогое подобие лисп-системы.

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

> В .Net по крайней мере компилируется только один раз, при запуске, далее JIT не работает, так что производительность не страдает.

Ну так лучше уж как в Лиспе, где компилируется только один раз, при компиляции. А при запуске всё давно скомпилированно-соптимизированно.

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

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

Это, мягко говоря, совсем не так. Грубо говоря, это ахинея.

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

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

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

> То есть компиляция в рантайме всё-же по мере необходимости таковой,

а не постоянно? А я уже испугался.


Зависит от кода. Конечно, просто так ничего там постоянно не компилируется. Но реальная компиляция во время исполнения не является чем-то не обычным, всё зависит от программиста.

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

> В .Net по крайней мере компилируется только один раз, при запуске, далее JIT не работает, так что производительность не страдает.

Ну так лучше уж как в Лиспе, где компилируется только один раз, при компиляции. А при запуске всё давно скомпилированно-соптимизированно.


По-сути это одно и тоже. Там цикл: запуск->компиляция->выполнение.
Тут: компиляция->запуск->выполнение(компиляция?)

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

> То есть компиляция в рантайме всё-же по мере необходимости таковой, а не постоянно? А я уже испугался.

Конечно же. И некоторые кастрированные реализации CL (такие как GCL) позволяют собирать бинарники раздельно и без вшитого внутрь компилятора вообще.

anonymous
()

И всё-таки непривычно для компилируемого языка. Привычно это или бинарь или байт код, но не исходники. Они настолько быстро компилятся?

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