Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is `let` implemented in Clojure and what is its overhead?

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.

like image 765
ffriend Avatar asked May 16 '12 02:05

ffriend


People also ask

What is let in Clojure?

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.

Why is Clojure called Clojure?

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.


2 Answers

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.

like image 126
mikera Avatar answered Sep 30 '22 12:09

mikera


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.

like image 37
amalloy Avatar answered Sep 30 '22 12:09

amalloy