Julia language - can we learn from it?

Hi All,

Since we’re in the headspace of designing better wheels, I thought I’d briefly tell you a bit about my experience learning Julia, a language designed for high-performance numerics.

https://docs.julialang.org

The language itself, from the position of typing and reading it, is scripty and clear. It lets you incrementally type things. If you leave things untyped, it returns maximally polymorphic expressions. So 2+4 is an expression that works for any datatype able to generate vales from integer literals and combine them with an + operator. In that sense it is a bit like Haskel if Haskel silently put independent type wildcards everywhere.

Each named operation is called a function. So + is a function. Functions have arbitrarily many methods, which are implementations of those functions for concrete datatypes, or for explicitly parameterised families of types. Imagine that the only tool you have in your toolbox is a single method typeclass, and you can make new instances of it by just declaring a def with that name and arity.

The julia compiler only ever generates specialised codepaths. It generates them as needed, expanding them as they are called. So rather than generating a combinatorial explosion of potential code, it just generates the ones you use in your binary.

Lastly, virtually all the interesting stuff in Julia is done through code rewriting. Expressions are first-class, can be introspected, rewritten. It has a quoting/splicing mechanic. So you can implement your higher order function that transforms one function into another as code that rewrites the code of the first function into an implementation of the second. When combined with with the function/method abstraction, this allows the “expression problem” to be essentially ignored, and toolkits for showing, or differentiating, or serializing, or all that good stuff, to be generated using very little code and in a very extensible manner.

Julia isn’t scala, obviously, but I think there are lessons to learn about tidy syntax, the getting started experience, and language design. Especially about removing unrequired ceremony.

2 Likes

I believe the scala-native master already does precisely this, and lists the Julia optimizer as part of its citations

2 Likes

The multi-method concept from clos inherited into Julia is very powerful and expressive. Scala methos masquerade as multi-methods with lots of gotchas for those who don’t think in terms of jvm.

Multimethods may be acceptable in the context of scripting languages used for numerical computations, but they do not scale to static types and production-ready systems in the large.

And I’m saying this based on discussions with people involved with Julia, who tried to add more static guarantees to Julia programs, but were bogged down by the fundamentally anti-modular nature of multiple dispatch (meaning tools have to know about the whole world before they can reason about a program’s behavior).

Type classes are a much cleaner way of achieving something similar to multiple dispatch, albeit more safely and at compile time.

As for using program generation to synthesize specialized implementations while avoiding combinatorial explosion, it’s a very old problem people have been exploring for a long time. For one of the latest efforts, see the (now-defunct AFAIK) dotty-linker project.

3 Likes

Perhaps it isn’t so much the multimethods themselves, but the scoping/visibility and precedence of them? Everything in julia seems to be global in scope in some sense, so that to interpret any line of code you need to know all of the methods available for the functions mentioned in that code. The all is very open-ended in julia. It’s very well defined in scala, by the implicit search scope rules.