Пусть против 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 принимает список привязок (пар имя-значение), за которыми следуют выражения для оценки в контексте этих привязок.
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