2016-09-18 10 views
1

Я новичок в функциональном программировании. Я читаю SICP книга. Я путаюсь с условиями использования для процедуры & данных.Разница между процедурой и данными в функциональном программировании?

В чем разница между процедурой & данных? Действительно ли они такие же?

Любая помощь будет оценена по достоинству. Благодарю.

ответ

2

Составная процедура - это процедура, состоящая из одной или нескольких других процедур. Это простое, простое определение, но оно становится немного сложнее, когда мы пытаемся применить те же рассуждения к данным.

Я считаю, что пример Гарольд Абельсон дает в лекции что-то вдоль линий:

Это перефразируя из памяти - Гарольд Абельсон, я надеюсь, что я сделал вам справедливость здесь.

Представьте, что мы должны были сделать +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 фактически реализованы, но мы выполнили контракт, и мы могли бы начать строить всякие действительно классные вещи с этим. Мы создали структуру данных из ничего, кроме лямбда - вытащили из воздуха!

+0

Awesome! Вы объяснили очень хорошо. Это очень пугает меня, но у меня мало путаницы. Я получу его больше, поскольку я продвигаюсь вперед в SICP. Благодарю. @naomik –