首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >(让(下一次(f猜测)) vs ((下一次(f猜测)

(让(下一次(f猜测)) vs ((下一次(f猜测)
EN

Stack Overflow用户
提问于 2019-12-26 02:56:04
回答 2查看 81关注 0票数 0

sicp的定点实践

代码语言:javascript
运行
复制
#+BEGIN_SRC scheme
(define tolerance 0.00001)

(define (fixed-point f first-guess)
  (define (close-enough? v1 v2)
    (< (abs (- v1 v2)) tolerance))
  (define (try guess)
    (let ((next (f guess)))
      (if (close-enough? guess next)
          next
          (try next))))
  (try first-guess))
(fixed-point cos 1.0)
#+END_SRC

#+RESULTS:
: 0.7390822985224024

参考行

代码语言:javascript
运行
复制
(let ((next (f guess)))

我假设添加了额外的括号,并将其更改为

代码语言:javascript
运行
复制
(let (next (f guess))

再运行一次,但拒绝工作

代码语言:javascript
运行
复制
#+BEGIN_SRC scheme
(define tolerance 0.00001)

(define (fixed-point f first-guess)
  (define (close-enough? v1 v2)
    (< (abs (- v1 v2)) tolerance))
  (define (try guess)
    (let (next (f guess))
      (if (close-enough? guess next)
          next
          (try next))))
  (try first-guess))
(fixed-point cos 1.0)
#+END_SRC

#+RESULTS:

有什么问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-26 03:04:36

这只是语法问题,您应该检查let的文档。它需要一个绑定列表和一个正文,其中每个投标都是一个包含两个元素的列表,一个变量名和一个表达式--所以这是正确的方法(添加额外的分行符来解释,但您不应该这样缩进):

代码语言:javascript
运行
复制
(let ( ; start list of bindings
      ( ; start binding
       next ; binding name
       (f guess) ; binding value
      ) ; end binding
     ) ; end list of bindings
  <body>)

你的尝试失败了:

代码语言:javascript
运行
复制
(let (next (f guess))
  ...)

..。因为它缺少分隔绑定列表的外部(),在主体部分之前。现在很明显,我们可以将多个绑定作为let的一部分,这就是为什么绑定列表的外部()是必需的。

票数 2
EN

Stack Overflow用户

发布于 2019-12-26 08:49:45

方案

我以为加了额外的括号

在方案中,我们不能假设。括号通常不是可选的,而是表达式语法的必要部分。

方案中的let语法(R5RS、R6RS、R7RS)是:

代码语言:javascript
运行
复制
(let <bindings> <body>) 

Syntax: <Bindings> should have the form

((<variable1> <init1>) ...)

因此,在您的示例中,next是变量,(f guess)是init形式。

试图省略一定程度的括号会导致语法错误。下列表格为无效计划。

代码语言:javascript
运行
复制
(let (next          ;  a symbol is not allowed, only (var init) lists
      (f guess))    ;  variable 'f' and init form 'guess'
  ...
  )

它的语法与其他一些Lisp语言略有不同。

Emacs Lisp

例如,请参见Emacs:3.6.1 let表达式的各个部分

因此,在Emacs中,可以只编写一个变量,以便将其绑定到nil

代码语言:javascript
运行
复制
(let ((var1 init1)
      var2
      (var3 init3)
      var4
      ...)
  ...)

通用Lisp

公共Lisp还允许省略init表单。语法:

代码语言:javascript
运行
复制
let ({var | (var [init-form])}*) declaration* form*

因此,在公共Lisp中,我们也可以拥有

代码语言:javascript
运行
复制
CL-USER > (let ((a 10)     ; a bound to 10
                b          ; b bound to NIL 
                (c))       ; c bound to NIL
            (list a b c))
(10 NIL NIL)

但在标准计划中..。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59483412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档