在评估条件后,我无法在Racket中设置变量。如果我有一个像
这样的函数定义(define foo
(lambda (x y z)
(cond
((> 3 2)
(what code here?)))))
如果条件的计算结果为true,我想将变量z设置为值10,语法是什么?
答案 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.简而言之,宏很棒。有关如何使用它们以及它们可以执行的操作,请参阅球拍指南。