Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lisp parenthesis question

This piece of code is from book : "Land Of Lisp" First version is from book. When I read it, i thought there are parenthesis "(" not necessary just before "at-loc-p" at 2nd line and ")" just after loc at 3rd line.

(defun person-at (loc pers per-locs)
       (labels ((at-loc-p (pers)
                 (eq (cadr (assoc pers per-locs)) loc)))
         (remove-if-not #'at-loc-p pers)))

But when I test this ,

(defun person-at (loc pers per-locs)
       (labels (at-loc-p (pers)
                 (eq (cadr (assoc pers per-locs)) loc))
         (remove-if-not #'at-loc-p pers)))

It came out :

Required arguments in AT-LOC-P don't match lambda list (CCL::FUNCNAME CCL::LAMBDA-LIST &BODY CCL::LABELS-FUNCTION-BODY).
[Condition of type CCL::SIMPLE-PROGRAM-ERROR]

I don't quiete understand. Need help. thank you.

like image 214
Don Lun Avatar asked May 08 '11 01:05

Don Lun


People also ask

What is the purpose of parentheses () in a programming expression?

In many computer programming languages, parentheses have a special purpose. For example, they are frequently used to enclose arguments to functions and methods. In languages such as Lisp, parentheses define an s-expression. In regular expressions, parentheses are used for pattern grouping and capturing.

What is brackets in scripting language?

Brackets, or braces, are a syntactic construct in many programming languages. They take the forms of "[]", "()", "{}" or "<>." They are typically used to denote programming language constructs such as blocks, function calls or array subscripts. Brackets are also known as braces.

What is Scheme language?

Scheme is a multi-paradigm programming language. It is a dialect of Lisp which supports functional and procedural programming. It was developed by Guy L. Steele and Gerald Jay Sussman in the 1970s. Scheme was introduced to the academic world via a series of papers now referred to as Sussman and Steele's Lambda Papers.


3 Answers

The LABELS in

(defun person-at (loc pers per-locs)
  (labels ((at-loc-p (pers)
             (eq (cadr (assoc pers per-locs)) loc)))
    (remove-if-not #'at-loc-p pers)))

has the syntax labels ((function-name lambda-list [[local-declaration* | local-documentation]] local-form*)*) declaration* form*, so you will have to provide a list of local function definitions for it to work.

Since those local function definitions are themselves parenthesized, you will have to pass labels a list of this structure: ((fun1 (...) ...) (fun2 (...) ...) ...).

Unfortunately, the stack trace and error message aren't very helpful in spotting the error here, since the message does not tell you that the problem is with labels, and it also isn't topmost in the trace. The 4: (CCL::NX1-LABELS ... would be a hint (debugger buffer on my local machine).

Take a look at the documentation for labels in the Hyperspec to learn more.

like image 164
danlei Avatar answered Oct 24 '22 15:10

danlei


In other languages, not Lisps, parenthesis are normally used to group operators and so are optional in many cases. But in Lisp parenthesis are always meaningful. There may not be extra or optional parenthesis.

Most often parenthesis around expression mean function or macro application:

(foo 1)

Two parenthesis at the start of expression in such a case may occur, for example, when the first element of expression is another expression, that is evaluated to a function itself. For instance, imagine function make-adder, which takes a number and returns another function with partially applied addition (btw, it's an example of currying):

(defun make-adder (number)
   (lambda (another-number) (+ number another-number)))

We can create function variable increment this way, and then apply it to variable:

(defvar increment (make-adder 1))
(increment 5)                      ; ==> 6

but we can also call it directly (ok, this will not work in Common Lisp, but same syntax works in other Lisps, called "Lisp-1", so I believe it's worth to mention it here) :

((make-adder 1) 5)                 ; ==> 6

making double parenthesis at the beginning. And, of course, both parenthesis are mandatory.

And one final case, which describes your situation, is when the language or user macro uses list of lists for its purposes (do you still remember, that Lisp program is itself a list of lists of expressions?). For example, defun knows, that its 1st argument must be a symbol, and its 2nd argument must be a list. And labels macro knows, that its 1st argument must be a list of definitions, each of which is a list itself. It was made to allow user to define more then one label at a time:

(labels ((definition-1) (definition-2) ...) 
   (do-this) (do-that) ...)

So, you can see, that each parenthesis mean something and you cannot drop them on your own.

like image 29
ffriend Avatar answered Oct 24 '22 16:10

ffriend


i thought there are parenthesis "(" not necessary

Well they are. You can't just add and remove parentheses as you please and expect it to work any more than you could use the symbol asdklfjhsbf in place of, say, defun and expect it to work. You have to give LABELS ((function-name lambda-list forms) ... ), and that's just the syntax of LABELS; if you don't follow it the compiler will raise an error.

like image 29
Nietzche-jou Avatar answered Oct 24 '22 14:10

Nietzche-jou