MIT Scheme Message Passing Abstraction

前端 未结 2 459
不知归路
不知归路 2021-01-23 23:07

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,

2条回答
  •  逝去的感伤
    2021-01-24 00:10

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

    The dispatch bit is almost OK:

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

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

    Right? Same with the letters:

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

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

    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.

提交回复
热议问题