Never called Lisp function - lisp

(defun func (in s f l)
(cond
((null in) (append l (list (list 'end (+ 1 f)))))
((eq (car in) 'foo) (foo-asd (cdr in) s f l))
((atom (car in))(atom-asd in (+ 1 s) (+ 1 f) l))
))
.
(defun atom-asd (in s f l)
(cond ((eql in nil) ())
(append l (list (list 'frob s (car in) (+ 1 f))))))
.
(defun foo-asd (in s f l)
(cond
((eql in nil) (append l (list (list 'frob s 'myst f))))
((func in s f (append l (list (list 'frob s 'myst (+ 1 f))))))
((foo-asd (cdr in) s f l))
))
.
Regarding this code if call (func '(foo x y) 0 0 ()) the function foo-asd will be called, then func is called again and it will enter the function atom-asd, when atom-asd ends it execution, all the program ends, without calling the recursive call foo-asd. I need foo-asd to be called, but i do not understand why it isn't called after atom-asd ends.

[4]> (trace func)
;; Tracing function func.
(func)
[5]> (trace atom-asd)
;; Tracing function atom-asd.
(atom-asd)
[6]> (trace foo-asd)
;; Tracing function foo-asd.
(foo-asd)
[7]> (func '(foo x y) 0 0 ())
1. Trace: (func '(foo x y) '0 '0 'nil)
2. Trace: (foo-asd '(x y) '0 '0 'nil)
3. Trace: (func '(x y) '0 '0 '((frob 0 myst 1)))
4. Trace: (atom-asd '(x y) '1 '1 '((frob 0 myst 1)))
*** - cond: variable append has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of append.
STORE-VALUE :R2 Input a new value for append.
ABORT :R3 Abort main loop
Break 1 [8]>
So in atom-asd:
(defun atom-asd (in s f l)
(cond
((eql in nil)
())
(append
l (list (list 'frob s (car in) (+ 1 f))))))
You have two predicates. one tests (eql in nil) which obviously is nil, then it checks if the variable append has a non nil value. Problem is append is not a bound variable. It is a binding in the function namespace, but here every term is inclused in one set of parentheses so append is by itself th eexpression that gets tested. You might have meant that it should do (append ...) when the first term didn't kick in and you should have written it like this:
(defun atom-asd (in s f l)
(cond
((eql in nil)
())
(t
(append l (list (list 'frob s (car in) (+ 1 f)))))))
With this version we get a result:
[8]> (func '(foo x y) 0 0 ())
5. Trace: (func '(foo x y) '0 '0 'nil)
6. Trace: (foo-asd '(x y) '0 '0 'nil)
7. Trace: (func '(x y) '0 '0 '((frob 0 myst 1)))
8. Trace: (atom-asd '(x y) '1 '1 '((frob 0 myst 1)))
8. Trace: atom-asd ==> ((frob 0 myst 1) (frob 1 x 2))
7. Trace: func ==> ((frob 0 myst 1) (frob 1 x 2))
6. Trace: foo-asd ==> ((frob 0 myst 1) (frob 1 x 2))
5. Trace: func ==> ((frob 0 myst 1) (frob 1 x 2))
((frob 0 myst 1) (frob 1 x 2))

Related

Why we can't use (values) like this?

(define (avg . l)
(/ (apply + l) (length l)))
(define (delist ls)
(apply values ls))
(avg (delist '(1 2 3))) ;;error
(avg 1 2 3) ;; return 2
without call-with-values, can I bind the value returned by values to each parameter in other ways?
can I bind the value returned by values to each parameter in other ways?
Here are most of the ways I know of to bind variables to returned values in Racket:
#lang racket/base
(define (list->values lst) (apply values lst))
(define-values (a b c) (list->values '(1 2 3)))
(displayln (+ a b c))
(let-values ([(d e f) (list->values '(4 5 6))])
(displayln (+ d e f)))
(require racket/match)
(match/values (list->values '(7 8 9))
([x y z] (displayln (+ x y z))))
(require srfi/8)
(receive (i j k) (list->values '(10 11 12)) (displayln (+ i j k)))
(displayln (call-with-values (lambda () (list->values '(13 14 15))) +))

EVAL: undefined function X

I keep getting some random errors while trying to call my function that has to return
the level of a node from a binary tree.
This is my method
(defun nodeLevel(x index l)
(cond
((null l) nil)
((equal (car l) x) index)
((equal (cadr l) 1) (nodeLevel ( x (+ index 1) (cddr l))))
((equal (cadr l) 2) (nodeLevel ( x (+ index 1) (cddr l))))
(t nodeLevel(x (+ index 1) (cddddr l)))
)
)
This is how i call it
(nodeLevel 'D '0 '(A 2 B 0 C 2 D 0 E 0) )
You have extra parentheses. When you call a function, the entire call goes in parens, but the arguments don't get their own set. You've written
(nodeLevel (x (+ index 1) (cddr l)))
What you probably meant was
(nodeLevel x (+ index 1) (cddr l))

LISP function which, given a number and a list, returns the first even number greater than n

I'm having trouble finding my error.
This keeps returning nil:
(even-greater-n 5 '(1 2 3 4 5 6 7))
(defun even-greater-n (n L)
(cond ((null L) nil)
((and (> (car L) n) (evenp n)) (car L))
(t (even-greater-n n (cdr L)))))
Your error
You are passing to evenp n
instead of (car L).
Iteration
This is relatively easy to implement using
loop:
(defun even-greater (n l)
(loop for k in l
when (and (< n k)
(evenp k))
return k))
(even-greater 5 '(1 2 3 4 5 6 7 8))
==> 6
Recursion
If you are required to use recursion, you can do it too:
(defun even-greater (n l)
(cond ((endp l) nil)
((and (< n (first l))
(evenp (first l)))
(first l))
(t (even-greater n (rest l)))))
(even-greater 3 '(1 2 3 4 5 6 7 8))
==> 4
Library
And, of course, Lisp has a very powerful library, including
find-if:
(defun even-greater (n l)
(find-if (lambda (k)
(and (< n k)
(evenp k)))
l))
(even-greater 2 '(1 2 3 4 5 6 7 8))
==> 4
You must look for (car L) is even or not.
Using find-if and a single, open-coded lambda function:
(defun even-greater (n list)
(find-if (lambda (item) (and (> item n) (evenp item))) list))
Using functional combinators:
;; Combine multiple functions with AND:
;; Returns a function of one-argument which
;; passes that argument to the functions in the list,
;; one by one. If any function returns nil, it stops
;; and returns nil. Otherwise it returns the value
;; returned by the last function:
(defun andf (&rest functions)
(lambda (arg)
(let (res)
(dolist (f functions res)
(unless (setf res (funcall f arg))
(return))))))
;; Returns a one-argument function which tests
;; whether its argument is greater than quant.
(defun greater (quant)
(lambda (arg) (> arg quant)))
;; "find it, if it is greater than n, and even"
(defun even-greater (n list)
(find-if (andf (greater n) #'evenp) list))

Evaluating Racket expression

Given these definitions:
(define s 8)
(define p (/ s 2))
(define (f s p)
(cond [(or (> s 0) p) 'yes] [(< s 0) 'no]))
I want to evaluate this expression:
(f 0 (and (< s p) (> s 2)))
So far I have:
⇒ (f 0 (and (< 8 p) (> s 2)))
⇒ (f 0 (and (< 8 4) (> s 2)))
⇒ (f 0 (and false (> s 2)))
⇒ (f 0 false)
How do I finish this?
You need to replace this with the body of f (the cond expression) with the parameters replaced by their matching arguments.
Racket sees that f is a procedure and evaluates it's arguments:
(f 0 (and (< s p) (> s 2))) ; ==>
(f 0 (and (< 8 4) (> 8 2))) ; ==>
(f 0 (and #f #t)) ; ==>
(f 0 #f) ; s=0, p=#f
Then the arguments is substituted for the variables in the body of f:
; ==>
(cond [(or (> 0 0) #f) 'yes]
[(< 0 0) 'no])
since both (or (> 0 0) #f) and (< 0 0) are #f the result is the undefined value chosen by the implementation. In racket it's #<void>
; ==>
#<void>
This could have been avoided by always have a else term:
(define (f s p)
(cond [(or (> s 0) p) 'yes]
[(< s 0) 'no]
[else 'banana]))
(f 0 (and (< s p) (> s 2))) ; ==> banana

number of sub-lists in a list, having an even sum, from odd levels in Lisp

I have a non-linear list. I need to find out the number of sub-lists at any level in the initial list, for which the sum of the numerical atoms at the odd levels, is an even number. The superficial level is counted as 1. I wrote something like:
(defun numbering (l level)
;counts the levels that verify the initial conditions
(cond
((null l) l)
((and (verify (sumlist l)) (not (verify level))) (+ 1 (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l))))
(T (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l )))
)
)
(defun verify (n)
;returns true if the parameter "n" is even, or NIL, otherwise
(cond
((numberp n)(= (mod n 2) 0))
(T f)
)
)
(defun sumlist (l)
;returns the sum of the numerical atoms from a list, at its superficial level
(cond
((null l) 0)
((numberp (car l)) (+ (car l) (sumlist(cdr l))))
(T (sumlist(cdr l)))
)
)
(defun mainNumbering (l)
; main function, for initializing the level with 1
(numbering l 1)
)
If I run "(mainnum '(1 2 (a b 4) 8 (6 g)))" I get the error: " Undefined function MAPCAR# called with arguments ((LAMBDA (A) (NUMEROTARE A #)) (1 2 (A B 4) 8 (6 G)))."
Does anyone know, what am I missing? Thanks in advance!
Well, that's true, there is no such function as mapcar#, it's just a typo, you missing space in this line:
(T (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l )))
It should be:
(T (apply '+ (mapcar #'(lambda (a) (numbering a (+ 1 level))) l )))
Here is a possible solution, if I have interpreted correctly your specification:
(defun sum(l)
(loop for x in l when (numberp x) sum x))
(defun test(l &optional (level 1))
(+ (if (and (oddp level) (evenp (sum l))) 1 0)
(loop for x in l when (listp x) sum (test x (1+ level)))))
(test '(1 2 (a b 4) 7 (6 2 g) (7 1 (2 (3) (4 4) 2) 1 a))) ; => 2
The function sum applied to a list returns the sum of all its numbers (without entering in its sublists).
The function test, for a list with an odd level, sum its numbers, and, if the result is even, add 1 to the sum of the results of the function applied to the sublists of l, 0 otherwise.
in numbering you should add the case when l is a number,so
(defun numbering (l level)
;counts the levels that verify the initial conditions
(cond
((null l) l)
((atom l)0)
((and (verify (sumlist l)) (not (verify level))) (+ 1 (apply '+ (mapcar #' (lambda (a) (numbering a (+ 1 level))) l))))
(T (apply '+ (mapcar #'(lambda (a) (numbering a (+ 1 level))) l )))
)
)
will resolve the problem