Существует как минимум три подхода:
- использовать примитивный Лисп для отработки рекурсии на функциональном языке программирования
- использовать функции более высокого порядка: MAP и REDUCE и стиль программирования без побочных эффектов
- использовать итерацию и побочные эффекты
Я покажу вам подход 2:
Одним из важных инструментов является функциональная абстракция . Используйте функции для реализации автономных функций, которые можно использовать повторно и которые можно легко протестировать.
Вам нужна цена. Напишите GET-PRICE
функцию.
(defun get-price (item price-list)
(getf price-list item))
Выше используется прайс-лист, представляющий собой список свойств . GETF
делает поиск. Вы можете повторно реализовать его как задачу.
Применение функции к списку и сбор возвращаемых значений называется * mapping 'в списке. К сожалению, Lisp предоставляет функции отображения, которые принимают один элемент за раз, а не два. Мы пишем один:
(defun map2 (function list)
(loop for (a b) on list by #'cddr
collect (funcall function a b)))
MAP2
сопоставляет список и применяет функцию к первому и второму аргументу, затем к третьему и четвертому ... он собирает результаты в новый список, который затем возвращается.
Выше используется конструкция LOOP
. Вы можете повторно реализовать его, используя DO
в качестве задачи.
(defun calc-total (cart price-list)
(reduce #'+
(map2 (lambda (item n)
(* n (get-price item price-list)))
cart)))
Выше используются две функции высшего порядка: REDUCE
и MAP2
. Более высокий порядок означает, что они принимают функции в качестве параметров. REDUCE
- это библиотечная функция в Common Lisp. Мы используем его для подведения итогов списка чисел. С помощью MAP2
мы вычисляем цену для каждого элемента корзины, умножая количество товаров на цену за товар.
CL-USER > (calc-total '(shirtA 3 shirtB 1) '(shirtA 25 shirtB 55))
130
РЕЗЮМЕ
Вышеуказанный подход имеет несколько преимуществ:
- у нас есть небольшие / компактные функции, которые легко понять и протестировать
- без видимых побочных эффектов
- базовая модель отображения и сокращения - это шаблон, который часто появляется при обработке списков и который легко понять
- функции легко комбинируются
- функция 'MAP2' - это новый полезный инструмент многократного использования
- расположение кода гораздо лучше читать
Для других подходов есть подсказки:
- вам нужно использовать рекурсивный вызов
- вам нужно использовать переменную для суммы, добавить цены в качестве побочного эффекта и вернуть сумму в конце.