Domanda

Voglio creare un'istanza locale di una classe Scanner Java in un programma clojure. Perché questo non funziona:

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

ma mi permetterà di creare un'istanza globale come questa:

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

Avevo l'impressione che l'unica differenza fosse la portata, ma apparentemente no. Qual è la differenza tra let e def ?

È stato utile?

Soluzione

Il problema è che l'uso di let è sbagliato.

Lascia che funzioni in questo modo:

(let [identifier (expr)])

Quindi il tuo esempio dovrebbe essere qualcosa del genere:

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

Puoi usare solo le associazioni lessicali fatte con let nell'ambito di let (le parentesi aperta e chiusa). Lascia solo creare una serie di vincoli lessicali. Uso def per creare un'associazione globale e consente di rilegare qualcosa che voglio solo nell'ambito di let in quanto mantiene le cose pulite. Entrambi hanno i loro usi.

NOTA: (Class.) è uguale a (new Class), è solo zucchero sintattico.

Altri suggerimenti

LET non è "crea un legame lessicale nell'ambito corrente", ma "crea un nuovo ambito lessicale con i seguenti collegamenti".

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

Sintassi corretta:

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

Semplificato: def è per le costanti globali, let è per le variabili locali.

La sintassi per loro è diversa, anche se i significati sono correlati.

let accetta un elenco di associazioni (coppie valore-valore) seguite da espressioni da valutare nel contesto di tali associazioni.

def accetta solo un binding, non un elenco, e lo aggiunge al contesto globale.

Potresti pensare a let come zucchero sintattico per creare un nuovo ambito lessicale con fn e applicarlo immediatamente:

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

Quindi puoi implementare let con una semplice macro e 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top