Variable binding: (re-) assignment, argument passing, `let`, scope

To add on to this, Julia doesn’t really show this distinction to someone using the language since it’s compiled JIT (just-in-time, or right before execution). Other languages like C show a much cleaner separation of the two, since a) there’s more than one way to compile a given file containing C source code to a runnable executable (meaning, there are multiple independent compilers for C) and b) since running the actual binary requires another step beside compilation, namely the actual call to some system provided function that’s bootstrapping execution. As far as I know, the second step doesn’t exist in Julia, because of the JIT compilation.

To stay with the example of C, both gcc and clang (the two most popular compilers for C, as far as I know) both support and actively do constant propagation and the like, but this is nothing codified into the C language specification - it’s more of an optimisation that’s not forbidden by the spec which is done to reduce execution time and (more or less minutely) increase compilation time. Julia also does this, but because the first call to a function is needed as “hey, compile and then run this”, it of course includes compilation time and after that also the execution time. Subsequent calls don’t need to be compiled again, so those calls don’t include compilation time, just the execution time. That’s also why it’s wrong to include compilation when talking about execution - it simply in general is not relevant at the time of execution what happens during compilation.

EDIT:
There is of course also precompilation of modules in julia and there are ongoing efforts to save precompiled functions and modules as a binary object to reduce function call overhead on the first call, but those efforts are largely in their infancy as far as I can tell and also don’t really change the overall point here, rather they support it.

4 Likes