0

How do we add conditional control to function arguments?

  (defun f (x)
    (let (x)
      (if (eq (x (or 1 2)))
      (print x)
    (print "Hey!"))))

I would like to call:

(f 1)
; 1
(f 2)
; 2
(f 3)
; Hey!
1

There are a bunch of things wrong with your code as is:

  • eq compares two Lisp objects by their identity. This happens to work with integers due to implementation details, but is not guaranteed to work with numbers in general. For example only (= 1 1.0) works as intended, all other comparisons will fail. Use = for that reason (except when comparing floats, then you should be comparing their difference against an appropriate threshold).
  • The function is passed x as argument, then a local variable x is introduced with nil for its value, shadowing the function argument. There is no way the comparison will ever work with that going on.
  • The syntax of the predicate doesn't make terribly much sense. You're passing the eq a single argument (it expects two, it's a comparison function after all). That argument is the result of calling x as a function which will fail (there's no such function because it's been bound in a separate namespace only). Even if it would work, x is passed (or 1 2) which will evaluate to 1 as that's the first truthy value.

I guess you meant to write this instead:

(defun f (x)
  (if (or (= x 1) (= x 2))
      (print x)
    (print "Hey!")))

The predicate passed to if is (or ... ...), where each argument is the result of comparing x to the number you're interested in. An alternative way of writing this would be the member function which searches a list for the first matching item, using equal for comparison (which happens to behave almost like = for integers):

(defun f (x)
  (if (member x '(1 2))
      (print x)
    (print "Hey!")))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.