С помощью call-with-values вы можете получить несколько результатов одного вызова. Передайте их другой процедуре как отдельные аргументы или соберите в один список для хранения.
Получите частное и остаток
Запускайте каждый пример на этой странице отдельно на площадке.
(call-with-values (lambda () (floor/ 17 5)) list)Результат
(3 2)floor/ возвращает частное 3 и остаток 2 как два значения. call-with-values передаёт их двумя аргументами в list. list возвращает один список (3 2), который можно сохранить в переменной.
Чтобы сразу выполнить вычисление с обоими результатами, примите их в два параметра.
(call-with-values
(lambda () (floor/ 17 5))
(lambda (q r) (+ (* q 5) r)))Результат
17call-with-values вызывает первую процедуру, производителя, без аргументов. Все возвращённые значения она передаёт второй процедуре, потребителю, как аргументы. Потребитель должен принимать это число аргументов с учётом параметра для оставшихся аргументов, иначе возникает E302.
Где требуется одно значение
Контекст значений — это место в выражении, для которого задано допустимое число значений. Каждый аргумент обычного вызова должен давать ровно одно значение. Это же правило действует для условия if, начального значения переменной и правой части set! или define.
(+ (values 1 2) 3)Диагностика
E320Первый аргумент + дал два значения там, где требовалось одно. Вызов (values) в том же месте вернёт ноль значений и тоже вызовет E320. Он не подставляет значение-заполнитель.
Каждый аргумент values сам должен давать одно значение. Аргументы вычисляются слева направо. Поэтому (values (values 1 2) 3) тоже вызывает E320.
Где допустимо другое количество
Результаты выражений перед последним выражением тела или begin отбрасываются. В этих местах допустимо любое число значений. Производитель call-with-values также может вернуть любое их число, если потребитель принимает соответствующее число аргументов.
| Выражение | Результат | Причина |
|---|---|---|
(+ (values 1) 2) | 3 | values возвращает ровно одно значение |
(begin (values 1 2) 3) | 3 | Два значения первого выражения отбрасываются |
(call-with-values (lambda () (values)) list) | () | list получает ноль аргументов и возвращает один пустой список |
(call-with-values (lambda () (values 1 2)) list) | (1 2) | list получает два аргумента и возвращает один список |
Сохраните несколько результатов как одно значение
Несколько возвращённых значений образуют пакет значений, который передаётся следующему вычислению. Для хранения результатов создайте список или вектор. Например, (list 1 2) создаёт одно значение с двумя элементами. Если передать этот список потребителю с двумя параметрами, он получит лишь один аргумент и возникнет E302.
В практическом руководстве есть полный пример сохранения списка. Правила числа аргументов приведены в главе о процедурах.