66

我在自学计划的第 1 天第 1 小时。不用说,我什么都不懂。所以我正在阅读The Little Schemer并使用这个东西:

http://sisc-scheme.org/sisc-online.php

作为翻译。

'例如,我需要使用

(atom? 'turkey)

以避免“未定义的变量”错误。根据'这本书, 是 Common Lisp 的东西。

我有两个问题:

  1. 我上面提到的口译员是好口译员吗?你能推荐另一个吗?我需要一个与The Little Schemer搭配得很好的。

  2. 是什么'

4

7 回答 7

63

表单'foo只是键入特殊表单的一种更快的方法

(quote foo)

也就是说,“不要评估foo 它的值替换它的名称;我真正的意思是名称foo本身”。

我认为 SISC 非常适合探索 TLS 中的练习。

于 2009-10-08T17:02:39.627 回答
29

您需要了解 Scheme 的基本评估规则。

首先

(atom? 'turkey)

该列表是一个函数应用程序,因此atom?被评估为一个函数。 'turkey是 的简写符号(quote turkey)。评估(quote turkey)给出符号turkey

因此,接下来将函数应用于符号turkey并计算返回值。

第二

(atom? turkey)

同样,我们有一个函数应用程序atom?并被评估为一个函数。这个时间turkey是一个变量。评估turkey给出了与它绑定的价值——它是什么。

因此,该函数将应用于变量的值turkey

概括

turkey是一个变量,它被评估为其值。'turkeyis (quote turkey),它被评估为符号turkey

Scheme 重用 s-expressions 并从 s-expressions 构建它的程序。这导致了有时 turkey应该是变量,有时应该是符号的问题。这对初学者来说有点混乱。一段时间后,你会看到它背后的力量。

于 2009-10-08T20:06:01.817 回答
15

SISC 很好,但更轻量级的在线 Scheme 执行器是http://codepad.org。它实际上不是 REPL,因为它不是交互式的,但它非常接近。您提交的代码在服务器端执行,而不是使用浏览器小程序。您可以通过短 URL 共享您正在运行的代码。

键盘上的about页面说它使用“MzScheme v372 [cgc]”。

我使用键盘进行各种快速片段测试(包括测试代码示例以获得 SO 答案!)。

对于引号语法,可以使用如下代码看到差异:

(let ((x 5))
  (display x) (newline)
  (display 'x) (newline))

这显示:

5
X

在第一种情况下,x计算并传递给display,它打印 5。在第二种情况下,符号 x(与字符串不同)被传递给display,它打印符号的名称。

于 2009-10-08T18:25:40.163 回答
11

的简写(quote ...)'将代码转换为数据。

stuff是一个符号,这意味着它可以是变量的名称或函数的名称等。
'stuff为您提供符号“东西”本身。

(dostuff "on" those 4 :parameters) 评估时,将dostuff使用四个参数运行函数:字符串、变量内容、数字和关键字。
'(dostuff "on" those 4 :parameters)当评估时将返回上面的代码,当评估时,它将依次运行dostuff具有这四个参数的函数..

例如:运行'''somecode,它返回''somecode。运行''somecode,它返回'somecode。运行'somecode,它返回somecode。运行somecode,并且......好吧......somecode将运行。

你可以说这'有点像 的对立面(eval..)

(eval (eval (eval '''(print "hello"))))会打印“你好”。-再
(eval (eval (eval ''''(print "hello")))注意一个- 不会打印任何东西,但它会返回代码本身!'eval(print "hello")

除了 lispers 倾向于将返回的代码(有时甚至是手写代码)称为“列表”而不是“代码”,原因会随着您深入挖掘而变得明显。祝你好运 :)

于 2014-12-06T13:46:32.537 回答
5

单引号字符是 (quote foo) 的简写方式,其中 quote 是仅返回 foo 而不对其进行评估的形式。

在 Scheme 或任何 Lisp 中真正要记住的一件事是默认情况下会评估所有内容。因此,在您不想评估的情况下,您需要一种方法来解决这个问题。

引用某些东西就是这样做的,而单引号只是需要更少的输入并导致更少的冗长代码。

于 2009-10-13T12:42:47.447 回答
4
  1. 我建议您转移到更好的环境,例如PLT Scheme,它有一个 IDE、调试器和许多库。随着您前进并开始编写更大的程序,您将需要它们。

  2. 单引号字符是“引号”表达式的语法糖,因此 'turkey 与 (quote turkey) 相同。基本上,“报价”所做的是关闭方案评估器。换句话说,“quote”逐字返回表达式。如果没有“quote”,Scheme 将尝试在当前环境中评估“turkey”。这不是 Common Lisp 的事情,而是 Lisp 的事情。Common Lisp 和 Scheme 是 Lisp 的两种方言。所有 Lisp 教程/书籍中都解释了“引用”的用法。另请参阅此问题的答案。

于 2009-10-09T03:24:54.343 回答
2

如果您正在寻找最好的 IDE,scheme请选择Dr Racket. 但是当开始Dr Racket 第一行应该是#lang scheme因为 Dr Racket有很多语言我们已经明确提到我们将使用哪种语言。

当我们想传递参数本身而不是传递参数的值时,我们使用引号。它主要与使用 C 编程语言中不可用的列表、对和原子期间传递的过程有关(大多数人开始使用 C 编程进行编程,因此我们感到困惑)这是 Scheme 编程语言中的代码,它是 lisp 的一种方言我想你可以理解这段代码。

(define atom?              ; defining a procedure atom?
(lambda (x)              ; which as one argument x
(and (not (null? x)) (not(pair? x) )))) ; checks if the argument is atom or not
(atom? '(a b c)) ; since it is a list it is false #f

最后一行 (atom?'abc) 将 abc 原样传递给程序以检查 abc 是否为原子,但是当您传递 (atom?abc) 时,它会检查 abc 的值并将值传递给它。因为,我们没有为它提供任何价值

于 2014-06-16T15:47:33.880 回答