Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Variables 在评估一个条件后,如何在球拍中设置一个变量_Variables_Binding_Scheme_Racket - Fatal编程技术网

Variables 在评估一个条件后,如何在球拍中设置一个变量

Variables 在评估一个条件后,如何在球拍中设置一个变量,variables,binding,scheme,racket,Variables,Binding,Scheme,Racket,我在评估状态后设置球拍变量时遇到问题。如果我有一个函数定义,比如 (define foo (lambda (x y z) (cond ((> 3 2) (what code here?))))) 假设我想将变量z设置为值10,如果条件的计算结果为true,那么语法是什么?在Scheme中,我们设置如下变量: (set! z 10) 。。。但这是不受欢迎的,通常你要不惜一切代价避免变异状态。记住,Scheme的核心是一种函数式编程语言;必须有更好的

我在评估状态后设置球拍变量时遇到问题。如果我有一个函数定义,比如

(define foo
  (lambda (x y z)
    (cond
      ((> 3 2)
        (what code here?)))))

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

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

(set! z 10)
。。。但这是不受欢迎的,通常你要不惜一切代价避免变异状态。记住,Scheme的核心是一种函数式编程语言;必须有更好的方法来完成您试图完成的任务,而不改变变量的值。最可能的情况是,您希望使用
z
参数的新值调用递归:

(foo x y 10)

正如其他海报所说,在racket中使用这种命令式的编程风格是一种不好的做法。尽管如此,但这并不意味着这件事做不到!第一次尝试将其作为函数执行时,可能会出现以下情况:

(define (setter variable condition value)
  (if condition (begin (set! variable value) variable) variable))
(define a 10)
(setter a #t 5)
a
运行此函数将返回5和10。这就是我们开始看到函数的词法范围的地方。变量总是在其作用域中定义的,这是一个很好的系统,允许我们使用“list”作为函数参数的名称,尽管list是racket中的函数。Racket将假定您指的是当前范围中定义的变量,并覆盖以前的变量

基本上,我们希望
(set!variable value)
调用发生在我们关心的范围内,即setter函数之外。请注意:
a(set!a10)a
返回10 5,表示它做了我们想要的事情。嗯,如果我们传递一个真实的条件,那么现在只要我们能使setter真正成为code
(set!variable value)
。这将把它放在期望的范围内

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

(define-syntax-rule (setter variable condition value)
  (if condition (begin (set! variable value) variable) variable))
现在,塞特做了我们想要的

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

正确返回10 5 5。简而言之,宏非常棒。请参阅球拍指南,了解一些关于如何使用它们以及它们可以做什么的优秀教程

通常,您避免修改Racket(和Scheme)中变量的值。通过这样做,最好询问您想要解决的问题,而不是您心目中的特定解决方案。因为Racket具有词法范围,所以
z
的范围是
foo
的内部范围。因此,在运行
foo
之后,无法访问
z
,名称和值都消失了。事实上还有更多的故事,因为编译器会将
z
压缩成一个唯一的符号,以避免全局变量名出现某种类型的错误。@benrudgers这很有意义,谢谢。谢谢您的详细解释。我不打算在Racket(或Scheme)中做很多工作,但宏听起来正是我需要考虑的。