MIT Scheme 消息传递抽象 [英] MIT Scheme Message Passing Abstraction

查看:40
本文介绍了MIT Scheme 消息传递抽象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我参加的计算机科学课程中,作为家庭作业,我们的任务是解决几个与消息传递有关的不同问题.除了一个,我已经能够解决所有问题,它要求以下内容:

In a Computer Science course I am taking, for homework, we were tasked with several different questions all pertaining to message passing. I have been able to solve all but one, which asks for the following:

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

Write a mailman object factory (make-mailman) that takes in no parameters and returns a message-passing object that responds to the following messages:

  • 'add-to-route:返回一个接收任意数量邮箱对象的过程并将它们添加到邮递员对象的路由"
  • 'collect-letters:返回一个接收任意数量的字母对象的过程,并且收集它们以备将来分发
  • 'distribute:将每封收集到的信件添加到邮递员路线上的邮箱address 匹配信件的目的地并返回其目的地的所有字母的列表没有匹配路由上的任何邮箱(注意:每次通过后'分发这邮递员对象不应该有收集的信件.)
  • 'add-to-route: return a procedure that takes in an arbitrary number of mailbox objects and adds them to the mailman object's "route"
  • 'collect-letters: return a procedure that takes in an arbitrary number of letter objects and collects them for future distribution
  • 'distribute: add each of the collected letters to the mailbox on the mailman's route whose address matches the letter's destination and return a list of any letters whose destinations did not match any mailboxes on the route (Note: After each passing of 'distribute the mailman object should have no collected letters.)

为了简化代码而给出的一些注释包括:

Some remarks that are given to make the code easier include:

  • 如果在一轮分发中将多封信分发到同一个邮箱,则任何一封其中可能是通过传递'get-latest-message返回消息的最新"信件到邮箱.

  • If multiple letters are distributed to the same mailbox in one distribution round, any one of them may be the "latest" letter whose message is returned by passing 'get-latest-message to the mailbox.

没有两个邮箱的地址相同.

No two mailboxes will have the same address.

邮箱或信件不会多次传递给邮递员.

No mailbox or letter will be passed to the mailman more than once.

distribute 返回的坏信不需要按特定顺序排列.

The bad letters returned by distribute do not need to be in a specific order.

使用<代码>.args 语法,用于接受任意数量的参数.

Use the . args syntax for accepting arbitrary amount of arguments.

这是我自己能够弄清楚的:

This is what I have been able to figure out for myself:

(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))

在这里可以给我的任何帮助将不胜感激,因为我已经尝试解决这个问题一段时间了,但无法从这里弄清楚该怎么做.

Any help that can be given to me here will be appreciated, as I have tried looking at this problem for a while, and cannot figure out what to do from here.

推荐答案

你的代码有各种各样的混淆.:) 让我们一步一步来.

Your code has all kinds of mix-ups. :) Let's proceed step by step.

dispatch 位几乎没问题:

(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 过程必须这样定义:

With such objects, a sample call will be (define ob (make-mailman)) and then ((ob 'add-to-route) box1 box2 ... boxn) etc. So add-to-route procedure must be defined this way:

(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))

对吧?与字母相同:

  (define (collect-letters . letters)
    (let ((mailbag (assoc 'MAILBAG self)))
      .....
      'DONE))

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

Now we can deal with the missing part, distribute-the-letters:

  (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 消息.

We assume that both letter and mailbox objects support the message type 'get-address to which they both return the same comparable address type of object, and that mailbox objects support 'put-letter message.

这篇关于MIT Scheme 消息传递抽象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆