"球拍领域"的奇怪代码示例

lam*_*kie 5 lisp scheme racket

我目前正在阅读"Realet Of Racket"这本书,到目前为止我非常喜欢这本书.但是,在第7章1/2,第74页,有一个代码示例,我只是没有得到.也许我的思绪拒绝弄清楚,因为我正在度假,但是,我根本不知道它做了什么.

(define (winners lst pred)
  (cond
    [(empty? lst) (list pred)]
    [else
      (define fst (first lst))
      (if (score> (record-score pred) (record-score fst))
        (list pred)
        (cons pred (winners (rest lst) fst)))]))
Run Code Online (Sandbox Code Playgroud)

他们没有真正在书中解释它.但是他们提供了一些提示:

  • "该功能的目的是从游戏记录列表中选择第一名的终结者."
  • "我们有以下形状的结构定义:( struct record(name score)) "
  • " lst是这样的记录的列表,而pred就是这样的记录.事实上,原始列表是(cons pred lst),并且根据得分进行排序."
  • "你明白获胜者是一个吃饭的功能,并且一次只能记录一条记录.当至少有一条记录时,它会选择第一条记录,将其命名为fst,并比较fst及其前辈的得分.在结果上,所有获胜记录都已被取消,或者获胜者必须继续寻找得分相同的球员."

我想这score>是一个错字.除此之外,我完全理解代码 - 在语法和语义方面.我只是没有实际使用它.这是什么以及为什么有人想要这个?

Syl*_*ter 5

不幸的是,您显示的代码只是为了向您展示本地定义是如何工作的。在同一个示例中,您还会看到(define sorted-lst (sort lst ...))哪些根本不起作用。

这是第 75 页的完整示例代码,其中包含第 74 页的所有部分:

(define (winning-players lst)
  (define sorted-lst (sort lst ...)) ;; local variable 
  (define (winners lst pred)         ;; locally defined procedure
    (cond
      [(empty? lst) (list pred)]
      [else
       (define fst (first lst))
       (if (score> (record-score pred) (record-score fst))           
           (list pred)           
           (cons pred (winners (rest lst) fst)))]))
  ;; START HERE:
  ;; uses both local variable and the locally defined procedure
  (winners (rest sorted-lst) (first sorted-lst))) 
Run Code Online (Sandbox Code Playgroud)

他们试图在以下代码中显示的是,在外部winning-players您无法访问sorted-list或使用该过程,winners因为它隐藏在winning-players' 范围内。

例如。如果您尝试(winners ...)在球拍交互窗口中使用,您会得到:

获胜者:未定义;不能引用未定义的标识符

如果您了解可以继续玩第 5 章的乐趣:)

与球拍捆绑在一起,您拥有racket/collects/realm. 有 2 个过程定义称为winners. 第一个在chapter 10,第二个在chapter 12

至于代码做什么的答案。代码中有错误,所以我们需要修复它。我的猜测是 score> 比较两个记录的分数。我猜它应该是这样的:

(struct record (name score) #:transparent)
(define (winning-players lst)
  (define (score> e1 e2)  ; defines a new local procedure
    (> (record-score e1)  ; that compares two records 
       (record-score e2)))

  ;; define sorted-list to be lst sorted by score in decreasing order
  (define sorted-lst (sort lst score>))  
  ;; procedure winners reduces the list to the elements 
  ;; that have same score as pred
  (define (winners lst pred)            
    (cond
      [(empty? lst) (list pred)]
      [else
       (define fst (first lst))
       (if (score> pred fst)           ;; changed to work with records
           (list pred)           
           (cons pred (winners (rest lst) fst)))]))
  ;; START HERE:
  ;; uses both local variable and the locally defined procedure
  (winners (rest sorted-lst) (first sorted-lst))) 

(define scores (list (record "John" 10) 
                     (record "Ben" 5) 
                     (record "Mary" 10) 
                     (record "Owen" 2)))  

(winning-players scores) 
; ==> (list (record "John" 10) (record "Mary" 10))
Run Code Online (Sandbox Code Playgroud)

它返回所有得分最高的列表。