As a programming language, Julia has some unusual features. It’s a fully dynamic language, yet rather than the “no talking about types” approach that many dynamic languages have adopted, Julia has an expressive type system, complete with parametric and dependent types. This is no accident – talking about types is unavoidable in technical computing. But types aren’t just used to describing the structure and layout of data in Julia – they are also essential for expressing behavior. Programs are organized around multiple dispatch – generic functions can be defined piecewise for various combinations of argument types. This allows the polymorphic behaviors rampant in mathematical code – arithmetic operators, numeric promotions, array indexing – to be expressed clearly, extensibly, and in a way that the compiler can reason about. Traditionally, this kind of flexibility and abstraction have come at the cost of performance. But by a combination of dynamic data-flow type inference (not Hindley-Milner!), and just-in-time code generation with aggressive specialization on runtime types, Julia’s compiler manages to generate efficient, low-level code despite all the abstraction. This talk will include lots of live coding to demonstrate concepts and provide on-the-spot examples to help answer questions.