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.