Blog post about my experiences with Julia

You don’t need me to approve the post or your edits, but since you asked for opinions, I gave mine. It all comes down to how you want your post to come across, and I think the arguments carry more weight when delivered in a more objective language.

BTW, I think you are entitled to post critical views, even if they are mostly about personal impressions, so don’t feel obliged to present a scientifically valid evaluation. It’s just that sweepingly negative posts tend to be a bit hard to swallow, and you should expect some pushback.

(Sidenote: If ‘political correctness’ simply referred to writing style, I think it would be a less controversial subject. It can be feel a bit like a ‘cheap shot’ when someone dismisses criticisms as simply ‘PC’.)

29 Likes

Irregardless of tone, I think your complaints are less about the Julia language than about libraries in the Julia ecosystem.

As someone who works on SciML libraries, I definitely agree that many have limited reference documentation. I would actually go a step further and say they also can have (too) limited internal commenting, which can make it hard to understand what some functions are doing / why they are taking a certain approach. Unfortunately I think this is reflective that many (most?) of the developers are adding features for their own research, and many SciML libraries are rapidly changing. Writing docstrings and comments is just not a high priority for most of the developers. Hopefully as the libraries further mature, and at this point most of the core DifferentialEquations.jl libraries are mature, docstrings can get added.

The comments on time to load DifferentialEquations.jl are/were well-known issues that a number of people are actively working on. FWIW, @time using DifferentialEquations is about 6 seconds on my M1 Macbook Air with the latest release and Julia 1.8-beta3. So this has dramatically improved in the past year, but could still be better. (And FWIW, @time using Plots is just over 2 seconds.)

By the way, your integrate function has a type stability issue – you initially make sum an integer but in the loop change it to a float. This can potentially have performance issues (though it looks like Julia makes sum a union of the two on 1.8 so maybe it won’t be problematic in practice).

19 Likes

I there there are two different things here: Rust has a fantastic tooling, and it provides certainly better error messages, and is easier to debug from that point of view. That is undisputed, an expected for statically typed languages in general, for Rust even most. There are discussions here in which people dream in having a tool like JET to do for Julia code what a static compiler does for Rust. Not quite there yet.

The ecosystem I usually see as the set of packages. Of course python has a much greater ecosystem in that sense, but Rust probably not (for numerical computing).

IMO the most clear pain point there, which I think is currently mostly unsolvable, is the discoverability of functions and methods for objects. And I not am not sure if there is a solution for that, because while multiple dispatch is unreasonably effective and powerful, it brings that tradeoff. You cannot contain the list of methods acting on a type in a closed list.

@Volker_Weissmann I got curious: what was the final code that you implemented in Rust? Is it available?

5 Likes

IMO the most clear pain point there, which I think is currently mostly unsolvable, is the discoverability of functions and methods for objects. And I not am not sure if there is a solution for that, because while multiple dispatch is unreasonably effective and powerful, it brings that tradeoff. You cannot contain the list of methods acting on a type in a closed list.

As someone who never used such tooling in C++/Java/Python, I don’t find this an issue with Julia. I think it is more about changing one’s mentality – if you are used to being able to type objname. and getting a list of functions you aren’t going to have that workflow anymore (though I agree it is useful!). Having never used that work flow it doesn’t bother me… I mean, wouldn’t C have a similar issue for discoverability? Plenty of people use C with no issues and I don’t see lots of complaints about discoverability for C…

7 Likes

For me it is also a minor paint point, but I can see that object oriented programming can make that easier. If you are a heavy library user, being able to get all methods that apply to each object by tabbing is good, I don’t dispute that.

The code simulates N Langevin trajectories and calculate the ensemble average or the autocorrelation function.
The full code can be found here but the most interesting part are these two functions: 1 2. For simplicity, you may imagine, that StandardEulerMaruyama is the only type implementing SingleTrajectory and StandardMulticore is the only type implementing Multicore.

1 Like

Certainly it is useful in object oriented languages! Though keep in mind it doesn’t show all functions that act on a given object, just those that are internal to a class… In object oriented languages I would at times find two versions of a function obj.name() and name(obj), and then be confused about which I should even use…

But in any case I certainly agree that better discoverability tooling would be great!

2 Likes

Searching for ODESolution in the documentation also shows no entry for ODESolution.

Look for the solution interface and you find a ton:

https://diffeq.sciml.ai/dev/basics/solution/

The issue of course is that this solution interface is not for ODESolution, but for all DESolutions, including SDEs, DDEs, etc. so it’s all about creating a common interface point.

As for reference docs… did you look at the sidebar? Here’s the pages you find if you just look at ODE:

https://diffeq.sciml.ai/dev/types/ode_types/
https://diffeq.sciml.ai/dev/solvers/ode_solve/
https://diffeq.sciml.ai/dev/types/nonautonomous_linear_ode/
https://diffeq.sciml.ai/dev/types/dynamical_types/
https://diffeq.sciml.ai/dev/types/split_ode_types/
https://diffeq.sciml.ai/dev/features/performance_overloads/

It gives you the information on every type. While we should improve the docstrings, missing 10 pages in the docs that hits the search criteria of “ODE” is a little odd.

12 Likes

There’s also https://diffeq.sciml.ai/dev/features/low_dep/

That clocks in near 2 seconds if someone is just using the ODE solvers.

6 Likes

I was going to mention that, but then I @time OrdinaryDiffEq and found it was 5 seconds vs. 6.5, so it didn’t seem worth complicating the comment more…

1 Like

Mmh. Would be better if there would a a ODESolution page that links to https://diffeq.sciml.ai/dev/basics/solution/.

You see the difference in style between DifferentialEquations.jl’s documentation and e.g. scipy.integrate.RK45 — SciPy v1.9.1 Manual? Maybe I have difficulties adapting to the other style.

3 Likes

Yup, we actually just discussed doing this on the diffeq Slack – it is a great suggestion. We need to add short doc strings to the various problems and solution types that link to the relevant doc page, to aid discovery in the REPL, VS Code, Pluto, etc.

4 Likes

If we do double it up, I hope we do it in a way that is programmatic instead copy pasting the same information everywhere

6 Likes

In that sense the docs that are available as function comments are less useful than they could.

First, I would like to have a macro that distinguished interface functions from internal implementations. These should appear separately on doc pages and searches.

For structures, in the absences of better docs, the list of fields and their types could be shown.

Also, some developer-defined help for doc searched would be nice. We could add keywords to these doc entries, “see also” tips, etc.

1 Like

Even “worse”, it’s not just DiffEq but SciML. The same solution interface applies to Quadarture.jl, DifferentialEquations.jl, GalacticOptim.jl, NonlinearSolve.jl, LinearSolve.jl, etc. So I’m trying to make it “the solution.u is always the value. If it’s an AbstractTimeSeriesSolution, it has solution.t for the independent variable”. And common keyword arguments: it’s always abstol and reltol, etc.

Trying to do that here: https://scimlbase.sciml.ai/dev/

Mentioned this in:

Definitely need help getting it done and it’s WIP.

Anyways, I’m hoping we get this right over the next year, in which case the docs of the commons will be much more clear. but for now, it’s 20 different docs, and too much pasting :sweat_smile:

13 Likes

Documenter can print only public and only private functions on their pages. This could be a solution, if the internal functions have function names that are not exported.

That is possible workaround, but there are functions that are not exported but are part of the interfaces. And the docs of the internal functions is also important, just not in the same place.

1 Like

Yes but Documenter allows to also just print the private ones, exactly at another place :slight_smile: Sure it does not solve the case for functions that belong to the interface but are not exported (they would end up with the internal ones).

2 Likes

Actually I just went thru the docs of Documenter again (long time since I hadn’t), and there are many (new?) features already available to organize the docs better, by showing docs of specific functions, etc. In terms of doc page generation the features are there (and yet it would be nice to use them as code decorations).

Another thing is that to be useful for the help> prompt, apropos searches, etc, so that the more careful doc writing and organization improved the REPL experience as well.

1 Like

What we’re still missing though is the multi-module docs. All of SciML is supposed to work together, and instead we have 20 separate documentations which all say almost the same thing in terms of interface.

6 Likes