When and How to use Types

Interpolations.jl is written the way it is such that you can obtain a specialized type that takes advantage of multiple dispatch for subsequent operations.

In terms of type stability, you want to get a consistent output type for a set of input types. Sometimes this means encoding some values as types. For a quick way to do so, see Val.

I suggest that you use tools like @code_warntype, @code_lowered, @code_llvm, and @code_native to explore what the compiler is doing.

Let’s take a simple example:

julia> f(x) = 5 + 5
f (generic function with 1 method)

julia> @code_lowered f(1)
CodeInfo(
1 ─ %1 = 5 + 5
└──      return %1
)

julia> @code_llvm f(1)

;  @ REPL[125]:1 within `f'
; Function Attrs: uwtable
define i64 @julia_f_3722(i64) #0 {
top:
  ret i64 10
}

julia> @code_native f(1)
        .text
; ┌ @ REPL[125]:1 within `f'
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $10, %eax
        popq    %rbp
        retq
        nopl    (%rax,%rax)
; └

Above we see that LLVM has figured out that it can precompute 5 + 5 and the assembly shows that the function just returns 10. It does not add 5 + 5 every time.

! is used for negation. The only unary operators are listed here:
https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm#L99-L100

2 Likes