在评估条件后如何在Racket中设置变量

时间:2015-12-09 22:20:29

标签: variables binding scheme racket

在评估条件后,我无法在Racket中设置变量。如果我有一个像

这样的函数定义
(define foo
  (lambda (x y z)
    (cond
      ((> 3 2)
        (what code here?)))))

如果条件的计算结果为true,我想将变量z设置为值10,语法是什么?

2 个答案:

答案 0 :(得分:2)

在Scheme中,我们设置如下变量:

(foo x y 10)

......但它不赞成,通常你想不惜一切代价避免变异。请记住,Scheme的核心是一种函数式编程语言;在不改变变量值的情况下,必须有更好的方法来做你想要完成的事情。最有可能的是,您希望使用{{1}}参数的新值调用递归:

{{1}}

答案 1 :(得分:0)

正如其他海报所说,在球拍中使用这种命令式编程风格是不好的做法。然而,话虽如此,但并不意味着它无法完成!作为函数执行此操作的第一次尝试可能如下所示:

(define (setter variable condition value)
  (if condition (begin (set! variable value) variable) variable))
(define a 10)
(setter a #t 5)
a

运行它返回5和10.这是我们开始看到函数的词法范围的地方。变量总是在它们的范围内定义,这是一个很好的系统,可以让我们做一些事情,比如使用' list'尽管列表是球拍中的一个函数,但作为函数参数的名称。 Racket将假设您指的是当前范围中定义的变量,并覆盖以前的变量。

基本上,我们希望(set! variable value)调用发生在我们关心的范围内,即在setter函数之外。注意: a (set! a 10) a返回10 5,表示它符合我们的要求。嗯,现在只要我们能让setter实际成为代码(set! variable value),如果我们通过它就是真实的条件。这将使其达到预期的范围。

我们可以!这就是Racket的Macro系统发挥作用的地方。在Racket(以及scheme和lisp语言)中,您编写的程序就像数字和布尔值一样,这意味着您可以操作它们并返回新值。

(define-syntax-rule (setter variable condition value)
  (if condition (begin (set! variable value) variable) variable))

现在,setter做了我们想要的。

(define a 10)
a
(setter a #t 5)
a

正确返回10 5 5.简而言之,宏很棒。有关如何使用它们以及它们可以执行的操作,请参阅球拍指南。