Multiple Values

Everything returns a value and that value could be a compound type like a list.

In many circumstances, the implicit assignment of multiple values to multiple variables (either named variables or function parameters) is a desirable effect. This is a common trope in many programming languages.

Idio does not specifically handle the return or receipt of multiple values but there are a number of helper functions.

function values [args]

return multiple values

Param args:

arguments to be tagged as multiple values

Type args:

list or any

Return:

list of multiple values

Rtype:

list

function call-with-values producer consumer

invoke consumer with the values returned from invoking producer

Param producer:

function to return multiple values

Type producer:

thunk

Param consumer:

function to accept as many values as producer generates

Type consumer:

function

Return:

return value of consumer

Rtype:

any

call-with-values is the fundamental operator in multiple values, all other functions are derivations of it.

Example:

(call-with-values
 (function #n (values 1 2 3 4))
 (function (a b c d) {
   printf "a + d = %s\n" (a + d)  ; a + d = 5
 }))

Here, the consumer function is called with arguments 1 2 3 4, the multiple values returned by the producer function.

template let-values mv-bindings body

invoke body in the context of the multiple values bindings

Param mv-bindings:

multiple values bindings, see below

Type mv-bindings:

list

Param body:

body form

Type body:

expressions

Return:

return value of body

Rtype:

any

mv-bindings takes the form ((formals init) ...) where init is an expression returning multiple values and formals is a list of variable names.

Example:

(let-values
 (((a b) (values 1 2))
  ((c d) (values 3 4))) {
   printf "a + d = %s\n" (a + d)  ; a + d = 5
 })

Here, the body function is called with the variable names a, b, c and d bound to values 1, 2, 3 and 4 respectively.

formals can be an improper list:

(let-values
 (((a b & c) (values 1 2 3 4))) {
   printf "c is %s\n" c                           ; c is (3 4)
   printf "a + (pht c) = %s\n" (a + (pht c))      ; a + (pht c) = 5
 })
template let*-values mv-bindings body

invoke body in the context of the multiple values bindings

Param mv-bindings:

multiple values bindings, see below

Type mv-bindings:

list

Param body:

body form

Type body:

expressions

Return:

return value of body

Rtype:

any

mv-bindings takes the form ((formals init) ...) where init is an expression returning multiple values and formals is a list of variable names.

let*-values is similar to let-values except the inner bindings are evaluated in the context of the outer bindings.

Example:

(let*-values
 (((a b) (values 1 2))
  ((c d) (values (a + b) (a - b)))) {
  printf "c=%s d=%s\n" c d                        ; c=3 d=-1
 })
template define-values formals expr

define multiple new variables from the multiple values returned from expr

Param formals:

variable names

Type formals:

list

Param expr:

expression returning multiple values

Type expr:

expression

Rtype:

any

Example:

define-values (a b & c) (values 1 2 3 4)

printf "a + (pht c) = %s\n" (a + (pht c)) ; a + (pht c) = 5

Last built at 2024-05-17T06:10:49Z+0000 from 62cca4c (dev) for Idio 0.3.b.6