1
(defun helper-2 (list) 
  (if (null (first (rest list)))
      0)
  (+ (distance ((car list) (first (rest list)))) 
     (helper-2 (rest list))))

I'm new to lisp and I'm writing a program to compute the perimeter of any polygon with input following clockwise order. My logic is that I use a helper method to compute the length of two points next to each other and do the sum. After recursion is done, I will do a separate call to calculate the length from the beginning point to its end and sum everything up. I've finished the distance method which takes 2 points and return the length.

(distance '(2 0) '(4 0)) ;this will output 2

helper-2 logic: assume we have 3 points a (2 0) b (3 3) c (4 0) This method is expected to sum up the distance between ab and bc. However, I keep getting "(car head) should be a lambda expression" error. Can anyone help? Thank you. Or could anyone give me a better way to compute the perimeter of a polygon?

(defun square (n) (* n n))

(defun distance (a b)
  (let ((h (- (second b) (second a)))
        (w (- (first b) (first a))))
    (sqrt (+ (square h) (square w)))))
2
  • 1
    As an aside, you might want to keep your use of first/rest and car/cdr consistent, for readability's sake. Mixing car with first/rest here is a bit confusing. There's also (cadr list) which works the same as doing (first (rest list)). Commented Nov 15, 2014 at 2:52
  • 1
    In Scheme, ((car args1...) args2...) would first evaluate (car args1...) to produce some value x and then tries to call x as a function with args2. In Common Lisp, a function call has to be of the form (xxx ...) where xxx is either a symbol or a lambda expression (car ...) isn't either. The implementation sees that's it's not a symbol, so figures that it should be a lambda expression, but it's not, and complains. Commented Nov 15, 2014 at 3:16

2 Answers 2

4

Your helper-2 function is wrong in two places:

  1. You should be using a two-armed if, so that it functions as an if/else.
  2. You have too many parentheses around the (car list).

Here's the fixed version:

(defun helper-2 (list) 
  (if (null (first (rest list)))
      0
      (+ (distance (car list) (first (rest list))) 
         (helper-2 (rest list)))))
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your answer. Another question. How do I use this function? I've tried (helper-2 '(2 0) '(4 0)) it says too many arguments. How do I pass in a list of points?
It sounds like you should use (helper-2 '((2 0) (4 0)))? I have not tested it, though.
it says too few parameters for special operator if
You've actually modified the code from what I've got, and it's incorrect. Please cut and paste my code and use it directly.
4

Section 3.1.2.1.2.3 Function Forms of the HyperSpec describes how a form that is a cons, such as ((car list) (first (rest list))), is evaluated:

How a compound form is processed depends on whether it is classified as a special form, a macro form, a function form, or a lambda form.

You can read the subsections linked to from that page for more details, but the essence is that since the first element of this list is not a symbol, the form as a whole must be a lambda form. According to 3.1.2.1.2.4 Lambda Forms a lambda form is a list where the first element is a lambda expression. `However, (car list) is not a lambda expression, so you get the corresponding error message.

You claimed that (distance '(2 0) '(4 0)) will output two, but that shows distance being called with two arguments. Even if ((car list) (first (rest list))) could be evaluated, it would produce just one value, and so (distance ((car list) (first (rest list)))) would call distance with just one argument. You should be doing this instead:

(distance (car list) (first (rest list)))

Also see:

2 Comments

Thank you for your answer. Another question. How do I use this function? I've tried (helper-2 '(2 0) '(4 0)) it says too many arguments. How do I pass in a list of points?
@AnOverflowedStack I'm glad I didn't see this comment until now, since it appears you asked the same thing in a new question, How do I pass in a list of list into a function?, in the meantime.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.