0

In the book page 258, the authors implement make-serializer like this:

(define (make-serializer)
  (let ((mutex (make-mutex)))
    (lambda (p)
      (define (serialized-p . args)
        (mutex 'acquire)
        (let ((val (apply p args)))
          (mutex 'release)
          val))
      serialized-p)))

In the book, there is a segment

Given a procedure p, the serializer returns a procedure that acquires the mutex, runs p, and then releases the mutex.

I have a question: why is val after release? I think val should be in the front of mutex 'release. Am I right?

  • You can find the code in http://inst.eecs.berkeley.edu/~cs61a/sp09/library/serial.scm – Walter Zhao Apr 06 '15 at 08:21
  • the *calculation* of value of `val` is already before the mutex release - it's in the lambda form's variable definition subform, the one for `val`, `((val (apply p args)))`. as soon as the value is calculated, mutex is released; then the saved value is returned. the point is to protect the _calculation_ of the value. – Will Ness Apr 09 '15 at 19:42

1 Answers1

1

The bodies of let, define, lambda and some other forms have implicit begins around their bodies. So that one doesn't need to write the begin except when you need one that isn't in a location that is the direct child of one of those forms. For instance that code with begins inserted looks like this:

(define (make-serializer)
  (begin
    (let ((mutex (make-mutex)))
      (begin
        (lambda (p)
          (begin
            (define (serialized-p . args)
              (begin
                (mutex 'acquire)
                (let ((val (apply p args)))
                  (begin
                    (mutex 'release)
                    val))))
            serialized-p))))))

The value of a begin form is the value of its last argument. If

(begin
  (mutex 'release)
  val)

Was

(begin
  val
  (mutex 'release))

Its value would be the value of (mutex 'release) rather than val. That is why val is after (mutex 'release).

Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • Thank you! But we are not talking about the same thing.I mean as the sequence of " 1、acquires the mutex-------2、runs p-------3、releases the mutex". But what I get from the code in the book is "1、mutex 'acquire-------2、mutex 'release--------3、val",which means thesequence of "1、acquires the mutex-------2、releases the mutex-------3、runs p".They are not in the same sequence. – Walter Zhao Apr 06 '15 at 15:51
  • @WalterZhao The steps are [1] acquire mutex [2] calculate `val` [3] release mutex [4] "return" `val`. Because `val` is lexically scoped within `serialized-p`, nothing can happen to it after [3] and before [4]. – ben rudgers Apr 09 '15 at 02:35
  • @ben rudgers. You mean when val is associated with the expression " apply p args ",the p process is calculated.So val is just the value of the expression,and at last "val" just return a value rather than execute p. I get it! Thank you very much – Walter Zhao Apr 09 '15 at 04:50
  • @WalterZhao Yes. As you know, *acquiring* the mutex means that other parts of the concurrent system are blocked until it is released. Therefore, the mutex should be *released* as soon as possible. – ben rudgers Apr 09 '15 at 13:11