It seems like the author isn't really defending against the bulk of the criticisms, which revolve around correctness and reliability, and instead highlights 'cool' language features. If you can't trust gradients or probability distributions / sampling to be correct, that's a pretty damning verdict for a language aimed at numerical calculations. The fact that it has some traction in academia (where the link from incorrect computation results to real-world consequences is extremely long-winded and hard to attribute) is worrying from that perspective. Imagine Boeing were to use Julia for its computations (not unlikely given that it has a great repuation for differential equation solvers).
I really like Julia, and I think this article does a great job of defending its design decisions. But I'm a bit disappointed that it doesn't address Yuri's main criticism, which is that there's some worrying correctness bugs in Julia that aren't addressed as well as they should be.<p>I'm no language expert, so I can't tell if Yuri's criticisms are just a function of the smaller number of people working on Julia vs a very popular language like Python, or whether the failings he discusses stand out <i>because</i> so many things Just Work in Julia, or whether it indicates some much deeper problem, so I've gone back to look at the original thread - <a href="https://news.ycombinator.com/item?id=31396861" rel="nofollow">https://news.ycombinator.com/item?id=31396861</a><p>I'm interested to hear what others think of Julia's longevity prospects. Its popularity in climate modeling and other scientific contexts suggest it will be around for the long haul, and that Julia projects needn't end up as abandonware for lack of footing. Is that accurate?
> One such operation can be to sell. The sell function can do things like marking the book object as sold<p>Maybe this isn’t a good example of OOP?<p>Does it suggest the author perhaps doesn't fully understand principles behind loosely coupled OO code?<p>If <i>is_sold</i> is an attribute of book, the class shouldn't have a <i>sell</i> method, but a <i>mark_as_sold</i>.<p>The action of <i>selling</i> is not the responsibility of a Book. Baking it into Book will create tight coupling between areas of the code (product and commerce) that should be loosely coupled. The "commerce" side may change for reasons unrelated to the "product" side. Keep'em separated.<p>And if we think for a minute, <i>is_sold</i> should not be a Book attribute in the first place. It seems to me this piece of information should be handled somewhere else related to inventory, not by the Book itself.<p>There should be a ProductEntry class, for instance. It could have a <i>product_type</i> and <i>product_sku</i> attributes, for example, pointing to a Book.<p>Even here, <i>is_sold</i> shouldn't be an attribute, but a method. It would have an <i>availability_status</i> attribute.<p>func is_sold(self) {
return self.status == ProductStatus.SOLD }<p>Ultimately, the inventory code should not care that it's a Book or whatever.<p>The logic of whether it's available or not doesn't belong to the product itself. What if someone bought, but returned it? Maybe it will be available for shipping tomorrow and the store wants to start reselling it already? Is it the Book responsibility to track that? No way.
To phrase succinctly the (direct) counter to the previous blog post: Julia makes possible the kind of combinatorial composition (and therefore, radical modularity & reuse) that is simply not possible in most languages. This will lead to some friction as the community figures out the right design patterns in these uncharted waters, but on the flip side one already gets many superpowers, provided one is careful about testing the composition works as expected, rather than just blindly assuming it does.
> Finally, it is also likely that CPUs will become faster over time and that tooling around reducing TTFX will improve.<p>I don't agree with this as a mitigation. This line of reasoning is why despite steady hardware improvements over the past few decades, responsiveness of (PC) programs and websites have stagnated or regressed.<p>To the main TTFX issue - I won't consider Julia until this is taken seriously.
> Based on the amount and the ferocity of the comments, it is natural to conclude that Julia as a whole must produce incorrect results and therefore cannot be a productive environment. However, the scope of the blog post and the discussions are narrow. In general, I still recommend Julia because it is fundamentally productive and, with care, correct.<p>If TFA really means "Most of the time if statements take the correct branch, and it's unusual for them to take the incorrect branch, and you should use tests to detect whether the if statements in your program are working" then I would appreciate it if TFA would come out and say that. I am sort of used to programming in environments in which if statements work 100% of the time.
I don't see how it addresses the original complaint. Vishnevsky basically stated that if you are trying to run a scientific experiment on a supercomputer, maybe it's a risky idea to use a new programming language with a new stdlib and a bunch of OSS libraries vs using an old language like C with very stable set of existing code because new things tend to have unknown bugs? Vishnevsky has a point, but unless you are running some critical computations on supercomputers, maybe it doesn't apply to you?<p>To be clear, in supercomputing environments people still use old versions of CentOS just to make sure that library version updates do not change their computation results. I don't think many people here would say "I am sticking to Ubuntu 16.04 because I am afraid that the updates to some library like gmplib will slightly change my computation results in a way that is hard for me to detect".<p>Also, just staying with the old doesn't mean it's correct. You can also introduce bugs to your libs. I think NASA thought this through long time ago and solved it by making sure critical parts of the code are implemented twice using different stacks with different programmers.<p>If you are NASA, CERN, LLNL, or a bank, maybe it's a good idea to implement your computations once in Python and once in Julia (by at least two different programmers) and compare the outputs. And I don't think in this situation Julia is any different from other languages (other than you may put too much trust into it and skip this dual implementation). Case in point: <a href="https://github.com/scipy/scipy/issues?q=is%3Aissue+is%3Aclosed+label%3Adefect+wrong" rel="nofollow">https://github.com/scipy/scipy/issues?q=is%3Aissue+is%3Aclos...</a>
I just came across Yuri's criticism for the first time, but it makes sense to me. I am not a user of Julia, but have followed it with interest since they published their first paper about it. With hindsight, it is clear that they would run into correctness issues due to their powerful composability features. The solution is obvious and hard at the same time: there must be a way to PROVE correctness. Of course, to incorporate a prover into Julia will be pretty hard, it is probably much easier to incorporate (some of) the ideas of Julia into a new shiny prover.
How can the author make the argument that OOP makes things too tightly coupled, then claim that it's up to the developer to check if every single coupling in their code is correct? The coupling is still tight, it's just not enforced by the compiler. There's a reason for tight coupling in OOP: it's better to let the compiler check for correctness rather than every single developer out there.
I do think that Julia in general isn't the best for interacting with C(based off of some experimenting 2 years ago). I have tried using it with a decent number of odd C libraries used in Scientific Computing(with actual capital S and C. Which always involved binary blob libraries.). I think if you control more of the stack it is a better language. But when using it with vendor provided binaries I ran into many many issues.<p>> "with actual capital S and C." This part was referencing the industry and not me being egotistic.
Various people have expressed skepticism of needing language level traits, but it's in vogue to be writing interface packages with no top level abstract types (see Tables.jl) because we don't have some way to extensibly express being part of multiple type trees.<p>It's challenging enough that Abstract Types have no interface specs (it's claimed that this is a feature, allows interfaces to develop over time), but it's even tougher when things get even looser with this new trend towards have untyped functions...even various interface package maintainers themselves have said the current state of affairs is difficult.<p>And if we do want to opt into abstract typing, you're going to be inheriting lots of functionality that could be better broken into smaller typeclass like components (see AbstractArray).<p>I think Julia is screaming for some capability to break up Abstract types and being able to inherit from multiple kinds of things, along with specified interfaces with these things.<p>The problem is that this is very difficult, given the complex subtyping system and multiple dispatch. Adding more complexity exacerbates already present method and typing decidability issues. People are working on this on the periphery, but I hope it can become a priority of the core team and that it's solvable.
My major problem with Julia is that writing performant code is a bit like writing Haskell.<p>You need deep understanding of the compiler to know what constructs will mess up performance. Especially how typeinfo is propagated.
I've noticed that any time you need to use the word "still" to argue for something, you've usually already lost the debate or the larger point.<p>I can't imagine anyone writing a post along the lines of, "Why I still recommend SQL for querying databases", even though SQL was conceived back in the 70's. "Still", in this context more often than not suggests that a grasping-at-straws is taking place.<p>Julia has a lot of neat features, but at the end of the day, it's a research language rather than a getting things done language.
> The idea is that when you are, for example, writing business logic with books, then you want to neatly put the operations on the book near the definition of the book.<p>That's not the idea. You put the code for the "internals" of a book near to its definition. In other words: The code that needs to see the private/protected members of a class. It is not good OOP - if I may be so bold as to use that phrase - to stick as much functionality as you can involving some class, into that class.
The example using Measurements.jl only works as a good example for composibility if you use `Number` as the type for the argument. If you happen to use Int then it doesn't work:<p><pre><code> using Measurements
plus_one(x::Int) = x + 1
plus_one(measurement(1))
ERROR: MethodError: no method matching plus_one(::Measurement{Float64})
Closest candidates are:
plus_one(::Int64) at REPL[2]:1
Stacktrace:
[1] top-level scope
@ REPL[3]:1
</code></pre>
This is perhaps my biggest annoyance with Julia. Concrete types cannot be subtyped, and hence cannot be extended by other packages. And explaining to researchers and scientists that they need to use abstract types to make their code more composable is exercise in frustration. I think computer scientists with experience programming in C++ may have good intuition for when to use concrete or abstract types in the function signatures, but research scientists in ML and optimization (in my experience) just don't do a good job of that. And just end up having awful Julia code to work with, that isn't really extendable. In my opinion, readability suffers greatly when you have to understand the type hierarchy in order to find out if your code will MethodError or not. For example, if the author use `plus_one(x::Rational) = x + 1` instead of `plus_one(x::::Number) = x + 1`, would the code that uses Measurements.jl have worked? Who knows just by looking at the code. It turns out it doesn't work and there's a MethodError. The built in type hierarchy is great, but third party packages are hit and miss.<p>Honestly a simple solution to this would be to allow concrete types to be supertypes of other types. My understanding is that there's no compiler related reason for this, and this is just for "good practices" but for the life of me I don't understand why this limitation was made. I've seen Julia code that creates a supertype abstract type for every concrete type they create, and it is just awful to deal with. Fortunately, it is somewhat easy to write a macro to make this happen, but still very annoying that one has to do this at all.<p>Combine that with the lack of a file system package modules (like in Python or Rust), the lack of any kind of doctests, the built in testing being so lackluster, you end up with really poorly organized code.<p>TSCoding has a 1 min video on why he doesn't program in Haskell anymore [1] and I can't help but feel his reasons directly apply to Julia too.<p>For example, in order to run that example for this comment, I had to run `add Measurements` and it took 7 minutes to download the package. Why is the "registry" for packages in Julia a giant git repository? It takes SO long to update every time. This is an example of a poor software engineering decision in an otherwise elegant language.<p>[1] <a href="https://www.youtube.com/watch?v=SPwnfSmyAGI" rel="nofollow">https://www.youtube.com/watch?v=SPwnfSmyAGI</a>
I like Julia a lot
I think it needs two things (for me)<p>1. better database support, also need to support BI Cubes likes MS SSAS<p>2. fix scoping rules<p>I created a small feature request on github, where I suggest a fix for their scoping (inspired a lot by perl), and I would like to take this opportunity to promote my suggestion, I think its a good one, that will make Julia nicer<p><a href="https://github.com/JuliaLang/julia/issues/37187" rel="nofollow">https://github.com/JuliaLang/julia/issues/37187</a>
Btw, you can totally have classes in Julia. And methods will be compiled like all other functions. It's just not considered particularly idiomatic.
R has multiple dispatch right with s4, I don't recall running into huge library compatibility issues with R? Is the only difference between R and Julia maturity where R has ironed out the sorts of bugs Yuri was running into?