LISP全球alist变量

时间:2012-10-22 03:08:44

标签: functional-programming lisp common-lisp

我是LISP的新手,这是我对其全局变量的问题。

我要做的是创建一个可以在结构中存储键值对的“alist”。这是我的示例代码:

(setq *x* '())

(acons 'apple 'fruit *x*)

*x*

(first *x*)

我希望我的输出看起来像,在我添加(apple.fruit)对之后,x应该是((apple.fruit)),但这是我得到的(在加载上述代码时) )

CL-USER> 
NIL
((APPLE . FRUIT))
NIL  <--- this is still nil?
NIL

任何人都可以帮助我,因为我不知道为什么我不能为变量x增加价值。

另外,我还有一个关于alist的问题:是否有办法通过键查找列表中的元素?
例如,对于上面的列表,如何使用密钥apple查找其对应的值fruit

谢谢

2 个答案:

答案 0 :(得分:4)

函数acons没有副作用,即它不会修改*x*

您必须setq结果才能获得acons *x*的结果:

(setq *x* (acons 'apple 'fruit *x*))

答案 1 :(得分:1)

如果你想进行功能编程,那么可变的全局变量肯定不是一种可行的方法。

功能编程主要关注通过调用带参数的函数进行计算。

解决方案通常是递归的。

比方说,我们有一份水果及其价格清单,我们想要为每个水果类别定价。让我们使用ACONS尝试递归解决方案。

(defun note-category-price (type price sums)
  (let ((pair (assoc type sums)))
    (if pair
        (progn (incf (cdr pair) price) sums)
      (acons type price sums))))

在上面的函数中,您可以看到该函数直接返回调用ACONS的结果。它没有存储。

(defun compute-price-sums (data sums)
  (if (null data)
      sums
    (compute-price-sums (rest (rest data))
                        (note-category-price (first data)
                                             (second data)
                                             sums))))

在上面的函数中,扩展数据结构将用于递归调用。

示例:

CL-USER 22 > (compute-price-sums
              '(apple 10 orange 20 banana 10 apple 20
                grape 5 orange 75 apple 30 peach 30
                orange 90 apple 20)
              nil)

((PEACH . 30) (GRAPE . 5) (BANANA . 10) (ORANGE . 185) (APPLE . 80))