lisp clojure let function

lisp - let vs def in clojure



function (6)

Quiero hacer una instancia local de una clase de Scanner Java en un programa clojure. Por qué esto no funciona:

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

pero me permitirá crear una instancia global como esta:

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

Tenía la impresión de que la única diferencia era el alcance, pero aparentemente no. ¿Cuál es la diferencia entre let y def ?


Corregir la sintaxis

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


El problema es que tu uso de let es incorrecto.

Deja que funcione así:

(let [identifier (expr)])

Entonces tu ejemplo debería ser algo como esto:

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

Solo puede usar los enlaces léxicos hechos con let en el ámbito de let (los parens de apertura y cierre). Solo crea un conjunto de enlaces léxicos. Utilizo def para hacer un enlace global y permite ligar algo que quiero solo en el alcance del let, ya que mantiene las cosas limpias. Ambos tienen sus usos.

NOTA: (Clase) es lo mismo que (Clase nueva), es solo azúcar sintáctico.


LET no es "hacer un enlace léxico en el ámbito actual", sino "crear un nuevo ámbito léxico con los siguientes enlaces".

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

(def s (foo whatever)) ;; s is bound here


La sintaxis para ellos es diferente, incluso si los significados están relacionados.

let toma una lista de enlaces (pares de nombre y valor) seguidos de expresiones para evaluar en el contexto de esos enlaces.

def simplemente toma un enlace, no una lista, y lo agrega al contexto global.


Se podría pensar en let como azúcar sintáctico para crear un nuevo alcance léxico con fn luego aplicarlo inmediatamente:

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

Entonces podrías implementar let con un simple macro y 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


Simplificado: def es para constantes globales, let es para variables locales.