I can see 2 ways of implementing let
bindings. First, as known from SICP, let
may be implemented as lambda function. This is convenient and simple, but taking into account the fact that each lambda (fn
) is translated into separate class in JVM and the number of times let
is used in average program, this seems very, very expensive.
Second, let
bindings may be translated directly into local Java variables. This gives very little overhead, but storing bindings on a stack breaks language semantics: in this case creation of closures is just impossible - saved values will be destroyed just after stack unwinding.
So what is actual implementation used in Clojure? Pointing to corresponding lines in Clojure source is appreciated.
Clojure let is used to define new variables in a local scope. These local variables give names to values. In Clojure, they cannot be re-assigned, so we call them immutable.
The name was chosen to be unique. I wanted to involve c (c#), l (lisp) and j (java). Once I came up with Clojure, given the pun on closure, the available domains and vast emptiness of the googlespace, it was an easy decision.
let
-bound variables are stored as final local values on the stack.
Since they are final, they can be bound into closures if needed (this is analogous how you can use a final local variable in an anonymous inner class in Java). Under the hood, the JVM copies the value into the object that represents the closure (where it is stored as a final field). As a result, the closure still works even after the stack frame goes away.
Overall, let-bound variables are extremely low overhead, you should have no hesitation at all from using them from a performance perspective. It probably isn't possible to do any better on the JVM.
Local variables are pointers, allocated on the stack, pointing to values/objects on the heap. The pointer goes out of scope, but the object remains alive as long as the closure retains a pointer to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With