Scheme符号的大小写敏感性

4
据我所了解,Scheme中的符号不区分大小写 - 也就是说,(eq? 'Hello 'hello)会被计算为#t(因为它们都被表示成符号'hello,而Scheme具有两个名称相同的符号是同一对象的属性)。然而,在我的实践中似乎并非如此,不论我尝试使用#lang scheme#lang racket#lang eopl版本的Scheme,事情似乎都是区分大小写的。有人有任何想法吗?

似乎对我来说并非如此:请解释。 - Scott Hunter
例如,表达式(eq? 'Hello 'hello)的求值结果为false。或者在“交互模式”下,如果我在提示符处键入“Hello”,则会打印出“Hello”,而应该打印出“hello”。 - Lord Cat
2个回答

9
简短/简单的回答是:大小写敏感性因标准而异,你使用的特定实现具有区分大小写的标识符。但这些信息可能孤立无助。那么出了什么问题呢?
考虑到你提到了#lang,很明显你正在使用Racket。Racket是Scheme的一个后代,但它不符合任何现有的Scheme标准。然而,Racket是可扩展的 - 它可以支持许多语言,甚至是用户定义的语言 - 因此,不同版本的Scheme是由Racket支持的。
哪些Schemes是区分大小写的?
在撰写本文时,存在三个相关版本的Scheme标准:R5RS、R6RS和R7RS。
- R5RS始终不区分大小写。 - R6RS始终区分大小写。 - R7RS默认区分大小写,但#!fold-case指令或include-ci表单可以禁用大小写敏感性。
正如你所看到的,这个问题并不是很明确:它在过去的三个标准中并没有保持一致。事实上,考虑到 R7RS 和 R6RS 都默认区分大小写,更准确地说,Scheme 现在是区分大小写的可能更加准确。然而,尽管 R5RS 已经过时了很长时间,但它仍然作为“Scheme”出现在许多书籍、解释器和编译器以及其他材料中,因此可能得出“Scheme 不区分大小写”的结论。

你使用的是哪个 Scheme?

没有一个。也许令人困惑的是,甚至 #lang scheme 也不是任何 Scheme 标准的实现。事实上,#lang scheme 是一种已被弃用的语言,已经完全被 #lang racket 取代(前者存在于 PLT Scheme 更名为 Racket 之前,主要是为了减少其“Scheme”不是实际的 Scheme 实现的混淆)。
因此,您可能会问,如何在Racket中获得实际的Scheme?好吧,Racket确实提供了各种Scheme标准的实现。 #lang r5rs#lang r6rs都是相关Scheme标准的内置实现。通过r7rs包,可以使用#lang r7rs获得R7RS实现。
Racket的所有语言都可以互操作,因此您可以选择自己喜欢的语言,尽管在Racket社区中往往不使用RnRS语言(#lang racket比任何Scheme实现更有用),但如果您想编写在不同Scheme实现上运行的程序,则它们可能很有用。

1
你可能想要提到(read-case-sensitive)过程。 - uselpa
1
非常好的概述。请注意,在Racket中,可以使用“#ci”来打开大小写不敏感的模式以对以下表达式进行比较。即#ci(eq? 'Hello 'hello)的结果为#t - soegaard
为什么 #ci() 只适用于符号,而不适用于字符串? - dtc

3
当我运行这个程序时:
#lang r5rs

(display (equal? 'abc 'ABC))

答案是#t。因此在这里您获得了大小写不敏感。

然而,如果你接下来输入

(equal? 'abc 'ABC)

在交互窗口中,你会得到 #f。我认为这可能是一个 bug,但修复它可能很困难。

我同意这是一个bug。很可能repl中没有设置大小写敏感参数。 - soegaard
是的,对我来说听起来像是一个 bug。Racket 处理 #lang 的模块读取器和顶层读取器是分开的,因为顶层读取器是无望的,所以很容易被忽视。 - Alexis King

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接