Fixing this undefined-function in lisp code? [closed] - recursion

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I am losing my mind over evaluating this code to find the error. I am not sure why I am getting an undefined function. Would someone please guide me to understand why? thanks!
O is supposed to be an object, and L a list. I am trying to attach O to the end of the list and return the list
(defun my_attach(O L)
(cond ((eq L nil )
O )
(t (cons (car L) (my-attach O (cdr L)) )
)
)
)

If you have copied correctly your code in the post, you have used two different names for the same function: my_attach (_ is the underscore character) and my-attach (- is the dash character).
Simply use the same name. For instance:
(defun my-attach(O L)
(cond ((eq L nil ) O)
(t (cons (car L) (my-attach O (cdr L))))))
But note that this will not produce the desired result (in fact it does not produce a proper list). Rather, you should use (list O) instead of O in the terminal case:
CL-USER> (defun my-attach(O L)
(cond ((eq L nil) O)
(t (cons (car L) (my-attach O (cdr L))))))
MY-ATTACH
CL-USER> (my-attach 3 '(1 2))
(1 2 . 3)
CL-USER> (my-attach 3 '())
3
CL-USER> (defun my-attach(O L)
(cond ((eq L nil) (list O))
(t (cons (car L) (my-attach O (cdr L))))))
MY-ATTACH
CL-USER> (my-attach 3 '(1 2))
(1 2 3)
CL-USER> (my-attach 3 '())
(3)
Finally, a note about the common writing conventions for Common Lisp programs:
it is preferred to use lower case identifiers;
compound words in identifiers are separated by -, not by _ as in other languages;
it is preferred to use if when there are only two cases in a conditional statement;
check for a value which is nil is commonly done with the predicate null;
the parentheses at the end of an expression are usually written on the same line of the last part of the expression.
So your function could be rewritten as:
(defun my-attach (o l)
(if (null l)
(list o)
(cons (car l) (my-attach o (cdr l)))))

Related

Performance Impact of Creating Enclosed Procedure in Scheme During Recursion

I'm making my way through the book The Little Schemer to start to learn to think in Lisp. As you get into it and really cover the use of lambdas, the 'remove' procedure is written in the following general form, which returns a remove procedure for arbitrary test test?:
(define rember-f
(lambda (test?)
(lambda (a l)
(cond
((null? l) (quote ()))
((test? (car l) a) (cdr l))
(else (cons (car l)
((rember-f test?) a (cdr l))))))))
I understand how this works just fine, but a plain reading of it suggests that at each recursive step, it is the procedure rember-f that is called again to generate a new enclosed procedure. This would mean when you call your returned procedure on a list, it calls rember-f to generate the same procedure again anew and then that new one is what is called for recursion (if that is not clear see my fix below). I understand that this may be optimized away, but in lieu of not knowing whether it is (and also in attempting to get my head around this syntax anyway), I managed after some experimentation to move the recursion to the procedure itself rather than the enclosing procedure as follows:
(define rember-f
(lambda (test?)
(define retfun
(lambda (a l)
(cond
((null? l) (quote ()))
((test? (car l) a) (cdr l))
(else (cons (car l) (retfun a (cdr l)))))))
retfun))
I have verified that this works as expected. The return value is a procedure that removes the first element of a list (arg 2) matching a value (arg 1). It looks to me like this one only calls rember-f once, which guarantees it only generates one enclosed procedure (this time with a name, retfun).
This is actually interesting to me because unlike the usual tail call optimization, which is about not consuming space on the call stack and so making recursion about as efficient as iteration, in this case the compiler would have to determine that (rember-f test?) is the enclosing procedure scope unmodified and so replace it with the same return value, which is the anonymous (lambda (a l) ...). It would not surprise me at all to learn that the interpreter / compiler does not catch this.
Yes, I know that scheme is a specification and there are many implementations, which get the various functional programming optimizations right to differing degrees. I am currently learning by experimenting in the guile REPL, but would be interested in how different implementations compare on this issue.
Does anyone know how Scheme is supposed to behave in this instance?
You are right to be concerned about the additional repeated lambda abstractions. For example you wouldn't write this, would you?
(cond ((> (some-expensive-computation x) 0) ...)
((< (some-expensive-computation x) 0) ...)
(else ...))
Instead we bind the result of some-expensive-computation to an identifier so we can check multiple conditions on the same value -
(let ((result (some-expensive-computation x)))
(cond ((> result 0) ...)
((< result 0) ...)
(else ...)))
You discovered the essential purpose of so-called "named let" expressions. Here's your program -
(define rember-f
(lambda (test?)
(define retfun
(lambda (a l)
(cond
((null? l) (quote ()))
((test? (car l) a) (cdr l))
(else (cons (car l) (retfun a (cdr l)))))))
retfun))
And its equivalent using a named-let expression. Below we bind the let body to loop, which is a callable procedure allowing recursion of the body. Notice how the lambda abstractions are used just once, and the inner lambda can be repeated without creating/evaluating additional lambdas -
(define rember-f
(lambda (test?)
(lambda (a l)
(let loop ; name, "loop", or anything of your choice
((l l)) ; bindings, here we shadow l, or could rename it
(cond
((null? l) (quote ()))
((test? (car l) a) (cdr l))
(else (cons (car l) (loop (cdr l))))))))) ; apply "loop" with args
Let's run it -
((rember-f eq?) 'c '(a b c d e f))
'(a b d e f)
The syntax for named-let is -
(let proc-identifier ((arg-identifier initial-expr) ...)
body ...)
Named-let is a syntax sugar of a letrec binding -
(define rember-f
(lambda (test?)
(lambda (a l)
(letrec ((loop (lambda (l)
(cond
((null? l) (quote ()))
((test? (car l) a) (cdr l))
(else (cons (car l) (loop (cdr l))))))))
(loop l)))))
((rember-f eq?) 'c '(a b c d e f))
'(a b d e f)
Similarly, you could imagine using a nested define -
(define rember-f
(lambda (test?)
(lambda (a l)
(define (loop l)
(cond
((null? l) (quote ()))
((test? (car l) a) (cdr l))
(else (cons (car l) (loop (cdr l))))))
(loop l))))
((rember-f eq?) 'c '(a b c d e f))
'(a b d e f)
PS, you you can write '() in place of (quote ())
Both procedures have the same asymptotic time complexity. Let's consider the evaluation of ((rember-f =) 1 '(5 4 3 2 1 0)).
A partial evaluation proceeds as follows:
((rember-f =) 1 '(5 4 3 2 1 0))
((lambda (a l)
(cond
((null? l) (quote ()))
((= (car l) a) (cdr l))
(else (cons (car l)
((rember-f =) a (cdr l)))))) 1 '(5 4 3 2 1 0))
(cons 5 ((rember-f = 1 '(4 3 2 1 0))))
Note that the creation of the temporary lambda procedure takes O(1) time and space. So it doesn't actually add any substantial overhead to the cost of calling the function. At best, factoring out the function will lead to a constant-factor speedup and the use of a constant amount less of memory.
But how much memory does it really take to make a closure? It turns out it takes very little memory. A closure consists of a pointer to the environment and a pointer to compiled code. Basically, creating the closure requires as much time and space as making a cons cell. So even though it looks like we're using a lot of memory when I show the evaluation, very little memory and very little time is actually used to make and store the lambda.
So essentially, by factoring out the recursive function, you've allocated a single cons cell rather than writing code which allocates that cons cell one time per recursive call.
For more information on this, see Lambda is cheap, and Closures are Fast.
to start to learn to think in Lisp
That book is not about thinking in lisp, but about recursive thinking, which is one of the ways of computation discovered in the 20th century by Goedel, Herbrand, Rozsa Peter.
Does anyone know how Scheme is supposed to behave in this instance?
After you finish the little lisper you should take the SICP, which will make you understand what kind of decisions an implementation of a language can make. You mean, how different implementations act. To understand their implementation decision, the best step to do is to learn it from SICP. Take care, unless you are already a certified computer science graduate, this texbook will take you a few years to master, if you study it each day. If you are already a graduate, it will take you only about 1 year to master.

CLisp - sorting and combining two lists in quicksort

I'm trying to implement quicksort in CLisp, and so far I'm able to partition the list around a pivot. However, when I try to combine and recursively sort the sublists, I get either a stack overflow or an error with let, and I'm not sure what's going wrong. Here's my code:
(defun pivot (n xs)
(list (getLesser n xs) (getGreater n xs))
)
(defun getLesser (m l)
(cond
((null l) nil)
((<= m (car l)) (getLesser m (cdr l)))
(t (cons (car l) (getLesser m (cdr l)))))
)
(defun getGreater (m l)
(cond
((null l) nil)
((> m (car l)) (getGreater m (cdr l)))
(t (cons (car l) (getGreater m (cdr l)))))
)
(defun quicksort (xs)
(cond
((null xs) nil)
(t
(let (partition (pivot (car xs) xs))
(cond
((null (car partition)) (cons (quicksort (cdr partition)) nil))
((null (cdr partition)) (cons (quicksort (car partition)) nil))
(t (append (quicksort (car partition)) (quicksort (cdr partition)))))))))
My idea was to have a local variable partition that is a list of 2 lists, where car partition is the list of number less than the pivot, and cdr partition is the list of numbers greater than the pivot. Then, in the final cond construct, if there were no numbers less than the pivot I would recursively sort the 2nd list; if there were no numbers greater than the pivot I would sort the 1st list; else I would recursively sort both and append them in order. Can anyone help me out?
Compiling the file gives you hints about wrong syntax.
GNU CLISP produces these diagnostics:
$ clisp -q -c foo.lisp
;; Compiling file /tmp/foo.lisp ...
WARNING: in QUICKSORT in lines 20..28 : Illegal syntax in LET/LET*: (PIVOT (CAR XS) XS)
Ignore the error and proceed
;; Deleted file /tmp/foo.fas
There were errors in the following functions:
QUICKSORT
1 error, 1 warning
SBCL produces similar diagnostics:
$ sbcl --eval '(compile-file "foo.lisp")' --quit
This is SBCL 1.3.1.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
; compiling file "/tmp/foo.lisp" (written 08 MAY 2019 08:58:54 PM):
; compiling (DEFUN PIVOT ...)
; compiling (DEFUN GETLESSER ...)
; compiling (DEFUN GETGREATER ...)
; compiling (DEFUN QUICKSORT ...)
; file: /tmp/foo.lisp
; in: DEFUN QUICKSORT
; (LET (PARTITION (PIVOT (CAR XS) XS))
; (COND ((NULL (CAR PARTITION)) (CONS (QUICKSORT #) NIL))
; ((NULL (CDR PARTITION)) (CONS (QUICKSORT #) NIL))
; (T (APPEND (QUICKSORT #) (QUICKSORT #)))))
;
; caught ERROR:
; The LET binding spec (PIVOT (CAR XS) XS) is malformed.
;
; compilation unit finished
; caught 1 ERROR condition
; /tmp/foo.fasl written
; compilation finished in 0:00:00.021
You can then look up the expected syntax in CLHS: http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/speope_letcm_letst.html
The syntax for LET is (LET BINDINGS . BODY), where BINDINGS is a list of bindings; each binding is a (SYMBOL VALUE) list. Alternatively, a binding can just be SYMBOL, which stands for (SYMBOL NIL). Your code is:
(let (partition (pivot (car xs) xs))
...)
Let's write one binding per line and normalize all bindings as a proper list:
(let ((partition nil)
(pivot (car xs) xs)))
...)
You can see that the code:
binds partition to NIL
has a malformed second binding: there are three elements, namely pivot, (car xs) and xs, which does not match the expected (SYMBOL VALUE) syntax.

debugging simple LISP functions. [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am very new to lisp, and am having a hard time even getting my feet wet. I'm sure once, I have a few functions working, I'll be able to build upon them and work on higher order functions, and more complex problems.
Can someone point out my errors in the following code.
(defun indeHelper(A L N)
(cond (Null N) nil)
((= A (first L) (cons N (indeHelper A (rest L) (+ 1 N)))))
(t (indeHelper A (rest L) (+ 1 N))))
(defun inde(A L)
(funcall indeHelper(A L 1)))
Also how would I call this? I have one function I think is working ok, but I can't get the syntax for calling it. Thanks for any help.
You have a number of syntax issues.
The syntax of COND is:
(cond (test1 body1...)
(test2 body2...)
...)
Your test1 is supposed to be (null n), and body1 should be nil, but you didn't wrap them in a level of parentheses. Then your other tests and bodies are outside cond, as should be apparent from the indentation.
It should be:
(defun indeHelper(A L N)
(cond ((Null N) nil)
((= A (first L) (cons N (indeHelper A (rest L) (+ 1 N)))))
(t (indeHelper A (rest L) (+ 1 N)))))
In the second function, you don't need to use funcall. That's used when you're calling a dynamically-determined function (e.g. when writing higher-order functions), but you're just calling a known function. It should just be:
(defun inde(A L)
(indeHelper A L 1))
If you did need to use funcall, the syntax is:
(funcall someVariable A L 1)
When using funcall, the arguments aren't put into a nested list, they're just ordinary arguments to funcall.

recursive scheme program to iterative

need help on making these two recursive programs in scheme iterative?
I made the recursion, but am stuck at creating an iteration for both.
question 1 - recursion
(define mylength
(lambda (l)
(cond
((null? l) 0)
(else (+ 1 (mylength (cdr l)))))))
question 1 - iteration?
question 2 - recursion
(define mylistref
(lambda (l index)
(cond
((= index 0)(car l))
(else
(mylistref (cdr l) (- index 1))))))
question 2 - iteration?
Scheme does not have any looping structures so your only option is to use recursion if you are traversing over some kind of data structure. You can read more about it here

Common lisp recursive macro in matrix addition

I have to write a recursive macro for list addition in Common Lisp (homework). What I have so far is :
(defmacro matrix-add-row (r1 r2 sum_row)
(if (not (and r1 r2)) `sum_row
(progn
`(matrix-add-row (cdr r1) (cdr r2) (cons sum_row (+ (car r1) (car r2))))
(reverse sum_row)
)
)
)
I call this function with
(matrix-add-row `(1 2) `(3 4) ())
and as an output I get unvaluated code instead of numbers (which leads going to infinite loop).
How to put , ` properly (or call the macro properly)?
Firstly, to me this seems a rather bizarre thing to do with a macro. I assume the point is that you use the macro to transform (matrix-add-row '(1 2) '(3 4)) to an explicit list of sums like (list (+ 1 3) (+ 2 4)).
Also, what you have written has several problems which look like you don't quite understand how the backtick works. So I think the easiest way to help is to solve an example for you.
Since this is homework, I'm going to solve a different (but similar) question. You should be able to take the answer and use it for your example. Suppose I want to solve the following:
Write a macro, diffs, which computes all differences of pairs of successive elements in a list. For example,
(diffs '(1 2 3)) should expand to (list (- 2 1) (- 3 2)), which will then evaluate to (1 1).
Note that my macro won't do the actual subtraction, so I can use it even if I don't know some of the numbers until runtime. (The reason I think this sort of question is a bit weird is that it does need to know the length of the list at compile time).
My solution is going to be used as a macro with one argument but if I want to use recursion I'll need to pass in an accumulator too, which I can start with nil. So I write something like this:
(defmacro diffs (lst &optional accumulator)
...)
Now what do I do with lst? If lst is nil, I want to bottom out and just return the accumulator, with a call to list at the front, which will be code to make my list. Something like this:
(defmacro diffs (lst &optional accumulator)
(cond
((null lst)
;; You could write `(list ,#accumulator) instead, but that seems
;; unnecessarily obfuscated.
(cons 'list accumulator))
(t
(error "Aargh. Unhandled"))))
Let's try it!
CL-USER> (diffs nil)
NIL
Not hugely exciting, but it looks plausible. Now use macroexpand, which just does the expansion without the evaluation:
CL-USER> (macroexpand '(diffs nil))
(LIST)
T
And what if we'd already got some stuff from a recursion?
CL-USER> (macroexpand '(diffs nil ((- a b) (- b c))))
(LIST (- A B) (- B C))
T
Looks good! Now we need to deal with the case when there's an actual list there. The test you want is consp and (for my example) it only makes sense when there's at least two elements.
(defmacro diffs (lst &optional accumulator)
(cond
;; A list of at least two elements
((and (consp lst) (consp (cdr lst)))
(list 'diffs (cdr lst)
(cons (list '- (cadr lst) (car lst)) accumulator)))
;; A list with at most one element
((listp lst)
(cons 'list accumulator))
(t
(error "Aargh. Unhandled"))))
This seems almost to work:
CL-USER> (macroexpand '(diffs (3 4 5)))
(LIST (- 5 4) (- 4 3))
T
but for two problems:
The list comes out backwards
The code is a bit horrible when we actually construct the recursive expansion
Let's fix the second part first by using the backtick operator:
(defmacro diffs (lst &optional accumulator)
(cond
;; A list of at least two elements
((and (consp lst) (consp (cdr lst)))
`(diffs ,(cdr lst)
,(cons `(- ,(cadr lst) ,(car lst)) accumulator)))
;; A list with at most one element
((listp lst)
(cons 'list accumulator))
(t
(error "Aargh. Unhandled"))))
Hmm, it's not actually much shorter, but I think it's clearer.
For the second part, we could proceed by adding each item to the end of the accumulator rather than the front, but that's not particularly quick in Lisp because lists are singly linked. Better is to construct the accumulator backwards and then reverse it at the end:
(defmacro diffs (lst &optional accumulator)
(cond
;; A list of at least two elements
((and (consp lst) (consp (cdr lst)))
`(diffs ,(cdr lst)
,(cons `(- ,(cadr lst) ,(car lst)) accumulator)))
;; A list with at most one element
((listp lst)
(cons 'list (reverse accumulator)))
(t
(error "Aargh. Unhandled"))))
Now we get:
CL-USER> (macroexpand '(diffs (3 4 5)))
(LIST (- 4 3) (- 5 4))
T
Much better!
Two last things. Firstly, I still have an error clause in my macro. Can you see how to trigger it? Can you think of a better behaviour than just outputting an error? (Your macro is going to have to deal with the same problem)
Secondly, for debugging recursive macros like this, I recommend using macroexpand-1 which just unfolds one level at once. For example:
CL-USER> (macroexpand-1 '(diffs (3 4 5)))
(DIFFS (4 5) ((- 4 3)))
T
CL-USER> (macroexpand-1 *)
(DIFFS (5) ((- 5 4) (- 4 3)))
T
CL-USER> (macroexpand-1 *)
(LIST (- 4 3) (- 5 4))
T
There are two problems with your logic. First you are calling reverse on each iteration instead of at the end of the iteration. Then you are accumulating the new values, through cons, in the cdr of the cons cell as opposed to the car.
Also I don't see why this have to be a macro so using a function.
(defun matrix-add-row (r1 r2 sum-row)
(if (or (endp r1) (endp r2))
(reverse sum-row)
(matrix-add-row (cdr r1)
(cdr r2)
(cons (+ (car r1) (car r2))
sum-row))))
(matrix-add-row '(1 2) '(3 4) ())
;; => (4 6)

Resources