2

Apologies if this is a beginner question. Harsh comments are welcome. I am learning LISP and got a snippet like the below. It checks a constant value in a list and returns only the elements greater than it.

(defun greaterthanX (l)
  (if l
    (if (> (car l) 5)
      (cons (car l) (greaterthanX (cdr l)))
      (greaterthanX (cdr l))
    )
  )
)

(print(greaterthanx '(1 2 3 4 5 6 7 8 3)))

Output : (6 7 8) 

My question is how do I pass a variable inside the recursive function and modify it instead of passing a constant value (ie. 5 in the above case)?

I am looking for something like this :

(defun greaterthanX (x l)
  (if l
    (if (> (car l) x)
      (cons (car l) (greaterthanX (cdr l)))
      (greaterthanX (cdr l))
    )
  )
)

(print(greaterthanx '5 '(1 2 3 4 5 6 7 8 3)))

3 Answers 3

4

you would additionally pass the x value in the two recursive calls to greaterthanX:

CL-USER 5 > (defun greater-than-x (x l)
              (if (consp l)
                  (if (> (first l) x)
                      (cons (first l)
                            (greater-than-x x (rest l)))
                    (greater-than-x x (rest l)))))
GREATER-THAN-X

CL-USER 6 > (print (greater-than-x 5 '(1 2 3 4 5 6 7 8 3)))

(6 7 8)   ; printed
(6 7 8)   ; repl output
Sign up to request clarification or add additional context in comments.

Comments

3

If you don't want the recursion to have to pass down the value, then you use an a local function:

(defun keep-greater-than (x l)
  (labels ((rec (l)
             (if l
                (if (> (car l) x)
                  (cons (car l) (rec (cdr l)))
                  (rec (cdr l))))))
    (rec l)))

The local function rec accesses the outer function's parameter x, which is visible to it.

1 Comment

This is a very common pattern. I do this for almost every recursive function that I write. +1
0

Also greater-than-x is nothing else than filter:

(defun greater-than-x (x l)
  (filter (lambda (el) (< x el)) l))

Or a typical reduce function. filter you can express als reduce:

(defun my-filter (fun l)
  (nreverse 
    (reduce (lambda (result el) 
              (if (funcall fun el)
                  (cons el result)
                  result))
            l :initial-value '())))

or recursion:

(defun my-filter (fun l &optional (acc '()))
  (cond ((null l) (nreverse acc))
        ((funcall fun (car l)) (my-filter fun (cdr l) (cons (car l) acc)))
        (t (my-filter fun (cdr l) acc))))

Comments

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.