Skip to content

Commit

Permalink
refactor till 2.14
Browse files Browse the repository at this point in the history
  • Loading branch information
JuanitoFatas committed Dec 2, 2012
1 parent 75098ee commit b06c1b9
Showing 1 changed file with 38 additions and 38 deletions.
76 changes: 38 additions & 38 deletions zhCN/ch2-cn.rst
Original file line number Diff line number Diff line change
Expand Up @@ -682,46 +682,46 @@ Lisp 不对程序、过程以及函数作区别。函数做了所有的事情(

也就是说,如果这个列表是空表,它的长度是 ``0`` ;否则它的长度就是 ``cdr`` 列表的长度加一。递归版本的 ``our-length`` 比较易懂,但因为它不是尾递归 (tail-recursive)的形式 (見 13.2 节),效率不是那么高。

2.14 作为对象的函数 (Functions as Objects)
2.14 函数作为对象 (Functions as Objects)
==========================================

函数在 Lisp 中就像符号、字串或列表那样稀松平常的对象。如果我们把一个函数的名字传给 ``function`` ,它会返回相关联的对象。 ``quote`` 一样, ``function`` 是一个特殊操作符,所以我们不需引用 (quote)它的参数
函数在 Lisp 中,如同符号、字串或列表那样是稀松平常的对象。如果我们把函数的名字传给 ``function`` ,它会返回相关联的对象。 ``quote`` 相同, ``function`` 是一个特殊操作符,所以我们不需引用 (quote)它的實參

::

> (function +)
#<Compiled-Function + 17BA4E>

这看起来很奇怪的返回值是在典型的 Common Lisp 实现中,可能的显示方法
这看起来很奇怪的返回值是在典型的 Common Lisp 实现中,函数可能的显示方法

到目前为止,我们仅讨论过 Lisp 显示它们与我们输入它们,看起来是一样的对象。这个惯例对函数不适用。一个内建函数像是 ``+`` ,在内部可能是一段机器语言代码 (machine language code)。一个 Common Lisp 实现可能选择任何它所喜欢的外部表示法 (external representation)
到目前为止,我们仅讨论过 Lisp 显示它们与我们输入它们,看起来都是一样的对象。这个惯例对函数不适用。一个内建函数像是 ``+`` ,在内部可能是一段机器语言代码machine language code。一个 Common Lisp 实现,可能选择任何它所喜欢的外部表示法(external representation

就如同我们可以用 ``'`` 作为 ``quote`` 的缩写,我们可以用 ``#'`` 作为 ``function`` 的缩写:
如同我们可以用 ``'`` 作为 ``quote`` 的缩写,可以用 ``#'`` 作为 ``function`` 的缩写:

::

> #'+
#<Compiled-Function + 17BA4E>
> #'+
#<Compiled-Function + 17BA4E>

这个缩写称之为升引号 (sharp-quote)
这个缩写称之为升引号sharp-quote

和别种对象一样,我们可以把函数当作参数传入。一个接受函数作为参数的函数是 ``apply`` 。它接受一个函数和一个参数列表,并返回把传入函数应用在传入参数的结果
与别种对象相同,我们可以把函数当作实参传入。一个接受函数作为实参的函数是 ``apply`` 。它接受函数和实参列表,并返回把传入函数应用在后面实参的结果

::

> (apply #'+ '(1 2 3))
6
> (+ 1 2 3)
6
> (apply #'+ '(1 2 3))
6
> (+ 1 2 3)
6

它可以接受任意数目的参数,只要最后一个参数是列表
它可以接受任意数量的实参,只要最后一个实参是列表即可

::

> (apply #'+ 1 2 '(3 4 5))
15
> (apply #'+ 1 2 '(3 4 5))
15

函数 ``funcall`` 做一样的事情但参数不需要包装成列表
函数 ``funcall`` 做一样的事情,但实参不需要包装成列表

::

Expand All @@ -730,14 +730,14 @@ Lisp 不对程序、过程以及函数作区别。函数做了所有的事情(

.. note::

什么是 lambda?
什么是 `lambda` ?

lambda 表达式中的 lambda 不是一个操作符。它只是个符号
在早期的 Lisp 方言里有一个目的:函数在内部用列表来表示
因此辨别列表与函数的方法,是检查第一个元素是否为符号 lambda 。
``lambda`` 表达式中的 ``lambda`` 不是一个操作符。只是一个符号
在早期的 Lisp 方言里, ``lambda`` 有一个目的:由于函数在内部是用列表来表示
因此辨别列表与函数的方法,是检查第一个元素是否为符号 ``lambda``

在 Common Lisp ,你可以用列表来表达函数,
但在内部被表示成独特的函数对象。因此不再需要 lambda
在 Common Lisp ,你可以用列表来表达函数,
函数在内部会被表示成独特的函数对象。因此不再需要 `lambda` 了
如果需要把函数记为

.. code-block:: cl
Expand All @@ -752,37 +752,37 @@ Lisp 不对程序、过程以及函数作区别。函数做了所有的事情(
也是可以的。

但 Lisp 程序员习惯用符号 lambda ,来开始写函数
因此 Common Lisp 为了这个传统而保留了 lambda 。
但 Lisp 程序员习惯用符号 ``lambda`` ,来撰写函数
因此 Common Lisp 为了传统,而保留了 ``lambda``

这个 ``defun`` 宏创造一个函数并替它命名。但函数不需要有名字,而且我们不需要 ``defun`` 来定义他们。像大多数的 Lisp 对象一样,我们可以直接引用函数。
``defun`` 宏,创建一个函数并给函数命名。但函数不需要有名字,而且我们不需要 ``defun`` 来定义他们。和大多数的 Lisp 对象一样,我们可以直接引用函数。

要直接引用一个整数,我们使用一系列的数字;要直接引用一个函数,我们使用所谓的 *lambda 表达式* 。一个 lambda 表达式是一个列表,包含符号 lambda ,伴随着参数列表,与一个由零个或多个表达式所组成的主体
要直接引用整数,我们使用一系列的数字;要直接引用一个函数,我们使用所谓的\ *lambda 表达式*\ 。一个 ``lambda`` 表达式是一个列表,列表包含符号 ``lambda`` ,接著是实参列表,以及由零个或多个表达式所组成的函数主体

下面的 lambda 表达式代表一个接受两个数字,并返回它们的和的函数
下面的 ``lambda`` 表达式,代表一个接受两个数字并返回两者之和的函数

::

(lambda (x y)
(+ x y))
(lambda (x y)
(+ x y))

列表 ``(x y)`` 是参数列表,跟在它后面的是函数主体。
列表 ``(x y)`` 是实参列表,跟在它后面的是函数主体。

一个 lambda 表达式可以被当成是函数的名字。就像普通的函数名称, lambda 表达式可以是函数调用的第一个元素,
一个 ``lambda`` 表达式可以作为函数名。就像普通的函数名称, lambda 表达式可以是函数调用的第一个元素,

::

> ((lambda (x) (+ x 100)) 1)
101
> ((lambda (x) (+ x 100)) 1)
101

而通过在 lambda 表达式前面贴上 ``#'`` ,我们得到对应的函数,
而通过在 ``lambda`` 表达式前面贴上 ``#'`` ,我们得到对应的函数,

::

> (funcall #'(lambda (x) (+ x 100))
1)
> (funcall #'(lambda (x) (+ x 100))
1)

lambda 表示法除前述用途外,还允许我们使用匿名函数。
``lambda`` 表示法除前述用途以外,还允许我们使用匿名函数。

2.15 类型 (Types)
=========================
Expand Down

0 comments on commit b06c1b9

Please sign in to comment.