Лексические закрытия по макропозволенному?

Существует ли способ сделать, что-то как лексическое использование закрытий макропозволило? То, что я хочу сделать, делают следующий макрос локальным рекурсивным помощником, который вызывает функцию на каждой комбинации вместо того, чтобы генерировать список, поскольку это делает теперь вызов макроса в результатах repl в:

CL-USER> (combinations nil '(1 2 3) '(4 5 6))
((1 4) (1 5) (1 6) (2 4) (2 5) (2 6) (3 4) (3 5) (3 6))

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

Я попытался превратить макрос в макропозволенный в макросе, который берет функцию, и строка' (nreverse (список, объект ,@vars))' заменяется' (func (nreverse (список, объект ,@vars)))', но я получаю ошибки, говоря, что func является неопределенной переменной или функцией.

Это - исходная функция:

(defmacro combinations (vars &rest lsts)
  (with-gensyms (item)
    `(loop for ,item in ,(car lsts) ,(if (null (cdr lsts)) 'collecting 'nconcing)
       ,(if (null (cdr lsts))
            `(nreverse (list ,item ,@vars))
            `(combinations (,item ,@vars) ,@(cdr lsts))))))

Это - то, что я попробовал макропозволенным и получаю неопределенную функцию 'func' ошибки.

(defmacro for-all-combonations (func &rest lst)
       (macrolet ((for-all (vars &rest lsts)
                    (with-gensyms (item)
                      `(loop for ,item in ,(car lsts) ,(if (null (cdr lsts)) 
                                                           'collecting 'nconcing)
                            ,(if (null (cdr lsts))
                                 `(func (nreverse (list ,item ,@vars)))
                                 `(for-all (,item ,@vars) ,@(cdr lsts)))))))
         (for-all nil lst)))
5
задан asm 20 February 2010 в 02:18
поделиться

1 ответ

В форме принимаются только символы A-Z, 0-9 и подчеркивание. Однако имена пользователей не чувствительны к регистру , поэтому можно использовать r '(? i) [a-z0-9_]+', чтобы правильно сопоставить все, а также различить пользователей.

-121--1153400-

Иногда люди составляют свои собственные условия, когда они не должны. «Низкоуровневый Javascript» - один из них. В Javascript нет ничего «низкого уровня.» Он интерпретируется во время выполнения в среде абстракций высокого уровня, таких как DOM.

-121--4096355-

Макросы не являются первоклассными объектами в Common Lisp, поэтому нельзя использовать эквивалент лексического замыкания в качестве макроса. Аналогичный эффект можно получить, создав функцию, которая создает список, являющийся допустимой программой Lisp, а затем оценивает его.

Это, вероятно, не очень хорошее решение вашей проблемы. Как сказал Райнер Жозвиг, макросы предназначены для манипулирования исходным кодом. Используйте их, если требуется новая синтаксическая форма, которая не встроена в язык. Не используйте их там, где вы можете писать то, что хотите с обычными функциями.

5
ответ дан 14 December 2019 в 19:11
поделиться