let vs def in clojure

后端 未结 6 1763
日久生厌
日久生厌 2020-12-15 03:07

I want to make a local instance of a Java Scanner class in a clojure program. Why does this not work:

; gives me:  count not supported on this          


        
相关标签:
6条回答
  • 2020-12-15 03:24

    LET is not "make a lexical binding in the current scope", but "make a new lexical scope with the following bindings".

    (let [s (foo whatever)]
      ;; s is bound here
      )
    ;; but not here
    
    (def s (foo whatever))
    ;; s is bound here
    
    0 讨论(0)
  • 2020-12-15 03:27

    You could think of let as syntactic sugar for creating a new lexical scope with fn then applying it immediately:

    (let [a 3 b 7] (* a b))  ; 21
    ; vs.
    ((fn [a b] (* a b)) 3 7) ; 21
    

    So you could implement let with a simple macro and fn:

    (defmacro fnlet [bindings & body]
      ((fn [pairs]
        `((fn [~@(map first pairs)] ~@body) ~@(map last pairs)))
       (partition 2 bindings)))
    
    (fnlet [a 3 b 7] (* a b)) ; 21
    
    0 讨论(0)
  • 2020-12-15 03:28

    Correct syntax:

    (let [s (Scanner. "a b c")] ...)
    
    0 讨论(0)
  • 2020-12-15 03:29

    Simplified: def is for global constants, let is for local variables.

    0 讨论(0)
  • 2020-12-15 03:40

    The problem is that your use of let is wrong.

    Let works like this:

    (let [identifier (expr)])
    

    So your example should be something like this:

    (let [s (Scanner. "a b c")]
      (exprs))
    

    You can only use the lexical bindings made with let within the scope of let (the opening and closing parens). Let just creates a set of lexical bindings. I use def for making a global binding and lets for binding something I want only in the scope of the let as it keeps things clean. They both have their uses.

    NOTE: (Class.) is the same as (new Class), it's just syntactic sugar.

    0 讨论(0)
  • 2020-12-15 03:44

    The syntax for them is different, even if the meanings are related.

    let takes a list of bindings (name value pairs) followed by expressions to evaluate in the context of those binding.

    def just takes one binding, not a list, and adds it to the global context.

    0 讨论(0)
提交回复
热议问题