10 ms·
Julia is such a wonderful language. There are many design decisions that I like, but most importantly to me, its ingenious idea of combining multiple dispatch w
by beeforpork 6y ago
Julia is such a wonderful language. There are many design decisions that I like, but most importantly to me, its ingenious idea of combining multiple dispatch with JIT compilation still leaves me in awe. It is such an elegant solution to achieving efficient multiple dispatch.
Thanks to everyone who is working on this language!
- skohan 6y agoWhat does it mean exactly? Or what is novel here?
- JulianMorrison 6y agoIt's like C++ template specialisation, but it happens when the compiler realises you need a particular version. Which may be at runtime, if you changed something.
- dan-robertson 6y agoExcept the language can choose from suitable templates (eg instead of a generic matrix multiply template for floats, it can use a library like LAPACK) and does so in a systematic way. It also has a feature (I can’t recall the name) which is a bit like fexprs (let’s say macros who’s inputs are the types of the arguments of a function) that can generate customised code (eg an FFT depending on the input size) on the fly.
- gugagore 6y agoI believe you're thinking of https://docs.julialang.org/en/v1/manual/metaprogramming/#Generated-functions https://docs.julialang.org/en/v1/manual/metaprogramming/#Gen... (but I don't find it helpful to compare to fexprs, which I think of as more about deferring evaluation, whereas generated functions are about "staged programming".)
- ddragon 6y agoThis video is good explaining the idea behind multiple dispatch in Julia if you have time: https://www.youtube.com/watch?v=kc9HwsxE1OY https://www.youtube.com/watch?v=kc9HwsxE1OY
- socialdemocrat 6y agoThe combination. E.g multiple dispatch without JIT would be really slow as you are picking a method to run at runtime based on the type of all the function arguments. That requires a linear search through a list of all possible combinations of input arguments. In a single dispatch language like most object oriented languages, you can do a simple dictionary/hash table lookup. Much faster. With the JIT Julia is able the optimize away most of these super slow lookups at runtime. Hence you get multiple dispatch for all functions but with fantastic performance. Nobody had done that before.
- mbauman 6y agoFWIW, Julia does segment its method tables into multiple layers depending upon size and type. Multiple dispatch is a strict superset of single-dispatch, and indeed the first layer is just a dictionary/hash table lookup on the first argument. If there's only one result there, you're done (and have the same ~cost for the same ~complexity).
- socialdemocrat 6y agoThanks, I didn't know that! Has it always been like that? I wondering where I got the idea that it was always a linear search from? Maybe that is just the conceptual way of explaining it.
- pjmlp 6y agoI advise you to check Common Lisp CLOS and Dylan.
- eigenspace 6y agoWhat the OP is talking about is julia's method-based JIT strategy coupling very well to multiple dispatch. JIT is not new, multiple dispatch is not new, and multiple dispatch + JIT also isn't new, but nmo existing langauges combined them in a way that allows for the fantastic, efficient devirtualization of generic methods that julia is so good at. This is why things like addition and multiplication are not generic functions in Common Lisp, it's too slow in CL because the CLOS is not able to efficiently devirtualize the dispatch. In julia, everything is a generic function, and we use this fact to great effect. CLOS and Dylan laid a ton of important groundwork for these developments, but they're also not the same.
- fiddlerwoaroof 6y agoIt’s not true that CLOS generic dispatch is slow: Robert Strandh and other have done a bunch of work showing that it’s possible to implement it efficiently without giving up the dynamic redefinition features that make CLOS such a nice system. There’s at least one video game project (Kandria) that’s been funding an implementation of these ideas so that generic functions can be used in a soft real-time system like a video game. The really nice thing about CLOS, though, is that the meta-object protocol lets you choose an implementation of OOP that makes sense for your use-case.
- eigenspace 6y agoYes, I don't doubt at all that it's possible to make CLOS dispatch fast. What I'm saying is that because historically people using CLOS had to pay a (often negligible) runtime cost for dispatch, it limited the number of places developers were willing to allow generic dispatch. Julia makes the runtime cost of (type stable) dispatch zero, and hence does not even give julia programmers an *option* to write non-generic functions (though it can be hacked in like with FunctionWrappers.jl). I'm not familiar with Strandh's work, but has it made the overhead of generic functions low, or has it completely eliminated it? Another thing I'll mention is that Julia's type system is parametric, and we allow values (not just types) in our type parameters which is immensely useful for writing generic high performance code. You can specialize methods on matrices of complex integers separately from rank 5 arrays of rational Int8s for instance. This is not a capability that CLOS or Dylan has as far as I'm aware, though the common refrain is that you can do it with macros, but that neglects that it's rather hard to get right, and will have limited use because such macro implementations of type parameters won't be ubiquitious. ________________________________ To be clear though, I'm not hating on Common Lisp or CLOS. The Common Lisp ecosystem is awesome and can do all sorts of really cool things that I wish we had in julia. I'm mostly just pushing back on the notion that Julia doesn't do anything new or interesting.
- chalst 6y agoJulia is the first language to really show that multiple dispatch can be efficient in performance-critical code, but I'm not really sure why: JIT concepts were certainly familiar to implementors of Common Lisp and Dylan.
- chalst 6y agoI guess the reason is that Julia's type system and standard libraries really guide users to use types that the JIT can unbox as far as possible.