Blog post about my experiences with Julia

No because it’s context dependent. For example, people use array with out of place for better Zygote support with neural networks, so even if u0 is a big standard array there are reasons to make it in or out of place.

Sure, but if u0 isa Number you have to use out of place right?

1 Like

Yes, and StaticArray. We can catch those in the DiffEqBase/solve.jl higher level handling.

1 Like

Error message improvements incoming probably by tonight.

https://github.com/SciML/DiffEqBase.jl/pull/746

I’ll need to think more about the right way to do the higher level problem/solution doc handling, but having two middle seat flights in a week is a good way to motivate busy work.

That said,

Just to be absolutely clear though, SimpleDiffEq.jl is not a flagship library of Julia. It’s specifically built and intended as a fringe library for teaching how to build differential equation libraries… that’s not a standard. It doesn’t have most of the high level handling of DifferentialEquations.jl, and doesn’t have most of the error checking. So I’m not surprised it’s a bit “too simple” to be a standard library, that’s exactly it’s point. Let me know if the docs say differently anywhere and I can clean that up.

For example, with SimpleEM it says:

This setup provides access to simplified versions of a few SDE solvers. They mostly exist for experimentation, but offer shorter compile times. They have limitations compared to StochasticDiffEq.jl.

One of these limitations is that they explicitly sidestep a lot of higher level error handling, so :person_shrugging: not sure what to do there.

8 Likes

@Volker_Weissmann I have to say that I didn’t find much of “constructive” in the criticism in the blog post :wink: E.g.

  • Some quite important bugs exist in important parts of the Julia eco-system

refers to using an unsupported setup.

  • Bad performance

refers to slow loading times of particular packages.

  • Unqualified statements like

Go To Definition commands in editors work worse for Julia than for other languages.

Julia routinely ignores this guideline.

(what are those other languages? when does it ignore it?)

I understand that you had hard time using julia. I don’t think that’s enough to claim that julia and its tools are of poor quality. After all there are some people out there who are using these tools, even like using them, they get their job done and they don’t suffer while doing it :wink:

Unfortunately the blogpost is written in a language/style which makes it very easy to be disregarded even if there are some valid points there. If you wanted to get some message through, then maybe picking another style would be better suited for the aim.


Edited at the request of @Oscar_Smith to remove statements that could be considered inflammatory.

3 Likes

Yes, but I did not talk about SimpleDiffEq.jl, I did talk about DifferentialEquations.jl .

Some quite important bugs exist in important parts of the Julia eco-system

refers to using an unsupported setup.

Removed.

Bad performance

refers to slow loading times of particular packages.

Yes? That’s what I wrote. Nothing wrong with my statement.

Go To Definition commands in editors work worse for Julia than for other languages.
what are those other languages?

Rust, C/C++, Python. But I did not find time for a proper comparison. It is titled “my experiences with Julia” and meant to show what I felt and noticed, not to be a scientific measurement.

Julia routinely ignores this guideline.

when does it ignore it?

Removed.

not being able to find solutions in DiffEq documentation,

Actually, I found it.

“I tried to use the tool; It didn’t work as I expected.”

Yes.

acknowledge that I maybe don’t know how to use the tools

I did not say that I know how to use these tools.

note that I can get the job done using other tools and simply leave

I wrote that I rewrote parts in Rust and that I’m not using Julia anymore.

I blame the tools or

I’m trying to described my experience with Julia. I think this is a useful thing to do.
I used Julia for a year, so I decided to write down how I felt that year.
This is not a call to action. I’m not saying any of these things should be changed - after all software engineering consists of tradeoffs, you cannot fix one thing without worsening another. Sure, static typing would make the error messages nicer and interpreting instead of JIT-compiling would decrease TTFP, but those changes would have their own drawbacks and I’m not saying that Julia should apply those changes. I’m just saying that we should be aware of the drawbacks Julia has and understand them. Understanding tradeoffs is important in software engineering. If you choose a language for a project you should know that you should not use Julia if TTFP is important. If you choose or design a language you should know that dynamic typing makes the error messages worse.

I don’t think that’s enough to claim that julia and its tools are of poor quality.

I’m sure all the authors of Julia are very smart people. I’m just describing certain problems, I’m not saying the authors of Julia could easily avoid these problems.

I never claimed to know a lot about Julia.
Also, note how the title is “My experiences with Julia”, not “Scientific measurement of Julia”.
So that shields me from basically all your criticism. As long as I actually had a certain problem, describing this problem can never be wrong, no matter if e.g. “change mental habits” would solve the problem.

Edited at the request of @Oscar_Smith to remove statements that could be considered inflammatory.

I’m fine. No need to do that.

8 Likes

You previously referenced MethodError: no method matching copyto! · Issue #48 · SciML/SimpleDiffEq.jl · GitHub, which is about SimpleDiffEq. Perhaps DifferentialEquations.jl would have given a similar error at that time, but in any case @ChrisRackauckas has now added more constructive error messages in Check and throw on incompatible initial conditions by ChrisRackauckas · Pull Request #746 · SciML/DiffEqBase.jl · GitHub. Hopefully that helps future users with this issue so it has been useful feedback. Thanks!

2 Likes

Some more docstrings:

https://github.com/SciML/SciMLBase.jl/pull/151

Still need to do the solution types.

I was addressing what you mentioned in the blog post.

I would consider myself a semi-experienced programmer. Less experienced than people who worked in the industry for years or decades, but certainly more experienced than the average scientist programmer. Julia made me feel like an absolute beginner again. Unlike other languages, even those I spent less time learning on, I hade trouble writing certain code or debugging certain errors that I would consider very basic. And I don’t mean that my solution looked unelegant, like the code of a beginner. No, I was literally not able to write certain basic things myself.
An example can be found here.

All of the solvers which aren’t the SimpleDiffEq solvers will now throw an informative error in that case:

julia> sol = solve(prob,Tsit5())
ERROR: Error: Initial condition incompatible with functional form.
Detected an in-place function with an initial condition of type Number or SArray.
This is incompatible because Numbers cannot be mutated, i.e.
`x = 2.0; y = 2.0; x .= y` will error.

If using a immutable initial condition type, please use the out-of-place form.
I.e. define the function `du=f(u,p,t)` instead of attempting to "mutate" the immutable `du`.

If your differential equation function was defined with multiple dispatches and one is
in-place, then the automatic detection will choose in-place. In this case, override the
choice in the problem constructor, i.e. `ODEProblem{false}(f,u0,tspan,p,kwargs...)`.

For a longer discussion on mutability vs immutability and in-place vs out-of-place, see:
https://diffeq.sciml.ai/stable/tutorials/faster_ode_example/#Example-Accelerating-a-Non-Stiff-Equation:-The-Lorenz-Equation    

Stacktrace:
 [1] get_concrete_u0(prob::ODEProblem{Float64, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, ODEFunction{true, typeof(f), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, isadapt::Bool, t0::Float64, kwargs::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol}, NamedTuple{(:u0, :p), Tuple{Float64, SciMLBase.NullParameters}}})
   @ DiffEqBase C:\Users\accou\.julia\dev\DiffEqBase\src\solve.jl:423
 [2] get_concrete_problem(prob::ODEProblem{Float64, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, ODEFunction{true, typeof(f), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, isadapt::Bool; kwargs::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol}, NamedTuple{(:u0, :p), Tuple{Float64, SciMLBase.NullParameters}}})
   @ DiffEqBase C:\Users\accou\.julia\dev\DiffEqBase\src\solve.jl:321
 [3] solve_up(prob::ODEProblem{Float64, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, ODEFunction{true, typeof(f), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, sensealg::Nothing, u0::Float64, p::SciMLBase.NullParameters, args::Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ DiffEqBase C:\Users\accou\.julia\dev\DiffEqBase\src\solve.jl:247
 [4] solve_up(prob::ODEProblem{Float64, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, ODEFunction{true, typeof(f), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, sensealg::Nothing, u0::Float64, p::SciMLBase.NullParameters, args::Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False})
   @ DiffEqBase C:\Users\accou\.julia\dev\DiffEqBase\src\solve.jl:239
 [5] solve(prob::ODEProblem{Float64, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, ODEFunction{true, typeof(f), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, args::Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}; sensealg::Nothing, u0::Nothing, p::Nothing, kwargshandle::KeywordArgError, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ DiffEqBase C:\Users\accou\.julia\dev\DiffEqBase\src\solve.jl:234
 [6] solve(prob::ODEProblem{Float64, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, ODEFunction{true, typeof(f), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, args::Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False})
   @ DiffEqBase C:\Users\accou\.julia\dev\DiffEqBase\src\solve.jl:228
 [7] top-level scope
   @ REPL[18]:1

Please critique the message if you think there’s any way to improve it.

17 Likes

Oh right. MethodError: no method matching copyto! · Issue #48 · SciML/SimpleDiffEq.jl · GitHub was and example of a bad error message, ODESolution from DifferentialEquations.jl was an example about Julia flagship libraries having bad references.

  1. Great change. I’m amazed that you actually did something like that.

  2. What I tried to say was not “dear julia authors, please improve this specific error message” or “dear julia authors, please improve error messages in Julia” but “dear users, consider using a language that is not Julia, ideally a static typed language because the error messages are bad, see this as an example”. Many things I criticized in my post were things that probably cannot be changed.

1 Like

I think this article (at least the updated version) brings up some good points and doesn’t read too much like a rant. I felt very similarly when first starting out with Julia - I especially related to this:

Julia made me feel like an absolute beginner again.

My experience with the flexibility of the type system was that I could reuse functionality in contexts that I did not expect to work. The downside was that when things didn’t work, it was not only hard to debug but also hard to determine if I should have expected it to work.

The wonderful community (and some colleagues who were more familiar with Julia) helped me a ton my first 2 years learning Julia, but it admittedly took quite a while to develop intuition for how to write and debug flexible Julia code.

11 Likes

I will say this is a rare place to say “consider using another language that is not Julia, because reasons”, if it is not with the intent to signal the authors that something can (and maybe should?) be improved. In the end, this is a forum in which we users try to learn, share and improve Julia as an ecosystem and community.

This is not meant as a critique to your blog (nice write-up) or to your experience using Julia, I can relate to your experiences, I suffered them in the beginning, and some still affects me.

Just wanted to say that the intent feels rare to me, but also thanks for the feedback!

(P.D. I’m not surprised that Chris Rackauckas did that, he is a really intelligent person and passionate about his work :smiley:).

6 Likes

But maybe that exactly is the consequence of Julia being pretty new(?) or unique(?) in the landscape of languages? I, for one, enjoy this feeling…

3 Likes

That’s a fair point! I do love the feeling of discovery that I sometimes get when I realize “woah, Julia can do that so easily?” Earlier on though, I often just felt like I just wasn’t “getting it” like the folks on Julia Discourse and Slack were, which was discouraging.

At least in my experience, though, Julia is a remarkably consistent language - many behaviors which were first surprising to me turned out to due to choices to ensure consistent behaviors.

2 Likes

Dynamic typing in a nutshell.

Let’s say: This is my description of the language. If you find something to improve do it, if not, don’t.

1 Like

You might also complain with the ArchLinux packager of Julia, no? They deliberately apply patches which cause the linking errors you complain about, it looks to me like you’re pointing the finger into the wrong direction. As far as I know, the package in Fedora repository is much better maintained and doesn’t have such issues. Also, the page you link shows the AUR package you can use which doesn’t have all these issues, so you may also follow the recommendation, no?

6 Likes

Everything can be fixed. We just need to figure out how to turn rants into action items and tackle them one by one. It’s more beneficial to hear this information than to never learn the issues of new eyes, so thanks for sharing.

The latency issues are harder to address though we’re pretty close to getting solutions for no compilation DiffEq modes

https://github.com/SciML/DiffEqBase.jl/pull/745

https://github.com/SciML/DiffEqBase.jl/pull/736

I hope that in a year or so we can at least have prebuilt binaries for the Array{Float64} cases.

21 Likes

May I describe my first impression of Julia? I don’t know how to express it in English, but in Chinese, it is “一见钟情”, which means I fell in love with it at the first sight.

Before Julia, I have years of experience with C/C++, Matlab, Python, and tried Fortran, Perl, Go, C#, VB, and D, none of them give me the same impression. I have some good impressions of Python after years of coding in C++, but I merely use it to do data analysis, plotting, and pseudo-coding due to speed concerns.

When I finally came across Julia, I had the feeling that I finally found my best tool for research. And it did boost my research, especially in the recent months with a better understanding of Julia.

34 Likes