Pergunta

Eu quero fazer uma instância local de uma classe Scanner Java em um programa Clojure. Por que isso não funciona:

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

mas me permite criar uma instância global como este:

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

Eu estava sob a impressão de que a única diferença era escopo, mas aparentemente não. Qual é a diferença entre let e def?

Foi útil?

Solução

O problema é que o uso do let está errado.

Let funciona assim:

(let [identifier (expr)])

Portanto, o seu exemplo deve ser algo como isto:

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

Você só pode usar as ligações lexicais feitas com let no âmbito da let (a abertura e parênteses de fechamento). Vamos apenas cria um conjunto de ligações lexicais. Eu uso def para fazer uma ligação global e permite a ligação de algo que eu quero apenas no âmbito do let como ele mantém as coisas limpas. Ambos têm seus usos.

NOTA: (Class.) É o mesmo que (nova Classe), é apenas açúcar sintático

.

Outras dicas

LET não é "fazer uma ligação de lexical no escopo atual", mas "fazer um novo escopo lexical com as seguintes ligações".

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

sintaxe correta:

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

simplificado:. def é para constantes globais, deixe é para variáveis ??locais

A sintaxe para eles é diferente, mesmo se os significados estão relacionados.

let leva um lista de ligações (valor pares nome) seguido por expressões para avaliar no contexto daqueles vinculativo.

def só tem uma ligação, não uma lista, e adiciona-lo para o contexto global.

Você poderia pensar em let como açúcar sintático para a criação de um novo escopo lexical com fn em seguida, aplicá-lo imediatamente:

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

Assim, você poderá implementar let com uma macro simples 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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top