Functional programming 函数式编程中程序和数据的区别?
我是函数式编程的新手。我在看书。我对用于过程和数据的术语感到困惑 程序和数据之间有什么区别?它们真的一样吗Functional programming 函数式编程中程序和数据的区别?,functional-programming,procedure,sicp,Functional Programming,Procedure,Sicp,我是函数式编程的新手。我在看书。我对用于过程和数据的术语感到困惑 程序和数据之间有什么区别?它们真的一样吗 任何帮助都将不胜感激。谢谢 复合程序是由一个或多个其他程序组成的程序。这是一个简单、直截了当的定义,但当我们试图将同样的推理应用于数据时,它会变得有点棘手 我相信哈罗德·阿贝尔森在讲座中给出的例子大致如下: 这是记忆中的释义——哈罗德·阿贝尔森,我希望我在这里公正地对待了你 想象一下,我们要做一个+rat程序,需要4个数字:numer1、numer2、denom1和denom2。调用它可能
任何帮助都将不胜感激。谢谢 复合程序是由一个或多个其他程序组成的程序。这是一个简单、直截了当的定义,但当我们试图将同样的推理应用于数据时,它会变得有点棘手 我相信哈罗德·阿贝尔森在讲座中给出的例子大致如下: 这是记忆中的释义——哈罗德·阿贝尔森,我希望我在这里公正地对待了你 想象一下,我们要做一个+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)
这真的很快就变得一团糟了。如果我们可以像对待简单的数字数据那样对待有理数数据呢?如果我们不必总是考虑单个组件的编号和名称呢?如果我们可以把有理数当作复合数据来处理呢
现在我们可以更好地表达我们的计算。将其与整数相加进行比较
(+ 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。它改变了我的生活
额外的苏打水
这种将数据作为代码的想法对我来说非常有趣。当我学习其他语言时,我从未质疑过对象和数组之类的东西。但当我研究SICP时,从不同的角度思考数据,我问了cons、car和cdr——它们到底是什么
最终,它们如何实现并不重要。如果我们只关心这三个程序,我们必须考虑他们履行的合同
- - - - Contract - - - -
For any x and y
(car (cons x y)) is x
(cdr (cons x y)) is y
- - - - - - - - - - - - -
直到我学习,我才看到我见过的最美丽的东西之一。我会在这里向你们展示计划
(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的实际实现方式,但我们已经履行了合同,我们可以开始用它来构建各种真正酷的东西。我们已经用lambdas做了一个数据结构——无中生有 复合程序是由一个或多个其他程序组成的程序。这是一个简单、直截了当的定义,但当我们试图将同样的推理应用于数据时,它会变得有点棘手 我相信哈罗德·阿贝尔森在讲座中给出的例子大致如下: 这是记忆中的释义——哈罗德·阿贝尔森,我希望我在这里公正地对待了你 想象一下,我们要做一个+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)
这真的很快就变得一团糟了。如果我们可以像对待简单的数字数据那样对待有理数数据呢?如果我们不必总是考虑单个组件的编号和名称呢?如果我们可以把有理数当作复合数据来处理呢
现在我们可以更好地表达我们的计算。将其与整数相加进行比较
(+ 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选择器。写t
这种方法意味着我们可以传递复合数据,而不是简单的、独立的数据,并在必要时在我们的过程中将其分离
从记忆中释义;资料来源:
不管怎样,你问这个问题是对的。复合过程和复合数据具有相似的语法这一事实意味着我们已经有效地模糊了代码和数据之间的界限
思维爆炸:代码就是数据;数据就是代码
继续阅读SICP。它改变了我的生活
额外的苏打水
这种将数据作为代码的想法对我来说非常有趣。当我学习其他语言时,我从未质疑过对象和数组之类的东西。但当我研究SICP时,从不同的角度思考数据,我问了cons、car和cdr——它们到底是什么
最终,它们如何实现并不重要。如果我们只关心这三个程序,我们必须考虑他们履行的合同
- - - - Contract - - - -
For any x and y
(car (cons x y)) is x
(cdr (cons x y)) is y
- - - - - - - - - - - - -
直到我学习,我才看到我见过的最美丽的东西之一。我会在这里向你们展示计划
(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的实际实现方式,但我们已经履行了合同,我们可以开始用它来构建各种真正酷的东西。我们已经用lambdas做了一个数据结构——无中生有 太棒了!你解释得很好。这很清楚我的困惑,但仍然有一点困惑。随着我在SICP的发展,我会得到更多。谢谢@Naomike在上一个car/cdr示例中使用闭包吗?太棒了!你解释得很好。这很清楚我的困惑,但仍然有一点困惑。随着我在SICP的发展,我会得到更多。谢谢@在上一个car/cdr示例中,它是否使用闭包?