我如何解释我的 Scheme 代码的这种意外行为? [英] How could I explain this unexpected behavior of my Scheme code?

查看:54
本文介绍了我如何解释我的 Scheme 代码的这种意外行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图定义一个像 '(() ()) 这样的数据结构初始化函数,以便我以后可以生成很多.

I was trying to define a data structure initialization function like '(() ()), so that I can generate many of it later.

在我定义它之后,init 函数按预期工作.但是在我使用set-car之后!在 (let* ...) 函数调用中,(init) 的行为发生了变化.

Right after I defined it, the init function works expectedly. But after I use set-car! inside a (let* ...) function call, the behavior of (init) changed.

我的问题是如何解释这种行为?

My question is how to explain this behavior?

; define init func
(define (init)
  (display "initializing goal space...")
  (newline)
  '(() ())
  )

; call init func
(init)

; use set-car! in (let* ...)
(let*
    ((x (init)))
  (display x)
  (newline)
  (set-car! x (list 'foo))
  (display x)
  (newline)
  )

; call init func again
(init)

<小时>

DrScheme 中的输出日志,lang = Textual(MzScheme,包括 R5RS)


The output log in DrScheme, lang = Textual (MzScheme, include R5RS)

Welcome to DrScheme, version 372 [3m].
Language: Textual (MzScheme, includes R5RS).
initializing goal space...
(() ())
initializing goal space...
(() ())
((foo) ())
initializing goal space...
((foo) ())
> 

推荐答案

让你的 init 函数返回 (list '() '()) 而不是 '(() ()).这将导致它在每次调用时返回一个新列表.

Make your init function return (list '() '()) instead of '(() ()). This will cause it to return a new list each time it's called.

文字数据,如'(() ()),是不可变的.这意味着尝试使用 set-car! 对其进行变异具有未定义的行为.这样做的原因是每次执行时都允许实现返回相同的文字数据实例,因此在这种情况下,使用您的原始代码,每次调用 init 实际上都返回相同的列表.

Literal data, like '(() ()), is immutable. That means that trying to mutate it using set-car! has undefined behaviour. The reason for this is that implementations are allowed to return the same instance of the literal data each time it's evaluated, so in this case, with your original code, each call to init was actually returning the same list.

这篇关于我如何解释我的 Scheme 代码的这种意外行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆