我想要一些关于“开始”+函数+调用变量的机制的澄清或资源,就像cond结构和以下函数中对“node”的调用一样。
坦率地说,我不明白为什么未能将循环调回“节点”会导致错误,哪个节点不再是节点对象,如下所述。
事实上,虽然我直觉地认为如果我称“树”改变“节点”的值我然后应该恢复原始值,我不明白为什么这需要在第二次检查时进行,因为如果“节点”没有在那里改变那么值..
我猜我的疑问是关于“开始”的构造,因为如果在循环函数的情况下我理解循环必须在“开始”语句的末尾被调用我不明白是什么应该要求一个论点..
(define tree
(lambda (node value)
(cond
((null? node)
(make-node value)) ; if I insert node at the end of this line I just get () as an output
((= value (node-value node))
(node-counter-set! node (+ 1 (node-counter node)))
node) ; in this position in Dr. Racket a simple ")" would do, but the Petit Chez Scheme implementation that we use for tests in class requires the call to "node"
((< value (node-value node))
(node-left-set! node (tree (node-left node) value))
node)
(else
(node-right-set! node (tree (node-right node) value))
node)
)))
这是包含以下内容的更大系统的一部分:
(define build
(lambda (root lon)
(cond
((null? lon)
lon)
(else
(build (tree root (car lon)) (cdr lon))
))))
(define make-node
(lambda (value)
(vector '() value '() 1)
))
(define node-counter-set!
(lambda (node value)
(vector-set! node 3 value)
))
(define node-left-set!
(lambda (node value)
(vector-set! node 0 value)
))
(define node-right-set!
(lambda (node value)
(vector-set! node 2 value)
))
(define node-value
(lambda (node)
(vector-ref node 1)
))
(define node-counter
(lambda (node)
(vector-ref node 3)
))
(define node-left
(lambda (node)
(vector-ref node 0)
))
(define node-right
(lambda (node)
(vector-ref node 2)
))
答案 0 :(得分:3)
&#34;我该如何关闭begin语句?&#34;
使用您想要的任何表达式。在计算时,该表达式的值将作为整个begin
表达式的值返回。
Scheme是面向表达式的语言。其中的每个代码片段 - 每个表单 - 都是一个表达式,而不是语句 - 它有一些价值。
变量不被称为&#34;它们被引用&#34;它们的值被使用。
有时变量引用的值是&#34;变异&#34; - 改变了。 E.g。
(vector-set! var ... )
更改var
引用的向量的实际内容。如果你要写(set! var 2)
,你会改变变量的绑定,即你会改变它引用的对象(迄今为止,数字 2 )。
使用这种变异操作的函数除了按照所有函数返回一些值之外,还被认为具有&#34;(侧)效果&#34; 。这里的效果将是实际内存驻留对象的改变,一个向量,可能在程序的其他部分可以访问。
答案 1 :(得分:2)
begin
块的值是块
> (define x (begin (print "hello") 3 2 1))
"hello"
> x
1
关于向量变异表达式的值的实现可能有所不同 - 有些返回修改后的向量,而有些返回void
或类似的东西。
因此,在你的tree
过程中,一些实现将要求你明确地给出node
作为表达式的值(并且这是一个明确的好习惯,而不是依赖于副作用,无论如何)。 / p>
答案 2 :(得分:2)
通常使用像vector-set!
这样的变异过程,表达式会计算出一些未定义的值。未定义我们的意思是实施者可以选择放置他们想要的东西。然后,大多数实现选择一个对象为&#34; undefined&#34;对象,但有些人可能会选择返回突变的对象,使你不必在那个实现中明确地执行它。请注意,如果您使用特定于实现的功能,则会获得特定于实现的代码,而不是符合Scheme报告的内容!
如果您希望node-counter-set!
评估您在过程中执行此操作的参数:
(define (node-counter-set! node value)
(vector-set! node 3 value) ; set value on the node. It returns an undefined value
node) ; last expression in the explicit begin we return the node
<强> BEGIN 强>
begin
是一个特殊形式,它按顺序计算表达式,除了最后一个表达式之外,我们只丢弃结果。因此,为了使这些表达有用,他们需要有像突变或输入/输出这样的副作用。
有begin
个地方没有直接放置。例如。过程的主体具有隐式begin
:
(lambda (x y)
(display x)
(newline)
(display y)
(newline)
(+ x y)) ; procedure returns the sum of it's arguments but have lots of sife effects first
cond
每个字词可能有多个结果,这是一个明确的begin
(cond
((= x y) (display "X and Y are same number") (+ x y))
...)
实际上它的语法糖是:
(if (= x y)
(begin (display "X and Y are same number") (+ x y))
...)