Песочница

Несколько значений и их количество

Принимайте несколько возвращённых значений, сохраняйте их в списке и находите ошибки, связанные с их количеством.

С помощью call-with-values вы можете получить несколько результатов одного вызова. Передайте их другой процедуре как отдельные аргументы или соберите в один список для хранения.

Получите частное и остаток

Запускайте каждый пример на этой странице отдельно на площадке.

LISPEX
(call-with-values (lambda () (floor/ 17 5)) list)

Результат

ВЫВОД
(3 2)

floor/ возвращает частное 3 и остаток 2 как два значения. call-with-values передаёт их двумя аргументами в list. list возвращает один список (3 2), который можно сохранить в переменной.

Чтобы сразу выполнить вычисление с обоими результатами, примите их в два параметра.

LISPEX
(call-with-values
  (lambda () (floor/ 17 5))
  (lambda (q r) (+ (* q 5) r)))

Результат

ВЫВОД
17

call-with-values вызывает первую процедуру, производителя, без аргументов. Все возвращённые значения она передаёт второй процедуре, потребителю, как аргументы. Потребитель должен принимать это число аргументов с учётом параметра для оставшихся аргументов, иначе возникает E302.

Где требуется одно значение

Контекст значений — это место в выражении, для которого задано допустимое число значений. Каждый аргумент обычного вызова должен давать ровно одно значение. Это же правило действует для условия if, начального значения переменной и правой части set! или define.

LISPEX
(+ (values 1 2) 3)

Диагностика

ВЫВОД
E320

Первый аргумент + дал два значения там, где требовалось одно. Вызов (values) в том же месте вернёт ноль значений и тоже вызовет E320. Он не подставляет значение-заполнитель.

Каждый аргумент values сам должен давать одно значение. Аргументы вычисляются слева направо. Поэтому (values (values 1 2) 3) тоже вызывает E320.

Где допустимо другое количество

Результаты выражений перед последним выражением тела или begin отбрасываются. В этих местах допустимо любое число значений. Производитель call-with-values также может вернуть любое их число, если потребитель принимает соответствующее число аргументов.

ВыражениеРезультатПричина
(+ (values 1) 2)3values возвращает ровно одно значение
(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.

В практическом руководстве есть полный пример сохранения списка. Правила числа аргументов приведены в главе о процедурах.