Шаг 15.
Функции пользователя. Невычисляемые функции

    На этом шаге мы разберем невычисляемые функции пользователя.

    Использование макросредств, предлагаемых последними версиями muLISP (85 и 87), - один из самых эффективных путей реализации сложных программ. При наличии макросредств некоторые функции в языке могут быть определены в виде макрофункций. Такое определение фактически задает закон предварительного построения тела функции непосредственно перед фазой интерпретации.

    К сожалению, в "младших" версиях muLISP (81 и 83) макросредства отсутствуют. Поэтому их приходится моделировать с помощью т.н. невычисляемых функций или NLAMBDA-функций.

    NLAMBDA-функция ("No-spread LAMBDA") - специальный вид лямбда-выражения, обеспечивающий передачу параметров функции по имени.

    Интерпретация невычисляемых функций производится в два этапа.

    На первом, который мы будем называть макрорасширением, происходит формирование лямбда-определения функции в зависимости от текущего контекста, на втором осуществляется интерпретация созданного лямбда-выражения.

    NLAMBDA-выражение имеет вид:


     (NLAMBDA (X1 X2 ... XN) FN)

    Первый аргумент функции NLAMBDA - (X1 X2 ... XN) является лямбда-списком (возможно, пустым!), X1, X2,...,XN - формальными параметрами.

    Второй аргумент функции NLAMBDA (FN) - это тело. Оно представляет собой произвольное выражение, значение которого может вычислить интерпретатор языка LISP. Таким образом:


Рис.1. Вид NLAMBDA-выражения

    Для того, чтобы применить NLAMBDA-функцию к аргументам, нужно в вызове функции поставить NLAMBDA-выражение вместо имени функции (этим будет образован лямбда-вызов):


     ( (NLAMBDA (X1 X2 ... XN) FN) A1 A2 ... AN)

    Здесь Ai (i=1,2,...,N) - выражения языка LISP, определяющие фактические параметры.

    Вычисление NLAMBDA-вызова (применение NLAMBDA-выражения к фактическим параметрам) производится следующим образом: формальные параметры связываются с соответствующими фактическими параметрами. Этот этап называется связыванием параметров.

    На следующем этапе с учетом образованных связей вычисляется тело лямбда-выражения, и полученное значение возвращается в качестве значения лямбда-вызова. Формальным параметрам после окончания вычисления возвращаются те связи, которые у них были перед вычислением лямбда-вызова.

    Весь этот процесс называют NLAMBDA-преобразованием.

    Вывод. Если вычислять значения аргументов функции не нужно, то такую функцию определяйте с помощью NLAMBDA-выражения. Например:


   $ ((NLAMBDA (X) (CDR X)) (1 (TIMES 1 2) 4))
   ((TIMES 1 2) 4))
   $ ((NLAMBDA (X) (CAR X)) ((TIMES 1 2) (PLUS 1 4)))
   (TIMES 1 2)
   $ (((NLAMBDA (X) (CAR X)) (PLUS TIMES)) 2 3)
   (PLUS 2 3)


    Замечание. С помощью невычисляемых функций (псевдомакросов) легко осуществляется определение новых синтаксических форм. Это необходимо, например, при добавлении в язык новых структур управления, типов данных или при реализации интерпретатора для нового проблемно-ориентированного языка. В частности, использование невычисляемых функций облегчает построение языка с лиспоподобной структурой,  0имеющего синтаксис, более удобный для пользователя.

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




    Следующий шаг будет посвящен поименованным функциям.




Предыдущий шаг Содержание Следующий шаг