Lisp 函数中针/大海捞针的排序

Ordering of needle / haystack in Lisp functions

在学习 Lisp 时,我看到如果一个函数有两个参数,一个是单个元素或子集(needle),另一个是列表(haystack),元素或子集永远是第一位的。

示例:

(member 3 '(3 1 4 1 5))
(assoc 'jane '((jane doe)
               (john doe)))
(subsetp '(a e) '(a e i o u))

对我来说,似乎 Lisp 中有一个规则,函数应该遵循这个指导:首先是部分,然后是整个事情。

这个发现实际上是基于 Lisp 中的指南,还是偶然发现的?

memberassoc 这样的函数至少是从 1960 年开始的。

我只是希望它遵循数学符号,例如在集合论中:

e ∈ m

由于 Lisp 使用前缀表示法,predicate/function/operator 排在第一位,元素第二位,集合第三位:

(∈ e m)

约翰·麦卡锡 Ph.D。数学专业。

一般来说,在 Common Lisp 中最后一个类似集合的参数也更有用:

(defun find-symbol (name package) ...)

Common Lisp 中的实际定义是:

(defun find-symbol (name &optional (package *package*)) ...)

这允许我们使用当前包作为有用的默认包。

让我们看看。 1960 年的第一个 McCarthy LISP 有时将列表作为第一个参数。参见 page 123 in this LISP manual。例如。

;; 1960 maplist
(defun maplist (list function)
  ...)

现在这可能是因为这个函数是最早创建的高阶函数之一。事实上,它早于第一个实现,因为它出现在第一篇 Lisp 论文中。在第 125 页的同一手册中,您会发现 sassoc,它看起来非常像今天的 assoc

(defun sassoc (needle haystack default-function)
  ...)

在接下来的 version 1.5 of the language 中,这两个看起来都一样。 (maplist 见第 63 页,sassoc 见第 60 页)

从这里到Common Lisp,分岔路又汇合。出现了很多新想法,但必须有理由打破兼容性才能真正做到这一点。我能想到一个原因,那就是支持多个列表。在 Common Lisp 中 maplist 是:

(defun  maplist (function &rest lists+)
  ...)

在 CLHS 中以 "wrong" 顺序快速搜索常见参数名称给了我 fill, map-into, and sort。可能还有更多。

Peter Norvigs style guide 说要遵循惯例,但没有比这更详细的了。在阅读 Scheme SRFI 时,他们经常在建议类似标准之前提到周围的实际实现以及 Common Lisp 作为解决方案的内容。在选择如何实现事物时,我也会这样做。