我是 Scheme 编程的新手,并试图在 if 条件中定义一个 var。例如,我有:
(if (< x y) (define x y) ) ;(GOAL: if x < y, than x=y..)
Run Code Online (Sandbox Code Playgroud)
但我得到了错误:
let: bad syntax (not an identifier and expression for a binding) in:...
Run Code Online (Sandbox Code Playgroud)
任何想法如何解决这个问题,将不胜感激。
ps对不起我的英语
与命令式语言不同,您应该避免不使用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))
Run Code Online (Sandbox Code Playgroud)
你可以做几个中间体 let*
(let* ((tmp (+ x y))
(tmp2 (* tmp y))) ; tmp is bound here
(do-something-with tmp2)); or tmp and tmp2
Run Code Online (Sandbox Code Playgroud)
您可以使用递归,通过递归更新内部过程中的 cur 和 lst :
(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
Run Code Online (Sandbox Code Playgroud)
这是define
已经定义的东西的错误,所以这就是我定义的原因
如果您需要执行此顶级操作,您可以:
(define min_xy (if (< x y) x y))
Run Code Online (Sandbox Code Playgroud)
min_xy
. 要破坏性地更改绑定(使其引用另一个值),您可以使用set!
(set! x (+ x 1)) ; increases x
Run Code Online (Sandbox Code Playgroud)
您将更改最本地化的定义,如果它不存在则是一个错误。这可用于创建生成器:
(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
Run Code Online (Sandbox Code Playgroud)