문제

I am working on a Lisp program that contains code to read in the dimensions of boxes and then sort them from shortest to longest lengths (and set each of these new lengths as new variables).

When I attempt to load my file into the interpreter, I get the following error:

 - SYSTEM::%EXPAND-FORM: invalid form (40)

Assuming this error is stemming from line 40 of my code, here are lines 34-45:

(defun get-box ()
    (let ((d1) (d2) (d3))
        (setf d1 (read))
        (setf d2 (read))
        (setf d3 (read))
        (list d1 d2 d3))
        (if (= -1 d1)
            (exit)
            (setf new-d1 (first (sort (d1 d2 d3)) #'<))
            (setf new-d2 (second (sort (d1 d2 d3)) #'<))
            (setf new-d3 (third (sort (d1 d2 d3)) #'<))
            (next-part-of-program (new-d1, new-d2, new-d3)))

Is there anything inherently wrong syntactically or semantically with my if statement in this code snippet? What does the EXPAND-FORM error come from/mean in Lisp?

Any help is greatly appreciated. Thanks!

도움이 되었습니까?

해결책

When you see a message mentioning symbols in the "SYS" package (also known as "SI" and "SYSTEM" in different implementations), especially when the symbols are internal (prefixed with two colons), and, moreover, their names contain non-alphanumeric characters (e.g., % or $), chances are this message is implementation-specific, and you will help us help you by mentioning which implementation you are using.

That said, I think you are using CLISP, in which case this 40 does not name a line in your file.

You either have a literal 40 in an inappropriate place in your file, or you have a variable with the value of 40 which you evaluate during macroexpansion with a misplaced comma.

다른 팁

An if can have only a single expression for the consequent, and a single for the alternative (the "else" part). If you need to write more than one expression, pack them inside progn. I believe this is what you intended:

(if (= d1 -1) ; condition. It's bad style to write Yoda conditions!
    (exit) ; consequent
    (progn ; alternative
     …))

Also, be aware that there seems to be a misplaced parentheses at the end of this line:

(list d1 d2 d3))

… And anyway, the above line is doing nothing, you can simply delete it. Also this part is wrong:

(sort (d1 d2 d3)) #'<)

It should be:

(sort (list d1 d2 d3) #'<)

And in here, the commas are wrong:

(new-d1, new-d2, new-d3)

Also, in this line the variables should have an initial value, and you should also declare new-d1, new-d2 and new-d3

(let ((d1) (d2) (d3))

With all the fixes in place, this is how the code should look:

(defun get-box ()
  (let ((d1 0) (d2 0) (d3 0) (new-d1 0) (new-d2 0) (new-d3 0))
    (setf d1 (read))
    (setf d2 (read))
    (setf d3 (read))
    (if (= d1 -1)
        (exit)
        (progn
          (setf new-d1 (first  (sort (list d1 d2 d3) #'<)))
          (setf new-d2 (second (sort (list d1 d2 d3) #'<)))
          (setf new-d3 (third  (sort (list d1 d2 d3) #'<)))
          (next-part-of-program new-d1 new-d2 new-d3)))))
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top