Опубликован: 19.03.2004 | Уровень: специалист | Доступ: платный
Лекция 6:

Свойства атомов и категории функций

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >

Гибкий интерпретатор

В качестве примера повышения гибкости определений приведено упрощенное определение Лисп-интерпретатора на Лиспе, полученное из М-выражения, приведенного Дж. Маккарти в описании Lisp 1.5 [ 1 ] .

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

"(ASSOC e al )".

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

Функция SUBR — вызывает примитивы, реализованные другими, обычно низкоуровневыми, средствами. ERROR — выдает сообщения об ошибках и сведения о контексте вычислений, способствующие поиску источника ошибки. Уточнена работа с функциональными аргументами:

(DEFUN EVAL (e al )
   (COND 
 
   ((EQ e NIL ) NIL ) 
   ((ATOM e )((LAMBDA (v )
         (COND (v (CDR v ) )
            (T (ERROR 'undefvalue )) )
      ) (ASSOC e al ) )
   )
   ((EQ (CAR e) 'QUOTE ) (CAR (CDR e )) )
   ((EQ (CAR e) 'FUNCTION )
      (LIST 'FUNARG (CADR fn ) al ) )
   ((EQ (CAR e) 'COND ) (EVCON (CDR e ) al ) ) 
   (T (apply (CAR e)(evlis (CDR e) al ) al ) )
) ) 
 
(DEFUN APPLY (fn args al )
   (COND
      ((EQ e NIL ) NIL ) 
      ((ATOM fn )
         (COND 
            ((MEMBER fn '(CAR CDR CONS ATOM EQ ))
               (SUBR fn agrs al ))
            (T (APPLY (EVAL fn al ) args al ))
) )

        ((EQ (CAR fn ) 'LABEL )
   (APPLY (CADDR fn )
         args
         (CONS (CONS (CADR fn )(CADDR fn )) 
            al ) ) )
 
((EQ (CAR fn ) 'FUNARG )
      (APPLY (CDR fn ) args (CADDR fn)) )

((EQ (CAR fn ) 'LAMBDA )
      (EVAL (CADDR fn )
         (APPEND (PAIR (CADR fn ) args ) al ))
(T (APPLY (EVAL fn al ) args al ))
) )

Определения ASSOC, APPEND, PAIR, LIST — стандартны.

Примерно то же самое обеспечивают EVAL-P и APPLY-P, рассчитанные на использование списков свойств атома для хранения постоянных значений и функциональных определений. Индикатор CATEGORY указывает в списке свойств атома на правило интерпретации функций, относящихся к отдельной категории, MACRO — на частный метод построения представления функции. Функция VALUE реализует методы поиска текущего значения переменной в зависимости от контекста и свойств атомов.

(DEFUN EVAL-P (E C)
(COND ((ATOM E) (VALUE E C))
   ((ATOM (CAR E))(COND ((GET (CAR E) 'CATEGORY)
         ((GET (CAR E) 'CATEGORY) (CDR E) C) )
         (T (APPLY-P (CAR E)(EVLIS (CDR E) C) C))
   ) )
   (T (APPLY-P (CAR E)(EVLIS (CDR E) C) C))
))
 
 
(DEFUN APPLY-P (F ARGS C)
(COND ((ATOM F)(APPLY-P (FUNCTION F C) ARGS C))
   ((ATOM (CAR F))(COND ((GET (CAR F) 'MACRO)
         (APPLY-P ((GET (CAR F) 'MACRO)
            (CDR F) C) ARGS C))
         (T (APPLY-P (EVAL F E) ARGS C))
   ) )
   (T (APPLY-P (EVAL F E) ARGS C))
))

Или то же самое с вынесением общих подвыражений во вспомогательные параметры:

(DEFUN EVAL-P (E C)
   (COND ((ATOM E) (VALUE E C))
      ((ATOM (CAR E))
         ((LAMBDA (V) (COND (V (V(CDR E) C) )
            (T (APPLY-P (CAR E)(EVLIS (CDR E) C) C))
         )) (GET (CAR E) 'CATEGORY) ) )
      (T (APPLY-P (CAR E)(EVLIS (CDR E) C) C))
))

 
(DEFUN APPLY-P (F ARGS C)
   (COND ((ATOM F)(APPLY-P (FUNCTION F C) ARGS C))
      ((ATOM (CAR F))
         ((LAMBDA (V) (COND (V (APPLY-P (V (CDR F)
            C) ARGS C))
               (T (APPLY-P (EVAL F E) ARGS C))
         ))(GET (CAR F) 'MACRO) ))
      (T (APPLY-P (EVAL F E) ARGS C))
))

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

Полученная схема интерпретации допускает разнообразные категории функций и макросредства конструирования функций, позволяет задавать различные механизмы передачи параметров функциям. Так, в языке Clisp различают, кроме обычных, обязательных и позиционных, — необязательные (факультативные), ключевые и серийные(многократные, с переменным числом значений) параметры . Виды параметров обозначаются пометкой &OPTIONAL, &KEY и &REST соответственно, размещаемой перед параметрами в LAMBDA списке формальных аргументов. При этом серийный параметр должен быть последним в списке.

(DEFUN FUNCALL (FN &REST AGRS) (APPLY FN ARGS))

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

(DEFUN EX-OPT (space &OPTIONAL dot (line 'x))
   (LIST space 'of dot 'and- line))
(EX-OPT 'picture)
(EX-OPT 'picture 'circle)
(EX-OPT 'picture 'circle 'bars)
6.2.

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

(DEFUN KEYLIST (A &KEY X Y Z) (LIST A X Y Z))

(KEYLIST 1 :Y 2) ;= (1 NIL 2 NIL)

(DEFUN LENGTH (L &OPTIONAL (V 0))
   (COND ((NULL L) V)
            (T (+ 1 (LENGTH (CDR L)))) 
)  )
 
((LENGTH '(1 2) 3)      ; = 5
 
(DEFUN REVERSE (L &OPTIONAL (M NIL))
   (COND ((NULL L) M)
            (T (REVERSE (CDR L) (CONS (CAR L) M) )) 
)  )
 
(REVERSE '(1 2 3))            ; = (3 2 1)
(REVERSE '(1 2 3) '(5 6))   ;= (3 2 1 5 6)

Такой подход к работе параметрами часто освобождает от необходимости во вспомогательных функциях, что упрощает и определение EVAL от обязательности упоминания а-списка. Если воспользоваться сводимостью ( COND ) к NIL при отсутствии истиного предиката и кое-где использовать отображения, то определение становится совсем компактным.

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >
Дарья Федотова
Дарья Федотова
Сергей Березовский
Сергей Березовский

В рамках проф. переподготовки по программе "Программирование"

Есть курсы, которые я уже прошел. Но войдя в курс я вижу, что они не зачтены (Язык Ассемблера и архитектура ЭВМ, Программирование на С++ для профессионалов). Это как?

Алина Ленкова
Алина Ленкова
Россия, Ставрополь, СФ МГУПИ, 2014
Валерий Ромашов
Валерий Ромашов
Россия