Functional programming 什么是情商?mit模式解释器中的谓词do?
我知道Functional programming 什么是情商?mit模式解释器中的谓词do?,functional-programming,scheme,lisp,Functional Programming,Scheme,Lisp,我知道(eq?obj1 obj2)仅当obj1和obj2引用内存中的同一对象时才会返回#t 1) (eq?2.6 2.6)返回#f,因为它们是浮点数,浮点数的表示形式在方案中不同。有人能解释一下它们在记忆中是如何表现的吗 2) 为什么成对和非空字符串经常返回#f,即使我们以前没有声明它们?例如:(eq?(cons12)(cons12)),当将相同的数字与eq?进行比较时,给出与equal?谓词相同的结果 例如,(define x 3)(define y 3)(eq?x y)返回#t 我还理解(e
(eq?obj1 obj2)
仅当obj1和obj2引用内存中的同一对象时才会返回#t
1) (eq?2.6 2.6)
返回#f
,因为它们是浮点数,浮点数的表示形式在方案中不同。有人能解释一下它们在记忆中是如何表现的吗
2) 为什么成对和非空字符串经常返回#f
,即使我们以前没有声明它们?例如:(eq?(cons12)(cons12))
,当将相同的数字与eq?
进行比较时,给出与equal?
谓词相同的结果
例如,(define x 3)(define y 3)(eq?x y)
返回#t
我还理解
(eq?“()”())
返回#t
,因为内存中只有一个空列表的表示形式,它是指向0的指针。要理解这一点,您确实需要了解Lisp通常如何表示对象。下面的内容并不是麻省理工学院计划的具体内容,甚至可能不适用于该计划(或任何具体的实施),但其目的是让您了解一般的考虑事项。除了下面绘制的表示法之外,还有其他可能的表示法,但它们都有类似的折衷
对象表示
首先,系统需要了解关于任何对象的两件事:
- 它是什么样的东西——它的类型李>
- 它的值是什么——表示对象的一些位模式
NIL
/()
执行此操作,这可能是一个特殊的“NIL”标记,单词的其余部分为零。我不确定这对这个计划来说可能没什么意义
但一般来说,你不能这样做:大多数对象都必须用指针存储,在最一般的情况下,单词中的标记位会说“it's something”,指针会指向某个对象,该对象既有对象的类型,也有对象的值,并且有几个单词长
像小整数一样立即存储的对象通常称为“未装箱”,而基于指针的一般对象称为“已装箱”
eq?
做什么
那么,eq?
做什么?简单:它告诉您这两个单词是否是相同的位模式:如果标记和指针/立即数值都是相同的位。这是非常快的(一条指令),但也非常原始
对于直接类型(如fixnums),它将告诉您这两个对象是否具有相同的值。对于指针类型,它将告诉您两个对象是否相同:如果两个指针指向相同的地址(并且具有相同的标记位,尽管如果没有,这将非常奇怪)。它不会告诉您两个指针类型是否表示相同的值,即使它们是不同的指针
实习:技巧
对装箱类型可以做的一个技巧是对它们进行实习:每次你准备制作一个新的装箱类型时,你都要看看之前是否制作了一个等价的装箱类型,如果已经制作了,你只需返回一个指向同一对象的指针。这意味着eq?
对于任何两个等效的内部对象都将返回true,因为它们实际上是同一个对象。只有当对象的数量相对较少时,如果对象是不可变的或实际上是不可变的,或者如果您有意想要这种实习行为,那么实习对象才真正有意义
浮点数
浮点数为32位或64位。因此,在64位系统上,可以立即表示32位单浮点:在字的一半有一些标记位和一堆零,在另一半有浮点位。但你永远不能为双浮动做这件事。即使对于单个浮动,您也需要一个特殊的“浮动”标记,而标记是一种极其稀缺的资源——可能只有8个。(当然,大多数Lisp在living memory之前都是32位的,32位Lisp甚至不能立即存储一个浮点。)
因此,一般来说,单浮点数和双浮点数都是装箱的。实习浮动是没有意义的,因为你可以
(define (x f)
(let ([g f])
(eq? g f)))
(x 1.0)
> (eq? 1 1)
#t
> (eq? (expt 2 20) (expt 2 20))
#t
> (eq? (expt 2 64) (expt 2 64))
#f
> (eq? (expt 2 62) (expt 2 62))
#f
> (eq? (expt 2 61) (expt 2 61))
#t
> (eq? (- (expt 2 62) 1) (- (expt 2 62) 1))
#t