Составная процедура - это процедура, состоящая из одной или нескольких других процедур. Это простое, простое определение, но оно становится немного сложнее, когда мы пытаемся применить те же рассуждения к данным.
Я считаю, что пример Гарольд Абельсон дает в лекции что-то вдоль линий:
Это перефразируя из памяти - Гарольд Абельсон, я надеюсь, что я сделал вам справедливость здесь.
Представьте, что мы должны были сделать +rat
процедуру, которая приняла номера: numer1
, numer2
, denom1
и denom2
. Вызов может выглядеть следующим образом:
;; naively add two rational numbers
(+rat numer1 denom1 numer2 denom2)
Теперь представьте себе, если мы хотим расширить это далее поддерживать умножение, вы по-прежнему необходимо ввести несколько переменных для каждого рационального числа
;; add then multiply
(define rat1 (+rat numer1 denom1 numer2 denom2))
(*rat (numer rat1) (denom rat2) numer3 denom3)
Это становится действительно беспорядочно очень быстро. Что делать, если мы можем обрабатывать наши данные о рациональном числе, например, мы делаем простые данные о числе? Что делать, если нам не обязательно всегда учитывать отдельные компоненты (numer
и denom
)? Что делать, если бы мы имели дело с нашими рациональными числами как составные данные?
;; add two rational numbers
(define m (make-rat 3 4))
(define n (make-rat 5 6))
(+rat m n)
;; add then multiply
(define o (make-rat 1 2))
(*rat (+rat m n) o)
Теперь мы можем выразить наши вычисления намного лучше. Сравните это с добавлением целых чисел
(+ 1 2)
(* (+ 1 2) 3)
Мы можем легко рассуждать об этих выражениях. Нам не нужно беспокоиться об отдельных компонентах (numer
и denom
) наших рациональных чисел, мы можем работать непосредственно с составными данными. Это поднимает невероятную нагрузку на нас, поскольку наша программа продолжает расширяться по сложности.
;; naive procedure
(define (+rat n1 d1 n2 d2)
(make-rat (+ (* n1 d2)
(* n2 d1))
(* d1 d2)))
;; compound data procedure
(define (+rat x y)
(make-rat (+ (* (numer x) (denom y))
(* (numer y) (denom x)))
(* (denom x) (denom y))))
В не наивной реализации, процедура ожидает x
и y
быть значения, которые были построены с make-rat
- или, по крайней мере, они должны иметь действительные numer
и denom
селекторы. Написание процедуры таким образом означает, что мы можем передавать составные данные вокруг - вместо простых, отдельных частей - и выделять их отдельно в наших процедурах по мере необходимости.
перефразируя из памяти; Источник: SICP Lecture 2B: Compound Data
Во всяком случае, вы правы, задавать вопрос. Сам факт, что составные процедуры и составные данные имеют похожий синтаксис, означает, что мы эффективно размыли линии между кодом и данными.
Взрыв разума: код - данные; данные - это код.
Продолжайте читать SICP. Это изменило мою жизнь.
Bonus Soda!
Эта идея данных как код мне очень интересна. Когда я изучал другие языки, я никогда не ставил под сомнение такие вещи, как «Объекты» и «Массивы». Но когда я изучил SICP, думая о данных по-разному, я задавал вопросы cons
, car
и cdr
- что они точно?
В конечном счете, как они реализованы неважно. Если нас просто беспокоят эти три процедуры, мы должны подумать о контракте, который они выполняют, и hellip;
- - - - Contract - - - -
For any x and y
(car (cons x y)) is x
(cdr (cons x y)) is y
- - - - - - - - - - - - -
Это не было, пока я не изучал Lambda Calculus что я видел один из самых красивых вещей, которые я когда-либо видел. Я покажу вам здесь, в Scheme & hellip;
(define (cons x y)
(lambda (p) (p x y)))
(define (car p)
(p (lambda (x y) x)))
(define (cdr p)
(p (lambda (x y) y)))
(println (car (cons 'x 'y))) ;; => 'x
(println (cdr (cons 'x 'y))) ;; => 'y
Что! Где «пара»? Где находится «список»? Где контейнер для данных? Где хранятся данные? Это прямо в коде.
код - данные; данные - это код.
Конечно, это, вероятно, не так, как cons
, car
и cdr
фактически реализованы, но мы выполнили контракт, и мы могли бы начать строить всякие действительно классные вещи с этим. Мы создали структуру данных из ничего, кроме лямбда - вытащили из воздуха!
Awesome! Вы объяснили очень хорошо. Это очень пугает меня, но у меня мало путаницы. Я получу его больше, поскольку я продвигаюсь вперед в SICP. Благодарю. @naomik –