# Discussion on "Why I no longer recommend Julia" by Yuri Vishnevsky

**URL:** <https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151>\
**Category:** Community\
**Tags:** discussion\
**Created:** [May 16, 2022, 2:33pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151 "2022-05-16T14:33:38Z")\
**Posts on this page:** 20\
**Page:** 14

<div class="post-metadata">

**Author:** ![rikh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rikh/32/204104_2.png) [@rikh](https://discourse.julialang.org/u/rikh)\
**Post date:** [July 1, 2022, 11:31am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/299 "2022-07-01T11:31:33Z")

</div>

> [@mfiano](#):
>
> I do have one point of criticism – the description of object-oriented programming. It is such a common mistake to make, given that not very many people are familiar with older OOP implementations.

That’s why I sticked to the Java, C#, C++ definition of OOP. Most people think of that flavor when talking about OOP. I’ve considered adding some footnote in the blog about that OOP is not strictly correctly implemented in modern languages, but that seemed to distract from the main story. By “correctly implemented”, I mean implemented according to the definition by the original creator of OOP. There is a nice talk on YouTube somewhere by the original creator. Maybe it was on a Smalltalk conference? He tells how everyone got OOP wrong. Can’t find it now, maybe you know the one

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 1, 2022, 11:39am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/300 "2022-07-01T11:39:11Z")

</div>

> [@mfiano](#):
>
> Common Lisp as an example, does not couple methods to classes.

But… Then what’s the difference between types and classes? I thought classes where types with methods in them.

---

<div class="post-metadata">

**Author:** ![mfiano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mfiano/32/37565_2.png) [@mfiano](https://discourse.julialang.org/u/mfiano)\
**Post date:** [July 1, 2022, 11:41am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/301 "2022-07-01T11:41:44Z")

</div>

All classes have a type of the same name, but not vice versa. That is, INTEGER is a built-in class, but a type describing an integer in the range of [0 10) is not a class.

Also no. The whole point of my post was to mention classes have nothing to do with methods. Multiple dispatch is not a new idea to Julia, after all.

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [July 1, 2022, 12:54pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/302 "2022-07-01T12:54:28Z")

</div>

Maybe this one in case others are interested.

> **[Ralph Johnson, Joe Armstrong on the State of OOP](https://www.infoq.com/interviews/johnson-armstrong-oop/)**
>
> Ralph Johnson and Joe Armstrong discuss the state of OOP, what Smalltalk got right/wrong and the image concept. Also: Joe decides he likes OOP as long as its done the Erlang way: focused on messaging.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 1, 2022, 12:54pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/303 "2022-07-01T12:54:37Z")

</div>

One lives and one unlearns, apparently. Yesterday I knew the difference between a type and a class, and had a vague idea about what interfaces mean. Today, after reading a bit more about them, I have not the faintest clue about any of them.

Carry on.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 1, 2022, 10:37pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/304 "2022-07-01T22:37:14Z")

</div>

I really wish the exact meanings of programming lingo remained the same across all languages and contexts, but it would be unfair to expect some primordial language theory to formally delineate every weirdly specific concept some future language comes up with.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 2, 2022, 3:27am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/305 "2022-07-02T03:27:46Z")

</div>

> [@jishnub](#):
>
> my point was more about finding the issues in the first place

It does appear that assuming 1-based indexing is all over the place and isn’t always marked with `require_one_based_indexing()`, e.g. `begin + n - 1` only works for `n in 0:typemax(Int)` if `begin` is 1.

I want to remark on an interesting complication for the task of hunting down 1-based assumptions in `Base`, `StatsBase`, and elsewhere. `require_one_based_indexing()` shows up in a lot of methods where there are \>1 input arrays, and even if one were to rewrite them to start at `firstindex` instead of 1, there’s still the issue of what to do with the inputs’ offset indices. For example, take the addition of matrix A and matrix B, yielding a matrix C. Let’s say A is 0-based and B is 1-based. This isn’t one of those offset indices applications where aligning A[1,1] and B[1,1] makes any sense, so we basically do `A.parent + B.parent`. But what should C’s indices be? 0-based, 1-based?

I would argue that at the most, such methods could be sensibly relaxed to calling a hypothetical `require_same_indices()`, and that restriction makes it unreasonably clunky to use `OffsetArrays`. At least `StaticArray`s do not support a conventionally obvious interface method (`setindex!`), so you know to avoid mutating`!` methods; it’ll be harder to check if a method uses `require_same_indices()` in some really nested method call.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [July 3, 2022, 9:37pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/306 "2022-07-03T21:37:17Z")

</div>

One thing about this discussion and the original blog post has been annoying me—the use of the phrase “correctness bug”. I view that phrase as a melodramatic and alarmist way of saying “bug”. Aren’t all bugs “correctness bugs”? Obviously code can have performance issues, but I hesitate to call performance issues “bugs”.

The [cpython repository](https://github.com/python/cpython) has [2,740 open issues](https://github.com/python/cpython/issues?q=is%3Aopen+is%3Aissue+label%3Atype-bug) with the label `type-bug`, which has the description “An unexpected behavior, bug, or error”.

Julia has a total of 3,383 open issues (Python has 6,773), but presumably not all of them are bugs. The `bug` label has not been applied as consistently in the Julia repo. Only 215 issues have the `bug` label, but there are probably more than 215 open bug issues for Julia.

So, the number of open bugs in Python and Julia is probably pretty comparable. Yuri’s blog post, and some of the comments in this thread, take an alarmist tone that implies that the Julia language is unreliable to use. Now I’m perfectly willing to admit that the Julia ecosystem probably has more bugs than major Python packages do, but I think that’s primarily because popular Python packages have many more users and many more developers.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [July 4, 2022, 1:15am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/307 "2022-07-04T01:15:44Z")

</div>

> [@tecosaur](#):
>
> I have a serious discoverability problem with Julia.

Just for information, I also think this is a serious problem. I asked for this feature here:

> <https://github.com/JuliaLang/julia/issues/43437>
>
> Hi!
> 
> I think a very nice feature would be if REPL can auto-complete keywords a…rguments. For example, let's say I have the following function:
> 
> \`\`\`julia
> function test(; key1, key2, key3)
> return nothing
> end
> \`\`\`
> 
> In REPL, if I press TAB in this condition:
> 
> \`\`\`julia
> julia\> test(; key
> \`\`\`
> 
> It should show me as options \`key1\`, \`key2\`, and \`key3\`.

which has an initial PR here:

> <https://github.com/JuliaLang/julia/pull/43536>
>
> Closes #43437 by implementing the feature.
> 
> \## The feature
> 
> I think it's a c…onvenient non-disruptive feature to have, thank you @ronisbr for thinking of it! The behaviour in this branch:
> \`\`\`julia
> julia\> function test(; key1, key2, key3)
> return nothing
> end
> test (generic function with 1 method)
> 
> julia\> test(; key#TAB
> key1= key2= key3= keys keytype
> \`\`\`
> As you can see, all suggested keyword arguments have a finishing \`=\`, both because it's useful to be able to distinguish them, and because that's probably what you want anyway (feel free to comment if you disagree!). If you want to use the \`foo(; bar)\` syntax, meaning \`foo(; bar=bar)\`, then it's fine as well since for that you need \`bar\` to exist, so it will be part of the suggestions:
> \`\`\`julia
> julia\> key1 = 3;
> 
> julia\> test(; key#TAB
> key1 key1= key2= key3= keys keytype
> \`\`\`
> 
> \## The intentionally not-implemented
> 
> In the cases like the previous example, I thought about restricting the REPL suggestions to only those keyword arguments, since any argument following a semicolon or another keyword argument must itself be a keyword argument, and thus, be of the form \`bar=barvalue\` or just \`bar\` if \`bar\` is both a known name and a keyword argument. But there is the special case of splat keyword arguments, of the form \`foo(; kwargs...)\` which is an exception since \`kwargs\` can be about anything. So I kept all the usual names for suggestions, I thought I'd mention the reasoning here for reference.
> 
> \## Update
> 
> See https://github.com/JuliaLang/julia/pull/43536#issuecomment-1037631704 below for a slightly more detailed view on what this PR implements.
> 
> (EDIT: I removed parts of this message which were not relevant anymore, mostly thanks to the PRs referenced below and some updates of this PR.)

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [July 4, 2022, 2:41am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/308 "2022-07-04T02:41:52Z")

</div>

> [@CameronBieganek](#):
>
> Aren’t all bugs “correctness bugs”?

I don’t think so. There’s a big difference between “Calling X with inputs Y produces an error” and “Calling X with inputs Y returns an incorrect result”. [Rereading the blog post](https://yuri.is/not-julia/), the latter is what he calls a “correctness bug”.

Those bugs are scary. His point is that because types like `Number` or `AbstractArray` are not crisply-defined concepts at the language level, different packages can make different assumptions, and that leads to “correctness bugs” (i.e. incorrect results), perhaps in a way that doesn’t happen (as much?) in languages that don’t encourage/enable interoperability as much as Julia does.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [July 4, 2022, 1:19pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/309 "2022-07-04T13:19:32Z")

</div>

I definitely agree correctness bugs are a big deal and very different from bugs where something throws where it shouldn’t or isn’t as fast as it should be.

Code is used to understand things and make decisions. If there’s a bug that compromises that understanding and e.g. invalidates an analysis for a paper, or a decision based on the results from the code, then that’s pretty bad. At work I use a label “correctness bug” on issue trackers to distinguish them from other bugs, and try to announce when they happen and are fixed so downstream consumers can re-run code. Luckily they are fairly rare compared to other bugs.

I don’t think these should be dismissed at all and agree with other commentators that we need an increased cultural emphasis on testing edge cases and communicating guarantees or lack thereof (e.g. interfaces, input checking/errors, assumptions documented).

---

<div class="post-metadata">

**Author:** ![Anil\_Joshi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anil_joshi/32/7869_2.png) [@Anil\_Joshi](https://discourse.julialang.org/u/Anil_Joshi)\
**Post date:** [July 4, 2022, 6:59pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/310 "2022-07-04T18:59:50Z")

</div>

> but I hesitate to call performance issues “bugs”

In almost all numerical codes, bugs manifest as performance issues, especially when solving multiphysics problems. Any kind of iterative solution program performs poorly if there are bugs in the code. In C, they are mainly memory overruns, incorrect indexing (0 based vs 1 based). Integer overflow or underflow sometimes updates a memory location instead of the intended one. These are problematic when one computes norms which are used as stopping criteria for iterations - inner iterative solvers called by an outer non-linear iterative loop.

Since Julia competes with C/C++ in NA space, performance issues should be called bugs unless otherwise proven that the performance issues are inherent due to limitations on the available algorithms whose asymptotic time/space complexity is proven to have these limitations.

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [July 5, 2022, 1:27am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/311 "2022-07-05T01:27:15Z")

</div>

Julia was created to exploit synergies of composability.

Yes it’s possible to compose things incorrectly (and to get an incorrect result, instead of a bug)

No, Julia does NOT have a correctness problem, if used correctly

 ![image](https://global.discourse-cdn.com/julialang/original/3X/4/b/4b7a528c003abdb4c79727e4afe3c2e7c5e1c2ee.jpeg)

---

<div class="post-metadata">

**Author:** ![simsurace](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simsurace/32/30216_2.png) [@simsurace](https://discourse.julialang.org/u/simsurace)\
**Post date:** [July 5, 2022, 10:46am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/312 "2022-07-05T10:46:14Z")

</div>

If you as a user train a model with a high-level library and silently get incorrect result because deep down in the internals there is a function that is not being AD’d correctly, it’s incredibly hard to debug that. It is not a fundamental problem, but one which is a consequence of the composability and no single entity being responsible for correctness. For example, the loglikelihood of some distribution may give incorrect gradients with some AD library that is stuck in an optimizer, while a different loglikelihood worked well. So you may change one aspect of your model and suddenly it does not work at all, or becomes 100x slower. It’s hard to say what was an incorrect use in this case, and the solution is not obvious without diving deep into the issue.

---

<div class="post-metadata">

**Author:** ![paulmelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmelis/32/35063_2.png) [@paulmelis](https://discourse.julialang.org/u/paulmelis)\
**Post date:** [July 5, 2022, 10:52am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/313 "2022-07-05T10:52:57Z")

</div>

> [@Albert\_Zevelev](#):
>
> Julia was created to exploit synergies of composability.
> 
> Yes it’s possible to compose things incorrectly (and to get an incorrect result, instead of a bug)
> 
> No, Julia does NOT have a correctness problem, if used correctly

As a user (not as a package developer), how would you know if you are using Julia correctly?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 5, 2022, 11:02am UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/314 "2022-07-05T11:02:13Z")

</div>

> For example, take the addition of matrix A and matrix B, yielding a matrix C. Let’s say A is 0-based and B is 1-based. This isn’t one of those offset indices applications where aligning A[1,1] and B[1,1] makes any sense, so we basically do `A.parent + B.parent`. But what should C’s indices be? 0-based, 1-based?

That’s an extremely dangerous way to think about the problem. Why does aligning indices not make sense? I expect `(A + B)[i,j] = A[i,j] + B[i,j]` (“location matters”). Indexing needs to be guided by a few axioms, the other key one being that `a[indxs][j] = a[indxs[j]]` implies that “the indices of the indices become the indices of the subset” (i.e., the indices of `indxs` become the indices of `a[indxs]`). We have good support for such axioms, except of course when people don’t implement them “properly.” Of course you can write a method `sum_without_worrying_about_indices` yourself, but that’s not what `+` should do.

The right answer to your question is, throw an error. And we do:

```julia
julia> A + B
ERROR: DimensionMismatch: dimensions must match: a has dims (Base.OneTo(3), Base.OneTo(4)), b has dims (OffsetArrays.IdOffsetRange(values=0:2, indices=0:2), OffsetArrays.IdOffsetRange(values=2:5, indices=2:5)), mismatch at 1
Stacktrace:

```

---

<div class="post-metadata">

**Author:** ![StatisticalMouse](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/statisticalmouse/32/43370_2.png) [@StatisticalMouse](https://discourse.julialang.org/u/StatisticalMouse)\
**Post date:** [July 5, 2022, 4:06pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/315 "2022-07-05T16:06:49Z")

</div>

No-one can be sure they’re writing correct code.

If you write ’boring’ code, it’s more likely to be correct.

Those are intentionally pointed comments. Prob not always true, but often they are.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 5, 2022, 6:36pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/316 "2022-07-05T18:36:10Z")

</div>

> [@tim.holy](#):
>
> Why does aligning indices not make sense? I expect `(A + B)[i,j] = A[i,j] + B[i,j]` (“location matters”).

I agree. The part that “doesn’t make sense” is aligning `C[1,1] = A[1,1] + B[1,1]` means that there’s a `A[0,0]` with no `B[0,0]`. One could force it to work by allocating extra elements so `C[0,0] = A[0,0]` and adding 2 NxN matrices makes a (N+Ma)x(N+Mb), and that doesn’t make sense to me either. As you said, a cheap check and throwing a `DimensionMismatch` error makes sense. Still seems like `OffsetArray`s are a bit more complicated to work with than other `AbstractArray`s, but I suppose if anybody deviates from 1-based indexing they’ll just need to be extra vigilant about dimension matching.

So any thoughts on matrix multiplication? Say 4x3 matrix X has indices (0:3, 1:3) and 3x2 matrix Y has indices (1:3, 2:3), do you think it’ll make sense for the 4x2 matrix Z to have indices (0:3, 2:3)? I can’t really think of any meaning for it, but if it’s disallowed then `OffsetArray`s must contend with more than just dimension mismatches (the 1:3 axes do match).

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [July 5, 2022, 7:55pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/317 "2022-07-05T19:55:10Z")

</div>

If I am composing things from 2 packages that were not designed to work together, I:

1. test things out with a bunch of sanity checks (on simple problems I already know the answer to)
2. study the underlying code for the functions I’m composing

I never just trust things will compose correctly… In any language

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [July 5, 2022, 9:51pm UTC](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151/318 "2022-07-05T21:51:47Z")

</div>

As I see it, many generic functions (morally) assume diagonal dispatch, i.e., require that arguments are of the same type. In case of adding matrices, this requires that the indices are from the same domain as addition requires that both arguments are elements from the same set/vector space etc. (Note that in Haskell this is often enforced in typeclasses, i.e., via type signatures `a -> a -> a` and the index is part of the type signature for array operations).  
The case of matrix multiplication is different though, as this corresponds to composition of linear maps and the only requirement is indeed that the inner domains agree. As an extreme example, we could even have named indices, i.e. `C[apples, peaches] = sum(A[apples, orange] * B[orange, peaches] for orange in oranges)` where all indices range over valid values from their corresponding domains, e.g., `apples = Fuji, Gala, Jonagold, ...`

[Previous page](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151.md?page=13)

[Next page](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151.md?page=15)
