Clojure closure

前端 未结 4 445
迷失自我
迷失自我 2021-01-31 19:43

the other day I was trying to come up with an example of closure in Clojure. I came up with and example I had seen before and thought it was appropriate.

Alas, I was tol

相关标签:
4条回答
  • 2021-01-31 20:17

    A closure is a function that has access to some named value/variable outside its own scope, so from a higher scope surrounding the function when it was created (this excludes function arguments and local named values created within the function). Your examples do not qualify, because every function just uses named values from their own scopes.

    Example:

    (def foo 
      (let [counter (atom 0)]
        (fn [] (do (swap! counter inc) @counter))))
    
    (foo) ;;=> 1
    (foo) ;;=> 2
    (foo) ;;=> 3, etc
    

    Now foo is a function that returns the value of an atom that is outside its scope. Because the function still holds a reference to that atom, the atom will not be garbage-collected as long as foo is needed.

    0 讨论(0)
  • 2021-01-31 20:24

    I wanted to have something that setup constant value(s) that are to be used each time.

    (def myran 
      (let [constrand (rand)]
        (fn [n] (* n constrand))))
    
    
    (myran 3)
    2.7124521745892096
    (myran 1)
    0.9041507248630699
    (myran 3)
    2.7124521745892096
    

    This will only set a value for "constrand" once. This is a very contrived example, but I wanted to be able to do something like:

    JavaScript: The Good Parts

    This is from: JavaScript: The Good Parts

    0 讨论(0)
  • 2021-01-31 20:29

    Function that returns function i.e higher order functions are nice examples of closure.

    (defn pow [n]
       (fn [x] (apply * (repeat n x))))
    
    (def sq (pow 2))
    (def qb (pow 3))
    
    0 讨论(0)
  • 2021-01-31 20:37

    Another example of closure. There are two functions that share the same environment (state).

    (defn create-object [init-state]
      (let [state (atom init-state)]
        {:getter (fn []
                   @state)
         :setter (fn [new-val]
                   (reset! state new-val))}))
    
    (defn test-it []
      (let [{:keys [setter getter]} (create-object :init-value)]
        (println (getter))
        (setter :new-value)
        (println (getter))))
    
    (test-it)
    => :init-value
       :new-value
    
    0 讨论(0)
提交回复
热议问题