# Addressing skill intersection issue and realizing Julia full potential

**URL:** <https://discourse.julialang.org/t/addressing-skill-intersection-issue-and-realizing-julia-full-potential/105739>\
**Category:** Community\
**Created:** [November 3, 2023, 4:46am UTC](https://discourse.julialang.org/t/addressing-skill-intersection-issue-and-realizing-julia-full-potential/105739 "2023-11-03T04:46:11Z")\
**Posts on this page:** 1\
**Showing post:** 6

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [November 3, 2023, 10:41am UTC](https://discourse.julialang.org/t/addressing-skill-intersection-issue-and-realizing-julia-full-potential/105739/6 "2023-11-03T10:41:22Z")

</div>

> [@Tarny\_GG\_Channie](#):
>
> to make X by composing A with B and then with C, you need to understand A,B, and C

I think that’s exactly the promise of Julia, you can compose and it just works? [There’s at least one exception, if you use `OffsetArray`s incorrecly, but then don’t do that, or if enable bounds-checking, and you will know, I think in all cases.]

> [@Tarny\_GG\_Channie](#):
>
> Let’s make an example. To make a source-to-source AD for common uses, you need to know linear algebra (because that’s a common use case), LLVM, loop optimization, perhaps SIMD, cache, maybe GPU, etc.

A.  
Let’s first take “realizing Julia’s full potential” to mean full speed, i.e. full runtime performance, and even tiny binaries.

One way would be to code in C style, type all your code, functions and structs with _concrete_ types (it’s not hard to avoid non-concrete, abstract. types).

This will result in no (possible) type instabilities, and then I believe thus no invalidations either.

This will result in the same speed as C, will not be idiomatic Julia code(?), though it has one loophole.

C doesn’t have GC, meaning its code is more complex, while sometimes (not always) faster). You can code in Julia without relying on the GC, use Libc.malloc and free, and then the languages are very comparable, and you could compile to tiny fast binaries with StaticCompiler.jl. It seems unfair to me to complain about Julia for speed or being hard to support e.g. GPUs, that seems easier than in C or C++.

You don’t need to know anything about LLVM (it’s an implementation detail, and is actually skipped after compilation for those small binaries).

To get full speed CPUs are just very complex (in any language), the compiler takes care of a lot for you, e.g. loop unrolling, and SIMD, though it can be manually tuned.

Potentially Julia should be taught this way? Some argue C or assembly should be taught first to learn the low-level details that really help you as a programmer. I think it’s a mistake to teach that way first, but you could do that even with Julia.

There is one other loophole here, C has globals and they are fast, but only if const in Julia:

> [@Would you want the REPL to warn against performance traps, at least non-const globals?](https://discourse.julialang.org/t/would-you-want-the-repl-to-warn-against-performance-traps-at-least-non-const-globals/105719):
>
> [https://www.reddit.com/r/Julia/comments/17m7knl/same\_code\_in\_julia\_takes\_6\_minutes\_vs\_15\_seconds/](https://www.reddit.com/r/Julia/comments/17m7knl/same_code_in_julia_takes_6_minutes_vs_15_seconds/) const s = 6; const L = sqrt(11); r(z) = 1 ./sqrt.(s^2 - (L-z).^2) That’s part of larger code that was 24x slower than needed, or even more. I believe it was (before changing at reddit, the only needed change?): s = 6; L = sqrt(11); before, and even a simple demo of the problem would be: r(a) = a + L @code\_native r(1) # the compiler obviously knows of this global problem. I would want whe…

B.  
What Julia is trying to do is cater to the Python and MATLAB crowd, work as other dynamic languages.

But Julia is less dynamic for speed-reasons, than e.g. Python, e.g. has potential of overflow of integer types. Those are defaults, Julia can be made as dynamic, and prevent overflows, or use `BigInt`s as new defaults. Could also be less strict regarding arrays, similar to Matlab, it’s just thought to be bad engineering.

> [@jakobnissen](#):
>
> On the other hand, we have
> 
> 1. Skills that are specifically required for Julia, and which we believe COULD be made obsolete by better design of Julia and its ecosystem. These include:
> 
> - How unreasonably hard it is to detect and amend code cache invalidations

It’s instructive to think about what needs to happen to get rid of invalidations. It’s entirely possible to do without them, as in A. It’s just that in Python where you don’t have them you don’t try as hard to compile and be generic. In C you can’t be generic (or could not, it has since added some features for, I think rarely used, Go has also added generic feature, less powerful than Julia’s).

Why do invalidations happen at all? Julia is recompiling for some reason (and while it’s an annoyance, it just works, though with annoyingly long “startup”); a type changed I think (but why?). _Even with the changes now needing recompilation, the recompilation is in theory avoidable, it’s just because of a performance-obsessed compiler, it could opt into less inlining and no recompilation._ When you program in Python you use fast C code with, and Python doesn’t have this problem since the C code is precompiled. But the limitation, is that then the binary code for that C code is static, it basically can’t be recompiled (Julia could limit itself in the same way, and even still support generic code). Since the precompiled code from C is static it also means, it can’t be generic, that code, i.e. it only works for some types, usually machine floats and machine integers, and strings, no alternative floats or integers. It also breaks the illusion that Python will not overflow your integers, _Python_ doesn’t, but when used with NumPy, NumPy does it for it.

For Julia to stay generic (a good thing) it needs NOT have compiler at runtime. It just needs to inline less. It means not quite as fast code at runtime. Some features in Julia, like eval, require either a compiler or an interpreter (Julia has both).

> [@jakobnissen](#):
>
> - How hard it is to track down and eliminate all allocations from Julia code

The compiler knows exactly where and when it’s (heap) allocating (or e.g. using a non-const global). It could show you with a WARNING when you define the function (if it knows, but it CAN’T know for all types, e.g. those not yet defined). I’m not sure we should be too concerned. Heap (and stack) allocations are very natural in a program. It’s just in some extreme cases we want to avoid or eliminate completely. They are however often a symptom of other problems, that go away if you address the allocations. Very possibly one code-path allocates, and another doesn’t. Which is not a problem, the compiler sees the whole picture. What’s more problematic is that you can call code that allocates, and also if your code is generic, then some code path may only allocate for some type, e.g. none of the default types, or what you have tested with. There’s probably no way around this except go with A. and no generic.

---

_[View the full topic](https://discourse.julialang.org/t/addressing-skill-intersection-issue-and-realizing-julia-full-potential/105739)._
