首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MIT方案消息传递抽象

MIT方案消息传递抽象
EN

Stack Overflow用户
提问于 2013-05-05 01:14:32
回答 2查看 923关注 0票数 1

在我正在选修的一门计算机科学课程中,关于家庭作业,我们被要求回答几个不同的问题,这些问题都与信息传递有关。我已经解决了除一个之外的所有问题,这要求如下:

编写一个不接受参数并返回消息传递对象的邮件对象工厂(make-mailman),该对象响应以下消息:

  • 'add-to-route:返回接收任意数量邮箱对象并将其添加到邮递员对象的“路由”的过程
  • 'collect-letters:返回一个过程,该过程接收任意数量的信函对象,并收集它们以供将来分发
  • 'distribute:将收集到的信件添加到邮递员路线上的邮箱,其地址与信件的目的地匹配,并返回目的地与路线上的任何邮箱不匹配的信件列表(注意:每次传递'distribute后,邮递员对象都不应该有收集到的信件)。

为使代码更容易编写而给出的一些注释包括:

  • 如果在一次分发中将多个信件分发到同一个邮箱,则其中任何一个都可能是“最新”信件,其消息通过将'get-latest-message传递到邮箱而返回。
  • 没有两个邮箱会有相同的地址。
  • 邮筒或信件将不超过一次传递给邮递员。
  • 分发退回的不良信件不需要按特定顺序排列。
  • 使用. args语法接受任意数量的参数。

这就是我自己想出来的:

代码语言:javascript
复制
(define (make-mailman)
  (let ((T '()))
    (define (route-adder . mobjects)
      (assoc mobjects T))
    (define (letter-collecter . lobjects)
      (assoc lobjects T))
    (define (add-to-route mobjects)
      (begin (set! T (cons (route-adder . mobjects) T)) 'done))
    (define (collect-letters lobjects)
      (begin (set! T (cons (sort-strings (letter-collecter . lobjects)) T)) 'done))
    (define (dispatch z)
      (cond ((eq? z 'add-to-route) add-to-route)
        ((eq? z 'collect-letters) collect-letters)
        ((eq? z 'distribute) "unsure of what to do here")
        (else "Invalid option")))
    dispatch))

我在这里所能得到的任何帮助都将受到感谢,因为我已经尝试了很长一段时间来研究这个问题,并且无法从这里知道该做什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-07 14:46:46

你的代码有各种各样的混淆。)让我们一步一步地前进。

dispatch位几乎没有问题:

代码语言:javascript
复制
(define (make-mailman)
 (let ...
  ...
  (define (dispatch msg)                ;; use short but suggestive var names
   (cond 
    ((eq? msg 'add-to-route)    add-to-route)
    ((eq? msg 'collect-letters) collect-letters)
    ((eq? msg 'distribute) 
       ;; "unsure of what to do here" <<-- Distribute the letters, what else?
                                distribute-the-letters)
    (else "Invalid option")))
  dispatch))

对于这样的对象,样例调用将是(define ob (make-mailman)),然后是((ob 'add-to-route) box1 box2 ... boxn)等。因此,必须以这种方式定义add-to-route过程:

代码语言:javascript
复制
(define (make-mailman)
 (let ((self (list '(ROUTE)           ; each mailman has a route, and a mailbag
                   '(MAILBAG))))      ; use suggestive name here (T, what T?)
  ...
  (define (add-to-route . mailboxes)
    (let ((route (assoc 'ROUTE self))) 
      (set-cdr! route
          (append mailboxes           ; there will be no duplicates
            (cdr route)))
      'DONE))

对吗?信中也是如此:

代码语言:javascript
复制
  (define (collect-letters . letters)
    (let ((mailbag (assoc 'MAILBAG self)))
      .....
      'DONE))

现在我们可以处理缺失的部分了,distribute-the-letters

代码语言:javascript
复制
  (define (distribute-the-letters)
    ;; for each letter in my mailbag
    (let* ((mailbag (assoc 'MAILBAG self))
           (mailboxes (cdr (assoc 'ROUTE self)))
           (letters (cdr mailbag)))
      (if (null? letters) ()
        (let loop ((letter  (car letters))
                   (letters (cdr letters))
                   (not-delivered ()))
    ;;   access its address, 
          (let* ((address (letter 'get-address))
            ;; (we assume it supports this interface, 
            ;;   or maybe that's part of a previous assignment)
    ;;     and find a mailbox on my route such that
                 (mbx (find-mailbox address mailboxes)))
    ;;     its address matches the letter's
    ;;     and if so,
             (if .....
    ;;        put that letter into this mailbox: 
               ((mbx 'put-letter) letter)
    ;;            (we assume it supports this interface, 
    ;;             or maybe that's part of a previous assignment)
    ;;     but if not, add letter to the "not-delivered" list
               ..... )
            (if (null? letters)
    ;; having emptied the mailbag, return the "not-delivered" list
              (begin (set-cdr! mailbag nil) not-delivered)
              (loop (car letters) (cdr letters) not-delivered)))))))

我们假设lettermailbox对象都支持消息类型'get-address,它们都返回相同的address类型的对象,而mailbox对象支持'put-letter消息。

票数 3
EN

Stack Overflow用户

发布于 2013-05-05 14:49:24

除了消息功能的细节之外,看起来您已经完成了它。然而,也有一些错误:

这个(route-adder . mobjects)应该是(router-adder objects),类似于(letter-collector . lobjects)

不需要使用begin(define (func . args) <body> ...)的主体隐式地包含在begin中。

具体而言,您的代码可以编写为:

代码语言:javascript
复制
(define (make-mailman)
  (let ((T '()))
    ;; ...
    (lambda (z)
      (case z
        ((add-to-route)    add-to-route)
        ((collect-letters) collect-letters)
        ((distribute)      distribute)
        (else (error "Invalid option"))))))

但你可能还不知道case或者lambda .

至于解决实际的消息传递功能。您需要维护一组邮箱,每个邮箱都要保存一组信件。一封信大概包括一个地址和一些内容(回执地址的额外信用)。分发行为将检查每个字母上的地址,并将其存入其邮箱。邮递员将需要持有信件(在他的路线收集-信件),直到指示分发。

为此,您可以首先构建更低级别的功能,然后使用较低级别来构建实际的消息传递功能。例如,开始时:

代码语言:javascript
复制
(define (make-letter addr content)
  `(LETTER ,addr ,content))
(define letter-addr cadr)
;; ...

(define (make-mailbox addr)
  '(MBOX ,addr))
(define mailbox-letters cddr)
(define (mailbox-letters-add mailbox letter)
  (set-cdr! (cdr mailbox) (cons letter (mailbox-letters mailbox))))

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

https://stackoverflow.com/questions/16380479

复制
相关文章

相似问题

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