2011-01-06 11 views
6

Acabo de revisar varios documentos sobre concurrencia de Clojure y encontré el ejemplo en el sitio web (http://clojure.org/concurrent_programming).Comprender el ejemplo de simultaneidad de Clojure

(import '(java.util.concurrent Executors)) 
(defn test-stm [nitems nthreads niters] 
(let [refs (map ref (replicate nitems 0)) 
     pool (Executors/newFixedThreadPool nthreads) 
     tasks (map (fn [t] 
        (fn [] 
        (dotimes [n niters] 
         (dosync 
         (doseq [r refs] 
          (alter r + 1 t)))))) 
       (range nthreads))] 
(doseq [future (.invokeAll pool tasks)] 
    (.get future)) 
(.shutdown pool) 
(map deref refs))) 

entiendo lo que hace y cómo funciona, pero yo no entiendo por qué [] es necesaria la segunda función fn anónima?

Muchas gracias,

dusha.

P.S. Sin este segundo fn [] obtengo NullPointerException.

Respuesta

5

Aquí es un ejemplo clásico del uso de funciones de orden superior:

;; a function returns another function 
(defn make-multiplyer [times] 
    (fn [x] 
    (* x times))) 

;; now we bind returned function to a symbol to use it later 
(def multiply-by-two (make-multiplyer 2)) 

;; let's use it 
(multiply-by-two 100) ; => 200 

En este ejemplo de código dentro fn fn funciona de la misma manera. Cuando el mapa invoca (fn [t] (fn [] ...)) obtiene inner fn.

(def list-of-funcs (map (fn [t] 
          (fn [] (* t 10))) ; main part 
         (range 5))) 
;; Nearly same as 
;; (def list-of-funcs (list (fn [] (* 0 10)) 
;;       (fn [] (* 1 10)) 
;;       ... 
;;       (fn [] (* 4 10)))) 


(for [i list-of-funcs] 
    (i)) 
; => (0 10 20 30 40) 

Actualización: Y como dijo Alex tareas en el ejemplo de código se une a la lista de callables que se pasan después a .invokeAll().

2

El primer fn es lo que el mapa usa para crear un seq de fn, uno para cada uno de los hilos. ¡Esto se debe a que las tareas son un conjunto de funciones! El método .invokeAll() está a la espera de una colección callables (funciones Clojure implementan la interfaz invocable)

de Clojure.org: Special Forms

FNS implementar las interfaces de Java que se puede llamar, Ejecutables y Comparator.

Cuestiones relacionadas