# Pre-runtime

**URL:** https://discourse.julialang.org/t/pre-runtime/42622
**Category:** New to Julia
**Created:** [July 6, 2020, 4:54pm UTC](https://discourse.julialang.org/t/pre-runtime/42622 "2020-07-06T16:54:22Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)
#### Post date: [July 6, 2020, 4:54pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/1 "2020-07-06T16:54:22Z")

</div>

Since Julia blurs the line between _compile time_ and _runtime_, shouldn’t we talk about _pre-runtime_ and runtime instead?  
For instance, can Julia catch type errors at pre-runtime?  
I hate when my Python code crashes for stupid shape-related mistakes that would’ve been caught at pre-runtime in languages such as Scala and Haskell.  
AFAICT, Julia leverages types to generate fast code and not so much to catch as many mistakes as possible at pre-runtime.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [July 6, 2020, 5:02pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/2 "2020-07-06T17:02:15Z")

</div>

> [@Kiuhnm\_Mnhuik](#):
>
> Since Julia blurs the line between _compile time_ and _runtime_ , shouldn’t we talk about _pre-runtime_ and runtime instead?

It might be blurry, but if you squint your eyes, you will see that there are two distrinct lines though. 🙂

> [@Kiuhnm\_Mnhuik](#):
>
> For instance, can Julia catch type errors at pre-runtime?

Not really when “normally programming” Julia. You could implement type of type checker yourself but in general in Julia, the exception will be thrown at runtime.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [July 7, 2020, 5:46am UTC](https://discourse.julialang.org/t/pre-runtime/42622/3 "2020-07-07T05:46:55Z")

</div>

> [@Kiuhnm\_Mnhuik](#):
>
> shouldn’t we talk about _pre-runtime_ and runtime instead?

There is already a term for the compilation pass: ahead of time (AOT). See

[![](https://global.discourse-cdn.com/julialang/original/3X/9/c/9c7dcad2631cec7ff3a22f67682c60b013a07c63.jpeg "JuliaCon 2017 | AoT or JIT: How Does Julia Work? | Jameson Nash") ](https://www.youtube.com/watch?v=7KGZ_9D_DbI)

> [@Kiuhnm\_Mnhuik](#):
>
> For instance, can Julia catch type errors at pre-runtime?

It is tricky to define what this means in the context of Julia. Eg

```julia
struct Foo end
f(a::Foo, b::Foo) = a + b

```

may error because the programmer hasn’t defined an applicable method for `+`. But if that is done before `f` is run, then everything is fine.

---

<div class="post-metadata">

### Author: ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)
#### Post date: [July 7, 2020, 6:02pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/4 "2020-07-07T18:02:16Z")

</div>

> [@Tamas\_Papp](#):
>
> There is already a term for the compilation pass: ahead of time (AOT).

I’m not describing the type of compilation, but a period of time. _pre-runtime_ is the interval of time (the starting point doesn’t matter) which ends when the program starts running.

> [@Tamas\_Papp](#):
>
> It is tricky to define what this means in the context of Julia. Eg
> 
> ```julia
> struct Foo end
> f(a::Foo, b::Foo) = a + b
> 
> ```
> 
> may error because the programmer hasn’t defined an applicable method for `+` . But if that is done before `f` is run, then everything is fine.

I said _at pre-runtime_ so there’s nothing tricky. The answer is simply “No”.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [July 7, 2020, 6:35pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/5 "2020-07-07T18:35:24Z")

</div>

You are talking about quite a few different aspects.

> [@Kiuhnm\_Mnhuik](#):
>
> Since Julia blurs the line between _compile time_ and _runtime_ , shouldn’t we talk about _pre-runtime_ and runtime instead?

Julia does’t blur the line between _compile_ and _run_. It merely interleave the **time** they happen. Since it never changes what is done before the run, there’s no need to rename that phase.

> [@Kiuhnm\_Mnhuik](#):
>
> For instance, can Julia catch type errors at pre-runtime?

This is a completely orthogonal question to compilation. The compiler is basically always transparent to the program. A C interpreter will have just as many static type checks as a C static compiler or one of them would not be a conforming implementation of the language. Julia is, above all, a dynamically typed language and adding static type check to the luaguage is changing that and isn’t about how compiler interleave with runtime. In fact, in order to get a well defined type checking before runtime, you need a clearly defined phase before running where the error can be thrown. A blur line between compilation and running as you claimed is actually exactly the opposite of what you want.

* * *

Now julia could run user code runtime and actually before compilation, those are macros, generated functions and (new) customized optimization passes. Out of these, pretty much only macro is defined as a separate phase (since type inferece and optimization is not well defined/don’t have a stable API). And you can of course do whatever check you want in a macro, just not based on the type info, which requires a complete change of language to have it’s own phase.

---

<div class="post-metadata">

### Author: ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)
#### Post date: [July 7, 2020, 9:30pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/6 "2020-07-07T21:30:30Z")

</div>

Does Julia do some kind of static checking during JIT compilation?  
Are type errors in statements (expressions) caught only if those statements (expressions) are actually executed (evaluated)?  
I suspect the answers are Yes and No, respectively.  
Python (without optional typing) can’t catch type errors in statements (expression) that are not executed (evaluated).  
Static languages such as C and C++ are expected to catch all those errors during (AoT) compilation.

You claim I’m talking about orthogonal concepts, but I don’t agree with you. The way Julia runs and compiles code _does_ influence the set of errors caught at runtime, which means that while Julia compilation model doesn’t alter the semantics of type-correct code, it _does_ influence the semantics of code that contains mistakes.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [July 7, 2020, 9:44pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/7 "2020-07-07T21:44:19Z")

</div>

> [@Kiuhnm\_Mnhuik](#):
>
> Does Julia do some kind of static checking during JIT compilation?

Kind of.

> [@Kiuhnm\_Mnhuik](#):
>
> Are type errors in statements (expressions) caught only if those statements (expressions) are actually executed (evaluated)?

More or less yes.

> [@Kiuhnm\_Mnhuik](#):
>
> Python (without optional typing) can’t catch type errors in statements (expression) that are not executed (evaluated).

This is wrong. CPython may not have that implemented and it might not be worth doing, but a JIT can for sure catch type errors just like the “static checking during JIT compilation” in julia. (and this is why I said “kind of” for the first question). PyPy for sure does it. (as well as whatever JIT it was from dropbox…)

> [@Kiuhnm\_Mnhuik](#):
>
> Static languages such as C and C++ are expected to catch all those errors during (AoT) compilation.

And that’s because they have a well defined compilation phase before the runtime. Again, as I said, the blur line here due to the nature of a dynamically typed language works against throwing an error at compile time.

> [@Kiuhnm\_Mnhuik](#):
>
> The way Julia runs and compiles code _does_ influence the set of errors caught at runtime, which means that while Julia compilation model doesn’t alter the semantics of type-correct code, it _does_ influence the semantics of code that contains mistakes.

No it does not. If compilation or other ways of running the code changes what errors are thrown, that’s a very serious bug that should be reported. We certainly have had such bugs before and probably still now.

---

<div class="post-metadata">

### Author: ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)
#### Post date: [July 8, 2020, 5:24pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/8 "2020-07-08T17:24:05Z")

</div>

> [@yuyichao](#):
>
> This is wrong. CPython may not have that implemented and it might not be worth doing, but a JIT can for sure catch type errors just like the “static checking during JIT compilation” in julia.

I never said it can’t be implemented that way. I meant Python can’t catch those errors _right now_, and it’s a little late to change that since you’d be breaking previous code.  
Just consider a Python function with many execution paths, some of which become type correct only later. Such function would be virtually impossible to JIT compile as a whole and separating the good from the bad execution paths based on the calling code is undecidable, in general.  
[last edit: OK, maybe there’s no need to separate the paths: one just compiles as much as possible.]

> [@yuyichao](#):
>
> If compilation or other ways of running the code changes what errors are thrown, that’s a very serious bug that should be reported. We certainly have had such bugs before and probably still now.

I’m not saying that if there are 3 different ways of running Julia code then you should get different behaviors.

What I’m trying to say is that the **initial** compilation model chosen for a new language influences the sets of errors which are caught at pre-runtime and runtime.  
Although compilation model and type checking are technically orthogonal, in practice they’re not because, for instance, it’s _natural_ for an **initially** fully interpreted language to catch errors later (if at all) than a JIT compiled language.  
I use the terms pre-runtime and runtime because that’s, IMHO, the only useful distinction, at least for the user, when talking about releasing a product with as few mistakes as possible.  
To someone who has programmed both in static (e.g. C++) and dynamic (e.g. Python) languages, Julia will appear as a hybrid because some errors which would be caught in popular static languages won’t be caught, and errors which wouldn’t be caught in popular dynamic languages will be caught.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [July 8, 2020, 5:56pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/9 "2020-07-08T17:56:34Z")

</div>

> [@Kiuhnm\_Mnhuik](#):
>
> Just consider a Python function with many execution paths, some of which become type correct only later. Such function would be virtually impossible to JIT compile as a whole and separating the good from the bad execution paths based on the calling code is undecidable, in general.

This is also the case in julia. The compiler makes no difference anywhere.

> [@Kiuhnm\_Mnhuik](#):
>
> Although compilation model and type checking are technically orthogonal, in practice they’re not because, for instance, it’s _natural_ for an **initially** fully interpreted language to catch errors later (if at all) than a JIT compiled language.

Well, sure. But I’m saying that the property you are quoting (blur line between compilation and run/interleaving time between them) is an strong argument against type checking, rather than for it, as what you mentioned in the first post.

Also, it has well passed that stage. With or without a compiler, it is not really a reason for making a breaking change to the language anymore.

> [@Kiuhnm\_Mnhuik](#):
>
> I use the terms pre-runtime and runtime because that’s, IMHO, the only useful distinction, at least for the user, when talking about releasing a product with as few mistakes as possible.

Sure. I have no problem with the name `pre-runtime`. However, in julia, it’s **not** the only concept that matters for the user, there’s macro expansion which separate parse time and lower/compile time.

> [@Kiuhnm\_Mnhuik](#):
>
> errors which wouldn’t be caught in popular dynamic languages will be caught.

I don’t believe this is the case, not in any way that’s related to compilation. The type errors you get are basically from explicit type check/assertion, which exists in other dynamic language (and in fact doesn’t make as much sense in a statically typed language), or method error, which is indeed not really present in many other languages but it’s the result of multiple dispatch and not compilation.

---

<div class="post-metadata">

### Author: ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)
#### Post date: [July 9, 2020, 4:11pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/10 "2020-07-09T16:11:04Z")

</div>

I don’t understand how Julia can produce fast code and yet be as dynamic as Python. I thought Julia (JIT) compiled functions as a whole and did type inference to produce efficient code. Maybe when type inference is not possible (because of “temporary” or “permanent” errors) it falls back on less efficient code? And what happens when the type information is finally available? You said the code is compiled only once, so I guess the user should call a function for the first time, triggering the JIT compilation, only when enough type information is available, for maximum efficiency?  
In practice I’d split the function into two simpler functions, of course. I’m just trying to clarify a doubt.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [July 9, 2020, 4:26pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/11 "2020-07-09T16:26:54Z")

</div>

> [@Kiuhnm\_Mnhuik](#):
>
> I don’t understand how Julia can produce fast code and yet be as dynamic as Python.

It’s not as dynamic in general but it is about as dynamic in terms of variable type. We don’t have meta class, for example, don’t have dynamically changable fields (roughly equivalent to ` __slots__ ` in python), and we allow annotating field for their types, which are about types but not about variables. We also don’t have local scope eval, which kills pypy performance very badly at least as of a few years ago, and we have overflowing integer arithmatics just like python 2 but unlike python 3.

> [@Kiuhnm\_Mnhuik](#):
>
> I thought Julia (JIT) compiled functions as a whole and did type inference to produce efficient code

Yes but it uses runtime type (and inferred types based on the caller), which has little to do with any type annotations so it has little static about it.

> [@Kiuhnm\_Mnhuik](#):
>
> so I guess the user should call a function for the first time, triggering the JIT compilation, only when enough type information is available, for maximum efficiency?

That is correct. (Although there’s also `precompile` function that lets you feed the type info manually and without running the function).

---

<div class="post-metadata">

### Author: ![Kiuhnm\_Mnhuik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kiuhnm_mnhuik/32/7572_2.png) [@Kiuhnm\_Mnhuik](https://discourse.julialang.org/u/Kiuhnm_Mnhuik)
#### Post date: [July 9, 2020, 7:53pm UTC](https://discourse.julialang.org/t/pre-runtime/42622/12 "2020-07-09T19:53:41Z")

</div>

Thank you for clarifying my doubts. I’m looking forward to using Julia as soon as it gets a little more mature, especially as a differentiable programming language. Python and Pytorch are enough for what I’m doing right now and Jax (based on tracing) adds some flexibility, but Python will never be truly differentiable.
