LINUX.ORG.RU

Красота в Common Lisp

 ,


1

1

Привет. У меня есть файл. Он имеет такой вид и подключается из asd-файла:

#+cool-feature
(toplevel-form)

#+cool-feature
(another-toplevel-form)

#+cool-feature
(declaim ...)

#+cool-feature
(declaim ...)

#+cool-feature
(yet-another-toplevel-form)

Фича :cool-feature добавляется в процессе компиляции до компиляции этого файла. А вот вопрос: как бы мне написать «#+cool-feature» всего лишь один раз в начале файла и охватить все эти формы разом? Т.е. что-то вроде

#+cool-feature
(block nil
  (form-1)
  (form-2)
  (declaration-1)
  ...)

Кстати, если фича не добавляется, можно вообще не компилять файл. Важное замечание: объявления должны быть в силе в compile-time.

Да, зачем мне это надо? У меня в одном файле список фич, с которыми прожект будет собран, но которые необязательны для работы и которые её тормозят (например, всякие проверки)

Можно использовать progn для этого.

#+cool-feature
(progn
  ...)

А вообще, feature expressions лучше не использовать.

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

Можно использовать progn для этого.

Так вот, чё cltlv2 пишет про declaim:

If a call to this macro appears at top level in a file being processed by the file compiler, the proclamations are also made at compile time. As with other defining macros, it is unspecified whether or not the compile-time side effects of a declaim persist after the file has been compiled (see section 25.1).

Значит ли это, что если спрятать его в progn, эффекты в compile-time от него уйдут?

А вообще, feature expressions лучше не использовать.

Чёй-то?

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

Он же читатет asd файл до того, как фича появится. У меня там что-то вроде:

(eval-when (:compile-toplevel :load-toplevel :execute)
    (pushnew :cool-feature *features*))
esandmann
() автор топика
Ответ на: комментарий от esandmann

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

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

If progn appears as a top level form, then all forms within that progn are considered by the compiler to be top level forms.

Интересно, а функция func-2 будет в топ-левеле?

(progn
  (defun func-1 ()
    ...))

  (progn
    (defun func-2 ()
      ...)
......
    )
...
  )

Раз func-1 в топ-левеле, тои вложенный progn там же. Соответственно, применяем «If progn appears as a top level form,...». Как это проверить?

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

Если дефан есть внутри дефана, то объявляемая им функция не будет видна в топлевеле, нет?

// И правда видна, это я привык к схемке

buddhist ★★★★★
()
Последнее исправление: buddhist (всего исправлений: 2)
Ответ на: комментарий от anonymous

Интересно, а функция func-2 будет в топ-левеле?

Будет. На этом многие макросы построены.

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

И правда видна, это я привык к схемке

Кстати, а в схемке (или её диалектах) можно сделать функцию, которая создаёт функцию глобального модуля?

Что-то типа

(defun maker (x)
  (setf (symbol-function (intern (format nil "DO-~A" x)) )
        (lambda () x)))

(maker 1)
(do-1) ; -> 1

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

Насколько я помню (не особо использовал не-чистоту), нельзя. И это одна из претензий любителей классических лиспов (picolisp, newlisp) к схемке.

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

Насколько я помню (не особо использовал не-чистоту)

Нашёл для Racket:

(define (maker x)
  (namespace-set-variable-value! 
     (string->symbol (format "do-~a" x))
     (lambda () x)))

> (maker 1)
> (do-1)
1

И это одна из претензий любителей классических лиспов (picolisp, newlisp) к схемке.

Классических — это с fexpr'ами? Там единственная существенная претензия: динамическая область видимости для let (включая eval). Все остальные претензии сводятся к «зачем всё так сложно?»

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

В Racket значит слегка приблизились к CL в этом плане

В Racket почти ко всему «слегка приблизились».

  • модули lazy и typed/racket — к Haskell.
  • Racket/load — к Picolisp (eval работает почти как там).
  • swindle = CLOS + generic setf + CL-подобные lambda.
  • datalog и racklog — к Прологу

всё вышеперечисленное может использоваться вперемешку в одном проекте: можно один модуль написать на racklog, а функции из него вызывать из swindle, например.

+ своя собственная система классов/объектов; своя собственная библиотека GUI, нативно выглядящая на Win32/MacOS/Linux (в случае Linux нативно = Gtk); своя собственная система подготовки текстов (и документации), умеющая генерировать HTML/PDF/TeX.

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.