Clojure函数的方案(替代)

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

我正在阅读Paul Graham的The Roots of List

我尝试过转换第5页上的函数subst,其定义如下:

(defun subst (x y z)
  (cond ((atom z)
         (cond ((eq z y) x)
               ('t z)))
        ('t (cons (subst x y (car z))
                  (subst x y (cdr z))))))

对其对应的Clojure实现。我没有使用任何一种语言的生产经验(我一直在阅读Clojure),因此,由于我正在阅读本文以了解LISP的起源,因此将不胜感激。我最接近的是这个(但这是非常错误的):

(defn subst
 [x y z]
 (if (not (nil? z)) z x)
     (if (= z y) x z)
    (cons (subst x y (first z))
          (subst (x y (rest z)))))
clojure lisp common-lisp
2个回答
0
投票

“ Traduttore,traditore”

(这可以翻译为“翻译,叛徒”,但这样做会破坏双关语,而这本身很有趣)

由于尚不清楚规范,因此很难在Clojure代码中暗示可能的修复。

即使Clojure作为consnil?函数,它们的含义也不与Common Lisp中的相同:有关详细信息,请参见clojure: no cons cells。在翻译subst之前,您必须确定Clojure的惯用用法是什么。

通常subst用于转换由cons单元组成的tree;请注意,例如subst不会递归到向量,字符串等。在这些树中,树的特定子集是Lisp形式的树。实际上,subst的一个重要用例是在代码生成过程中搜索并替换表单。

据我所知,如果将自己限制为Clojure Cons类型,则将不支持将代码作为数据使用。由于Clojure代码也使用数组表示法,因此您可能需要递归到数组对象中。因此,如何翻译subst并不是一个容易确定的问题。

一个可能的起点是阅读LispReader.java,以确定构成AST的对象集,并查看您要执行哪种代码遍历。

我的建议是首先独立学习那些语言。有了彼此的一点经验,您将有更好的方法来了解彼此之间的相似性和差异性。


0
投票

这就是我要做的,包括进行验证的单元测试:

LispReader.java

但是,尽管我真的认为Paul Graham的书(ns tst.demo.core (:use tupelo.core tupelo.test) (:require [clojure.walk :as walk])) (defn subst [pat tgt listy] (walk/postwalk (fn [elem] (if (= elem tgt) pat elem)) listy)) (dotest (is= (subst :m :b [:a :b [:a :b :c] :d]) [:a :m [:a :m :c] :d])) 确实令人不寒而栗,但我不会花很多时间阅读有关Common Lisp的40年历史的文章。

Clojure已将Lisp的最新技术发展到至少一个数量级(我想说的更像是2)。主要改进包括JVM的使用,持久性数据结构,并发性,语法和数据文字,仅举几例。

请参阅此Hackers & Painters列表,并可能以Getting Clojure或类似名称开头。

© www.soinside.com 2019 - 2024. All rights reserved.