Hacker News new | past | comments | ask | show | jobs | submit login
Julia: A fresh approach to numerical computing (arxiv.org)
215 points by sveme on Nov 8, 2014 | hide | past | favorite | 138 comments



I've been playing around with the Cxx library (currently only works with a source build of bleeding edge Julia) https://github.com/Keno/Cxx.jl It allows you to basically embed ordinary C++ code in Julia code, to interface with C++ libraries at runtime, and to slurp in entire .h files unmodified. (It also in theory allows a C++ REPL mode to be written, though such a thing does not exist for Julia yet.)

It makes very clever use of a really amazing new language feature in Julia 0.4, namely staged functions. At first it looked like it was manipulating C++ via strings sent to the Clang compiler at runtime, which sounded really slow and awful. But then it dawned on me how it really worked, and I was amazed.

I've actually convinced three or four of my colleagues (mathematicians) to work on building a computer algebra system with Julia that will interface to various packages such as Pari/GP, flint, Singular, possibly Gap. We meet weekly to discuss design and to try and work on an initial implementation.

The rate at which Julia is improving and the community is increasing is astonishing. We are at the stage where Julia is offering us language features we haven't even dreamed up a use for! And yet the language remains elegant and easy to learn.


For reference, a staged function is something sorta similar to a macro, except it lets you take advantage of Julia's inferred type info. Contrived (and wholly redundant) example:

  stagedfunction foo(x)
      if x == Int
          :(2x)
      else
          :x
      end
  end

  y = 1
  foo(y)  == 2
  y = 1.
  foo(y) == 1.0 
Again, just like a macro, except that before `x` is quoted you work with the type of y instead of the symbol `y`. This means you can do even more crazy code specialisation, including on e.g. matrix dimensions or generating appropriate FFI calls based on arbitrary input types. It has zero overhead and you can use it just like a regular function.

Very cool, and I think people will do really interesting things with this (especially after mixing them with macros).


This sounds very similar to an approach called Lightweight Modular Staging (pioneered in Scala by the Oderski group - http://scala-lms.github.io/ and also in Lua - http://terralang.org/). While this is great for specializing numeric code based on runtime invariants like dimensionality, I think people are finally looking at using the idea in other domains - for example, runtime generation of DSL code on a per instantiation basis. Imagine taking a high level SQL query, building the operator tree in a Julia DSL and optimizing that, and then JITing the entire thing taking into account low level storage details and the particular sets of operators and joins (http://msr-waypoint.com/en-us/events/dcp2014/rompf.pdf). This is very exciting to see in another typed language!


You mean like blaze in python?: http://blaze.pydata.org/docs/v_0_6_5/index.html


Blaze has a bit of a broader focus than what I was talking about, since blaze mostly offloads the actual computation to a particular backend. But a combination of blaze and a custom lowering of the computation into machine code using numba would be similar (although without the type safety for guaranteeing that certain optimizations are possible)


I believe that the numba compilation is planned for the coming year.


wbhart This sounds like a really interesting project! Is it already on Gitub? I suspect there are others in the Julia community who would love to join the effort too when you have something ready.


It is, essentially. https://github.com/wbhart/Nemo.jl

See the wiki for a few bits of our planning that have actually made it online. Our current focus is twofold: 1) interface to Singular (http://www.singular.uni-kl.de/) from Julia 2) write a Singular interpreter in Julia (as an independent implementation of the Singular language). (Of course Julia will always be the main language of Nemo. The Singular interpreter will simply be a way for current users of Singular to benefit from Julia/Nemo and for users of Nemo to leverage the vast quantity of Singular library code out there written in the Singular language. And to have that code run faster of course.)

Yesterday we called the Singular C++ library, initialised it and created a Singular ring from within Julia for the first time. So very early days in that direction.

What is already committed on GitHub is a Julia interface to the flint library (which is pure C). Nemo is still a prototype, but you can Pkg.clone/Pkg.build it (Windows 32/64 support is there but clunky).

I will be visiting the Pari/GP people in January and working on a Nemo interface to Pari then.


What are the advantages of using Singular for the project vs. Axiom or Maxima?


Singular is only a component of the project. Maxima and Axiom contain almost none of the mathematical knowledge contained in the Singular project. No one wants to write hundreds of thousands of lines of code in some other system.


From the article: " A pervasive idea that Julia wishes to shatter is that technical computing languages are “prototyping” languages and one must switch to C or Fortran for performance. The consequences to scientific computing have been more serious than many realize."

I think this provides a very succinct summary of the Julia paradigm at a very high level.


I'm trying to push haskell for that too. But the more decent tools and choices, the better for everyone. :-)


Despite having a very similar title, this is a rather different paper from http://arxiv.org/abs/1209.5145. We had to upload a version of this paper for a grant application, but it's still somewhat in progress.


That's right. The purpose was to have twin papers - one for the Computer Science community focussed on language implementation, which is the earlier paper.

This paper focusses on motivating the design of Julia for the larger scientific community. Any comments will be incredibly valuable in improving the quality of the paper.


It's great to have a paper like this on the arXiv, I believe this is the right way to reach the scientific community.

Some ideas for improvements:

The package directory could be mentioned more prominently.

It's a bit tricky to select code in the PDF, not sure if much can be done about this?


I guess we can publish the IJulia notebooks with the examples and even just the code as plain .jl files.


What I would like to know before jumping in a new programming language is what it sucks at and how badly it sucks there.

Never in my life have I ever heard anyone say anything good about how wonderful it is language X is good at y which is what it was designed for. I have however heard plenty of people cursing languages for not doing something which they thought was an "obvious" thing for a language to do and X didn't.


Julia's non-incremental stop-the-world garbage collector is quite bad.

I ran into problems with this when trying to implement an algorithm that creates and destroys lots of temporary objects, where each object is a wrapped C struct that can point to a large amount of extra memory (the algorithm in question is doing polynomial division, where each coefficient is a polynomial represented by a C object).

The Julia version of this program runs unexpectedly slowly and uses gigabytes of memory, even though a few megabytes should be enough. The same code runs much faster if you do it in C and free every temporary object when it's no longer used, or even you do it with a Python C extension. Since Python uses reference counting, the objects get freed as soon as they fall out of scope.

But Julia allocates thousands of objects at a time before running the GC. Inserting manual GC calls is even worse -- the memory usage drops, but the program slows down by an order of magnitude (every GC takes a long time, even if you've just allocated a couple of objects since the last time).

Part of the problem is that the C code in question uses an object pool to speed up frequent allocations and deallocations. But even if you disable the pool, Julia performs worse than you would hope. A good generational/incremental GC would solve the problem.



That's good to know!


Julia's http library, and furthermore the extensive communities around tech stacks like node.js and ruby. Although Julia is focused on mathematical problems, its still often important to pull data from resources on the net (google weather just as a trivial example). Or outputting results to a website to share results dynamically. This is one area where Python shines - being both a strong web framework (Flask and Django)as well as with scipy and pandas library for computation.

As a bootstrap to letting us do things like stream audio from the Web Audio API, and use Julia inside of an existing web app was to build a Node.js and Julia bridge:

https://github.com/waTeim/node-julia

It worked out very conveniently that Node.js through node-gyp can use C libraries, and Julia can run inside a C context.

I think the strongest use cases are node streams, and also online-learning models such as a recommender system. I.e. pass to Julia what the user has been interested in, and simply get back a few suggested items of high correlation.


This very much depends on what you want to do with it and what your background is. Here are some things that might bother you.

* Julia's approach to OOP is via multimethods, not the usual class/inheritance model. This might be annoying for people who don't want to learn how to be an effective programmer in the other paradigm.

* Julia's garbage collector is not generational/incremental and in some corner cases, GC can take 10 times longer than the actual function you are running (typically it is between 5% and 50%). This would make Julia unsuitable for HFT, real-time games, web browsers of the future and other real-time applications. (Edit: see Viral's post in the same thread. Incremental GC is in the works. This is genuinely my experience of Julia to date. No sooner do you need something, and someone competent is already working on it, if they haven't already done it!)

* Julia sucks at predicate dispatch. It doesn't have it. Granted, neither does any other language except Gap and one other I forgot. So if you are used to that feature, you would find Julia a step down. (Edit: yes of course Julia does not need/want predicate dispatch. It's just an illustration of something that could bother you if you were really, really used to something. I just happen to have colleagues who really are used to this.)

* Julia is tied to LLVM, so if you want to be on the CLR/DLR or JVM, you are out of luck.

* Julia currently doesn't have static compilation (I hear it is being actively worked on). This makes it more difficult to deploy binaries.

* Julia does not have Haskell-like separation of effects from pure functions. This might not appeal to type purists.

* Julia functions can fail at runtime where statically typed/compiled languages would pick up the errors at compile time.

* As popular as it is, Julia is still not in the top 50 programming languages by measure of usership.

* Julia's support of mutable C-style structs allocated on the stack, as opposed to pointers to heap allocated objects is still somewhat lacking. This creates some challenges in efficient C FFI in corner cases, especially in combination with GC.

* Julia doesn't have inheritance of data types (it is really a dual to a data focused language, which is sensible -- you typically have far more functions than data types in a program -- but it's still hard for traditional OOP users to get used to).

* The Julia abstract type system is somewhat linear, which makes it a little less flexible as far as contracts/interfaces are concerned, if you choose to implement things that way.

Of course Julia has so many features that make it worthwhile, that it is worth investigating for many projects. It has multimethods, (static) dependent typing, very easy and efficient C interface (soon C++ interface), C-like performance is possible, garbage-collection, macros, runtime console (REPL), great numerical features, Jit compilation, a good selection of libraries/packages, a package manager, profiling, various development tools, a good (highly intelligent and helpful) community.


Static compilation is not too far away:

https://github.com/JuliaLang/julia/pull/8656 https://github.com/JuliaLang/julia/pull/8745

Being tied to LLVM is real, but we do have JavaCall.jl to call Java code.

https://github.com/aviks/JavaCall.jl


* lack of threads: they do support multiple processes which can be useful for splitting up work for large computation, but not a substitute for threads

* module compilation is not cached, so if you use very many modules your start-up times can be slow

* error messages sometimes require some head scratching. For example, it's not uncommon to get an error that there's no available function convert(::SomeType, (Some, Args)) when there's no obvious convert() to be seen in the code in question. Occasionally the stack trace will be missing from errors, or there won't be a line number. Obviously this is improving quickly, but can be frustrating.


The first two are both WIP. Threading is https://github.com/JuliaLang/julia/tree/threads (although it hasn't been updated in a little while) and static compilation of modules is https://github.com/JuliaLang/julia/pull/8745


That's great to see. It's sometimes hard to keep up with everything that's going on. Incidentally I really got a kick out of the recent s/Uint/UInt/ rename (https://github.com/JuliaLang/julia/issues/8905). It took a day or so to propose and do it. To compare, java will probably never fix it's spelling oddities (for example int and Integer). Very refreshing to see fundamental things like that be fixed and so quickly!


Just to play devil's advocate about the Java capitalization, I suspect the difference between `int` and `Integer` is quite intentional: `int` is a "primitive", immutable value type, while `Integer` is a class. Since by convention, Java's classes are capitalized, while its primitives are spelled the way they are in C, there's some sense here.


Our error messages do require a fair amount of work and so do line numbers in stack traces. Keno's debugger is almost ready though, and will greatly help.


Arrays are indexed starting at 1. I asked about this and Jeff said it just depends which types of problems end up having to use +1 or -1. I said anything mod n is now going to have the +1 and he actually paused for quite a while. I know it's an unsolvable debate, but I thought indexing from 1 went out with Fortran. I also would have thought the math folks would prefer to start at zero.


Don't forget matlab starts at 1. R starts at 1. Mathematica starts at 1 by default, though you can override that for any given array.

1-based indexing is very common in mathematical software.


Indeed, zero-based indexing is sort of a ridiculous concession to the hardware (whether that be data/address line labelling by power of two or offsets from a memory location) if bit-twiddling isn't your goal. (Even binary operations don't necessarily imply bit-twiddling at the conceptual level, even if that's what's going on under the hood.) We've just become rather used to counting by calling the first thing zero (and somehow have managed to forget that we had to learn that).


Having started in Matlab I still regularly forget that indexes start at zero in c# and end up with errors. I feel like either option is just catering to user preference at this point, as I don't feel there's a conclusive winner logically.


For me it's less about saving characters overall and more about making things as simple as possible in the basic case.

I'd much rather have +1 scattered throughout my code (though I tend not to) than have to do -1 in my head at the repl, personally.


What a fantastic list. And just to echo what the parent said, I find this so much more interesting than a list of 'good parts', which are generally easy to glean from the official docs.

Back to Julia: lack of CUDA support was a limiting factor for me when I tried it a year ago.


The JuliaGPU organization pulls together projects that address this:

https://github.com/JuliaGPU

However, we personally feel that the path Intel is taking with Knight's Landing, is likely to be the best of both worlds - GPU and general purpose - assuming it materializes for real in 2015.


Dictionary performance is still slow from what I can't tell. Like 2x slower than Python last time I checked.

https://groups.google.com/forum/#!topic/julia-users/hxfR70Ro...

I also find the dataframe library to be much harder to use/not much faster than pandas.

Great community though.


Right now, DataFrames is handicapped by problems with how DataArrays was designed. With some revisions coming in Julia 0.4, it should be possible to fix a lot of the worst problems (esp. performance) with DataFrames.


The combination of DataFrames and multi-threading will be really amazing, when we get there. I personally use it quite regularly for production work, over pandas - and as John says above, with Julia 0.4, DataFrames will be much better.

I think that being not faster than Pandas is pretty good, since it is written in C and heavily optimized.


The dataframe dev is really responsive though. We worked through a bug together a few weeks back. Nice experience overall.


Something I love about Hackernews: the dataframe dev actually wrote a sister post to yours (John Myles White).


I would say Julia sucks for embedded programming :); building graphical clients - although not badly as there are various js libaries that it can chat to, games programming, it's not great at data base interaction although once you have the data in it it is fine (frames). The last point is a bit of a development area I would expect to see because Julia has a console and this means that interactive querying would be great - like SQL on steroids but currently without the sql unfortunatley.

Julia shines at developing efficient reusable code for crunching numbers. The type system is really nice, and the syntax is very clean and natural (to me!)


There is work happening on the UI side in Julia. While we are some ways away from building graphical clients in Julia, we do have GTK bindings and such.

For some interesting ideas borrowed from Elm, do see: https://github.com/shashi/Patchwork.jl


Is anyone working on direct Qt bindings (I don't consider using PyCall a viable option). Qt is a bit harder to wrap since it is C++, but it look like Lua has been able to auto generate bindings based on the Qt headers.


Keno Fischer, who recently created the Cxx package [1] used to be a Qt dev, so I wouldn't be terribly surprised if we see such bindings materialize in the future, using Cxx, of course. That said, I don't want to speak for him, so if someone wants this, they should maybe go ahead and start working on it!

[1] https://github.com/Keno/Cxx.jl


May be documentation will need some time to catch up vis-a-vis the likes of R, Python etc., Understandably since it is a new language this may probably remain so for quite some time? For e.g., when I was trying to find out how to generate "n" random numbers in a uniform distribution from a range of -x to +x. In R the code is as simple as runif(n,-x,x). In matlab, it is a little bit contrived by offsetting and multiplying with the interval etc., But in Julia, the details do not go beyond the standard random functions that do not let you do this and no pointers to documentation beyond. But finally I was lucky to find an entry in the mailing list where I figured out I needed to use the "Distributions" package using the "using" command. Even then , the results were delivered in multiple precision points -> 1.1234, 1.123456 etc.,

In R computing an outer product while passing a custom function is easy. Something like outer(x,y, some function of (x,y)) is pretty straight forward. Not sure how to achieve this in Julia.

Nevertheless, as the language grows and as more idioms are documented and widely used, lif will be simpler I guess.


What I'd like to know when learning a new language is: why can't this be done in an existing language?

Take for example the R programming language. Things you do in this language can be perfectly well done in e.g. Python too. Same goes for the MATLAB language.


R (1976)[1] and Matlab (1984)[2] both predate Python (1991)[3], so I guess the answer is because the 'existing' language didn't exist.

As far as Julia goes it aims to bring strong typing and very fast native performance for numerical operations. Neither of which R, Matlab, or Python provide. Seems perfectly reasonable to me.

[1]: http://en.m.wikipedia.org/wiki/S_(programming_language)

[2]: http://en.m.wikipedia.org/wiki/MATLAB

[3]: http://en.m.wikipedia.org/wiki/Python_(programming_language)


Uhh, R is not from 1976, S is - as you note from your footnotes.

There's a direct and strong lineage, but they're not the same.

As someone who remembers when version 1.0 of R was released, I can say pretty confidently that it was well after 1976 :)


Isn't this... exactly what the linked paper tries to explain? The very first three bullet points are a great overview of the traditions Julia breaks away from, and the rest explains how the language enables that.

Can you clarify which parts can easily be done in other languages and how?


Julia is homoiconic, so it can do things non-homoiconic languages can't do. E.g. symbolic differentiation of Julia expressions.

Of course Lisp and Scheme can do this too, but it's virtually non-existent in any common language today. SICM makes heavy use of this.

Now, is there any other language with Lisp-like macros and static typing?


R is actually homoiconic. It's somewhat awkward and not a language feature that many packages exploit, but it's there. I wouldn't describe R as having Lisp-like macros, though... maybe "macro-like functions."

edit: and _definitely not_ static typing.


Typed clojure


When do you call a language "homoiconic" exactly? When it exposes its own AST (abstract syntax tree) structure? In that case, you can call any language homoiconic, whenever somebody builds a library that can transform a given AST back into executable code.

I'm not sure if it is a very distinctive feature.


It's not about any "given" AST, it's about having a computable representation of any code. For example, if I pass you a higher order mathematical function that calculates the first derivative of another function (f), you can create an algorithm that integrates the function symbolically, thus obtaining (another) primitive (related to the original f by a constant).

Note that I mean to symbolically calculate derivatives and integrals, not numerically. A homoiconic language can deconstruct any object representing code and can construct another object based on the underlying structure of the original, not based on any particular value of the original. The original doesn't even need to be invoked at all.

In mathematical parlance, a homoiconic language allows implementing functionals, as opposed to mere higher-oder functions (which is nothing more than function composition).

Please note that all this works with higher-order functions. You don't have to have a textual representation of the function. A.i. you don't parse your own source code.

LISP was actually invented to be able to implement functionals and symbolic calculations like this. The original paper demoed implementing function differentiation (among other things).


So, to understand what you are saying, is it true that in LISP, you can write a function F that can take any function object G, and turn it into an equivalent AST of G?


The spirit of your statement is true, but the precise formulation is incorrect. In LISPs, when you pass a function, you pass a list that defines the function. There is no special "turn into AST" step. Executable code is data, and you can create genuinely new executable code out of this data. There's no special "turn code into data" or "find the data corresponding to this code" step. Code just is data.


Typed Racket?


Is that the one with

    (: fun (natural natural -> real))
procedure signatures?


I believe so.


Never heard of it. Will check it out.


Racket is a scheme derivative, actually it consists of several languages including some domain specific ones, that all are compatible with each other. It also has a _very_ nice C foreign function interface (much better than Haskells for example).


Thanks for the note. When I first heard "typed racket" I thought: "oh no, an obscure dialect of an already obscure language" and I was slightly disappointed, but now I understand that typed racket is not a derivative of racket, but rather racket is a domain of languages including typed languages. This makes it much more interesting to me. Thanks for the note.


One of the few things I don't like is that it lacks a bit for object-oriented programming. Specifically:

- It doesn't use the object.method() syntax, which is often more natural and readable than method(object).

- Support for interfaces but I'm not 100% sure about that.


When you think in types rather then objects it makes more sense. Or at least I think `+(u, v)` or `u + v`, is more natural then `u.plus(v)` or `u.+(v)`

I the former case u and v are of numeric types that fulfil some numeric properties, so no interfaces are necessary, they are implied.


> Or at least I think `+(u, v)` or `u + v`, is more natural then `u.plus(v)` or `u.+(v)`

I definitely agree with that, I said that object.method() style is often more natural. Typically when you have an object with some internal state and you want to send a message to it that will change its state. For example: threadPool.run(command) feels more natural than run(thread_pool, command).


It's more natural to you (and to be fair, most programmers who have used OOP languages) purely because you're used to languages which work that way.


No, it is not some arbitrary choice, it confirms to the [second] most dominant word order in natural languages: subject-verb-object.


In fact, the most common word order in natural languages is subject-object-verb.

https://en.wikipedia.org/wiki/Subject%E2%80%93object%E2%80%9...

But SVO is a close second, and certainly more common than verb-subject-object (the equivalent of `function(arg1, arg2)`).


> purely because you're used to languages which work that way.

You don't know that. I think that for people new to programming both styles can be natural, depending on the specific situation.


I agree, and that was largely my point.

People discuss certain styles as being more natural, but in nearly every case (including this syntactical debate) I assert that it is solely due to what the most mainstream languages do and thus what people are more used to seeing.

That's not the same as being natural


If a language makes the dot and the method invocation brackets optional, then `u + v` and `u.+(v)` would be semantically identical. The former would just syntax sugar for the latter.


It is only more natural for functions that take a single argument, which depending on your point of view and type system is of course all of them.

From a mathematical standpoint what you are doing is to consider instead of objects X themselves, arrows from some fixed object I, x : I -> X (roughly speaking the "I points of X", in the category set I could for example be the one element set), then given another arrow f : X -> Y, the composition I -> X -> Y, would be denoted x . f, and you would actually find that in familiar cases this is precisely f(x).

However for this to actually be natural, ideally you wouldn't write x . add(y), but (x,y).add and if you follow that line of thought you would probably understand why stack based languages enjoy some popularity (the stack models the cartesian product).

Object oriented languages instead have for every I point x of X, a bifunctor hom_x(,), where hom_x(Y,Z) denotes all arrows from Y to Z, that "use" the point x (usually denoted by self or this). At least in mathematics, such an arrow can sometimes be extended to an arrow in Hom_X(Y,Z). In the case of addition above, you start off with + : (X , X ) -> X and use currying to get add : X -> hom(X,X) and pullback along x, to get $x^{\ast}add = add_x \in hom_x(X,X)$, which you then denote by x.add.

So you are right, the object method syntax is more natural and there even was a brief period in the 60s-70s when some mathematicians argued that it should be taught.


Object.method() doesn't really make sense due to multiple dispatch, I think.


Why? It can be just a syntactic sugar for method(object).


I think the point is that it special-cases the first object, at least in the syntax. You _could_ write it that way, but since the method is chosen based on all the object types, it doesn't make much sense to do so.


One could have a language where object.method(args) does single dispatch on "defined in a class" methods while method(object, object,...) does multiple dispatch on generic methods.

That could get really confusing for the language's users, though, if there were name clashes between the two, and they would be there in any reasonably large program.

And of course, argument order already gives the first and last arguments special attention.

Another way to diminish that special-casing is going to the extreme other end: object.object.object.method(). Remove the now superfluous parentheses and replace the periods by spaces and you end up with Forth.


The point was that object.method() is sometimes more readable. For example I find web_socket_manager.reconnect_if_needed() more readable than reconnect_if_needed(web_socket_manager).


That's because you are used to thinking in terms of objects, whereas in Julia the focus is on data and operations on data (the two are often conflated but they aren't the same).


I think in both depending on the situation.


Hm, well it sort of does make sense if you have tuples, it would be just

(object_1,...,object_n).method


Julia is really more a functional language than an object oriented one. Not saying that's not a valid point (at least to the extent that favourite paradigm is subjective) but just to point out that it's about more than just syntax.

It wouldn't really make sense for Julia to support object.method() any more than it would for Haskell to, superficial as it may seem.


I've seen julia described as "functional" a lot, but is that accurate? There are first-class functions for sure, but the "idiomatic julia" approach to a lot of problems is to allocate a large block of memory, pass around a reference to it and mutate it in place. i.e. all side effects. My terminology might be off, but that's not usually what I think of when I think of functional programming.


I think there's a distinction between idiomatic code and code written for performance. Performance-conscious code looks a lot like C in most languages, not just Julia. Julia just happens to have a lot of that kind of code because it makes it easy to write.

But look at the high-level, user APIs and you tend to see the more functional side – `fft(x)`, `plot(y)` etc., all pure functions which return expressions. Mutation is possible but discouraged via the `!` modifier.

Functions are the primary unit of abstraction – larger programs tend to be designed as collections of functions as opposed to object hierarchies. Higher-order functions like map and filter (aka "functionals") are encouraged.

So I tend to view Julia as a nice functional language which lets me drop down easily when I need to.


I recently started a project in Julia and, excited by the prospect of a smart JIT compiler, wrote everything in a declarative function style with maps, reduces, and filters. The result was slower than than equivalent Python code. I swallowed my aesthetic sense and rewrote every function imperatively, with for loops updating some mutable array, and now it is quite fast. But I am no longer enjoying coding as much. I switched to Julia for speed, but that speed seems to come at the cost of having to write very imperative code.

In terms of day-to-day programming, I'm not sure what makes Julia a better functional language than Python or Ruby. From my limited experience, it isn't speed.

I understand that work is under way to speed up anonymous function calls and to improve type inference on arrays resulting from `map`, etc. Once that is done then I will consider Julia a nice functional language.


"Idiomatic" might have been the wrong way for me to put it, but it seems like one of the biggest advantages and fundamental design decisions of Julia is that it makes numerical computing through side effects _very easy_. Most performance-conscious code doesn't just look like C in other languages, it is C! So I see your point, but I still wish there were a better way to convey exactly the mix of high and low level code that Julia's aiming for.


I wish there was a language like Julia but with a first-class OOP support. Sometimes the OOP approach is more readable and easier to reason about than functional approach.


Believe it or not it's actually perfectly feasible to implement first-class objects and inheritance on top of Julia. You can even integrate it with multiple dispatch (via some metaprogramming and manipulation of the type system) and get object~method(x,y) syntax.

I didn't want it enough to flesh out the prototype (and would argue that Julia's native approach is better anyway) but it's inevitable that someone will do this eventually.


When you say "OOP approach", I'm reading "OOP in the style of the C++/Java/C#/etc branch of the OOP family tree".

Not all OOP languages look remotely like what you're describing.


> I'm reading "OOP in the style of the C++/Java/C#/etc branch of the OOP family tree".

You read mostly right. But the OOP language I like the most is Ceylon (it also has a first-class support for the functional paradigm).


In particular I'm thinking of things like Dylan or CLOS. When people from the more typical OOP backgrounds see stuff like that often their heads explode.

I recently got into an argument with some coworkers over type classes. My argument was that it all made sense when viewed from the Dylan/CLOS/S4/etc lens, and that this was very much OOP, just not what they were used to. Many of them weren't buying what I was selling, but IMO they were using too strict a definition of OOP.


I tried CLOS, not a fan to be honest. OOP (or functional) isn't a very well-defined concept... I like what languages such as Ceylon, C# or Julia (to an extent) are doing - solid support for both OOP and functional styles. Because you typically need both, some problems are more readable and natural in OOP, others in FP.


On that I fully agree. And going back to your statement that it isn't a very well-defined concept, I think that the two concepts aren't nearly as orthogonal as many would have you believe, it's just that the ways that the two communities have solved similar problems over the years appear to be alien to each other.


Julia supports multiple dispatch OO, which is more powerful than what you get from traditional OO languages. Or do you purely mean the x.foo(y) syntax rather than foo(x,y)?


Yes, it's just about readability.


That seems like a pretty decent description of python, right? :)


Yeah, I like Python but it's slow and Julia seems better designed in many ways :) I'm now using Julia when I don't need Pythin libs.


Check out the PyCall[1] and PyPlot[2] packages, then. Julia has pretty good integration with python. I've been pretty happy calling matplotlib from julia. (You probably already know about these packages, but just in case you didn't...)

[1]: https://github.com/stevengj/PyCall.jl

[2]: https://github.com/stevengj/PyPlot.jl


It is interesting that in future versions of C++, object.method() is an active area of discussion: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n416...


For anyone in the Chicago area, Leah Hanson is giving a free Julia workshop next weekend (11/15):

http://www.meetup.com/JuliaChicago/events/216950712/

Should be a great way to get introduced to the language and pose your nagging questions to a community expert.


Her blog is also a great resource to pick up some of the more useful parts of the language.


Not to mention her forthcoming O'Reilly book, "Learning Julia"!


Yes, this paper, as the title suggests, was written perhaps for the community as a whole, but perhaps in particular for the numerical computing community. Most especially, there are many ideas in this paper that are entirely unfamiliar to that community, and this paper hopes to change that. Hope you enjoy the reading. (We probably will make some updates. The spelling fix of the title was already processed yesterday and will appear tomorrow or Monday.)


I am a little weary of the hype around a language whose unique selling point is speed. Where else in Julia is there significant innovation versus Python? The latter seriously has it all when it comes to scientific computing, and if anybody is not already running vectorized numpy code, or trivially compiling critical for loops to c-like speed using Numba/Cython, then they're missing out on performance which has nothing to be ashamed of versus any of the newer kids on the block.

I have been weary of the Julia pitch which was basically "lets brew R, Python, and Matlab (all >20 years old with massive and unrivalled ecosystems and all serving their purposes very well, thank you) into one "new" language and put a nice logo on it". How is this language seriously the leap forward that one needs to abandon the current awesome toolsets, with all their battle tested libraries, other than a nebulous "speed" argument which in many cases, judging by the comments and my own experience in financial data matrix operations, is not even fully accurate? Ready to be persuaded otherwise if I can be shown that other than "speed" there are hefty reasons to move from Python and abandon the almost endless choice of richly varied tools that I have at my disposal already.


You should read the paper, but Julia's also a really nicely designed language in general. It's hard to communicate how great multiple dispatch + a powerful type system is without trying it out (though, again, the paper does a good job), but yeah, it really helps you get a lot of generality as well as performance. When you use Cython, you immediately lose that generality.

Then there's the really powerful metaprogramming capabilities, which are absent from the languages you've mentioned. I can't emphasise it enough: the paper this comment thread is about does a great job of explaining why these things are compelling.

Also, you may be interested in [1], an argument that language performance is valuable even if you don't need it yourself.

[1]: https://medium.com/the-julia-language/performance-matters-mo...


Compelling argument in your link about how performance for others allows for better libraries for everyone. I am still concerned that Julia does not go far enough in breaking the imperative programming mould, but I think it's disingenuous not to give it a serious try in more than trivial exercises. I have to say though that I have learned R, Python and Golang in the past 8 years and all of them are basically imperative (though R's vectorisation-everywhere is impressive - wish it was all just faster); I hope Julia will give me something dramatically more interesting. I say that because the LLVM has ushered in a period of radically easier language development, so we are likely to be spoiled for choice in the next 5 years. I hope Julia has done enough to put itself way out there in in terms of innovation to make the sizeable investment of time for myself and library developers, worthwhile. Altogether however I cannot be anything other than impressed with the dogged and convincing pitch that you and others are making for it, which somewhat lowers the risk of investing time in a dead end. And even if it doesn't work out all hunky, at least I'll know that Python will face serious competition, and that can only be good, even for Python.


How does the upcoming and even current numba+blaze power duo not allow library designers to easily write fast code?


Well that was the point of my original message. I am using numbapro and easily getting to c-speed with R-like vectorized convenience right now. It's why I question the "speed" argument as a non-argument when compared with Python. And I haven't even started using the cuda approach... You allude to another point though: Python is not standing still. Python and its environment is a mighty high mountain for Julia to climb if it's not going to move the game forward significantly so that its big ecosystem disadvantage is compensated. Julia cannot just do incremental improvement - it doesn't have enough momentum to make that a winning strategy. It needs to leapfrog to take on Python.

I should add one more point though. The post mentions Matlab 15 times and Python only 7. It's possible this whole Julia effort will be successful with the Matlab crowd which, up to now, has been watching with horrified fascination from the sidelines as open source ate its lunch.


Nice. Do you find yourself having to contort code to work with numbapro?


I've been using Julia for a few months and I love it! Being able to process arrays in a function as if it was a single variable is super awesome, and as a result my code uses far fewer for/while loops.


Am I the only person not seeing the promised performance with Julia? As a concrete example I recently ported some non-trivial legacy matlab code I use at work to both python/numpy and Julia. The port was basically a straight port of matlab code making only the necessary syntax changes to make the code run. And much to my surprise Julia run twice as slow as Octave and 4 times as slow as python. Adding type annotations helped but I never got closer than 50% slower than Octave. In earlier test I've seen cases where Julia was literally 12 times slower than python/numexpr in real world code.

I really want to love Julia and everything I read about it makes me think it's the language for me, but every time I try to write non-toy code the performance is always worse than python.


Did you read the performance tips?[1] The mailing list is pretty good at helping with problems like that. Using global variables is a pretty common performance killer.

[1] http://julia.readthedocs.org/en/latest/manual/performance-ti...

edit: As a direct reply to your question, yes, lots of people fail to find performance improvements when they first port code to Julia. But they often discover those improvements 10 minutes after someone with more Julia experience looks over their code :)


> The port was basically a straight port of matlab code making only the necessary syntax changes to make the code run.

Then it is not surprising at all that you do not get any speed benefit. I would expect a serious slowdown.

Idiomatic MATLAB and Numpy has lots of vectorized expressions because they are so crappy at loops. However, in vanilla Julia those vectorized expressions cannot be JIT'ed. Now if you were to write them out as explicit loops then JIT will take a stab at making things faster.

I do like the economy of words of vectorized expressions a whole lot, this is the reason why I am so excited about https://github.com/lindahua/Devectorize.jl


On vectorized code we are on par usually, but sometimes GC performance hurts. There is a patch for this in the works. Could you post the code snippets to julia-users mailing list?


I've observed a huge performance boost over python -- I wrote a simple artificial neural network trained using backpropagation in both languages and my Julia code ran orders of magnitude faster. Something is clearly screwed up with your implementation of Julia. There is no way octave should be running faster.


Octave occasionally runs faster than Julia for transliterated vectorized vector and matrix operations. Julia then runs much faster when those operations are devectorized or replaced with builtin functions. But that's a pretty common source of these issues (at least on the mailing list.)


It would be good to know where we are slow, so that we can fix it. Can you for an issue with an example on github?


I'll do it right now. These aren't issues I've personally run across, though, just stuff on julia-users.

edit: Nevermind! On rereading the mailing list thread (especially this message [1]), I might have mischaracterized the issue slightly. It probably came from speed issues with small integer powers (i.e., there are faster ways to exponentiate small integer powers than there are for general exponentiation that Julia hadn't been using but other software like matlab and octave were), and that issue in Julia seems to be fixed now.[2]

[1] https://groups.google.com/d/msg/julia-users/n3LfteWJAd4/jag6...

[2] https://github.com/JuliaLang/julia/issues/2741


The biggest challenge I'm facing now is how to convince those around me to take the leap and step over to Julia. We have a wealth of legacy code in MATLAB, C++ and Fortran. I've seen the various methods to call these codes from Julia, but in the case of C++, it seems that only rudimentary support is provided.

My goal is to port a lot of my code to set up astrodynamics simulations. I've even created a placeholder Github repo for it [1]. Just have to find the right strategy to involve the dev in my existing projects and get my colleagues to chip in.

[1] https://github.com/kartikkumar/Astro.jl


Nice paper guys. Any plan to get something peer-reviewed? It would be useful for motivating biologists.

Anyone interested in using Julia for bioinformatics is invited to contribute to, or follow the progress of, the BioJulia project: https://github.com/BioJulia/Bio.jl


Yes, we do want to submit it to a SIAM journal. It does seem that we are already getting interesting feedback here. The BioJulia team will probably write a paper on Julia in Biology and publish in a related journal, just like Miles Lubin and Iain are doing with JuMP in the OR community.


Yup, we'll definitely do one for BioJulia - but we've got a way to go before we reach that stage :)


Are there any mature visualization libraries for Julia yet? I'm pretty excited about this language, but I couldn't find any visualization tools that had good documentation.


Gadfly is an excellent ggplot2-style plotting package:

http://gadflyjl.org

Winston is a most traditional plotting API:

http://winston.readthedocs.org/en/latest/examples.html

You can also plot seamlessly via Python using PyPlot:

https://github.com/stevengj/PyPlot.jl

They are all quite well documented.


Thanks. I guess I would disagree with the assertion that Gadfly is "quite well documented". It has some docs, but they are mostly just a list of parameters (with no indication of what values you could/should set them to) and maybe one example, e.g. http://gadflyjl.org/geom_boxplot.html

Perhaps it's all very obvious if you're already familiar with ggplot2, but as somebody without an R background, I found their docs extremely spartan.


Still working my way through them myself. Useful examples working through docs would be useful. Most seem to presume a lot of knowledge of the libraries.


You are right - package documentation has some ways to go. Currently we don't yet have a mechanism to do `help()` on a package function, but we expect that to change in 0.4.


Would love to help in some way.


I believe there are bindings to plot.ly


One of the plot.ly engineers uses Julia, I think and wrote a package with bindings. Doesn't seem to be actively maintained:

https://github.com/plotly/Plotly-Julia


Here are the docs: https://plot.ly/julia/


The one based indexing pretty much kills the entire thing for me.


Then you are missing out on a wonderful programming tool for a very superficial reason. I wish indices were offsets like C and not indexes like Lua, but I'll deal with it for all the language gives.


anyone know where I can get a juliabox.org invite code?


Shoot me an email - viral@mayin.org


Mind if I shoot you an email too for an invite?


Yes - happy to share codes with anyone. Also, we will be simplifying the invite system in the next few days so that JuliaBox will let you in without any code by default.

In the rare cases of a surge, such as an HN mention, it will auto-release account approvals as the surge subsides in a few hours. Once you do have access, you will continue to have access, even during surges. Basically, we are just trying to manage our compute budget better.


is it just me or is arxiv.org down? HN effect?


for anyone experiencing issues with arxiv.org, mirror: http://uk.arxiv.org/abs/1411.1607




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: