Why I'm Betting On Julia
evanmiller.org
evanmiller.org
If you make a programming language that people who don't like programming love enough to spread by word of mouth when not near a computer, which technically-oriented people also love, that's a lot like the OSX terminal + nice GUI blend.
That's a pretty rare thing. And for collaborative science it's pretty important. Often, you'll have people in a bio lab who are very proficient in their area of biological expertise, but who would be solving the wrong problem by spending 2 years trying to become C++ hackers. On the other hand, there are a lot of people who write computational libraries, but know they have to translate them to matlab, or write a matlab wrapper and pray that their users can get it to compile which might sound simple to folks here, but is really frustrating for less computationally oriented people when something goes wrong.
I really love Scipy and friends and I also think Julia is a promising system.
First class arrays and array literals. It's a wonderful thing… like Matlab but very smartly designed.
The type dispatch system makes so much sense for mathematical work. It's simply how math is done. And Stefan Karpinski (co-creator) often compares it to linguistic grammars, too, which may be a stretch but I think there's some truth to it. It just feels right. And it makes things very extensible, right down to the core language.
And the core language is indeed mostly Julia itself. Compared to NumPy where things are often implemented in C or Cython. I've tried to hack on some Cython things in NumPy and was immediately turned off. It was so hard to debug and run interactively.
Julia's interactivity is wonderful. The IJulia project brings over some of the best user experience of NumPy (in my opinion)… which is not NumPy but IPython.
And the community is so very great and supporting. The package system is such a great asset and really lowers the bar to entry.
See this post on the implementation of IHaskell[1] for more details. My understanding is that IJulia uses the same concepts. Notably, when running IJulia, you can't even use %%magics to change back to Python mode.
1. http://andrew.gibiansky.com/blog/ipython/ipython-kernels/
(Also, it's firmly endorsed by the language creators. Stefan recently gave a talk using IJulia).
One of advantages of Julia touted by the authors is that much of the Julia system is written in the Julia language making it easy for users to understand many of the algorithms and contribute to the system. In practice I don't know how true that is (it seemed to spend a long time compiling C/C++ code when I last built it) but I can see the rationale.
The collaboration between the scientific Python and Julia communities in recent months has been awesome to watch.
Julia is more concise than Python. The language was designed to work with multidimensional arrays; it wasn't bolted on afterwards. There is no difference between a 2D array and a matrix; * always does matrix multiplication and .* always does element-wise multiplication. There is no awkwardness involving differences between NumPy arrays and Python lists. Everything has a type, and you can make a multidimensional array that efficiently stores values of any type. You can define your own types and define how arithmetic operators act on them with a minimal amount of code.
Julia's type system makes writing efficient algorithms easy without sacrificing any performance. If you define your own immutable type and define your own operators on it, Julia can make those operators run as fast as they would on ordinary values. In addition to general matrices, we have diagonal, symmetric, and tridiagonal matrices. The same routines that work on general matrices work on these as well with the same syntax, just more efficiently.
Julia uses multiple dispatch instead of traditional class-based OO. Methods are not a part of the object; instead, they operate on the object. Different methods with the same name can be defined to work on different types, or a single method can operate on a set of types, but the functions it calls may be implemented differently for each of these types. This is a better fit for technical applications, where the data doesn't change much but the methods do.
Julia is homoiconic, which is more useful than this article makes it seem :). It's easy to write code that writes code. If built-in language features aren't enough to get good performance with concise syntax, you can write a hygenic macro that does this for you.
I love the multiple dispatch part about julia though.
My fear however is, that unlike Python, Julia will lack enough libraries, especially on the unscientific part (GUI, databases, network, all the other stuff you need).
The thing is that the multiplication operation for matrices is matrix multiplication, not elementwise multiplication. When you apply a polynomial like x^2 + y to matrices, you do not want to apply the polynomial elementwise – you want to square the x matrix and add the y matrix to it.
x = linspace(0,10, 1000)
y = (x<5)*4.0
z = x**2 + y
Of course I can just use matrices and then I have the information at hand that I am doing linear algebra right now: x = matrix([[3, 0],
[9, 5]])
Out[28]:
matrix([[ 9, 0],
[72, 25]])
x**2 + x
I think this is not too much boilerplate and gives nice semantic information within the sourcecode. However, if you want to perform this with a 2d array object, you can also use its dot method: In [ 1]: a
Out[ 1]:
array([[ 9, 0],
[72, 25]])
In [ 2]: a.dot(a)
Out[ 2]:
array([[ 81, 0],
[2448, 625]])
In [ 3]: a * a
Out[ 3]:
array([[ 81, 0],
[5184, 625]])
The approach of the matrix object nicely takes into account that operands of a "normal" multiplication `*` commute, so the elementwise multiplication fits the picture here. Wheres matrix multiplication - which is non-associative for most matrices - is performed by a different method.Both approaches have their merits.
foo(arg)
where I would like to pass either strings or numbers that uses an operator + which polymorphically concats or performs addition. In this respect like languages that offer special string concatenating operators (like Haskell ++ or Lua with ..).More generally: I think that + and * should always commute for the applied types and mixing them should follow the rules of associativity.
But as a long-time R user, I'm hesitant to bet the farm on Julia for a project at work where it would be ideally suited. Maybe there's a way to squeeze it in on the side.
The moment you need an extra dimension (or anything other than 2 really) Matlab's ‘everything is a matrix’ approach falls apart. Matlab is a toy language in so many ways and this is just another one.
It's a pity that Julia adopted Matlab's pop matrix semantics instead of some solid and general principles from APL or J. Even modern Fortran would have been a better model for an array DSL. From what I've read of the Julia docs, they actually want you to write loops. But Julia looks great otherwise. With macros and a good compiler, maybe the array features can be fixed at some point.
Yes, but this is rapidly improving. Julia has Gtk bindings that have seen a lot of improvement over the past two months. There are ODBC and SQLite interfaces, a MySQL interface is in progress, and probably others.
Julia has the advantage that you can write fast bindings in pure Julia, which alleviates the extra cognitive and tooling overhead of writing extensions in C.
Building a language ecosystem is a bit of a ponzi scheme - but it has real potential for a great payoff at the end!
Matlab you have .* ./ .^ and probably more and for good reason.
I don't really see it as being awkward it actually very useful when needed, can be confusing if you're learning a language and think .* might be dot product though.
The title is flaming and shallow in any measure of programming language discussion...
"The problem with most programming languages is they're designed by language geeks, who tend to worry about things that I don't much care for. Safety, type systems, homoiconicity, and so forth."
can be rewritten as:
"The problem with most software is that they are designed by computer geeks, who tend to worry about things that I don't much care for. Information security, thread safety, modularity, hardware acceleration, system design, and so forth."
Some people are really interested in making compilers, right? While others (such as me) just want to do cool things with them.
His point is the same way I feel: stuff like type systems and homoiconicity (I don't even know what that means) don't interest me. I'd rather think about the work that I'm doing.
Also, these things are a step or two above my level of understanding (but probably not the op's).
I do care about security, thread safety, modularity, etc... but I can't really contribute to the debate about how we get there.
For example, his purpose, and Julia's main use case, is often different from that of either a language designer or a software engineer: e.g. performance and fast prototyping are first order concerns (together with a decent scientific library), and everything else, like longevity, ability of future code reuse, or simplifying work of teams are way, way down the list. The reason of course is that ~90% of code is written by one person, for himself, to effectively run once and produce one paper, and to be never touched by anyone ever again. At least, this is what I see in my field, which is largely dominated by Matlab (and Matlab-like syntax is definitely a huge asset here).
And this is when you really want to have a language that can be used to build up real abstraction.
Among compiled languages, isn't that Fortran, especially since Fortran 90 on have multidimensional array operations, like Julia, Numpy, and Matlab.
The problem with Fortran is interoperabality with other libraries; if you leave scientific computing, you're basically out of luck. Writing a GUI is just not going to happen. It is really fast, but it is also not as easy for prototyping since it is also compiled like C. Finally, Fortran does have the kind of stigma coming from older versions like 77 - and it's still really easy to write REALLY bad and unmaintainable code with it if you're not minding the newer language features. Especially OOP (since Fortran 2003) feels a bit tacked on.
1. A pretty significant amount of code is PHP serving broken HTML + Javascript, stuff which favours pragmatism over purity (to the degree that even some of the most pragmatic people hate it with a passion). These languages are popular because the authors focused on delivering results, not naval gazing.
2. When a language community starts talking up its the theoretical features with a passion, it's a red flag. Odds are, the documentation will be obtuse, and the community will bite noobs who don't know the theory. Even if they try to be nice to beginners, it's against their instincts to give simplified (if technically incorrect) answers. If your High School math teacher told you that "differentiation finds the slop of a graph, by finding f(x+e) / f(e) where e is really small", she was lying, but it's a good kind of lie.
A pedantic explanation will just confuse people, and stop most of them from understanding it well enough to learn how to appreciate the technicalities.
About 2: The Haskell community is one of the friendliest I know, yet, it is one with the strictest theoretical background.
PHP was popular for a number of reasons, I think mostly because of the easy mix of HTML and PHP tags as well as the ready-to-run Apache/PHP/Mysql setup. From a maintainability standpoint, a lot of people suffer from this.
Its the same point that people have had about "Clean Code" and Unit tests. Some think it keeps them from getting work done. When a unit test of mine suddenly fails, I silently know, that some other person has just now also broken their code and does not know about this, will find out eventually but will not see why immediately. While they try to find their bug, I have already fixed mine and implemented tons of features in the time.
I also disagree that the popularity of Node stems from "getting disparate groups of programmers to code in the same language". From what I've observed, it's not that back-end programmers are suddenly giddy at the prospect of getting to use Javascript on the server, it's that front-end programmers get to apply their existing knowledge of Javascript to back-end development.
It's also possible to run Julia with some of Intel's advanced profiling tools like VTune:
http://software.intel.com/sites/default/files/blog/477490/ju...
More info: http://software.intel.com/en-us/blogs/2013/10/10/profiling-j...
However, he did address library availability, and that argument resonates with me. I've never met a FFI I didn't come to loathe. I've had java, ruby, and python FFI libraries fail to satisfy my needs despite half a dozen bugfixes between them. What this man says about having to write wrappers, despite abundant and loud promises to the contrary, is completely true. You don't have to wander far off the beaten path before a typical FFI goes belly-up. POD structs usually suffice (Sure, we support POD structs! Oh, you want to nest them / align them / make arrays of them / have them hold pointers / ...? We don't support that "yet". Worse: they support it but it's buggy.). Heavens help you if your argument has (gasp) an initializer or one of the arguments is a reference. Maybe things have changed in the last ~5 years, but I doubt it.
If Julia's intimate connection with LLVM makes it practical to implement a better FFI or hybridize FFI + wrapper code when necessary, it will have a very valuable advantage over python for purposes of scientific computing. Maybe even enough to displace it in the long run.
EDIT: By "hybridize" I mean that the ability to embed asm,C,C++ in Julia with the same ease that you can embed asm in C/C++ would be a KILLER feature.
I've felt that pain. With so many new programming languages popping up, I've been wondering if the next killer programming improvement isn't strictly a programming language at all, but rather something that rethinks the linker, manages execution, and facilitates interfaces between larger blocks of code (maybe in multiple languages).
I'm not sure there is any way around the impedance mismatches between languages. They're all slightly different for a reason. Perhaps clean C APIs are the best we can hope for.
CLR has an approach for that by defining what is known as CLS, Common Language Subsystem.
Likewise they have a similar approach on WinRT, known as Type Providers.
However they also have their impedance mismatches, as you are only allowed to use types that are usable by all languages that target such runtimes.
The benefit is that they still allow for an higher level of code abstractions than pure C functions.
Not that all the other JVM, CIL, etc aren't approaches that yield some improvements, but something that upgrades capability or accessibility at the level of the ABI linkage level is going to be a wider impact.
COM is the basis for most Windows APIs since XP, and the basis for the new WinRT runtime.
Lets see how it might look like with Windows 9.
The JVM offers a better place to tackle these issues. Scala and Java cross calling is often more than adequate. Perhaps a Julia compiler for the JVM could be a step in the right direction.
I'm looking forward to giving the workshop at UChicago. It'll be my third time presenting an Intro to Julia workshop.
CL-USER> (defun f(x) (* x x))
F
CL-USER> (disassemble 'f)
L0
(leaq (@ (:^ L0) (% rip)) (% fn)) ; [0]
(cmpl ($ 8) (% nargs)) ; [7]
(jne L33) ; [10]
(pushq (% rbp)) ; [12]
(movq (% rsp) (% rbp)) ; [13]
(pushq (% arg_z)) ; [16]
(movq (% arg_z) (% arg_y)) ; [17]
(leaveq) ; [20]
(jmpq (@ .SPBUILTIN-TIMES)) ; [21]
L33
(uuo-error-wrong-number-of-args) ; [33] >>> def f(x):
... return x * x
...
>>> import dis
>>> print dis.dis(f)
2 0 LOAD_FAST 0 (x)
3 LOAD_FAST 0 (x)
6 BINARY_MULTIPLY
7 RETURN_VALUESo, this is going to be really slow inside a loop. Would the compiler be able to optimize it into a single multiply instruction if it could prove that the input had to contain integers?
CL-USER> (defun f (x)
(declare (fixnum x)
(optimize speed (safety 0) (debug 0)))
(the fixnum (* x x)))
CL-USER> (disassemble #'f)
; disassembly for F
; Size: 19 bytes
; 0337CE2F: 488BCA MOV RCX, RDX ; no-arg-parsing entry point
; 32: 48D1F9 SAR RCX, 1
; 35: 480FAFCA IMUL RCX, RDX
; 39: 488BD1 MOV RDX, RCX
; 3C: 488BE5 MOV RSP, RBP
; 3F: F8 CLC
; 40: 5D POP RBP
; 41: C3 RET
NILThose things may help him get things done, but they're for other people to worry about while he works on his own stuff.
Also, am I the only one that doesn't know what 'orthogonal' means? I assume from the context it means that these things aren't mutually exclusive.
Not really sure about 'homoiconicity,' either.
FYI
This statement is built on a false dichotomy. And it is not really true for Julia, take the type system for example, sophisticated AND unintrusive.
Julia's great strength, I think, is that it was designed by folks with very good grounding in language design, but who prioritized practicality.
This makes me a bit cautious about the language. Scientific computing people are often very smart but they are not programmers or computer scientists and may do funny things that a computer scientist would not. Like one based indexing of arrays in Julia. This is not a big deal but I'm a bit wary that there may be some nasty surprises for a language geek computer scientist like me :)
Another example is the byte addressing of UTF-8 strings, which may give an error if you try to index strings in the middle of a UTF-8 sequence [1]. s = "\u2200 x \u2203 y"; s[2] is an error, instead of returning the second character of the string. I find this a little awkward.
There's a flip side to this too, if you're dealing with scientific computing there seems to be a wide variety of scientific computing libraries available in Julia [2].
Overall I find this language very interesting and it is on my shortlist of new languages to take a look at when time permits.
[1] http://docs.julialang.org/en/latest/manual/strings/#unicode-... [2] http://docs.julialang.org/en/release-0.2/packages/packagelis...
Strings in Julia are meant to be addressed in for loops; they index by byte not character because it's slow to index by character once you include Unicode. Julia trys, in general, to give you control over low-level things rather than hiding them with magic.
I like Julia because it's homoiconic, because of it's type system, because multiple dispatch is fun and new, and because it's just plain fun to write. I do static analysis, not math/science.
Yes, it's a little awkward, but to understand why this tradeoff was made, think about how you'd get the nth character in a UTF-8 string. There is a tradeoff between intuitive O(n) string indexing by characters and O(1) string indexing by bytes.
The way out that some programming languages have chosen is to store your strings as UTF-16, and use O(1) indexing by two-byte sequence. That's not a great solution, because 1) it takes twice as much memory to store an ASCII string and 2) if someone gives you a string that contains a Unicode character that can't be expressed in UCS-2, like 🐣, your code will either be unable to handle it at all or do the wrong thing, and you are unlikely to know that until it happens.
The other way out is to store all of your strings as UTF-32/UCS-4. I'm not sure any programming language does this, because using 4x as much memory for ASCII strings and making string manipulation significantly slower as a result (particularly for medium-sized strings that would have fit in L1 cache as UTF-8 but can't as UCS-4) is not really a great design decision.
Instead of O(n) string indexing by characters, Julia has fast string indexing by bytes with chr2ind and nextind functions to get byte indexes by character index, and iterating over strings gives 4-byte characters. Is this the appropriate tradeoff? That depends on your taste. But I don't think that additional computer science knowledge would have made this problem any easier.
> Yes, it's a little awkward, but to understand why this tradeoff was made, think about how you'd get the nth character in a UTF-8 string. There is a tradeoff between intuitive O(n) string indexing by characters and O(1) string indexing by bytes.
I understand the problem of UTF-8 character vs. byte addressing and O(n) vs. O(1) and I have thought about the problem long and hard. And I don't claim to have a "correct" solution, this is a tricky tradeoff one way or the other.
I think that Julia "does the right thing" but perhaps exposes it to the programmer in a bit funny manner that is prone to runtime errors.
> The way out that some programming languages have chosen is to store your strings as UTF-16, and use O(1) indexing by two-byte sequence.
Using UTF-16 is a horrible idea in many ways, it doesn't solve the variable width encoding problem of UTF-8 but still consumes twice the memory.
> The other way out is to store all of your strings as UTF-32/UCS-4. I'm not sure any programming language does this, because using 4x as much memory for ASCII strings and making string manipulation significantly slower as a result (particularly for medium-sized strings that would have fit in L1 cache as UTF-8 but can't as UCS-4) is not really a great design decision.
This solves the variable width encoding issue at the cost of 4x memory use. Your concern about performance and cache performance is a valid one.
However, I would like to see a comparison of some real world use case how this performs. There will be a performance hit, that is for sure but how big is it in practice?
In my opinion, the string type in a language should be targeted at short strings (long strings are some hundreds of characters, typically strings around 32 or so) and have practical operations for that. For long strings (kilobytes to megabytes) of text, another method (some kind of bytestring or "text" type) should be used. For a short string, a 4x memory use doesn't sound that bad but your point about caches is still valid.
> Instead of O(n) string indexing by characters, Julia has fast string indexing by bytes with chr2ind and nextind functions to get byte indexes by character index, and iterating over strings gives 4-byte characters. Is this the appropriate tradeoff? That depends on your taste.
This is obviously the right thing to do when you store strings in UTF-8.
My biggest concern is that there will be programs that crash when given non-ascii inputs. The biggest change I would have made is that str[n] should not throw a runtime error as long as n is within bounds.
Some options I can think of are: 1) str[n] returns n'th byte 2) str[n] returns character at n'th byte or some not-a-character value 3) Get rid of str[n] altogether and replace it with str.bytes()[n] (O(1)) and str.characters()[n] (where characters() returns some kind of lazy sequence if possible, O(n))
You're right, this boils down to a matter of taste. And my opinion is that crashing at runtime should always be avoided if it is possible by changing the design.
> But I don't think that additional computer science knowledge would have made this problem any easier.
There is a certain difference in "get things done" vs. "do it right" mentality between people who use computers for science and computer scientists. The right way to go is not in either extreme but some kind of delicate balance between the two.
Most languages, from C and C++ to Python and Java were not created by "computer scientists".
Usually it's either programmers that studied math or came from some other profession (physicists, linguists like Larry Wall, even philosophers).
>Another example is the byte addressing of UTF-8 strings, which may give an error if you try to index strings in the middle of a UTF-8 sequence [1]. s = "\u2200 x \u2203 y"; s[2] is an error, instead of returning the second character of the string. I find this a little awkward.
That makes perfect sense if Julia cannot yet handle indexing strings on graphemes.
In essense, there is NO "second character" that you're getting when "byte indexing" a string. You might get one (if it's ascii all the way), or more possible you'll just get an invalid part of a character as a byte.
In other languages with similar limitations (like PHP) you get a broken result with no warning at all.
A friend of mine is really proficient with R; when I walked him through some of the R patterns that are very confusing/irregular to me, he sort of laughed: he could see what I was saying but he said "with R you can't worry about things too much, you kind of just have to just go with it."
If Julia can serve some of the same use cases but in a better-designed way, sign me up!
Just curious -- what patterns bothered you the most with R btw?
It's mostly around the multitude of subtly different types and the ways you convert between them. I think I also remember strange things like lists having named attributes in addition to list members that just seemed totally wrong and confusing to me.
I wish I could give you better specifics but it's been several years since I've done anything with R.
I've kept an eye on Julia and would love to use it in my everyday work, but also know that for now that's just not possible because of how many built-in functions and packages I rely on.
However solving this is just a function of time and community (Julia just needs their Hadley Wickham). I remember when people scoffed at Python because it has nowhere near the ecosystem that Perl did.
R's strength is not its language, it's the people. You need methods articles with supplements written in Julia, not R, for people to switch.
There is also a pretty good Julia-Python interface (https://github.com/stevengj/PyCall.jl) and bindings to Matplotlib (https://github.com/stevengj/PyPlot.jl).
[1] : http://www.burns-stat.com/pages/Tutor/R_inferno.pdf [PDF]
https://www.stat.auckland.ac.nz/~ihaka/?Papers_and_Talks
But now apparently Julia also fulfills Ihaka's requirements for the basis on the "new R" system, so I wonder is the need-for-speed part of the R community is considering a switch to Julia, instead of building a "new R" from scratch?
You want a fast car, but don't care much for having an aerodynamic design, hmmm..
EDIT: In retrospect I now think he means he wants to be able to create the project fast, and this is not about performance.
In dynamic programming languages it is definitely easy to get shit done, at least initially.
However as a project progresses to the point where a lot of refactoring takes place and there's more than a handful of people working on it, a good static typing language will make sure that shit keeps on getting done and things won't break due to a subtle typing error. Things will be caught by the compiler even before you get running the test suite.
In other words, automatic program-correctness check is a crucial feature if project goes larger. And type check is actually one of the simplest, easiest and fastest way to archive that.
But most dynamic languages doesn't provide type-check. Really sad.
Adding type annotation on dynamic language is a kind of best mix of two worlds, and Julia seems pushing this approach even further - JIT static types from type annotation.
irb(main):001:0> 1 + "hello"
TypeError: String can't be coerced into Fixnum
from (irb):1:in `+'
from (irb):1
from /usr/bin/irb:12:in `<main>'http://scholarworks.umass.edu/cgi/viewcontent.cgi?article=10...
Julia's target audience is technical computing, and a large fraction of software in this space is built to solve a particular problem that only might matter for 6 months or a year. You might be trying to simulate the behavior of an experiment you just designed, for example, or trying to analyze a very specific property of a data set. These codes are often very tightly coupled to the scientific problem, and are only ever used in the context of a particular short-lived project. You do the experiments, write the paper, and move on with your life.
To be clear, I don't think Julia itself encourages this pattern any more or less than another language. But it's a very common pattern for scientists, so they often don't care about long-term maintainability.
Granted, this sometimes comes back to bite them later, if they discover the old code is good for a newer experiment, or they need to go back and re-validate results. But this doesn't always happen, and it's not like they're running a live service with customers -- when they finish a given paper, it's actually not unlikely that no one will ever need to use that software again. It's not easy to argue that they should care about maintainability when there's a decent chance this is one-off code.
And probably few buyers who want fast cars care about aerodynamic design per se -- they care about speed; sure, if better aerodynamics is what's necessary then so be it, but they would also prefer a fast car with poor aerodynamics and a huge engine to the very aerodynamic and fuel efficient, but slow one.
I think what he means is that 'safety, type systems, homoiconicity...' may or may not be important, but he's more worried about the end result.
So if other people want to work on those things, good for them. He's going to be working on his own stuff.
I'm going to put together a BioJulia team is anyone is interested in playing.
In my opinion the problem with computational biology is that most biologists are not keen to improve beyond a basic level of programming.
Numpy/pandas are good. But as evidenced by the Julia benchmarks, Numpy is relatively very slow. Also, most things that slow down computational bio are to do with much broader aspects of the language than linear algebra libs. Most successful standalone sequence analysis software is written in C or C++ for this reason.
I have been in the field of computational biology for (practically) 3 years. In this time, I have seen my fair share of bad tools and silly approaches to very basic problems. A lot of the computer science folks may not realize it, but there is a lot of trouble of basic software engineering sort in computational biology. There is a lot of old, unmaintaned code, messy projects implemented in multiple languages, and (of course) bugs. It does not appear that anybody checks or maintains their code after publication - the projects often die after they appear in a journal once.
There is a number of reasons that the situation is the way it is. One of the sadly obvious ones is that the academics do not have the time or desire to maintain their code. Some of the project would require full-time coders to be maintained - and that is indeed the case for some of the bigger and more popular tools. This results in the fact that some projects never take off or live up to their potential - for the simple lack of time. The wasted effort means that a lot of work is being re-done and science in general stagnates because of that. There is no easy solution to this problem (other than centralizing the efforts somehow - but that is the question of community, not tools).
The issues that can be made better are the following (and I will start with the most obvious ones first):
1) We need a language that is both easy to write in and is fast enough for production. Too many times there exist projects that are written in multiple languages. I have myself partaken in a few of those. The high level code is usually written in python or perl (I shiver of the thought), while the heavier numerical things are done in C or C++. This creates a rather large divide in terms of who does what - quite often folks only know a single high level language - so the numerical implementation stays opaque with only a single person knowing how it works. This means that projects of that sort quickly become unmaintainable. There is also a lot of glue code written - and God help you if you need to understand how perl-guts work. If there was a single sane implementation for both high level and numerical stuff, it will solve a lot of those problems.
2) We need a fast language. Building on the previous argument - the reason for splitting is quite often performance. This means that we use a single language for both layers - and we get the "Node.js" effect (I'm not sure who to reference this phrase to) - both front- and back-end stuff comes together. This also means that you are not penalized for using complicated data structures in your numeric code - so one level of separation falls away automatically.
3) We need a language with a large number of capabilities. Julia community is aiming to replicate a lot of the functionality of R. That means that it is already possible to use Julia for, say, an undergraduate statistics course. There is absolutely no reason (other than the historical, of course) why R is used by the statisticians. It was written by statisticians for statisticians - and has a lot of nice features. However, that means that a lot of the efficiency considerations have been missed. R does a whole lot of data copying - which is ridiculous for large data sets. For the growing crop of statisticians it will barely make a difference which language is used - I would go as far as to say that a lot of undergrads will not even notice the difference, but those who will, will thank us later.
4) We need a functional language. Much rather, we need a multi-paradigm language that has a strong functional basis. The advantages of the functional approach are too many to name here - and I am afraid this is already becoming incomrehensive. A lot of formal math and stats is really easily translatable into functional mindset - and that is a great boon if you are trying to implement an algorithm out of a math paper. Also, Julia does not restrict you to think in a particular way - it is very adatable to your thinking patterns.
These are just a few reasons that I would try give to support a case for a new language in the scientific community.
The source of this app can be found here:
https://github.com/gokmen/julia.kdapp
I'm happy to answer any questions :)
They don't have IJulia (yet) though.
Maybe it's just me, but in the apps I write in dynamic languages, the bottleneck is rarely in the language. It's usually in some IO.
EDIT: some sentence in the article gave me the impression he was using this for non-math-heavy stuff which is why I said this
^^ This is the use case for Julia.
Mostly I was responding to the idea that there is a relationship between dynamic languages and IO bottlenecks. This is certainly often the case in things like web development, where dynamic languages dominate, but under the hood, Julia has relatively little in common with Python/Ruby/JS/PHP/etc, in terms of how it's implemented or, especially, what it's intended to do.
[1] Of course, you might still represent the majority of people using dynamic languages, but you get my point.
There are a lot of reasons to want speed in a dynamic language.
What about maintainability? "Code as if the next guy to maintain your code is a homicidal maniac who knows where you live." -Kathy Sierra and Bert Bates
In my experience, making something work and making it (relatively) faster is easy. Making it easy to read is hard.
Even in a prototype, you may need to rework a particular piece of code multiple times before it works correctly. Even with a prototype, you may need to use it as a reference for your official version. Even with a prototype, you may end up having to use that as the official version (usually not by my choice).
Also, caring about speed 2nd is shocking to me (but maybe I just come from a different world). What if it isn't fast enough on your first attempt? Won't you wish your code was maintainable so you could change it to be faster?
From my experience, this isn't the case at all. A lot of the time my first attempt is in Python. The first attempt is really more of a prototype or a proof of concept. If the code works and I want to productize it, the code needs to be sped up. I have (at least) 2 choices: (1) make the Python code as fast as possible or (2) rewrite the whole thing in C/CUDA. If I take option 1, performance gains will be marginal and I still probably won't be happy with the performance of the software. Option 2 might take a bit longer, but at least I'll get something performant out. As I'm just throwing out and rewriting the first attempt, I don't actually care at all if it was maintainable code. I don't even care if the ideas in it were well explained/commented, because they're all my ideas and they're still fresh in my mind and I'm just going to rewrite the code and then document/clean up the fast version.
The appeal of Julia is that I no longer have to do this rewrite to make my code fast. Furthermore, if I don't have to do this rewrite, it is actually in my interest to make my first version of the code be maintainable and well documented.
A former co-worker of mine was having trouble understanding the results of her experiment. The simulation software she was using had been the gold-standard implementation for over a decade. The code was clear, well documented, and well engineered. However, my co-worker decided to re-invent the wheel and write her own. The results of her code exactly matched the results of her experiment. Thus, she designed a new experiment and predicted the results with the standard code and her own. After performing that experiment, her simulation was vindicated. It eventually came out that the standard code made assumptions that were invalid in a huge portion of the phase space.
It's important, as a scientist, to be able to perform the same experiment twice and get the same result. However, it's far more important to perform to different experiments and get the same result. If measuring my body temperature a hundred times with the same thermometer isn't nearly as useful as measuring it twice with two different thermometers. Having one piece of code that runs on on a hundred different computers, giving the same result every time, isn't as useful as having two different, independent code bases.
I do my best to make my code maintainable. I have everything up on github. I'm constantly trying to improve the documentation. However, if my code is still being used ten years from now, we have failed as scientists. What should happen is that a new code base should be written that does the same things that my code claims to do. If we get the same results, then great. If we don't, then we find out why.
But that's not happening. There's no plans for an independent re-interpretation. Everyone keeps using my code, because it's clear and it "works". If my code was less maintainable, then that re-implementation would eventually occur and they would be able to check my results. Only then would we truly know if my code works or if it just "works". I'm not going to do that, but I'd understand the reasoning behind it.
I'm in Chicago (and a U of C grad!). I might come to the meetup if I can.
Julia may have just saved my project (which was dying because it needed a good scripting language that was fast)!
[1]: http://docs.julialang.org/en/latest/manual/embedding/
[2]: http://docs.julialang.org/en/latest/manual/calling-c-and-for...
Multiple dispatch can make interfaces simpler: you can easily offer several "versions" of a function by changing which arguments they take, and you can define those functions where it makes sense, even if those places are spread across multiple modules or packages. Julia provides great tools (functions) that make methods discoverable, help you understand which method you're calling, and help you find the definition of methods.
Looking at some Julia code (the base library or major packages) might give you a better idea of how Julia uses multiple dispatch.
"The problem with most programming languages is they're designed by language geeks, who tend to worry about things that I don't much care for. Safety, type systems, homoiconicity, and so forth. I'm sure these things are great..."
Yes, those things are great. They ultimately aid in helping the programmer tackle the inevitable complexity that arises when building systems in a maintainable way.
i lead the Python Tools for Visual Studio project at msft and would be curious if there is interest.
as a side note, if you do you use Python & require Python/C++ debugging, PTVS now supports it: http://www.youtube.com/watch?v=wvJaKQ94lBY#t=10
Integrating with Pkg as Julia Studio does would be another important feature, as well as providing some sort of integrated plotting/graphics widget (a backend canvas along with plot navigation and image export, ideally supporting more than one of Julia's plotting backends).
I would certainly contribute to an alpha- or beta-testing effort :)
It was easy to see how useful and expressive the language was by just doing a few Project Eulers.
Julia is a kind-of-fine language that is designed to appeal Matlab users first of all by its syntactical looks. Just like Javascript was designed to appeal to C and Java users by imitating their look.
Under the hood, Julia is quite a smart development, not only in terms of code generation, but also in terms of datatypes and object models.
Multiple dispatch is something that more or less only Lisps typically offer natively (and Dylan). When working with types (especially in dynamically strongly typed languages) this is often something what I am missing in other languages. Consider Python:
if isinstance(x, Y):
...
elif isinstance(x, Z):
...
This feature alone shows that the authors of Julia are rather the thoughtful language-loving authors.So I would like to leave the small scope of the article but look at the greater picture: Julia and its competitors. There are actually quite a few on the market. A few domain-specific numerical libraries exist for C/C++/Fortran for scientific purposes (ROOT at Cern, etc.). They are more or less falling out of fashion. For a long time, Matlab has been dominant in some faculties for evaluation and working with data, process signals and images. It is not by accident that Matlab was created as a convenient Wrapper to Fortran libraries at the time. From a software developer's perspective, Matlab is for Cowboys.
Next to its high price (and the vendor lock in forced upon college and university students who are trained for matlab when there exist suitable open source alternatives), the most appalling thing about Matlab is its poor performance as a programming language. While its easy to write small scripts, solve linear algebra problems and plot a few things, I have hardly seen well organized Matlab code and I just think that it is impossible. While Matlab licenses cost heaps of money, support is not good and upon a version change you have to spend considerable amounts of work getting around API changes.
The Matlab clones available (Octave) are generally unimpressive. I think this has to do with the big effort of copying Matlab and the need to develop the whole tool stack (parser, interpreter, libraries). Contributors are hard to find because octave hardly offers any benefit over the original, like ReactOS with Windows, Octave can only react. I still value the effort of the octave folks, they have done some great work!
Scientific Python has chosen a slightly different path. Taking the fairly uncontroversial programming language Python, the authors created an infrastructure of thematically separated modules. While eliminating the need to design and implement an own programming language, a lot of work could be spent on building useful libraries. Also, existing libraries were reusable (databases, XML, etc.) and Python is a really convenient programming languages for both Newbies and professional software developers. So with this pragmatic approach, the contributers have created one of the best environments for scientific software development and would be my suggestion for anyone at the moment who just wants to use one system.
What still amazes me: While working in an ipython notebook (http://ipython.org/notebook.html) on some numerical calculations, I can just pull up Sympy (http://sympy.org) and perform some symbolic computations (Fourier transforming some function analytically or taking the derivative of some other, etc.).
Oh, and have I told you about how Scipy can replace R for really cool statistical analyses?
The part where Julia kicks in now is the point that Matlab has a lot of market ground, especially with engineers who are not extraordinarily passionate about programing. For some people the burden of learning another syntax is just too big, they are not full time programmers but spend their time more with acquiring data and using the results. I really hope that some of them who are not willing to switch to scientific python can agree on switching to Julia.
Full Disclosure: I have occasionally been forced to work with Matlab (so I do have some experience with it without being an expert) and it was not fun. This is one of the reasons I would like all Scientists to have the chance of choosing a good environment that is suitable for them. If its Matlab for some, so be it ;-) I have never looked back.
Nah, we have no shortage of contributors:
http://hg.savannah.gnu.org/hgweb/octave/
http://hg.savannah.gnu.org/hgweb/octave/file/052cc933aea6/do...
As I see it, this will be Julia's main market. Younger engineers (read: "non-CS engineering students", i.e. electrical, mechanical, civil, etc) may encounter Python in college and become proficient in it, but because of historical reasons most of their assignments require some combination of Matlab, C, or Fortran. Even in group projects where the students have more independence with their choice of tools, if only one person in the group knows Python, the group will probably default to one of the common tools. When time is a scarce resource and time spent learning Python doesn't show much promise of improving your class performance, most students will neglect it.
Julia, at first glance, looks very familiar to a practicing engineer or scientist who is experienced with Matlab or Octave. It's the sort of thing that you could teach yourself in a weekend, and teach others at work if need be. Not necessarily the low level cleverness of the language or some of the more advanced uses of it, but enough to Get Stuff Done(TM). And that's what matters to most technical types without a background in CS. They will appreciate elegance and safety when they see it, but they're not going to decide what tools to use based on those factors.
Then because professors demand it, colleges buy Matlab campus licenses and "encourage" their staff/students to use it, incorporate in teaching and research.
Sadly, when the student is not on campus anymore, he/she cannot reevaluate old date and in the new job they then demand a matlab license. Its the Matlab tax.
real :: x(-10:10)
is a real vector of 21 elements from -10 to 10.
You can certainly do it with Matlab (provided you have purchased the symbolic toolbox of course).
Oh, and have I told you about how Scipy can replace R for really cool statistical analyses?
Sure, it can for some things, but why?
My thing with Python is that it kinda loses to Matlab for non-statistical work (except perhaps for select fields, like network analysis or language processing), and to R/SAS/Stata (depending on type of job and personal preference) for statistical stuff. Of course all of these (other than R) are proprietary and not cheap, but most universities have all of them anyway, and businesses just buy what they need.
btw: did you first learn Matlab, or Python? In my experience, there is a tendency for people who start with Matlab to dislike Python, and for people who start with Python to dislike Matlab :) Probably has something to do with some basic things being just so slightly different, and therefore bothersome.
Also, the Matlab IDE these days is actually quite decent -- does Python have something similar?
Quick google search yielded: http://networkx.github.io/ do not know how it compares though.
I switched to Sci.Python at the point where I had difficulty treating time series data with Matlab. I know there is a toolboxy-thingy from mathworks but it either was not available or I did not find the documentation. Anyway, I quickly got started with Pandas. I had prior knowledge of Python and other mainstream programming languages before.
Spyder is a Matlab-ish IDE with a variable explorer, etc. Some like the Ipython Notebook which I think is great for demonstrations and teaching, but eventually does not scale when projects grow bigger.
For time series data, I'd personally pick R though, or perhaps SAS if it's large enough -- at least if any statistical analysis is involved...
I need to check out Spyder.
I think enthought offers commercial tooling and support and also a IDE platform with tools for data story telling etc.. I usually use vim.
And there's a python IDE called spyder which is similar to the matlab IDE.
Python destroys matlab in all other regards. Once you've tried it for a while you'll understand the value of a general purpose programming language with advanced numerical capabilities
"Safety, type systems, homoiconicity, and so forth. I'm sure these things are great, but when I'm messing around with a new project for fun, my two concerns are 1) making it work and 2) making it fast."
Uhhh... Call me crazy, but wouldn't the "so forth" be what you care about if #2 is that important to you?
The Julia plotting packages are Winston, Gadfly, and Gaston. You can find detailed discussions of which one to use on the julia-users mailing list.
The benefits of automation are mostly denied to me because I haven't the time to learn Julia or properly use the Python skills I already possess. I do however have the time to link and configure objects ala Scratch and Apple's Automator, or the first generation of what was once Allaire's Cold Fusion. Its not just me, either. The demand for automation tools is pervasive in business and education, but the time and innate skills needed to program effectively belong to a subset of the needy. Bring me a language that is truly a means to an end and take my money.
There is an github-issue about the closure slowdown, but I don't have it handy. Both can be worked around, by writing in a lower level style, e.g. by using explicit loops acting on pre-allocated buffers, avoiding higher-order functions, etc. The pre-allocated buffers can be a lurking hazard though (Rust avoids the danger in the same strategy with its safe immutable "borrow" idea). I felt like these workarounds were giving up too much of the advantages of a high level approach for my own tastes.
I have converted to Rust to avoid the garbage collection for sure, and I'm extremely pleased with the performance. It would be nice having a REPL though, I do miss that. And I do intend to stay involved with Julia. I'm sure the situation will improve.
Good high performance garbage collectors aren't easy (and they are easy to take for granted after being on the JVM for a while) - that's probably the biggest challenge for Julia as a high performance language, IMO.
Manual entry on calling C: http://docs.julialang.org/en/latest/manual/calling-c-and-for...
Blog post on passing Juila callback functions to C code: http://julialang.org/blog/2013/05/callback/
That sounds like someone who has not had to maintain any kind of software for more than 2 days.
Such an organized site where you could drill down to topics of interest through broader categories would really be helpful. It would be best, of course, if it was set up and accessed through julialang.org as something official.
I don't know how to do that or I would. It isn't reputed to be very difficult to set up a phpBB site and I'm sorta hoping some enthusiast who does know how picks up on it.
One thing -- can we call agree that dictionary literals begin and end with '{}', that arrays are zero-indexed and that an index into a unicode string is properly a character and not a byte? Or are we doomed to permute endlessly on details such as these? I wish any new languages would set aside a large set of tempting innovations and just go with the flow on the smaller points.
["one"=> 1, "two"=> 2, "three"=> 3] # -> Dict{ASCIIString,Int64}
{"one"=> 1, "two"=> 2, "three"=> 3} # -> Dict{Any,Any}I stopped right there. Node.js has only a few great use cases where it shines and in the real world, the vast majority of shops have not switched to using it.
Of course not. 'Switching' is usually more pain than it's worth, especially if your previous solution works. New start-ups are likely the ones who will be using it, just as Rails took off in the start-up world.
Likewise, R and Python are going to continue to be in use in existing projects, and Julia is the potential future...
Or you could use something like Coffee-script from front-to back. It's a very easy eco-system to get into.
How has it "shaken things up"? It is yet another irrelevant mess of crap a few dumb web monkeys use. There's one of those every other month.
function foo(bar, baz)
end
and 1-based indexing of arrays (although Julia's use of that was to be similar to MATLAB).