Question

Je souhaite créer une instance locale d'une classe Java Scanner dans un programme clojure. Pourquoi cela ne fonctionne-t-il pas:

; gives me:  count not supported on this type: Symbol 
(let s (new Scanner "a b c"))

mais cela me permettra de créer une instance globale comme celle-ci:

(def s (new Scanner "a b c"))

J'avais l'impression que la seule différence était la portée, mais apparemment pas. Quelle est la différence entre let et def ?

Était-ce utile?

La solution

Le problème est que votre utilisation de let est incorrecte.

Laissé fonctionne comme ceci:

(let [identifier (expr)])

Votre exemple devrait donc ressembler à ceci:

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

Vous ne pouvez utiliser que les liaisons lexicales faites avec let dans le cadre de let (parent et ouvrant). Laissons simplement créer un ensemble de liaisons lexicales. J'utilise def pour créer une liaison globale et permet de lier quelque chose que je veux uniquement dans le cadre de la let, car cela permet de garder les choses propres. Ils ont tous deux leur utilité.

NOTE: (Classe.) est identique à (nouvelle classe), c'est juste du sucre syntaxique.

Autres conseils

LET n’est pas "créer une liaison lexicale dans la portée actuelle", mais "créer une nouvelle portée lexicale avec les liaisons suivantes".

(let [s (foo whatever)]
  ;; s is bound here
  )
;; but not here
(def s (foo whatever))
;; s is bound here

Corrigez la syntaxe:

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

Simplifié: def concerne les constantes globales, let concerne les variables locales.

La syntaxe pour eux est différente, même si les significations sont liées.

let prend une liste de liaisons (paires nom-valeur) suivies d'expressions à évaluer dans le contexte de celles-ci.

def prend juste une liaison, pas une liste, et l'ajoute au contexte global.

Vous pourriez penser à laisser comme un sucre syntaxique pour créer une nouvelle portée lexicale avec fn puis l'appliquer immédiatement:

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

Vous pouvez donc implémenter laisser avec une simple macro et 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top