当前位置:  开发笔记 > 编程语言 > 正文

clojure:没有利弊细胞

如何解决《clojure:没有利弊细胞》经验,为你挑选了3个好方法。

我听说clojure没有大多数lisp语言的cons细胞.

这是否意味着clojure列表不以空列表结尾?

任何人都能解释这究竟意味着什么?



1> Rainer Joswi..:

Lisp为它提供了原始的cons数据结构和符号.

参见John McCarthy,符号表达式的递归函数及其机器计算,第一部分,1960年,第3章,符号表达式的递归函数.

该章介绍:

符号表达式由原子和符号表达式组成,使用点符号表示: ( a . b )

用于缩写某些符号表达式的列表表示法 (a b c)

nil用于终止列表的原子符号

原始功能car,cdr,cons,eqatom

其他几个功能:ff,subst,equal,null,cadr,caddr,null,append,among,pair,assoc,sublis,apply,eval,...

在早期的Lisp中,添加了改变cons单元的函数:( rplaca意思是替换汽车)和rplacd(意味着替换cdr).参见John McCarthy等人的LISP 1.5程序员手册.从1962年.这些函数允许我们编写破坏性函数,并允许我们创建循环的基于cons的数据结构,如循环列表.

Common Lisp

通常,Lisp方言实现了大部分.Common Lisp也不例外,它的功能在Common Lisp标准中描述:Conses.使用上述功能的示例:

; pair two lists into a list of cons cells
; the function pair is called pairlis in Common Lisp
CL-USER 17 > (pairlis '(john mary eva) `(34 29 40))
((EVA . 40) (MARY . 29) (JOHN . 34))

; find a cons cell in a list of cons cells, based on the content of the car of those cons cells
CL-USER 18 > (assoc 'eva
                    (pairlis '(john mary eva)
                             `(34 29 40)))
(EVA . 40)

; create a tree out of cons cells and atoms
CL-USER 19 > (cons (cons 10 20) (cons 30 40))
((10 . 20) 30 . 40)

; a cons cell is not an atom
CL-USER 20 > (atom (cons 1 2))
NIL

; a cons cell is not nil
CL-USER 21 > (null (cons 1 2))
NIL

; substitute an item with a new one in a tree
CL-USER 22 > (subst 30                          ; new
                    'bar                        ; old
                    '((10 . 20) . (bar . 40)))  ; tree
((10 . 20) 30 . 40)   ; also written as  ((10 . 20) . (30 . 40))

; substitute several items in a tree, using an assoc list
; to describe the substitutions
CL-USER 23 > (sublis '((a . 10) (d . 40))      ; substitutions
                     '((a . b) . (c . d)))     ; tree
((10 . B) C . 40)

列表是符号表达式的特例.它们通常没有点写:

CL-USER 24 > '(a . (b . nil))
(A B)

Common Lisp还支持变异操作rplacarplacdLisp 1.5:

CL-USER 25 > (let ((c (cons 0 1)))              ; create a cons
               (print c)                        ; print it
               (print (rplaca c 'foo))          ; replace the car
               (print (rplacd c 'bar))          ; replace the cdr
               (print (eq c (rplaca c 'baz)))   ; identical ?
               (values))
(0 . 1)      ; the cons cell
(FOO . 1)    ; car replaced
(FOO . BAR)  ; cdr replaced
T            ; still the same object

Emacs Lisp

Emacs Lisp还实现了上述功能:

ELISP> (sublis '((a . 10) (d . 40))                                             
               '((a . b) . (c . d)))
((10 . b) c . 40)

Clojure的

Clojure不支持John McCarthy所描述的这些符号表达.它没有缺陷单元,没有点符号,也没有提供上述接口.例如,原子 意味着Clojure中完全不同的东西.cons没有创建一个利弊细胞.列表不是由cons细胞组成的.

在Clojure中,一个点只是另一个符号:

user=> (count '(1 . 2))
3

有一个原始函数来构造列表:

user=> (list 1 2 3)
(1 2 3)

结果应该是一个列表:

user=> (list? (list 1 2 3))
true

有一个函数叫cons:

user=> (cons 0 (list 1 2 3))
(0 1 2 3)

不知何故,这不是一个列表:

user=> (list? (cons 0 (list 1 2 3)))
false

基本上Clojure使用不同的数据结构( - > 序列,逻辑列表)和自己的命名和语义.即使名称与Lisp名称相似,也不要指望它们做同样的事情.

方案

编程语言Scheme还提供与上述类似的cons单元.它缺少一些功能,但可以很容易地实现.例如,sublis可以在Scheme中实现(参见initdr.scm):

(define (sublis alist tree)
  (if (pair? tree)
      (cons (sublis alist (car tree))
            (sublis alist (cdr tree)))
      (if (assv tree alist)
          (cdr (assv tree alist))
          tree)))



2> Thumbnail..:

Clojure确实有一个缺点:clojure.lang.Cons.

它用于cons调用的结果

......别无其他:既不是列表,也不是矢量,也不是任何类型的懒惰序列.

它也不能用于一般的物体对:尾部/ rest/ cdr 是一个序列,而不是一个序列Object.

如果你cons在列表,矢量或懒惰序列上的东西,你会得到一个Cons.

但是,正如其他答案所说的那样,没有任何函数可以处理Cons.它们都是按顺序处理的.

另一个用途:conj进入一个不确定的序列(矢量列表,既不设置也不映射......)产生一个Cons.



3> jmargolisvt..:

根据clojure.org的这个页面:

缺点,首先休息操纵序列抽象,而不是具体的利弊细胞

Clojure列表不以空列表结尾,它们不是传统的cons单元格.它们是实现排序的数据结构. 这个关于抽象编程的页面解释了Clojure对"seqable"结构的方法,包括列表:

通常,对抽象的编程可以让您在不同的数据结构上使用函数库,而不管这些数据结构的实现方式.

所以Clojure的列表是像他们实现利弊细胞cons,first以及 rest但这仅仅意味着它们共享一个通用的接口.它们的底层实现有所不同,但它们都是"可选的".

推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有