Scheme how to define var in if condition

2019-09-06 13:45发布

I am newbie to Scheme programming and trying to define a var in if condition. For example, I have:

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

But I got the error:

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

Any ideas how to resolve this, would be greatly appreciated.

p.s. Sorry for my English

标签: scheme racket
2条回答
趁早两清
2楼-- · 2019-09-06 14:04

Using define is wrong; you are not defining a function here. There are two solutions:

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

Or

(set! x (if (< x y) y x))      ; sets x to y if (x<y) is true; else sets x to x
查看更多
别忘想泡老子
3楼-- · 2019-09-06 14:09

Unlike imperative languages you should refrain not use define or set! to update variables where you can avoid it. In some circumstances it's needed, like in generators. Since you don't have a full code example where you'd like to do this I cannot see what obvious solution is to be used.

The way to store intermediate values if by let or recursion:

;; 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))

You can do several intermediates by let*

(let* ((tmp (+ x y))
       (tmp2 (* tmp y))) ; tmp is bound here
  (do-something-with tmp2)); or tmp and tmp2

You you can use recursion, where you update cur and lst in th innner procedure by recursion:

(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

It is an error to define something that is already defined so thats why I defined

If you need to do this top level you can:

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

min_xy. To alter a binding destructively (get it to reference another value) you can use set!

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

You'll alter the most local definition and it's an error if it doesnæt already exist. This can be used for creating generators:

(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
查看更多
登录 后发表回答