Scheme如何在条件中定义var

时间:2013-11-02 12:05:49

标签: scheme racket

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

(if (< x y) (define x y) ) ;(GOAL: if x < y, than x=y..)

但是我得到了错误:

let: bad syntax (not an identifier and expression for a binding) in:...

如何解决这个问题的任何想法,将不胜感激。

P.S。对不起我的英文

2 个答案:

答案 0 :(得分:4)

与命令式语言不同,您应该避免使用defineset!来更新可以避免变量的变量。在某些情况下,它需要,如在发电机中。 由于您没有完整的代码示例,因此我无法看到使用哪种明显的解决方案。

通过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))

您可以按let*

执行多个中间体
(let* ((tmp (+ x y))
       (tmp2 (* tmp y))) ; tmp is bound here
  (do-something-with tmp2)); or tmp and tmp2

你可以使用递归,通过递归更新cur和lst in innner过程:

(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

define已定义的内容是错误的,这就是我定义的原因

如果你需要做这个顶级,你可以:

(define min_xy (if (< x y) x y))

min_xy。要破坏性地改变绑定(让它引用另一个值),您可以使用set!

(set! x (+ x 1)) ; increases x

你将改变最本地的定义,如果它还没有存在则是一个错误。这可以用于创建生成器:

(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

答案 1 :(得分:0)

使用define是错误的;你没有在这里定义一个函数。有两种解决方案:

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

(set! x (if (< x y) y x))      ; sets x to y if (x<y) is true; else sets x to x