码迷,mamicode.com
首页 > 编程语言 > 详细

程序设计语言中的语法糖

时间:2015-01-18 22:42:40      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:

语法糖是什么呢?按我现在的理解,如果一门语言没有某个语法,照样可以通过其它更通用的方式来表达某种语义。这种语法的引入,只不过是 让表达语义更方便了。那么这个语法,就叫语法糖。

Scheme 中有两个关键字 lambda, let ,我目前的理解是,他们就是语法糖。

lambda

lambda 用来定义一个匿名函数。有时候,一个函数我们只在一个地方用一次,完全没必要给它定义一个名字,这时候,我们就用 lambda 定义 一个匿名函数。

如果没有 lambda ,那么我们定义函数时,会使用下面这种方式:

(define (pi-sum a b)
  (define (pi-term x)
    (/ 1.0 (* x (+ x 2))))
  (define (pi-next x)
    (+ x 4))
  (sum pi-term a pi-next b))

其中像 pi-term 和 pi-next 这样的小函数,完全可以通过 lambda 定义一个匿名函数。

(define (pi-sum a b)
  (sum 
    (lambda (x) (/ 1.0 (* x (+ x 2))))
    a 
    (lambda (x) (+ x 4)) 
    b))

let

let 用来定义局部变量,其实没有局部变量,我们也可以表达相应的语义,只不过有了 let ,定义起来更方便了。由于之前没有函数式语言 编程的经验,完全不知道没有局部变量要怎么办,所以还是看一个例子。

计算

f(x,y) = x(1+xy)^2 + y(1-y) + (1+xy)(1-y)

我们可以通过

a = 1 + xy
b = 1 - y
f(x, y) = xa^2 + yb + ab

来定义这个函数,这里面的 a, b 就相当于局部变量,那么在没有局部变量语法的情况下,我们怎么定义这个函数呢?

办法就是定义一个内部函数,将形式参数设定为 a, b,然后将 1 + xy 和 1-y 作为实际参数传递进去:

(define (f x y)
  (define (f-helper a b)
    (+ (* x (square a))
       (* y b)
       (* a b)))
  (f-helper (+ 1 (* x y))
            (- 1 y)))

而如果引入 let 这个语法糖后,定义起来就变得直观,容易多了:

(define (f x y)
  (let ((a (+ 1 (* x y)))
        (b (- 1 y)))
    (+ (* x (square a))
       (* y b)
       (* a b))))

从这里可以看出,let 作用域内分两部分,一部分定义局部变量,另一部分是函数体。

通过对 SICP 这部分的学习,我明白了,什么是本质上的东西,什么是语法糖。本质上的东西是对函数及求值方式的定义,他们形式简单,功能强大, 大部分语义都可以通过这些定义出来。只是为了方便,我们引入了语法糖,来更容易地表达语义。

关于 lambda 这个词的来源,书中也有介绍,这是历史原因,源于 Alonzo Church 的 lambda 演算。lambda 演算为研究函数定义, 函数应用提供了坚实的数学基础。我还隐约记得在程序设计语言课上,老师教我们用 lambda 演算定义自然数,加法等运算法则,true/false, if/else 等等。你可以看出,这些本质的东西,可以表达非常非常多的东西,功能异常强大。

注:这是我学习 SICP 后的总结与思考,例子也都来自于此书。

程序设计语言中的语法糖

标签:

原文地址:http://blog.csdn.net/on_1y/article/details/42846275

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!