2014-01-07 3 views
0

Я встречаю ошибки при передаче объектного аргумента макросу. Должен ли я приводить аргумент, помещать его в список или не цитировать его?Передача аргумента объекта макросу

Я хочу использовать Clozure Common Lisp для генерации и запуска нескольких процессов параллельно с помощью блокировки чтения-записи для управления выводом данных в другой процесс. With-write-lock - это макрос, который ждет, пока данная блокировка не будет доступна для доступа к записи, а затем выполнит ее тело с сохраненной блокировкой. Тем не менее, я получаю ошибки независимо от того, как я пытаюсь передать блокировку с записью-записью. У меня проблемы, я думаю, потому что я не понимаю, как передать объект блокировки макросу с записью-записью. Если я связать замок с символом я получаю ошибки деструктурирующие:

(let ((l (make-read-write-lock))) 
    (with-write-lock l (1+ 1))) 
==> 
> Error: L can't be destructured against the lambda list (LOCK), because it is not a proper list. 

While executing: (:INTERNAL CCL::NX1-COMPILE-LAMBDA), in process Listener(4).

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

(with-write-lock (make-read-write-lock) (1+ 1)) 
==> 
;Compiler warnings for "/Users/frank/Documents/Lisp/threaded/act-parallel.lisp" : 
;In an anonymous lambda form at position 18: Undeclared free variable MAKE-READ-WRITE-LOCK 

Error: Unbound variable: MAKE-READ-WRITE-LOCK While executing: #, in process Listener(4).

Am Я неудача, потому что понимает, как передать объект в макрос или я буду криво, потому что или что-то более конкретно к с-записи замок?

Вот макрос-записи-замок, который поставляется с Clozure Common Lisp (macros.lisp):

(defmacro with-write-lock ((lock) &body body) 
    (let* ((locked (gensym)) 
     (p (gensym))) 
    `(with-lock-context 
     (let* ((,locked (make-lock-acquisition)) 
       (,p ,lock)) 
     (declare (dynamic-extent ,locked)) 
     (unwind-protect 
       (progn 
       (write-lock-rwlock ,p ,locked) 
       ,@body) 
      (when (lock-acquisition.status ,locked) (unlock-rwlock ,p))))))) 

ответ

3

Список лямбда для этого макроса аргументы уничтожения того.

((lock) &body body) 

Означает, что он хочет, чтобы первый аргумент был списком, который содержит блокировку, а затем форму тела. Это довольно стандартный список макросов аргумент в CL, вы можете использовать его как это:

(with-write-lock (lock) 
    ..... body forms ....) 

Так что ваши примеры будут

(let ((l (make-read-write-lock))) 
    (with-write-lock (l) (1+ 1))) 

И:

(with-write-lock ((make-read-write-lock)) (1+ 1)) 

соответственно. Обратите внимание на дополнительные парсеры вокруг первого аргумента. Для подобных макросов см with-open-file или destructuring-bind

(with-open-file ("path/to/file" :open :args) 
    .... body ...) 

(destructuring-bind (one two three) '(1 2 3) 
    .... body forms ...) 
Смежные вопросы