It's up to you...
But if you want to learn about recursion the answer is 'yes, you need to!'

First I wrote the following:Check if a list contains only numbers (assume it's not empty).
Code: Select all
CL-USER> (defun numbersp (lst)
(cond
((numberp (car lst)) 'car-is-a-number)
(nil)))
NUMBERSP
CL-USER> (numbersp '(1 2 3))
CAR-IS-A-NUMBER
CL-USER> (numbersp '(a 2 3))
NIL
Code: Select all
CL-USER> (defun numb (lst)
(cond
((numberp (car lst)) (numb (cdr lst)))
(nil)))
Code: Select all
(defun numbersp (lst)
(cond
((null lst) T)
((numberp (car lst)) (numbersp (cdr lst)))))
Code: Select all
(defun numbersp (lst)
(cond
((null lst) T)
((numberp (car lst)) (numbersp (cdr lst)))
(t nil)))
Thanks a lot, both of you.Philipp wrote:For simlicity, the task was defined to work with not-empty lists only. So very good!
By the way, though cond returns nil by default, I think it's convention to always state the 'fall-through'-case in cond, like so:This way it's clear that you didn't just forgot a case.Code: Select all
(defun numbersp (lst) (cond ((null lst) T) ((numberp (car lst)) (numbersp (cdr lst))) (t nil)))
Philipp wrote: Extract the numbers!Code: Select all
(defun numbers (lst) ...) > (numbers '(1 2 a b 3 c 4 1)) => (1 2 3 4 1)
Code: Select all
(defun numbers (lst)
(labels ((is-number (elt)
(numberp elt)))
(delete-if-not #'is-number lst)))
Code: Select all
(defun numbers (lst)
(setq new-lst '())
(cond
((numberp (car lst)) (cons (car lst) new-lst) (numbers (cdr lst)))
((null lst) new-lst)
(t (numbers (cdr lst)))))
Code: Select all
(let ((new-lst (list)))
(defun numbers (lst) ...)
Code: Select all
(defun numbers (lst)
(let ((new-lst (list)))
(labels ((list-walker (list) ....))
(list-walker lst)
(nreverse new-lst)) ;assuming you're using push or cons to build your list you need to reverse it when you're done
Code: Select all
(defvar *a* 3) ;*a* is now defined as special
(defun test-a () *a*)
(test-a) ;This yields 3
(let ((*a* 5)) ;Even though we use let, *a* was already special and will not become lexical
(test-a) ;Because *a* is special, we can shadow it at run-time with let, and the effect will propagate to functions defined earlier
(let ((b 4)) ;b is now lexical
(defun test-b () b)) ;Since b is lexical, it's value will be locked in when we compile this function
(test-b) ;this yields 4
(let ((b 6))
(test-b) ;this also yields 4, because due to b's lexical nature, we cannot shadow it any more.
Just do (delete-if-not #'numberp lst) -- is-number serves no purpose here. (But please name your argument "list" rather than "lst")sycamorex wrote:Code: Select all
(defun numbers (lst) (labels ((is-number (elt) (numberp elt))) (delete-if-not #'is-number lst)))