book [clojure programming] confuse

199 views
Skip to first unread message

Johnny Wong

unread,
Sep 8, 2015, 6:32:58 AM9/8/15
to Clojure
pdf version page 165:

"

Promises don’t detect cyclic dependencies

This means that (deliver p @p), where p is a promise, will block indefinitely.

However, such blocked promises are not locked down, and the situation can be resolved:


(def a (promise)) (def b (promise))

(future (deliver a @b))   ;-------1

(future (deliver b @a))   ;--------2

(realized? a) ;= false (realized? b) ;= false

(deliver a 42)                 ;--------3

;= #<core$promise$reify__5727@6156f1b0: 42> @a

;= 42 @b

;= 42


1----Futures are used there to not block the REPL.

2-----a and b are not delivered yet.


3-----Delivering a allows the blocked deliveries to resume—obviously (deliver a @b) is going to fail (to return nil) but (deliver b @a) proceeds happily.


"



why " deliver a @b is going to fail " ?  1 and 2  are just two independent threads , "deliver a 42" will unblock thread 2 , and then thread 1 will be unblocked .



pdf version page 165:


"

An immediately practical application of promises is in easily making callback-based APIs synchronous. Say you have a function that takes another function as a callback:


(defn call-service

[arg1 arg2 callback-fn]

; ...perform service call, eventually invoking callback-fn with results...

 (future (callback-fn (+ arg1 arg2) (- arg1 arg2))))


Using this function’s results in a synchronous body of code requires providing a call- back, and then using any number of different (relatively unpleasant) techniques to wait for the callback to be invoked with the results. Alternatively, you can write a simple wrapper on top of the asynchronous, callback-based API that uses a promise’s blocking behavior on deref to enforce the synchronous semantics for you. Assuming for the moment that all of the asynchronous functions you’re interested in take the callback as their last argument, this can be implemented as a general-purpose higher-order function:


(defn sync-fn [async-fn] (fn [& args]

(let [result (promise)]

(apply async-fn (conj (vec args) #(deliver result %&))) 

@result)))



((sync-fn call-service) 8 7) 

;= (15 1)

"


what is the pointer of function sync-fn ? what is the execution sequence of  functions such as sync-fn,call-servervice, and callback-fn ?      statement "((sync-fn call-service) 8 7) ", where is the callback-fn parameter ?




Moe Aboulkheir

unread,
Sep 8, 2015, 1:22:27 PM9/8/15
to clo...@googlegroups.com
Johnny,

On Tue, Sep 8, 2015 at 11:32 AM, Johnny Wong <zhanla...@gmail.com> wrote:

why " deliver a @b is going to fail " ?  1 and 2  are just two independent threads , "deliver a 42" will unblock thread 2 , and then thread 1 will be unblocked .

Thread 1 is waiting on delivering a result to "a", though, which has already happened with the outer (deliver a 42) - one result per promise.

what is the pointer of function sync-fn ? what is the execution sequence of  functions such as sync-fn,call-servervice, and callback-fn ?      statement "((sync-fn call-service) 8 7) ", where is the callback-fn parameter ?

After the apply, call-service ends up being invoked as (call-service 8 7 #(deliver result %&)) - the callback-fn is that final anonymous function which delivers the "result" promise a sequence of its arguments (%&).  sync-fn is geared towards multiple invocations - a named example may be very slightly clearer:

(def call-service-sync (sync-fn call-service))
(call-service-sync 8 7) ;; => (15 1)

The sequence is:
 - Invoke (sync-fn call-service), which returns a wrapper around call-service, using a callback-fn which is internal to the wrapper (consumers of sync-fn are trying to ignore callback-fn)
 - Invoke the returned function/wrapper with the arguments to the wrapped (call-service) function (8 7), minus callback-fn
 - The wrapper forwards these arguments to call-service, plus a callback-fn which delivers its arguments to a promise
 - The wrapper blocks on dereferencing the promise
 - The outermost caller receives the value delivered to the promise

Take care,
Moe

johnny wong

unread,
Sep 9, 2015, 11:15:57 PM9/9/15
to clo...@googlegroups.com
@Moe
        thanks for your explanation ,finally understand  the author’s point.

Best regards

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/C92OCoEXjCo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages