Julia’s type system is not particularly user-friendly. For example, it has both a “String” and a “SubString” type which cannot always be interchanged. Their language design seem to be much more concerned with execution speed than programmer productivity — Python has the balance in the opposite direction, but they’ve been gradually improving performance for years, and this is much easier to improve after the language design is set in stone, especially as more and more people add typing info to their programs.
The issues with the type system and weak static analysis are the biggest gripes for me. The other features of Julia still make using it worthwhile, but it's rather frustrating to code compared to any language with good static type inference and a powerful type annotation system.
I largely agree, Julia is such a cool language and had so much potential. It definitely surprised me when they went with Swift instead, but realizing that Chris Lattner worked at Google at the time explained a lot. Unfortunately, every time I try to get into Julia, it just feels awkward coming from Python and a bit like stepping back in time.
The stupidest, (stupidest in the sense that I really wish they didn't bother me, because they're silly things!), things that bother me are:
1. The 'end' keyword. It's everywhere! Loops, if-else statements, function bodies. I mean I understand why it's helpful for parsing and providing more info to the compiler, but honestly, I would've rather we just stuck with curly braces '{}'! At least it's fewer characters to type and it just feels less crowded on screen while reading. It feels like such a petty complaint, but honestly, it feels like I'm writing Pascal or Matlab all over again. Which leads me to my second point.
2. The default choice of 1 based indexing. I'm not going to go into it, because plenty of people before me have beat this dead horse already[1][2][3], but I can't help but be saddened by this choice and its implications. It's important to acknowledge the fact that Julia started as a competitor to Matlab and Octav, so it makes sense from that perspective. However, it could have been a much more general purpose language, with huge performance benefits over popular interpreted languages like Python, JS, and Ruby. It could have been a unifying force in the scientific computing community, bridging the gap between R and Python users with a greenfield approach that would have been a force to be reckoned with. Instead, rightly or not, it's viewed largely as 'just' a matlab replacement.
Now, regardless of whether 1 or 0 based indexing is truly 'better' or the 'end' keyword is no big deal, the reality is that there's a huge demographic of potential users that won't buy into Julia, because it doesn't quite feel as ergonomic as Python/JS/Ruby and won't take it seriously as a general purpose language, because it looks/feels like Matlab and they only use 'real' programming languages. Again, I'm not saying this is right, but it is the reality we're faced with and it just feels like a huge missed opportunity and bums me out.
Personally I would like to see Julia go full static typing. The dynamicness of its current type system seems to offer me no advantages and is constantly causing me problems with performance. My code ends up covered in type declarations because I'm never sure when types are concrete or not,which kind of defeats the point of implicit typing. A lot of the time a seamingly innocuous change will result in Array{Float64,1} getting changed to Array{Any,1} which then gets propagated automatically though the whole program, since functions can't have return types.
Julia claims to be the future of numerical computing, but they seem to put more effort into coming up with fancy abstractions that no engineer or scientist will ever understand than working on basic numerics. For example, the array implementation is very hit or miss and much much slower than and has much more complicated semantics than arrays in Fortran. I think this is due to the fact that arrays are not first class objects in the language, and probably because the authors don't do much multidimensional high performance work.
Every time Julia pops up I can't help but get disappointed all over again. I was so intrigued by multiple aspects of the language, and even the type system seemed promising at first. However the inability to subtype concrete types is a total dealbreaker for me.
Everything else - even much of the type system - is extremely interesting. However the inability to subtype concrete types means you are essentially stuck with the unfortunately common inability to trivially specify how the heck your program is modeling your problem.
I just want the ability to specify an Apple_Count is not an Orange_Count without having to define my own damn operators. Why do so many languages make this so hard?
And Julia was so close, until one little sentence moved it so far away.
these are all very valid pain points with Julia, except I disagree with calling Julia "way more dynamically typed than Python."
I think of Julia as statically duck-typed, which sounds cursed but is incredibly useful IMO. like if you have `foo(x,y,z)=x+ycow(z)`, foo() will work for any x and y with compatible `+` operators, if there's a `cow()` that will accept whatever type `z` is. But it's still static - your code will throw a compile error* if x and y can't be added, or if cow() won't take your z. And unlike Python, Julia can dispatch on types, so you can implement cow() for whatever you want. the type system is, in fact, absurdly powerful. the downside seems to be that it's formally undecidable sometimes, and that you fundamentally can't enforce output types for functions passed as arguments.
the speed is a drag, but it feels like getting a train up to speed - it's slow getting ready to do absurdly heavy lifting.
Julia is a language that looks very simple, but the more you use it, the more you realize how complex and unpredictable it is.
I think that Union types do more harm than good (why would you want a function to return Union of int and float instead of compile error? It totally slows down the program)
Array{Number} is totally different from Array{:<Number}, and shouldn’t be allowed, as it is inefficient.
1-based indexing was a mistake, and I have seen it emitting inefficient code in the PTX compiler.
But the worst and hardest part is the rule/heuristic for multiple dispatch: it’s so complex, that it isn’t even documented. It should probably throw more errors and be predictable instead of trying to be so smart.
I think Julia actually does a pretty good job of showing that the problem isn't types. The problem is semantics. Julia's restriction is eval to the global scope is a perfect example of this. It has a pretty minor on code, but a massive effect on performance. Python has a ton of things like this where a slightly different (and totally breaking) semantic change prevents optimization.
Julia is weird.. it's like someone saw all of TypeScript's or F#'s opaque type errors and then thought "wouldn't it be better if all of these could happen... at run time?"
In seriousness I have been enjoying it a lot over Python, but I'd kill for static typing.
It's highly expressive (comprehensions, functional-style all-statements-are-expressions, anonymous named tuples, and heaps more) and these features seem to be usable without sacrificing performance, in a way that I've not yet seen in any other language.
I wish Julia was much more Lisp/Scheme-like in terms of syntax. If they'd just focused on making a more performant, typed-Scheme (or improving one of the existing ones), that would be much more interesting for me.
I took a dip in to Julia recently, and found it to be a mishmash of Lisp, Haskell, Matlab and Fortran ideas, wrapped in Python-like syntax.
I guess that can be appealing for people coming from those worlds, and for those for whom speed trumps everything else.
For me the loss of a Lispy syntax and the price of working with a relatively immature language wasn't worth it for me. I'd just rather use something with reasonable performance that's more Lispy.
Yeah, that's true. I think there are three major limitations.
- First, code that is intentionally (or out of neglect) opaque to the compiler. For example, someone may simply forget to write type stable code, or someone might intentionally create a function barrier to specialize some code
- Second, Julia has no standard way of encoding constrains on types. That's good, because someone else can make up a new type you never thought about, and throw it into your functions, and if it has implemented all the right methods, it will work. But it also means you can never guarantee your code will work for any type.
- Third, Julia encodes less information in the type system - e.g. the use of result types is not common.
I have a very high opinion of Julia's dynamic type system. Some static type systems are not very expressive, e.g., Elm, which encourages hacky workarounds. Julia's type system encourages specificity, which exposes problems early.
Yes. I really like Julia but I wish there was language that had all of the advantages of Julia but none of the drawbacks (for me it's lack of static typing, function(object) vs the more readable object.function(), 1-based indexing).
Julia is regarded as similar in syntax to python, or at least they have similar readability. What I love about it though (fyi not a CS degree person here) is the elegant way it handles types, and generics. User defined types perform just as fast as the built-ins, and I never seem to labor over design choices needed to generate fast computation.
Multiple dispatch is such a great way not to have to write boilerplate code for every method, somehow java seems very awkward in comparison.
Julia feels like a thoughtfully designed and carefully constructed language. I don’t havd the training to understand why exactly.
Thanks for your answer! I think it‘s a tradeoff between syntactic simplicity and explicitness. I enjoy languages like Scala or Rust that are more explicit, but I enjoy Julia as well (partly because of its simplicity).
I'm not sure I'd call Julia a dynamically typed language, each variable can have one and only one (possibly abstract) type which allows the JIT to avoid boxing and opens up plenty of optimisations.
I'm not particularly convinced that Julia's object model leads to inefficient memory access either.
Also, 1-indexed arrays are a major turn-off.
reply