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

При написании кода на Common Lisp я использую SLIME. В частности, я компилирую буфер, содержащий определения функций, используя C-C C-k, а затем переключаюсь на REPL для запуска этих функций. Размещение исполняемого кода для запуска этих функций в буфере не работает так хорошо. Если в коде есть ошибки, это может привести к беспорядку.

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

sbcl --script foo.lisp

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

Это аналогично условию Питона.

if __name__=='__main__':

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

Этот пост в блоге, озаглавленный «Использование SBCL для сценариев оболочки Common Lisp», найденный случайным поиском в Google, содержит

;; If run from command line, the following if-test will succeed

(if (> (length sb-ext:*posix-argv*) 1)

    ;; Code that is executed from the command line only goes here

)

Включенный код действительно не запускается компилятором внутри SLIME, но он не также не запускается с помощью sbcl --script.

ОБНОВЛЕНИЕ: Спасибо Всеволоду Демкину за полезный ответ и дополнения. Далее следуют некоторые примечания об этом ответе, составленные из комментариев к этому ответу. @Всеволод, если ты добавишь это в свой ответ, я их удалю.

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

  2. Первым шагом является определение макрофункции чтениядля символа макроса #! . Как указано в ссылке «При встрече с символом макроса программа чтения Лиспа вызывает свою макрофункцию чтения». Функция чтения определяется вызовомset-dispatch-macro-character. Итак, когда #! символ set-dispatch-macro-character вызывает лямбда-функцию, определенную в теле. Затем эта функция добавляет ключевое слово :noscriptк переменной*features* . См. также обсуждение того, для чего хороши макросы чтения в вопросе SO. Макросы чтения: для чего вы их используете?.

  3. Обратите внимание, что ключевое слово :noscriptдобавляется к *features*именно тогда, когда #! присутствует символ. Кроме того, #! символ присутствует, когда код запускается внутри интерпретатора, например. при использовании слизи, но видимо отсутствует (удален) из программы
    text by sbcl --scriptзапускается. Поэтому :noscriptдобавляется к *features*, когда код запускается в интерпретаторе, но не при запуске как
    сценарий.

  4. Теперь мы используем встроенные макросы чтения #-/#+, которые, как сказал Всеволод, ведут себя аналогично #IFDEF/#IFNDEFв языке C.Они проверяют символ
    в *функции*. В этом случае #-:noscriptпроверяет отсутствие :noscript, а #+:noscriptпроверяет наличие :noscript.
    Если эти условия выполняются, он запускает соответствующий код. Чтобы обернуть блок кода, можно использовать prognвот так: #-:noscript (progn ).

  5. Наконец, необходимо вызвать set-dispatch-macro-characterперед запуском кода, использующего эту функциональность. В случае sbclможно положить это в файле инициализации ~/.sbclrc. Обратите внимание, что этот подход не зависит от того, является ли реализация Common Lisp SBCL.

  6. Более простой альтернативой, упомянутой в списке sbcl-devel, является использование ключевого слова :SWANKпри вводе *features*в
    . REPL внутри emacs с использованием SLIME. SWANK — это серверная часть SLIME. SLIME, вероятно, правильнее называть SLIME/SWANK, так как эти два клиент-серверные компоненты клиент-серверной архитектуры. Я нашел это сообщение в блоге под названием Понимание SLIME, что было полезно.

    Таким образом, можно использовать #-:swankи #+:swankтак же, как #-:noscriptи #+:noscript, за исключением того, что не нужно писать никакого кода.Конечно, это не сработает, если вы используете интерпретатор командной строки sbcl, например, с тех пор :SWANKне будет отображаться в *features*.

10
задан Community 23 May 2017 в 10:34
поделиться