Функция длины в «Опытном махинаторе»

Я читал «Опытного интригана» и наткнулся на это определение функции length

(define length
  (let ((h (lambda (l) 0)))
    (set! h (L (lambda (arg) (h arg))))
    h))

Позже они говорят:

Каково значение (L (лямбда (арг) (ч арг)))? Это функция

(lambda (l)
  (cond ((null? l) 0)
     (else (add1 ((lambda (arg) (h arg)) (cdr l))))))

Я не думаю, что понимаю это полностью. Я предполагаю, что мы должны определитьLсамих себя как упражнение. Я написал определение Lв определении length, используя letrec. Вот что я написал:

(define length
  (let ((h (lambda (l) 0)))
    (letrec ((L
              (lambda (f)
                (letrec ((LR
                          (lambda (l)
                            (cond ((null? l) 0)
                                  (else
                                   (+ 1 (LR (cdr l))))))))
                  LR))))                  
    (set! h (L (lambda (arg) (h arg))))
    h)))

Итак, Lпринимает функцию в качестве аргумента и возвращает в качестве значения другую функцию, которая принимает список в качестве аргумента и выполняет рекурсию по списку. Я прав или безнадежно ошибаюсь в своей интерпретации? В любом случае определение работает

 (length (list 1 2 3 4))  => 4
5
задан Óscar López 13 November 2013 в 15:22
поделиться