С помощью call-with-values вы можете передать два возвращённых значения другой функции. Чтобы сохранить их вместе, соберите их в один список процедурой list.
Примите два значения как два аргумента
Выполните этот пример целиком на площадке.
(call-with-values
(lambda () (values 3 4))
(lambda (a b) (+ (* a a) (* b b))))Результат
25Сначала call-with-values вызывает (lambda () (values 3 4)) без аргументов. Эта процедура возвращает два значения, 3 и 4.
Затем call-with-values вызывает вторую процедуру, передавая каждое значение отдельным аргументом. Параметры a и b получают 3 и 4, поэтому сумма квадратов равна 25.
Первую процедуру называют производителем, а вторую — потребителем. Пакет значений — это все значения, возвращённые одним вызовом. Здесь в нём два числа, которые потребитель получает по отдельности.
Сохраните результаты в списке
Выполните этот пример целиком, чтобы сохранить оба числа под одним именем.
(define saved
(call-with-values (lambda () (values 3 4)) list))
savedРезультат
(3 4)Здесь потребитель — list. Он получает два аргумента и создаёт один список. define сохраняет этот список в saved.
values возвращает значения вызывающему коду. Для хранения соберите их в список или вектор. Список из двух элементов считается одним значением, хотя содержит два числа.
Проверьте, сколько значений нужно следующему вызову
Потребитель должен принимать столько аргументов, сколько значений вернул производитель. В первом примере у него два параметра. list принимает любое число аргументов.
Каждое выражение аргумента обычного вызова, условие, начальное значение переменной и правая часть присваивания требуют одного значения. Сначала примите несколько результатов через call-with-values, чтобы использовать их в этих местах. Саму процедуру-производитель можно сохранить в переменной и передать в call-with-values.
(values) возвращает ноль значений. Их может принять потребитель, допускающий вызов без аргументов. Этот вызов также подходит для мест, где результаты отбрасываются, например перед последним выражением в begin.
Измените пример
В первом примере замените (values 3 4) на (list 3 4). Сможет ли потребитель с двумя параметрами по-прежнему обработать результат?
Ответ
Возникнет E302, ошибка числа аргументов. Теперь производитель возвращает один список, поэтому потребитель получает один аргумент. Его два параметра требуют двух аргументов. Используйте values, чтобы вернуть два числа по отдельности.
В главе о нескольких значениях указано, сколько значений допустимо в каждом месте программы. Фиксированное и переменное число аргументов описано в главе о процедурах.