Scratchpad

Julia Programming

Writing Functions

Julia functions can be written as one-liners. For example, the core of the Mux.jl middleware library consists entirely of one-liners:

mux(f) = f
mux(m, f) = x -> m(f, x)
mux(ms...) = foldr(mux, ms)

stack(m) = m
stack(m, n) = (f, x) -> m(mux(n, f), x)
stack(ms...) = foldl(stack, ms)

branch(p, t) = (f, x) -> (p(x) ? t : f)(x)
branch(p, t...) = branch(p, mux(t...))

(Source)

For multi-line functions, I prefer using begin blocks rather than function blocks:

# Good: Function definition via assignment
trapezoid_rule(fn, a, b, n) = begin
    delta = (b - a) / n
    nodes = (a + delta * k for k in 0:n)
    weights = (delta * (k == 0 || k == n ? 0.5 : 1) for k in 0:n)
    sum(fn(node) * weight for (node, weight) in zip(nodes, weights))
end

# Less Good: Using the "function" keyword
function trapezoid_rule(fn, a, b, n)
    # insert code here
end

This is just a personal style preference, and an unusual one at that. My rationale is as follows:

  1. The function keyword is uneccesarrily large (fn or def would have been sufficed).
  2. Assignment expressions are how one-line functions are defined. So using them for multi-line functions adds some consistency.

Compilation

Julia is not an interpreted languages. Rather, functions are compiled directly into native machine code. Consider the following function:

f(x) = x * x

Calling the @code_native macro on an evaluation of this function will show the native code:

julia> @code_native f(3)
    .text
    imulq   %rdi, %rdi
    movq    %rdi, %rax
    retq
    nopl    (%rax,%rax)

(Comments removed. Your results might differ). Notice that the generated code differs based on the argument type(s):

julia> @code_native f(3.0)
    .text
    vmulsd  %xmm0, %xmm0, %xmm0
    retq
    nopw    %cs:(%rax,%rax)

LLVM is used as the compilation backend. Use the @code_native to see the LLVM bytecode generated by the compiler frontend.

Linux Files

A file is an interface for accessing system resources. Most familiarly, they can be used to access data stored on disk. But they have other uses as well:

On GNU/Linux systems, file i/o is provided by the libc library. Check out the libc manual for authoritative information. This guide will cover some of the functionality presented in chapters 11 through 16. Code examples are given in Julia (via the ccall function to interface with libc).


Created 2020-03-20. Last updated 2020-06-22. View source.