有人可以推荐解释Homoiconicity概念的文章,特别是使用Clojure。为什么Clojure是homoiconic,但在Java等其他语言中很难做到这一点?
答案 0 :(得分:24)
答案 1 :(得分:7)
当我学习Lisp时,当我了解到lisp在两个阶段中“编译”,读取和编译以及代码用相同的数据结构表示时,同理性的想法是有道理的:
所以它从你的大脑到.class文件一直都是s表达式。你甚至可以编写写s表达式的s表达式。所以你可以说“代码是数据”或“代码就是数据”,因为这听起来更好。
答案 2 :(得分:5)
'homoiconicity'的整个想法略有混淆,并不适合Lisp。 Lisp中的内部和外部表示不同。外部表示基于文件中的字符。内部表示基于Lisp数据(数字,字符串,列表,数组......),并且是非文本的。这和人物一样怎么样?有内部表示,没有相应的外部表示(例如编译代码,闭包,......)。
Lisp与许多其他编程语言的主要区别在于,Lisp有一个简单的源代码数据表示 - 一个不基于字符串的数据表示。
显然,代码可以在基于文本的编程语言中表示为字符串。但是在Lisp中,源可以用原始Lisp数据结构来表示。外部表示基于s表达式,s表达式是将分层数据表示为文本的简单模型。内部模型的表示基于列表等。
这就是评估者得到的:内部表征。不是1到1版本的文本输入,但已解析。
基本型号:
请注意,READ和PRINT适用于任意Lisp数据,它具有打印表示和读取器,而不仅适用于Lisp表单。根据定义,表单是Lisp编程语言中的有效表达式。
答案 3 :(得分:4)
这是一个做符号分化的简短程序。 这是LISP操纵自己的代码的一个例子。 尝试将其翻译成另一种语言,看看为什么LISP对这类事情有好处。
;; The simplest possible symbolic differentiator
;; Functions to create and unpack additions like (+ 1 2)
(defn make-add [ a b ] (list '+ a b))
(defn addition? [x] (and (=(count x) 3) (= (first x) '+)))
(defn add1 [x] (second x))
(defn add2 [x] (second (rest x)))
;; Similar for multiplications (* 1 2)
(defn make-mul [ a b ] (list '* a b))
(defn multiplication? [x] (and (=(count x) 3) (= (first x) '*)))
(defn mul1 [x] (second x))
(defn mul2 [x] (second (rest x)))
;; Differentiation.
(defn deriv [exp var]
(cond (number? exp) 0 ;; d/dx c -> 0
(symbol? exp) (if (= exp var) 1 0) ;; d/dx x -> 1, d/dx y -> 0
(addition? exp) (make-add (deriv (add1 exp) var) (deriv (add2 exp) var)) ;; d/dx a+b -> d/dx a + d/dx b
(multiplication? exp) (make-add (make-mul (deriv (mul1 exp) var) (mul2 exp)) ;; d/dx a*b -> d/dx a * b + a * d/dx b
(make-mul (mul1 exp) (deriv (mul2 exp) var)))
:else :error))
;;an example of use: create the function x -> x^3 + 2x^2 + 1 and its derivative
(def poly '(+ (+ (* x (* x x)) (* 2 (* x x))) 1))
(defn poly->fnform [poly] (list 'fn '[x] poly))
(def polyfn (eval (poly->fnform poly)))
(def dpolyfn (eval (poly->fnform (deriv poly 'x))))
答案 4 :(得分:2)
正如Rainer Joswig指出的那样,有充分的理由怀疑同质性这个概念的效用,以及Lisps是否实际上是同构的。
homoiconiticy的原始定义集中在语言的内部和外部表示之间的相似性。规范的例子是Lisp,带有s表达式。
有(至少)两个有关该定义和示例选择的问题。
第一个异议涉及外部代表。在Lisp的情况下,我们假设外部表示是一个s表达式。然而,在大多数实际编程环境中,程序源的实际表示是包含字符串的文本文件。只有在解析了这个文本之后,表示才真正是一个s表达式。换句话说:在实际环境中,外部表示不是s表达式,而是文本。
第二项反对意见涉及内部代表。由于性能原因,Lisp解释器的实际实现通常不会在内部直接对s表达式进行操作。尽管可以根据对s表达式的案例分析来定义Lisp,但通常不会这样实现。因此,内部表示实际上并不是一个s表达式。
事实上,人们甚至可能会围绕同质性的概念提出进一步的问题:对于一个封装良好的机器,我们无法通过定义观察其内部运作;在该视图中,使关于机器内部表示的任何语句都没有意义。更一般地说,原始定义存在的问题是,程序的单个外部和单个内部表示的想法与现实不匹配。实际上,存在一整套表示,包括程序员大脑中的电子,屏幕发出的光子,程序文本,机器代码以及在CPU中移动的电子。我在一篇名为Don't say “Homoiconic”
的文章中更广泛地写了这篇文章答案 5 :(得分:0)
这似乎很明显,但第一个来源可能是:
http://en.wikipedia.org/wiki/Homoiconicity
http://c2.com/cgi/wiki?DefinitionOfHomoiconic
一般情况下解释了同质性,您也可以找到原始来源。正如使用Lisp的例子所解释的那样,它离Clojure不远。