【问题标题】:SICP Lisp/Scheme - recursive return value gets lostSICP Lisp/Scheme - 递归返回值丢失
【发布时间】:2021-09-20 00:01:16
【问题描述】:

我正在编写一个简单的函数,它递归检查x(列表)是否是remaining(列表列表)的元素。

不知何故,从最里面的框架返回的#f 没有正确地冒泡到顶部:

#lang sicp

(define (was_seen? remaining x)
  (cond ((null? remaining) #false)
        ((eq? (car remaining) x) #true)
        ((was_seen? (cdr remaining) x))
  )
)


; test variables

(define seen (list(list 'a)))
(define z (list 0))


; now the test

(was_seen? seen z)
; expected: #f; returns blank (evaluated to #void when seen via debugger)


(was_seen? (cdr seen) z)
; expected: #f; returns #f as it should. 
; This is what the inner (recursive) call - correctly - evaluates to. 
; It's just that this #f doesn't get properly returned to the global caller?

这一定是一些愚蠢的简单,但我找不到什么。任何帮助将不胜感激。

【问题讨论】:

  • 提示:((was_seen? (cdr remaining) x)) 子句返回什么?
  • 为什么(null? x)时返回false?列表列表可以包含一个空列表。
  • @coredump 在这种情况下,它将评估为#false,因为(cdr remaining) 是空的,所以它将命中cond 的第二个谓词。

标签: list recursion scheme lisp sicp


【解决方案1】:

cond 返回第一个条件为真(即不是#f)的子句主体的值,或者如果它们都不为真,则返回else 子句的值。

如果没有一个条件为真,并且没有else 子句,则返回#void

在你的情况下,没有一个条件是真的,因为递归调用是假的。

将最后一个子句更改为else 子句,以便返回递归调用的值。

(define (was_seen? remaining x)
  (cond ((null? remaining) #false)
        ((eq? (car remaining) x) #true)
        (else (was_seen? (cdr remaining) x))
  )
)

如果子句中没有正文,您可能会认为您依赖于返回条件值的快捷方式。但这仅在条件为真时才会发生,因此这是将返回值的子句。条件为假时不适用。

【讨论】:

  • 报告未指定返回为#void。它称其为未定义的值,并且故意未指定。 MIT Scheme 返回开发人员不应该使用的逻辑值,因为它使程序实现特定。在以后的报告中建议未指定的值与返回的对象相同,但这不是必需的。我通常喜欢"BaNaNa" 作为未指定的值,所以我的实现中没有#void:-p
  • @Sylwester 我在简化,因为实际返回的值不相关,只是它没有返回他预期的原因。
猜你喜欢
  • 1970-01-01
  • 2013-03-18
  • 2010-12-12
  • 1970-01-01
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-07
相关资源
最近更新 更多