-1

I'm learning lisp by myself and I can´t figure out why am I getting this error. If somebody could help me that would be great :)

This is the condition where I'm getting the error:

(cond ((equal c1 caracter) (push caracter pilatemp))
    ((or (equal c2 caracter) (equal c3 caracter) (equal c4 caracter) (equal c5 caracter) (equal c6 caracter))
        ((loop
            (setf t1 (jerarquia(caracter)))
            (setf t2 (jerarquia(first pilatemp)))
            if((or (= t1 t2) (> t1 t2)) (return))
            (push (pop pilatemp) piladef))
        (push caracter pilatemp)
            ))
    ((equal c7 caracter) ((loop
                    if((equal (first pila) c1) (return))
                    (push (pop pilatemp) piladef))
                (pop pilatemp)))
    (T (push caracter piladef))
)

And here is the "jerarquia" function:

(defun jerarquia(x)
(setf c1 ")")
(setf c2 "+")
(setf c3 "-")
(setf c4 "^")
(setf c5 "*")
(setf c6 "/")
(setf c7 "(")
(cond ((equal c1 x) 5)
    ((equal c4 x) 4)
    ((equal c5 x) 3)
    ((equal c2 x) 2)
    ((equal c7 x) 1)
    (T 0)))

Here's the error I'm getting:

*** - SYSTEM::%EXPAND-FORM:
(LOOP (SETF T1 (JERARQUIA (CARACTER)))
  (SETF T2 (JERARQUIA (FIRST PILATEMP))) IF
  ((OR (= T1 T2) (> T1 T2)) (RETURN)) (PUSH (POP PILATEMP) PILADEF))
should be lambda expression
7
  • (jerarquia caracter), not (jerarquia(caracter)) ... parameters to functions don't get extra parentheses. Commented May 19, 2014 at 20:42
  • you are right thanks, but still getting the same error :/ Commented May 19, 2014 at 20:58
  • Why the double parens before LOOP? Commented May 19, 2014 at 21:02
  • I wrote the double parens because I wanted (push caracter pilatemp) to be inside of the <Action> of the second condition but not inside of the loop. I don't know if that's ok or not :/ Commented May 19, 2014 at 21:15
  • possible duplicate of Common lisp error: "should be lambda expression" Note that that duplicate was the first result searching for "should be lambda expression" site:stackoverflow.com on Google. Commented May 19, 2014 at 23:46

2 Answers 2

2

It's clear that you are quite confused about how SExpressions are put together to create valid Common Lisp programs. That's common for a beginner. Let me take a stab at giving you a very brief introduction.

The simplest thing are atoms. Things like Alpha, +, 12, -23.4; those four are respectively two symbols, two numbers. The plus sign is a symbol, just like alpha.

The next simplest thing are function calls, i.e. invoking a function. For example: (+ 1 2). The function in that example is addition, and it's associated with the symbol +.

Function calls are common in all programming languages. And typically they evaluate them left to right bottom up. So (F (G 1 2) (H 3 5)) will call G, then H, then F. If they want to do something else they introduce syntax, like if statements, loops, etc. etc.

Which brings us t the next thing, a clever thing. In Lisp all the syntax appears at first blush just like a function call. So you get things like: (if (< a b) (f a) (f b)). Which is not evaluated bottom up, but top down so that it can decided based on the first form which of the two calls on F it should make.

These top-down forms come in two flavors, special forms and macros, but for a beginner that's not important. These forms are used instead of the syntax you find in other languages. The evaluator/compilers glance at the first term in the list to decide if it's a simple function call or a bit of syntax.

Which lets us explain the error you observed in your posting. The evaluator (or compiler) saw ((loop ...) ...), and the first term in that is (loop ...). That bewildered the evaluator. It expects to see a symbol. Of course the error message is entirely opaque, but that's because things are a bit more subtle than I'm making them out to be. For a beginner that doesn't matter.

The form (cond ...) is another example of a form this isn't a simple function call, but is instead more like syntax. The when it glanced as the first element, i.e. cond, it knew to expect (cond (??? ...) (??? ...) ...etc...) where the ??? are forms it will used to decide if it should run that branch's ...

There are numerous other problems with your code. I'd recommend that you get a lisp REPL and experiment with things in much smaller pieces. The loops are broken. The "((OR (..." suffers the same problem of the first form not being a symbol. It appears that your calling strings that contain a single character "characters" rather than strings, that's tacky but tolerable.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks a lot, now I understand more about Lisp and I've restructured my program :)
0

Lisp differs from most other languages in that parentheses matter.

Specifically, (foo) is not the same as foo and ((foo)).

When you write (JERARQUIA (CARACTER)), lisp thinks that you want to call JERARQUIA on the return value of the function CARACTER, not the value of the variable CARACTER.

Similarly, when you write ((loop ...) ...), lisp must interpret (loop ...) as a function designator, which can be either a symbol or a lambda expression (or (setf ...)).

Therefore, all you need to do to avoid this error is remove the extra set of parens, replacing ((loop ...)) with (loop ...).

5 Comments

I wrote the double parens because I wanted (push caracter pilatemp) to be inside of the <Action> of the second condition but not inside of the loop. It doesn't matter if I just write one paren?
as I said, foo, (foo) and ((foo)) are very different things. please remove the extra parens.
use emacs to properly format your code. this will pinpoint the error for you without even having to evaluate it in Lisp
@user3654129 Common Lisp requires you to get your parentheses correct. This is different from other languages you might be used to. Parentheses change the meaning of your program. You cannot add or remove them because you feel like it. They are never optional or meaningless.
If you want to have multiple "actions" in a cond, you could wrap them in a (PROGN ...), but it happens to be the case that cond has an "implicit progn", so in this specific case, an extra wrapping of progn would't do anything.

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.