Why typeof is built-in?

One could define typeof(x::T) where T = T. So why is it built-in instead of coded in Julia?

You really don’t want it to be overloadable, because then people might try that. For that purpose a builtin is just fine. Not to mention that the compiler can generate efficient code for typeof even when it doesn’t know the type of the variable while your proposed definition would fall back to a dynamic dispatch (that then internally calls jl_typeof in C). That’s all optimizable of course, but there’s just no benefit to making it a generic function.

4 Likes

Recently I had a similar issue with ifelse. What is the benefit of it being built-in? Is it because then the compiler can avoid branching and if it were overloadable it would not be possible?

No, ifelse is horrible and will go away.

4 Likes

Thanks! Good to know, because this is what I thought it should be, but low level stuff is often tricky.

Can you eliminate it before Julia 2.0?

Sure, just define ifelse(b, x, y) = b ? x : y.

2 Likes

For introductory users, the ternary operator is pretty tough for them to mentally parse… So I hope that this sort of definition stays around in one form or another (for when short circuiting isn’t needed, and clarity is at a premium)

Honestly I think condition ? value : othervalue is very clear.

1 Like

Why is it horrible?

1 Like

Ah you mean no longer making it a builtin.

Primarily because type inference/optimizations can’t use the conditional to reason about the arguments (e.g. type inference may know that the condition implies something about the types of the arguments, but since the arguments are evaluated first it can’t use that to optimize without turning ifelse back into ?:).

I thought that the purpose of ifelse was to reap performance benefits by avoiding branching, and that for example vectorization was prevented by branching. Is that no longer relevant?

2 Likes

The hardest thing for the vectorizer about branches is to proof that both branches are free of side effects. The branch itself isn’t an issue (at least on latest llvm). So a eagerly evaluating branch is still somewhat useful but it can just be implemented as a branch and an intrinsic isn’t useful.

2 Likes