работать с локальными переменными и возвращать их во вложенных циклах Common Lisp - PullRequest
0 голосов
/ 31 мая 2018

У меня есть следующий код, и у вложенного цикла есть проблема: я стремлюсь реализовать CLOS multi-dispatch (multi-методов) для академических целей.У меня есть список аргументов, переданных универсальной функции.Универсальная функция (gf) содержит список методов.В свою очередь, каждый метод в универсальной функции содержит список классов (специалистов), которым принадлежат аргументы, с которыми он работает.Чтобы метод был применим, каждый аргумент, передаваемый обобщенной функции, должен быть экземпляром или подклассом его соответствующего специалиста в методе, содержащемся в списке методов обобщенной функции.В частности, проблема заключается в работе с локальными переменными и возвращении их во вложенные циклы.

(defun compute-applicable-methods (gf &rest args)
     (loop for method in (generic-function-methods gf)
                    do (loop for specializer in (method-specializer method)
                              for arg in args
                               counting (instancep arg specializer) into matched_args
                                  )
         when (= matched_args (count args)
        collect method ) ))

1 Ответ

0 голосов
/ 31 мая 2018

Без правильного отступа и форматирования кода вы не должны писать ни кода, ни кода на Лиспе.С Lisp у вас также нет никаких оправданий, потому что IDE сделает отступ для вас.

Исправлено отступ:

(defun compute-applicable-methods (gf &rest args)
  (loop for method in (generic-function-methods gf)
        do (loop for specializer in (method-specializer method)
                 for arg in args
                 counting (instancep arg specializer) into matched_args
                 )
        when (= matched_args (count args)
                collect method ) ))

Тем не менее код странно отформатирован.Улучшения:

(defun compute-applicable-methods (gf &rest args)
  (loop for method in (generic-function-methods gf)
        do (loop for specializer in (method-specializer method)
                 for arg in args
                 counting (instancep arg specializer) into matched_args)
        when (= matched_args (count args)
                collect method)))

Первое, что вы видите, что функция = не имеет правильного списка аргументов.collect и method не должны быть аргументами для =:

(defun compute-applicable-methods (gf &rest args)
  (loop for method in (generic-function-methods gf)
        do (loop for specializer in (method-specializer method)
                 for arg in args
                 counting (instancep arg specializer) into matched-args)
        when (= matched-args (count args))
        collect method))

Внутренний LOOP не возвращает никакого значения, и вы учитываете локальную переменную matched-args, которую вы не 't use.

Если вы не используете переменную, давайте удалим ее:

(defun compute-applicable-methods (gf &rest args)
  (loop for method in (generic-function-methods gf)
        do (loop for specializer in (method-specializer method)
                 for arg in args
                 count (instancep arg specializer))
        when (= matched-args (count args))
        collect method))

Теперь внутренний LOOP возвращает значение, но мы его не используем.Улучшение:

(defun compute-applicable-methods (gf &rest args)
  (loop for method in (generic-function-methods gf)
        for matched-args = (loop for specializer in (method-specializer method)
                                 for arg in args
                                 counting (instancep arg specializer))
        when (= matched-args (count args))
        collect method))
...