Пусть против def в ближайшем будущем

Я хочу сделать локальный экземпляр Java Scanner класс в закрытой программе. Почему это не работает:

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

но это позволит мне создать глобальный экземпляр вроде этого:

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

У меня сложилось впечатление, что единственной разницей была сфера, но, видимо, нет. В чем разница между let а также def?

6 ответов

Решение

Проблема в том, что вы используете let неправильно.

Пусть работает так:

(let [identifier (expr)])

Итак, ваш пример должен выглядеть примерно так:

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

Вы можете использовать только лексические привязки, сделанные с помощью let, в области let (открывающая и закрывающая части). Пусть просто создает множество лексических привязок. Я использую def для создания глобальной привязки и let для привязки чего-то, что я хочу, только в области действия let, поскольку она поддерживает чистоту. У них обоих есть свое применение.

ПРИМЕЧАНИЕ. (Класс.) Такой же, как (новый класс), это просто синтаксический сахар.

LET - это не "сделать лексическую привязку в текущей области видимости", а "создать новую лексическую область видимости со следующими привязками".

(пусть [s (foo что угодно)];; s связан здесь);; но не здесь
(def S (Foo независимо));; s связан здесь

Упрощенно: def для глобальных констант, пусть для локальных переменных.

Правильный синтаксис:

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

Синтаксис для них различен, даже если значения связаны между собой.

let принимает список привязок (пар имя-значение), за которыми следуют выражения для оценки в контексте этих привязок.

def просто берет одну привязку, а не список, и добавляет ее в глобальный контекст.

Вы могли бы думать о let как синтаксический сахар для создания новой лексической области с fn затем примените это немедленно:

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

Чтобы вы могли реализовать let с простым макросом и 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
Другие вопросы по тегам