Please explain lisp's multiple-value-bind
Asked Answered
M

1

12

I've read the docs (several different versions!) but I can't quite get my head wrapped around multiple-value-bind.

Here's what I (think I) know:

  • The first parameter is a list of variables that are going to get bound.
  • The next parameter is a list of values that get bound to the variables.
    • Am I right that these 2 lists have to be the same length?
  • The last parameter (is it optional?) is a body of code that can act on the variables with their newly-bound values.

That sure seems to be how the docs read, and it fits with code I'm reading but not-quite following. I get into trouble when I try to create a multiple-value-bind statement from scratch, as a test. I end up with results like this:

? (mulitple-value-bind (x y z) (values 11 22 33) (+ x y z)) ;; EDIT: contains typo
> Error: Unbound variable: Y
> While executing: CCL::CHEAP-EVAL-IN-ENVIRONMENT, in process Listener(7).
> Type cmd-/ to continue, cmd-. to abort, cmd-\ for a list of available restarts.
> If continued: Retry getting the value of Y.
> Type :? for other options.
1 > 

(I was sort of hoping for output along the lines of 66.) (I'm using Clozure-CL if it matters, though I don't think it should.)

Also, I'm looking at some sample code (trying to understand Project Euler Problem 24) that reads like this:

(multiple-value-bind
    (q r)
    (floor n m)
    (cons (nth q lst) (permute-b r (remove-nth q lst)))
)

(NOTE: I may have mis-indented it, which may be affecting my lack of understanding)

What I don't get about this is it looks to me as if there are 2 variables being multiply-bound (q & r), but only one value (floor n m). Or is the other value the cons statement, and there is no body?!

As you can see, I completely don't get multiple-value-bind; please enlighten me.

Thanks!

Meyerbeer answered 27/7, 2013 at 18:18 Comment(2)
Thanks Chris for pointing out typo in my original. I'm going to leave it in because otherwise the question doesn't make much sense (turns out I understood better than I thought; I just can't type! :) Excellent explanation, thanks!Meyerbeer
"The next parameter is a list of values that get bound to the variables" -- no, it's a form that evaluates to multiple values "The last parameter (is it optional?)" -- it's an implicit progn, so 0 or more formsStash
R
17

Your first example with the "unbound variable" is due to your misspelling multiple-value-bind. Try fixing the spelling; you should see a different result.

As to your second question, floor returns two values, the floor and the remainder. Remember that values is not the only function that returns multiple values!


So, basically, the multiple-value-bind form looks like this:

(multiple-value-bind (var-1 .. var-n) expr
  body)

where expr is an expression that returns multiple values, which are bound to the variable names given in var-1 .. var-n; those variables are available for use in body. It is okay for expr to return more or fewer values than are given as variables; nil is used as the default value for any absent values, and any excess values are discarded.

Retrogressive answered 27/7, 2013 at 18:32 Comment(1)
Aha! Sure enough, fixing typo fixed it. So maybe I understand m-v-b better than I thought I did!Meyerbeer

© 2022 - 2024 — McMap. All rights reserved.