比如, deleteremove 的一个具有破坏性的版本。虽然它可以破坏作为参数传给它的列表,但它并不保证什么。在大多数的 Common Lisp 的实现中,会出现下面的情况:

    正如 remove 一样,如果你想要副作用,应该对返回值使用 setf

    1. (setf lst (delete 'a lst))

    破坏性函数是怎样回收利用传给它们的列表的呢?比如,可以考虑 nconc —— append 的破坏性版本。[2]下面是两个参数版本的实现,其清楚地展示了两个已知列表是怎样被缝在一起的:

    函数 类似 mapcar ,但它是用 nconc 把函数的返回值 (必须是列表) 拼接在一起的:

    1. > (mapcan #'list
    2. '(a b c)
    3. ( A 1 B 2 C 3)

    这个函数可以定义如下:

    使用 mapcan 时要谨慎,因为它具有破坏性。它用 nconc 拼接返回的列表,所以这些列表最好不要再在其它地方使用。

    1. (mapcan #'(lambda (c)
    2. (children x)))

    这个函数调用 copy-list 时存在一个假设 —— chlidren 函数返回的是一个已经保存在某个地方的列表,而不是构建了一个新的列表。

    一个 mapcan 的无损变体可以这样定义:

    如果使用 mappend 函数,那么 grandchildren 的定义就可以省去 copy-list

    1. (mappend #'children (children x)))