Почему мы используем преобразование последовательности в выражение в интерпретаторах Lisp? - PullRequest
2 голосов
/ 09 мая 2020

Я читаю SICP, который использует диалект схемы lisp. У меня вопрос: почему существует необходимость в функции преобразования последовательности в выражение, как определено ниже, которая используется в условных определениях, но не используется в выражениях if?

(define (sequence->exp seq)
    (cond ((null? seq) seq)
          ((last-exp? seq) (first-exp seq))
          (else (make-begin seq))))

(define (make-begin seq) (cons 'begin seq))

Ниже приводится определение выражения if, которое не требует преобразования последовательности в выражение:

(define (if? exp) (tagged-list? exp 'if))
(define (if-predicate exp) (cadr exp))
(define (if-consequent exp) (caddr exp))
(define (if-alternative exp)
    (if (not (null? (cdddr exp)))
        (cadddr exp)
        'false))

(define (eval-if exp env)
  (if (true? (eval (if-predicate exp) env))
      (eval (if-consequent exp) env)
      (eval (if-alternative exp) env)))

Ниже приводится определение условного выражения, предикат которого требует преобразования последовательности в выражение.

(define (cond? exp) (tagged-list? exp 'cond))

(define (cond-clauses exp) (cdr exp))

(define (cond-else-clause? clause)
    (eq? (cond-predicate clause) 'else))

(define (cond-predicate clause) (car clause))

(define (cond-actions clause) (cdr clause))

(define (cond->if exp) (expand-clauses (cond-clauses exp)))

(define (expand-clauses clauses)
    (if (null? clauses) 
        'false ; no else clause
    (let ((first (car clauses))
         (rest (cdr clauses)))
        (if (cond-else-clause? first)
            (if (null? rest)
                (sequence->exp (cond-actions first))
                (error "ELSE clause isn't last: COND->IF"
                clauses))
            (make-if (cond-predicate first)
                     (sequence->exp (cond-actions first))
                     (expand-clauses rest))))))

1 Ответ

2 голосов
/ 09 мая 2020

Выражение if может оценивать только одно последовательное выражение или одно альтернативное выражение. Но выражение cond оценивает последовательность выражений, связанных с условным предложением, которое истинно. Процедура sequence->exp необходима для преобразования последовательности выражений в одно выражение. Оборачивая последовательность в форму begin, создается одно выражение, которое может быть оценено как последовательное или альтернативное выражение в выражении if.

Цель sequence->exp вызовов в опубликованном коде предназначены для облегчения преобразования выражений cond в выражения if; следовательно, любая последовательность выражений, найденная в ветви cond, должна быть преобразована в одно выражение во вновь созданном выражении if.

...