是否可以将函数嵌入为 LISP 列表元素?

问题描述 投票:0回答:1

考虑创建日期库的示例。我们可能有一个列表,将月份索引映射到该月的天数:

(defparameter *daymap* '(0 31 28 31 30 31 30 31 31 30 31 30 31))

假设我们还有一个跟踪一年的全局变量:

(defvar *year* 1900)

有没有办法定义

*daymap*
列表,以便 `(nth 2 daymap) 在闰年计算为 29?

我已经尝试了以下(和类似的),但没有成功:

(defparameter *daymap* '(0 31 #'(if (= 0 (mod *year* 4)) 28 29) 31 30 31 30 31 31 30 31 30 31))

在 REPL 中输入

(nth 2 *daymap*)
计算结果为:“
#'(if (= 0 (mod *year* 4))
”而不是
28 
29

lisp clisp
1个回答
0
投票

可以将函数嵌入为列表元素:函数是一流的。然而

nth
只获取某个列表的第 n 个元素。如果该元素是一个函数,那么该值就是一个函数:它不会神奇地为您调用它。

但是你的例子很混乱。

#'x
读作
(function x)
,因此
'(1 2 #'(if ...) ...)
读作
'(1 2 (function (if ...))'
。这段数据没有任何功能,而是一个以
function
开头的列表。

如果要将函数嵌入到列表中,您需要确保匿名函数的语法正确,并且列表不能是文字数据。比如说

(defparameter *daymap*
  `(0 
    31 
    ,(lambda () (if (= 0 (mod *year* 4)) 28 29))
    31 30 31 30 31 31 30 31 30 31))

现在您可以轻松地在

nth
周围写一些垫片来执行您想要的操作:

(defun nth/call (n list)
  (let ((it (nth n list)))
    (if (functionp it)
        (funcall it)
      it)))

甚至

(defun nth/force (n list)
  ;; MUNGE
  (do ((it (nth n list)
           (if (functionp it) (funcall it) it)))
      ((not (functionp it)) it)))
© www.soinside.com 2019 - 2024. All rights reserved.