Песочница

Создание и потребление нескольких значений

Используйте `values` для пакета значений и `call-with-values` для передачи consumer с подходящей арностью.

Проверьте запуском

LISPEX
(call-with-values (lambda () (values 3 4)) (lambda (a b) (+ (* a a) (* b b))))

Наблюдаемый результат

OUTPUT
25

Разберите приём

  1. Получите пакет. Первая lambda возвращает два значения, 3 и 4, а не строит список.
  2. Согласуйте потребителя. У второй lambda два параметра, поэтому её арность точно совпадает с пакетом.
  3. Вычисляйте обычно. Внутри потребителя a и b — обычные одиночные значения, а арифметика возвращает 25.

Как рассуждать

  • Помещайте producer в специальный producer context, а не в операнд вызова, тест, инициализатор или RHS присваивания.
  • Consumer получает каждое произведённое значение отдельным аргументом и обычно проверяется на арность.
  • Используйте (values) осознанно для нуля значений в допускающих отбрасывание путях.

Проверьте себя

Замените потребителя на list. Какой результат сохранится и чем он отличается от пакета производителя?

Ответ

Получится обычный список (3 4). call-with-values передал два аргумента, а list намеренно построил одно хранимое значение.

Частая ошибка

Не кодируйте семантические multiple values обычным списком, если вызывающий ожидает арность значений.

Куда дальше

Все контексты значений определены в руководстве, а ошибка несовпадающей арности — в главе о процедурах.

Контексты нескольких значений · Процедуры и арность