Разница между процедурой и данными в функциональном программировании?
Я новичок в функциональном программировании. Я читаю книгу SICP. Я запутался с условиями, используемыми для процедуры и данных.
В чем разница между процедурой и данными? Они действительно одинаковые?
Любая помощь будет оценена. Благодарю.
1 ответ
Сложная процедура - это процедура, которая состоит из одной или нескольких других процедур. Это простое и понятное определение, но оно становится немного сложнее, когда мы пытаемся применить те же аргументы к данным.
Я полагаю, что пример, который Гарольд Абельсон дает в лекции, является чем-то вроде:
Это перефразирует из памяти - Гарольд Абельсон, я надеюсь, что я сделал тебе здесь справедливость.
Представьте, что мы должны были сделать
+rat
процедура, которая заняла 4 числа: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 Лекция 2B: Составные данные
В любом случае, вы правы, задавая вопрос. Тот факт, что составные процедуры и составные данные имеют похожий синтаксис, означает, что мы эффективно размыли границы между кодом и данными.
Взрыв разума: код - это данные; данные это код.
Продолжайте читать SICP. Это изменило мою жизнь.
Бонус Сода!
Эта идея данных как кода очень интересна для меня. Я никогда не сомневался в таких вещах, как объекты и массивы, когда изучал другие языки. Но когда я изучал SICP, думая о данных иначе, я задал вопрос cons
, car
, а также cdr
- что они конкретно?
В конечном счете, как они реализованы, не имеет значения. Если мы просто обеспокоены этими 3 процедурами, мы должны подумать о контракте, который они выполняют...
- - - - Contract - - - -
For any x and y
(car (cons x y)) is x
(cdr (cons x y)) is y
- - - - - - - - - - - - -
Только когда я изучил Lambda Calculus, я увидел одну из самых красивых вещей, которые я когда-либо видел. Я покажу вам здесь, на схеме...
(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
фактически реализованы, но мы выполнили контракт, и мы могли бы начать с этого создавать действительно классные вещи. Мы сделали структуру данных из ничего, кроме лямбд - извлеченных из воздуха!