我想编写一个程序来查找Scheme中二次方程的根。我使用LET进行某些绑定。
(define roots-with-let
(λ (a b c)
(let ((4ac (* 4 a c))
(2a (* 2 a))
(discriminant (sqrt ( - (* b b) (4ac)))))
(cons ( / ( + (- b) discriminant) 2a)
( / ( - (- b) discriminant) 2a)))))
我将4ac
定义为判别因为我不想要(* 4 a c)
。即使我已定义(4ac (* 4 a c))
,它也会给我这个错误:
展开:模块中的未绑定标识符:
4ac
。
我的问题是如何评估(什么顺序)?如果我想4ac
let
,我应该写另一个内let
吗?有更好的方法吗?
答案 0 :(得分:31)
使用let*
代替let
。
let
和let*
之间的区别如下:
let*
从左到右绑定变量。早期的绑定可以用于进一步向右(或向下)的新绑定。
let
可以被认为是简单lambda抽象的语法糖(或宏):
(let ((a exp1)
(b exp2))
exp)
相当于
((lambda (a b)
exp)
exp1 exp2)
答案 1 :(得分:8)
4ac是一个带数值的变量,所以(4ac)没有意义。
LET绑定所有变量,但变量不能用于值的计算。
这不起作用:
(let ((a 1) (b 1) (c (* a b)))
c)
使用:
(let ((a 1) (b 1))
(let ((c (* a b)))
c))
上面介绍了A和B的第一个LET。在第二个LET中,A和B现在都可用于计算C。
或者:
(let* ((a 1) (b 1) (c (* a b)))
c)
答案 2 :(得分:3)
这里需要special let
-construct(let*
),因为let-definition中的变量互相引用。
定义范围而不是评估表达式是一个问题(在通常的let
- 定义中,评估的顺序无关紧要,因为值可能不会互相使用)
答案 3 :(得分:2)
使用let时,绑定在任何实体中都不可见。请使用let *代替并查看RNRS文档以获取详细信息。