【问题标题】:Run length encoding of a list in scheme (R5RS) [duplicate]方案中列表的运行长度编码(R5RS)[重复]
【发布时间】:2021-02-13 11:20:03
【问题描述】:

(Question Details image -- describes RLE encoding)

我的rle 函数中的(if ((equal? (car coins) (cadr coins))) 代码段不起作用,函数停止工作。

 (define (element-index  lst element)
  (let loop ((counter 1) (temp lst))
    (if (= element (car temp))
        counter
        (loop (+ counter 1) (cdr temp)))))

 (define (rle coins)
   (cond ((null? coins) '()))
      (if ((equal? (car coins) (cadr coins)))
          (rle (cdr coins))
           (append '( cons (element-index (coins) (car coins)) (car coins))
                   '( cons (rle (cdr coins))))))

【问题讨论】:

    标签: list scheme racket r5rs non-procedure-application


    【解决方案1】:

    我不会回答如何解决run-length encoding的问题,而是基本的语法问题。

    对此的总结是:在许多编程语言中,通常在数学符号中,括号用于控制操作的顺序,并且通常或多或少是可选的。因此,例如1 + 2 * 3 可能表示“将 2 乘以 3,然后将结果加 1”,而 (1 + 2) * 3 表示“将 1 和 2 相加,然后将结果乘以 3”。但是1 + (2 * 3) 的含义与1 + 2 * 3 相同,与(((1 + (2 * 3)))) 的含义相同。

    Scheme 或 Lisp 家族的语言从来都不是这种情况。在这些语言中,括号是语言语法的一部分,它们绝不是可选的:它们必须要么存在,要么不存在。

    因此,特别是,Scheme 中表达式语法的简化版本可能是:表达式要么是

    • 一些原子的东西,比如变量引用;
    • 类似(op ...)的形式,其中op是一些运算符。

    在第二种情况下括号不是可选的:它们是语言语法的一部分。特别是如果您考虑像

    这样的表达式
    ((foo ...))
    

    然后这匹配第二种情况,其中 op 现在整体上是(foo ...)(并且没有参数),而 that 又再次匹配第二种情况opfoo 的情况。所以这是一个表达式,它的操作符是另一个表达式,而 that 表达式的操作符是foo:它不是一个被一些可选括号包裹的表达式,特别是不是((foo ...))(foo ...) 相同的情况。

    那么,if 的语法是:(if 表达式 结果 alternate)。好吧,让我们看看你的if

    (if ((equal? (car coins) (cadr coins)))
        ...
        ...)
    

    所以这里的表达式((equal? (car coins) (cadr coins)))。好吧,这与 (op ...) 的情况相匹配,其中 op(equal? (car coins) (cadr coins)),而这又与该情况相匹配,因此它将评估为返回#t#f。所以表达式与(#t)(#f) 相同。而#t#f 是布尔值:它们不是你可以调用为函数的东西。

    这至少是您代码中的错误之一。还有其他的,但这似乎是最重要的,因为这也是您在对另一个答案的评论中犯的错误。

    总而言之:括号在 Scheme 中从来都不是可选的:它们要么是语言语法所必需的,要么是禁止的。


    另一种说法是,在“传统的 Algol 风格”语言中,括号通常有两个用途:

    • 它们充当语法的关键和强制性部分,通常用于函数参数,如 f(x, ...),但有时也用于其他语法目的,如 C 中的 if (...) ...
    • 它们用于对表达式进行分组,以控制有时需要但通常是可选的计算顺序。

    在 Lisp 家族语言中,只有前一个目的存在。

    【讨论】:

    • 或者,简而言之,JS 中的 op(a, ...) 是 Lisp 中的 (op a ...)。所以 Lisp 的 ((op ...)) 是 JS 的 op(...)()
    • @WillNess: 是的,但关键是 JS 中的 (op(a, ...)) 在 Lisp 中甚至不可能(或永远不需要)(也许是 (begin (op a)),但不是真的,因为那更像如果 JS 是一种表达式语言,{op(a, ...)} 会是什么)。请参阅最后的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 2012-08-17
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 2012-07-11
    相关资源
    最近更新 更多