SBCL - «недопустимый вызов функции» в функции цикла - PullRequest
1 голос
/ 23 октября 2019

Это общий пример кода, который я программирую:

(defun test (a b)
  (loop for x in '(a b) collect
    ((setf a (+ a b))
    (loop for y in '(a b) 
          (setf a (+ a b))
          (loop for z in '(a b) 
            (setf a (+ a b))))
    (list a b))))

Когда я вызываю функцию (тест) в REPL, это дает мне «недопустимый вызов функции», как вы можете видеть ниже:

> (test 1 1)

debugger invoked on a SB-INT:COMPILED-PROGRAM-ERROR in thread
#<THREAD "main thread" RUNNING {10005E85B3}>:
  Execution of a form compiled with errors.
Form:
  ((SETF A (+ A B))
 (LOOP FOR Y IN '(A B) (SETF A (+ A B)) (LOOP FOR Z IN '(A B) (SETF A
                                                                      (+ A
                                                                         B))))
 (LIST A B))
Compile-time error:
  illegal function call

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(FRED5 #<unused argument> #<unused argument>)
   source: ((SETF A (+ A B))
            (LOOP FOR Y IN '(A B) (SETF A (+ A B)) (LOOP FOR Z IN '(A B) (SETF A
                                                                                 (+
                                                                                  A
                                                                                  B))))
            (LIST A B))
0] 0

>

Кажется, я что-то не так с первыми (цикл для) параметров, но я не могу выяснить, что. Кто-нибудь может помочь с этим, пожалуйста? Спасибо!

РЕДАКТИРОВАТЬ 1:

Итак, я внес коррективы @Rainer Joswig и @Xero Smith предложили:

(defun test (a b)
  (loop for x in '(a b) collect
    (setf a (+ x 1))
    (loop for y in '(a b) do
          (setf a (+ y 1))
          (loop for z in '(a b) do 
            (setf a (+ z 1))))
    (list a b)))

НоТеперь я получаю следующую ошибку:

> (test 1 1)

debugger invoked on a SB-INT:COMPILED-PROGRAM-ERROR in thread
#<THREAD "main thread" RUNNING {10005E85B3}>:
  Execution of a form compiled with errors.
Form:
  (LOOP FOR X IN '(A B)
      COLLECT (SETF A (+ X 1)) (LOOP FOR Y IN '(A B)
                                     DO (SETF A (+ Y 1)) (LOOP FOR Z IN '(A B)
                                                               DO (SETF A
                                                                          (+ Z
                                                                             1)))) (LIST
                                                                                    A
                                                                                    B))
Compile-time error:
  during macroexpansion of (LOOP FOR X ...). Use *BREAK-ON-SIGNALS* to intercept.

 (LOOP FOR Y IN '(A B)
       DO (SETF A (+ Y 1)) (LOOP FOR Z IN '(A B)
                                 DO (SETF A
                                            (+ Z
                                               1)))) found where a LOOP keyword or LOOP type keyword expected
current LOOP context: COLLECT (SETF A (+ X 1)) (LOOP FOR Y IN '(A B)
                                                     DO (SETF A
                                                                (+ Y
                                                                   1)) (LOOP FOR Z IN '(A
                                                                                        B)
                                                                             DO (SETF A
                                                                                        (+
                                                                                         Z
                                                                                         1)))).

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

Ответы [ 3 ]

4 голосов
/ 23 октября 2019
(defun test (a b)
  (loop for x in '(a b) collect  ; X unused
        ((setf a (+ a b))      ; error: not a function, too many parentheses
         (loop for y in '(a b)    ; Y unused
               (setf a (+ a b))       ; error: no DO 
               (loop for z in '(a b)   ; z unused
                     (setf a (+ a b))))  ; error: no DO
         (list a b))))
3 голосов
/ 23 октября 2019

Ваше исправление по-прежнему неверно. collect принимает одну форму в качестве аргумента. Теперь у вас есть collect (setf ...) (loop ...).

С другой стороны, предложение do принимает несколько форм.

Возможно, эта функция - то, что вы ищете, или закройте:

(defun test (a b)
  (loop for x in '(a b)
        do (setf a (+ a b))
           (loop for y in '(a b) 
                 do (setf a (+ a b))
                    (loop for z in '(a b) 
                          do (setf a (+ a b))))
        collect (list a b))))

Если вы хотите объединить внешний цикл setf, for y и (list a b) в одно предложение collect, тогда требуется progn:

(defun test (a b)
  (loop for x in '(a b)
        collect (progn (setf a (+ a b))
                       (loop for y in '(a b) 
                             do (setf a (+ a b))
                                (loop for z in '(a b) 
                                      do (setf a (+ a b))))
                       (list a b))))
2 голосов
/ 23 октября 2019

Это ваша проблема: ((setf a (+ a b)) замените ее на (setf a (+ a b)). Это ошибка, потому что выражение ((setf a (+ a b)) не является функцией.

...