Это очень сложно без фактической реализации приведения языка к более примитивной форме. В качестве примера представим следующее:
(count-ifs '(let ((if +))
(if 1 2 3)))
; ==> 0
0
- правильное значение, поскольку if
- это теневое связывание if
, а схема поддерживает теневое копирование, поэтому результатом этого выражения является 6
, а не 2
. let
можно переписать так, чтобы вы могли проверить это вместо:
(count-ifs '((lambda (if)
(if 1 2 3))
+))
; ==> 0
Возможно, это не похоже на улучшение, но здесь вы можете исправить это:
(define (count-ifs expr)
(let helper ((expr expr) (count 0))
(if (or (not (list? expr))
(and (eq? (car expr) 'lambda)
(memq 'if (cadr expr))))
count
(foldl helper
(if (eq? (car expr) 'if)
(add1 count)
count)
expr))))
(count-ifs '((lambda (if)
(if 1 2 3))
(if #t + (if if if))))
; ==> 2
Задача состоит в том, чтобы расширить макросы. На самом деле вам нужно сделать макроэкспандер, чтобы переписать код так, чтобы единственными привязками, создающими форму, был lambda
. Это тот же объем работы, что и создание 80% компилятора Scheme, поскольку, как только вы его отключите, все остальное легко.