Функциональное программирование




Массивы. Макросы. Пример программы на лиспе - часть 3


Таким образом при вызове макро сначала вычисляется тело (этап называется расширением) и формируется выражение.

На втором этапе вычисляется полученное выражение, и полученное значение возвращается как результат.

Вызывая macro с разными аргументами получим разные результаты. Если мы вызываем:

(do-times (print count) 10)

После вычисления тела получим:

(do ((count 10 ( - count 1)))

(( zerop count) nil)

(print count))

Печатается числа от 10 до 1.

Можно определить функцию обратной печати чисел

(defun print-number (n)

(do-times (print count) n))

( print-number 5)


9.3.2 Разработка макро

При разработке макро необходимо выполнить три шага:

  • Написать пример функции,которую должна формировать макро,
  • Выделить общие части для нескольких функций и переменные. Переменные части обозначить переменными, выделить запятыми и вынести в аргументы. Постоянные части записать напрямую.
  • Определить макро,которое реализует этот вызов.

    Пример. Надо определить макро

    term-search, которая будет просматривать список и выделять первый элемент удовлетворяющий заданному условию.

    Шаг1. Сформулируем пример. Запишем тело для поиска чисел:

    (setq l '(s d 3 d)) (setq item 5) _ (do (( tail l (cdr tail))) ((null tail) nil) ( cond ((numberp (car tail)) (return (car tail))))) ~~~~~~~

    Шаг2. Выделяем общие части список

    lis - l и предикат

    predicate - number.

    Шаг3.Формируем макро

    (defmacro term-search ( predicate lis) ` (do (( tail , lis (cdr tail))) ((null tail) nil) (cond ((,predicate (car tail)) (return (car tail))))))


    9.4 Пример программы на лиспе. Дифференцирование выражений.

    Напишем программу дифференцирования алгебраических выражений. Для наглядности ограничимся алгебраическими выражениями в следующей форме:

    (+ x y) (* x y)

    Сложение и умножение можно свободно комбинировать.

    Например,

    (*(+ a ( * a b)) c)

    Программируя непосредственно получаем

    (defun diff0 ( l x) (cond (( atom l) (if (eq l x) 1 ;l=1 0));l=константа (( eq (first l) '+) (list '+ (diff0 (second l) x) (diff0 (third l) x))) (( eq (first l) '*) (list '+ (list '* (diff0 (second l) x) (third l)) (list '* (diff0 (third l) x) (second l)))) (t l)))




    Содержание  Назад  Вперед