Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is a reasonable article, but way out of date now. Almost all issues raised were solved a while ago.


I say this as a huge Julia fan, but the point is not the specific bugs in the article, but the culture of not prioritizing correctness in computation. The initial response by many (not all) in the community was look, those specific bugs are fixed; all languages have bugs; more importantly - look at the benchmark speeds of these computations! Which only reinforced this negative perception.

My understanding is that it's a difficult problem to solve, and there are people working on traits/interfaces - but these are still peripheral projects and not part of the core mission to my knowledge. In practice, composability problems arise seldomly, but there is no formal way to guard against it yet. I believe there was some work done at Northeastern U. [1] toward this goal but it's still up to the user to "be careful", essentially.

[1] https://repository.library.northeastern.edu/files/neu:4f20cn...


> the culture of not prioritizing correctness in computation

On the contrary, it is my impression the experienced Julia programmers, including those involved in JuliaLang/julia, take correctness seriously. More so than in many other PL communities.

> there are people working on traits/interfaces - but these are still peripheral projects and not part of the core mission to my knowledge

What exactly do you mean by "traits" or "interfaces"? Why do you think these "traits" would help with the issues that bug you?


True, actually they are good in following up on numerical correctness, so I should be rephrase 'correctness in computation' to 'correctness in composition' - the types of bugs that arise from mashing a lot of modules together. On the one hand it's not a Julia issue but a package ecosystem issue.

I think you're actually even more active in the Julia community so maybe I don't have to summarize the debate but these are the types of traits and interface packages being developed that are meant to formalize how modules can be used and extended by others.

https://github.com/rafaqz/Interfaces.jl

https://discourse.julialang.org/t/interfaces-traits-in-julia...


What I wanted to say is that I'm skeptical regarding "interfaces", either as a language feature or as a package. Although TBH I have not yet given any specific "interfaces" design more than a cursory glance, so my position is not really justified.


> the culture of not prioritizing correctness in computation.

In a language with pervasive use of generic methods, I don't know what actually means. If I write a function like:

    function add3(x, y, z)
      x + y + z
    end
Is it correct or not? What does "correct" even mean here? If you call it with values where `+` is defined on them and does what you expect, then my function probably does what you expect too. But if you pass values where `+` does something weird, then `add3()` does something weird too.

Is that correct? What expectations should someone have about a function whose behavior is defined in terms of calls to other open-ended generic functions?


I should have been more precise in my language - it's not numerical correctness but composability correctness. They won't appear in a simple example like the one you provided, but more complicated ones are provided in the original post - in the example it partially centers around how getindex should be used with a particular struct and so on.


There's nothing numerical in my comment. There's just arguments and function calls, which happened to be named "+".

My point is that there is an implied contract that `add3()` only does what you expect if you pass it values where `+` happens to do what you expect. When you have a language with fully open generic methods like Julia, it's very powerful, but the trade-off is that every function is effectively like middleware where all it can really say is "if you give me things that to delegate to the right things, I'll do the right thing too".

When I'm writing `add3()`, I don't know what `+` does. I'm writing a function in terms of open-ended abstractions that I don't control, so it's very hard to make any promises about the semantics of my function.


Your perspective tracks with mine. Without contracts, either specified in documentation or as static guarantees, it is hard or impossible to build robust programs.

In Julia it's almost as if every function is an interface, with (usually quite terse) documentation as its only semantic constraint. For example, here is the full documentation for `+`: https://docs.julialang.org/en/v1/base/math/#Base.:+

I love Game Programming Patterns, by the way! Laughed out loud when I first saw the back cover.


> Without contracts, either specified in documentation or as static guarantees, it is hard or impossible to build robust programs.

Right. I think a big part of this is expectation management. Julia lets you compose unrelated libraries much more freely than most other languages do. That's very powerful, but if you come into it expecting all of those compositions to magically work, I think you just have an unrealistic expectation.

There's no silver bullet when it comes to code reuse and Conway's Law can't be entirely avoided.

> I love Game Programming Patterns, by the way! Laughed out loud when I first saw the back cover.

:D


> Julia lets you compose unrelated libraries much more freely than most other languages do. That's very powerful, but if you come into it expecting all of those compositions to magically work, I think you just have an unrealistic expectation.

Yep, and it is unfortunate that this unrealistic expectation is explicitly encouraged by the creators of the language:

> It is actually the case in Julia that you can take generic algorithms that were written by one person and custom types that were written by other people and just use them together efficiently and effectively.

It seems worth reiterating that on a personal level I really like and appreciate the vast majority of the folks I’ve met in the Julia community. I’m glad I got to hang out with them and learn from them. But in my opinion setting expectations like this fosters bad science.


Agreed 100%.


When I look, an issue such as "the base `sum!` is wrong" is still an open issue. Which, I think, is a bit ridiculous.


This is a typical example:

• The documentation (currently) of the function warns not to use it this way;

• This is a rather perverse use of the function(s) that would be unlikely unless you’re trying to break things;

• The discussion on the issue page demonstrates the exact opposite of a culture not caring about correctness;

• This kind of stuff doesn’t matter to all the scientists who are actually using Julia to do real work.

Nevertheless, sum!() and friends should be, somehow, made to avoid this problem, certainly.


I've nearly exclusively used Julia since 2017. I don't think this is a perverse use of such functions -- long ago I naturally guessed I could use `cumsum!` on the same input and output and it would correctly overwrite the values (which now gives a similar warning in the documentation). However, when I first used it that way I tested if it did what I expected to verify my assumption.

It is good the documentation is now explicit that the behavior is not guaranteed in this case, but even better would be if aliasing were detected and handled (at least for base Julia arrays, so that the warning would only be needed for non-base types).

Still, the lesson is that when using generic functions one should look at what they expect of their input, and if this isn't documented one should at least test what they are giving thoroughly and not assume it just works. I've always worked this way, and never run into surprises like the types of issues reported in the blog post.

Currently there is no documentation on what properties an input to `sum!` must support in the doc string, so one needs to test its correctness when using it outside of base Julia data types (I haven't checked the broader docs for an interface specification, but if there is one it really should be linked in the docstring).


But your use of cumsum!() seems natural; I can see using it that way, and might have done so myself. The use of sum!() under discussion seems weird, though.




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

Search: