This is my “map” for Julia features:
1. Multiple dispatch
- we can extend methods after code loading or object construction
- simplifies code, e.g. promotion rules: Conversion and Promotion · The Julia Language
2. Dynamic dispatch
Multiple and dynamic dispatch complement each other, but they are quite different things. Dynamic dispatch leads to choosing the right method at runtime, so we can implement predicate dispatch or combine code with abstract (non-inferred) and concrete (inferred) types. It is based on type inference, method specialization, method call inlining:
- https://dl.acm.org/doi/pdf/10.1145/3276490
- https://julialang.org/assets/blog/julia-dynamic-2012-tr.pdf
3. Staged compiler
Combination of interpreter and static compiler that use type information to update compiled code.
- At any point in code we can parse additional code (or data schema) that will be compiled in runtime and continue execution.
- Traits - we can define compile-time functions on types that emulate multiple inheritance. The Emergent Features of JuliaLang: Part II - Traits · Invenia Blog
- Metaprogramming: Generated functions - we can use type information at parse time and generate specialized code Abstraction in technical computing pages 78-79
- Metaprogramming: interpreter tweaks - thing which you never can do with compiled third-party libraries (you can just use their API as is, not change their behaviour). We can change how third-party code, attach some hooks with additional code: https://youtu.be/lyX-isPDS2M , GitHub - oxinabox/AutoPreallocation.jl: What if your code allocated less? Remember what memory we needed last time and use it again every time after etc.
- We can leverage compiler complexity and solve problems just adding new syntax or macros that solves our problem before compiler stage, e.g. Loop fusion: More Dots: Syntactic Loop Fusion in Julia
4. Composability
I would mention a bunch of interesting solutions in platform and package manager like:
- Persistent binary artifact storage + Yggdrasil + build system for any platform combinations: Home · BinaryBuilder.jl
- Clang.jl - automatic C wrapper code generation (used in BinaryBuilder) that helps for many third-party libraries to just work
- RecipesBase Overview · Plots
- Package extensions
- Another interesting solutions to switch backends in runtime: https://www.youtube.com/watch?v=t6hptekOR7s
- Shell wrapper Shelling Out Sucks , Put This In Your Pipe
5. Rich and simple interfaces
Small amount of required methods and a plenty of optional with default behaviour for:
- collections: AbstractArrays, Iterators, Indexing
- Tables
- FileIO
- TranscodingStreams
- composable logging system: GitHub - JuliaLogging/LoggingExtras.jl: Composable Loggers for the Julia Logging StdLib
6. Code generation and DSL
- simple DSL for commang arguments: GitHub - carlobaldassi/ArgParse.jl: Package for parsing command-line arguments to Julia programs.
- code generators between data representations
- AOS / SOA: Overview · StructArrays
- deserialization interfaces with lowered types: Home · StructTypes.jl
- compile-time programming for small portions of code: GitHub - AlgebraicJulia/CompTime.jl: Library for compile-time computing in julia
But there are some difficulties for newcomers as well:
- Method invalidations: dynamic code loading conflicts with method inlining Analyzing sources of compiler latency in Julia: method invalidations
- Types redefinition problem: constant types conflicts with interactive code changes
- And some others, see my earlier comment here:
What steps should the Julia community take to bring Julia to the next level of popularity? - #283 by sairus7