2

Let's say, I want to call function foo, which requires 2 arguments a and b. (foo a b).
And in some use cases, the values of those parameters depend on each other, like this:

(let (a
      b)
  (if (something-p)
      (progn 
        (setq a 'a1)
        (setq b 'b1))
    (progn
      (setq a 'a2)
      (setq b 'b2)))
  (foo a b))

Is there a (lisp) pattern for this kind of problem? (Or do I need to write my own macro for that?)

2 Answers 2

5

Examples:

Applying a list:

(apply #'foo
       (if (something-p)
          (list 'a1 'b1)
          (list 'a2 'b2)))

Similar, but with multiple values:

(multiple-value-call #'foo
  (if (something)
     (values 'a1 'b1)
     (values 'a2 'b2)))

Binding multiple values:

(multiple-value-bind (a b)
    (if (something)
        (values 'a1 'b1)
        (values 'a2 'b2))
  (foo a b))

Nested let:

(let ((something (something-p)))
  (let ((a (if something 'a1 'b2))
        (b (if something 'b1 'b2)))
    (foo a b)))
Sign up to request clarification or add additional context in comments.

Comments

3

Your example does not really illustrate the parameters' mutual interdependence. As for the conditional aspect, you can embed arbitrary conditions into your function call. So you could have e.g.:

(foo (if (something-p) 'a1 'a2)
     (if (something-p) 'b1 'b2))

EDIT: If you're concerned about multiple evaluations of something-p, you can always store the value of a single evaluation in a let variable like this:

(let ((c (something-p)))
  (foo (if c 'a1 'a2)
       (if c 'b1 'b2)))

2 Comments

Yes my example is bad, I'm sorry. In you solution (something-p) gets evaluated twice, what if that is not wanted (because of side-effects)?
Edited my answer to include that scenario.

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.