Scheme 如何在if条件下定义var的方案

Scheme 如何在if条件下定义var的方案,scheme,racket,Scheme,Racket,我是Scheme编程的新手,尝试在if条件下定义var。例如,我有: (if (< x y) (define x y) ) ;(GOAL: if x < y, than x=y..) 如果您有任何关于如何解决此问题的想法,我们将不胜感激 p、 对不起,我的英语使用define是错误的;这里没有定义函数。有两种解决方案: (if (< x y) (set! x y) (void)) ; if x < y set x = y; else do nothing (如果(

我是Scheme编程的新手,尝试在if条件下定义var。例如,我有:

(if (< x y) (define x y) ) ;(GOAL: if x < y, than x=y..)
如果您有任何关于如何解决此问题的想法,我们将不胜感激


p、 对不起,我的英语使用define是错误的;这里没有定义函数。有两种解决方案:

(if (< x y) (set! x y) (void)) ; if x < y set x = y; else do nothing
(如果(


(设置!x(如果(
(if (< x y) (set! x y) (void)) ; if x < y set x = y; else do nothing
(如果(


(set!x(if(define
set!
来更新可以避免的变量。在某些情况下,需要使用它,如在生成器中。 因为您没有一个完整的代码示例,所以不知道要使用什么明显的解决方案

通过
let
或递归存储中间值的方法:

;; within the let block x shadows the original x 
;; with the smalles of the outer x and y
(let ((x (if (< x y) x y)))
    (do-something x))
(define (mmin x . xs)
  (define (min-aux cur lst)
    (cond ((null? lst) cur)
          ((<= cur (car lst)) (min-aux cur (cdr lst)))
          (else (min-aux (car lst) (cdr lst)))))

  (min-aux x xs)) ; start recursion
可以使用递归,通过递归更新Inner过程中的cur和lst:

;; within the let block x shadows the original x 
;; with the smalles of the outer x and y
(let ((x (if (< x y) x y)))
    (do-something x))
(define (mmin x . xs)
  (define (min-aux cur lst)
    (cond ((null? lst) cur)
          ((<= cur (car lst)) (min-aux cur (cdr lst)))
          (else (min-aux (car lst) (cdr lst)))))

  (min-aux x xs)) ; start recursion
min_xy
。要以破坏性方式更改绑定(使其引用另一个值),可以使用
set!

(set! x (+ x 1)) ; increases x
您将更改most本地定义,如果它不存在,则为错误。这可用于创建生成器:

(define (generator start alter-proc)
  (lambda ()                           ; returns a procedure taking 0 arguments
    (let ((old start))                 ; temporary store what start points to
       (set! start (alter-proc start)) ; change what the local start points to
       old)))                          ; return the old value     

(define counter (generator 1 (lambda (x) (+ x 1))))
(counter) ; ==> 1
(counter) ; ==> 2

(define doubler (generator 1 (lambda (x) (* x 2))))
(doubler) ; ==> 1
(doubler) ; ==> 2
(doubler) ; ==> 4

与命令式语言不同,您不应该在可以避免的地方使用
define
set!
来更新变量。在某些情况下,需要使用它,例如在生成器中。 因为您没有一个完整的代码示例,所以不知道要使用什么明显的解决方案

通过
let
或递归存储中间值的方法:

;; within the let block x shadows the original x 
;; with the smalles of the outer x and y
(let ((x (if (< x y) x y)))
    (do-something x))
(define (mmin x . xs)
  (define (min-aux cur lst)
    (cond ((null? lst) cur)
          ((<= cur (car lst)) (min-aux cur (cdr lst)))
          (else (min-aux (car lst) (cdr lst)))))

  (min-aux x xs)) ; start recursion
可以使用递归,通过递归更新Inner过程中的cur和lst:

;; within the let block x shadows the original x 
;; with the smalles of the outer x and y
(let ((x (if (< x y) x y)))
    (do-something x))
(define (mmin x . xs)
  (define (min-aux cur lst)
    (cond ((null? lst) cur)
          ((<= cur (car lst)) (min-aux cur (cdr lst)))
          (else (min-aux (car lst) (cdr lst)))))

  (min-aux x xs)) ; start recursion
min_xy
。要以破坏性方式更改绑定(使其引用另一个值),可以使用
set!

(set! x (+ x 1)) ; increases x
您将更改most本地定义,如果它不存在,则为错误。这可用于创建生成器:

(define (generator start alter-proc)
  (lambda ()                           ; returns a procedure taking 0 arguments
    (let ((old start))                 ; temporary store what start points to
       (set! start (alter-proc start)) ; change what the local start points to
       old)))                          ; return the old value     

(define counter (generator 1 (lambda (x) (+ x 1))))
(counter) ; ==> 1
(counter) ; ==> 2

(define doubler (generator 1 (lambda (x) (* x 2))))
(doubler) ; ==> 1
(doubler) ; ==> 2
(doubler) ; ==> 4


define
可用于任何绑定,而不仅仅是功能该选项在R6RS方案中是可选的,因此
(如果(
是合法的。@Sylvest但在Racket中它不是可选的。@sepp2k True。一些R5RS限制保留在#!Racket中。
定义
可用于任何绑定,而不仅仅是功能。替代方案在R6RS方案中是可选的,所以
(如果(
是合法的。@Sylvester但在Racket中它不是可选的。@sepp2k-True。一些R5RS限制保留在#!Racket中。也许你可以添加多一点上下文,因为这看起来非常不规则;-)也许你可以添加多一点上下文,因为这看起来非常不规则;-)我理解令人沮丧的
设置--但不是
定义
,它与
一样,只允许您创建绑定。事实上,在球拍中,
define
通常被鼓励与
let
相比,以减少“向右漂移”缩进。但是,即使你不喜欢那种喜欢定义的风格,我也不明白为什么要阻止它?@GregHendershott我只是为了更新绑定而反对它。许多实现支持这种使用,即使它不是正确的方案。使用
define
来定义全局或过程(它作为
letrec
工作)当然可以。感谢您的回答和解释:)@sylvester ok我明白了。拍子中的FWIW类似于
(begin(define x 1)(define x 2))
是模块(文件)中的一个错误:“模块:标识符的重复定义:x”。当然,回复是另一回事@格雷根德肖特球拍和伊卡洛斯是例外。它的工作原理是
set在赤壁计划中,鸡、赌博、诡计和斯大林。所有标准一致,因为它不应该发生在源文件中。我理解令人沮丧的
set--但不是
定义
,它与
一样,只允许您创建绑定。事实上,在球拍中,
define
通常被鼓励与
let
相比,以减少“向右漂移”缩进。但是,即使你不喜欢那种喜欢定义的风格,我也不明白为什么要阻止它?@GregHendershott我只是为了更新绑定而反对它。许多实现支持这种使用,即使它不是正确的方案。使用
define
来定义全局或过程(它作为
letrec
工作)当然可以。感谢您的回答和解释:)@sylvester ok我明白了。拍子中的FWIW类似于
(begin(define x 1)(define x 2))
是模块(文件)中的一个错误:“模块:标识符的重复定义:x”。当然,回复是另一回事@格雷根德肖特球拍和伊卡洛斯是例外。它的工作原理是
set在赤壁计划中,鸡、赌博、诡计和斯大林。所有标准一致,因为它不应该出现在源文件中。