Live data from Hacker News

Correctness and composability bugs in the Julia ecosystem

yuri.is

261–270 of 419 posts

Re: Correctness and composability bugs in the Julia ecosystem

#261

My opinion is that Julia was too ambitious from day one. Reimplementing the whole scientific computing stack AND a new modern language with an innovative type system and introspection AND perfecting tooling is just too big an effort. The priority for correctness has been drowned out by too much other issues and we are here with a 10 years old language with a very perfectionist and ambitious mindset that is still a ra…

If Julia followed your recommendation, it would be irrelevant before it ever started.

There is no way for a new language to be useful or relevant unless it brings significant improvements.

Re: Correctness and composability bugs in the Julia ecosystem

#262
Think about programing layers: A->B->C->D->...->Compiler->binary->output, where A is the end programmer, and B, C, D are the libraries and modules. I think what the article describes is not much different from issues in any complicated software systems, as quite a few comments also pointed out. However, when the language become more expressive and compiler become more clever, more of the issues will be rooted from the the compiler->binary link. I think this is inevitable with the current model of how software works, which I can simplify as: A -> [super compiler] -> output

The middle part is the concatenation of all the middle links and handles the complexity necessary to translate from language to output. As we trying to make A less complex, the middle [super compiler] will get more complex, and more buggy because of the complexity.

I believe the fundamental issue with this model is the lack of feedback. A feedback on output, and A makes change (in A) until output get correct. With the big complex and opaque middle, for one, we can't get full feedback on output -- that is the correctness issue. The more complex the middle gets, the less coverage the testing can achieve. For two, even with clear feedback -- a bug -- A cannot easily fix it. The logic from A to output is no longer understandable.

I believe the solution is to abandon the pursuit of magic solution of A -> [super compiler] -> output but to focus on how to get feedback from every link in A->B->C->D->...->compiler->binary->output

For one this give A a path to approach and handle complexity. A can choose to check on B or C or ... directly on output, depending on A's understanding and experience. For the least, A can point fingers correctly.

For two, this provides a path to evolve the design. The initial design on which handles which or how much complexity is no longer crucial. Each link, from A, to B, to C, ... to compiler can adjust and shift the complexity up and down, and eventually settle down to a system that fits the problem and team.

I believe this is how natural language works. Initially A tells B to "get an apple" and they directly feedback on the end result of what apple B gets to A and may alter layer of A by expanding into more details until it gets the right result. Then, some of the details will be handled by B and A can feed back on B's intermediate response for behavior. As the world gets more complex, the complexity at the layer A stays finite but we added middle layers. Usually, A only need feedback on its immediate link (B) and the final output, but B needs to be able to feedback on its next immediate link, and if A is capable, A may choose to cut-out the one of his middle man.

Re: Correctness and composability bugs in the Julia ecosystem

#263

Earlier quoted context omitted.

> I agree, code should never do that. It should be `eachindex(A)` Will that generate the same code as "i in 1:length(A)"? Maybe whoever wrote that didn't believe so at least, or perhaps didn't find it so at the time. The reason @inbounds would have been used is performance, so that's likely why the for loop header was written that way?

I think it should be fine for performance AFAIU to use `eachindex` instead; at least I know `eachindex` plays nicely with LoopVectorization.jl with no performance costs there. That said, I think you're exactly right that people may wonder just this and use the seemingly "lower-level" form out of concern with or without testing it.

One of my intentions with the rewrite is to let `@turbo` to change the semantics of "unreachable"s, allowing it to hoist them out of loops. This changes the observed behavior of code like

  for i = firstindex(x):lastindex(x)+1
    x[i] += 2
  end
where now, all the iterations that actually would have taken place before the error will not have happened. But, hoisting the error check out when valid will encourage people to write safer code, while still retaining almost all of the performance. There is also a class of examples where the bounds checks will provide the compiler with information enabling optimizations that would've otherwise been impossible -- so there may be cases with the rewrite where `@inbounds` results in slower code than leaving bounds checking enabled.

Re: Correctness and composability bugs in the Julia ecosystem

#264
post #212

Earlier quoted context omitted.

> Thanks for the honest assessment. What about correctness/ composability of compiler transforms like AD, reliability of GPU acceleration and predictability of optimizations? (basically what you've discussed in some of your compiler talks). I don't think we really have a good answer yet, but it's actively being worked on. That said, I don't think we can be faulted for that one, because I don't think anybody really ha…

Glad to hear it's being worked on! > That said, I don't think we can be faulted for that one, because I don't think anybody really has a good answer to this particular design problem. Agreed! To be clear, If there's any implication of "fault" it was certainly not in a moral sense or even anything around making poor design decisions. Julia's compiler is being asked to do many new things with semantics that necessarily…

> But none of those, except for dex, has a solution for fusing kernels that rely on loops.

The LV rewrite will. Some day, I'd like to have it target accelerators, but unlike fusion, I've not actually put any research/engineering into it so can't make any promises.

But my long term goal is that simple loops in -> optimized anything you want out. Enzyme also deserves a shout out for being able to generate reverse mode AD loops with mutation.

Re: Correctness and composability bugs in the Julia ecosystem

#265

I tried Julia but the compilation time for interactive use was just too insane. I ended up paying £125 for MATLAB. Nothing else really remotely compares to MATLAB's plotting facilities.

I use Matlab daily, and the plotting is indeed excellent.

But the language itself is a horrible kludgy mess. Most of the development time is spent on input parsing and contorting your code into a vectorized shape.

Re: Correctness and composability bugs in the Julia ecosystem

#266

Correctness in Julia feels like it'll never happen, because interfaces seem like they'll never happen. Correctness guarantees / interfaces and slow startup are both my biggest pain points in Julia. I often think what would happen if every Julia dev just dropped the language and used Rust instead. A scientific ecosystem in Rust would be amazing.

As someone who really likes both Rust and Julia, there is absolutely no way Julia's scientific users would switch to a static language. Rust is slow to write, verbose, also suffers from long compile times, has no REPL or garbage collector... It is deeply unsuitable for scientific coding.

Re: Correctness and composability bugs in the Julia ecosystem

#267

So this one is a tough one for me, because Yuri has certainly spent significant time with Julia and I think he's a very competent programmer, so his criticism is certainly to be taken seriously and I'm sad to hear he ended up with a sour opinion. There's a lot of different issues mentioned in the post, so I'm not really sure what angle to best go at it from, but let me give it a shot anyway. I think there's a couple…

The big language design problem that I think this post highlights is that the flip side of Julia's composability is that composing generic code with types that implement abstractions can easily expose bugs when the caller and the callee don't agree on exactly what the abstraction is. Several of the bugs that Yuri reported are a very specific case of this: there's a lot of generic code that assumes that array indexing…

> What you really want is a way to generically express behaviors of an abstraction in a way that can be automatically tested.

The pure FP ecosystems in Scala often accomplish this in the form of "laws", which are essentially bundles of pre-made unit tests that they ship alongside their core abstraction libraries.

Re: Correctness and composability bugs in the Julia ecosystem

#268

I'm not sure what to make of this. Yuri is great and I'll certainly miss having him in the Julia community. Yes, of course there are bugs. We work on fixing them all the time. If there are just too many for you, or we are too slow at fixing them for you, then OK I understand you might walk away. With these kinds of posts (and the reactions to them) lots of issues tend to get conflated. For example there are issues wi…

I've worked on large engineering projects in physical disciplines. When I am the customer, I often bring in a group of independent experts to review the design products. Often these experts provide inputs that are not 100% usable in the form they're provided. One may have to disentangle their conflation of related-but-not-the-same issues, or ignore the specific solutions they propose, etc.

That being said, I have learned the hard way not to ignore or trivialize these review inputs, even if they are not immediately actionable as-provided. Users and reviewers are really good at figuring out weak areas or flaws even if they can't articulate the solutions, fully unentangle related issues, or do all the generalization or abstraction that would make those issues easier to address. There is usually some truth underlying the negative feedback.

The article looks to potentially be an example of an expert review in the above vein. If you are able to take a step back, you might find the HN discussion on this submission to provide further inputs to help figure out how any of this should be channeled into language, practice, and ecosystem improvements. Certainly there is more to work with here than little "to take away other than that we should work even harder on bugs and quality."

Re: Correctness and composability bugs in the Julia ecosystem

#270

Earlier quoted context omitted.

I'll be honest, based on my experience with Julia, this makes me more worried about using e.g. libuv in production systems now, not less. I understand your opinion that "The easier it is to look at the code, the easier it is to find issues with it", but I don't think that has anything to do with the fact that `prod((Int8(100), Int8(100)))` and `prod([Int8(100), Int8(100)])` disagree, because someone decided to specia…

The problem in this case (as with most issues regarding `@inbounds`) is that this text was written before arrays with non-standard indices existed in Julia. So the example was correct at the time it was written, just like the StatsBase code was correct. Old code needs careful checking to fix all these occurrences.

Discussed in a sibling thread: https://news.ycombinator.com/item?id=31401155.
Post reply on HN