Because it saves time you’d otherwise spend on discussing and implementing formatting preferences. If one package is good enough for most people, then at least most packages will be formatted reasonably and this aligns people’s expectations of what Julia code looks like. I think that’s preferable to having many different opinions floating around on what are essentially pretty arbitrary decisions anyway.
This will only work anyway if the defaults chosen are good enough, as otherwise people won’t want to use it. But if they are, and usage is simple, I think this package can succeed. I’d use it.
But that is clearly not the case: even if you pick one set of rules, there will be discussions (like this one), or see the open issues for Runic.jl.
The idea that picking a set of defaults and moving on (about anything, including issues much broader than code formatting) will quench discussion forever so we can Get Work Done is an illusion. Reasonable people will continue to disagree or just ask questions from time to time.
Well you can see it in other ecosystems that it can work. It doesn’t have to, but it can. This discussion here is just one, but it potentially replaces many others being held in individual repos down the line.
But the alternative also just exists, if you do not Agree with Runic.jl, you can just continue to use JuliaFormatter and config it to all your personal preferences.
I think having both these is a very good equilibrium. I am currently using JuliaFormatter, but thinking a bit less about how it is configures is something that I feel is very nice.
Also the choices I for now see in Runic.jl are better than what my current own config (slightly modified JuliaFormatter defaults) does.
And I agree, if we can get more people to use just one (sure opinionated, set by just a few people, currently maybe just Fredrik) – is a point for discussion. Still, for me a really great initiative!
I should perhaps note that Runic isn’t really strict with what syntax you use (e.g. short form vs long form function definitions etc). For example, adding two variables in Julia can be done with +(a, b) or a + b. Runic doesn’t care what you pick, but if you pick the function style it will be formatted as +(a, b) and if you pick the infix version it will be formatted like a + b.
The main thing with formatters (and in particular no-config formatters perhaps) is that it completely eliminates this discussion (in e.g. code review) and you don’t have to think about formatting when you write the code. Perhaps it doesn’t matter much for single-person projects, but when you start to collaborate on something it is nice that the style is consistent and not depending on who authored the function.
I also think it simplifies code review. I see quite often that contributors make formatting changes elsewhere in the code base which will then result in another review cycle when you have to ask the contributor to remove unrelated changes. If you enforce a style in CI then if CI pass you don’t need to or should not comment on the style.
I don’t know. Is there a way to configure something like formatprg in VSCoder perhaps? Or some extension that let’s you configure external formatters like conform.nvim perhaps? It would be nice not to have to write a full extension at least. I can ask in the #vscode channel on Slack.
Right, the idea isn’t to come up with rules that everyone approves of. The idea is to come up with something that people can accept so that configuration is not needed.
Right, I guess Go is the prime example. All Go code look the same because all Go code is formatted with gofmt because it was available already early on and everyone bought into the idea. See for example https://www.youtube.com/watch?v=PAAkCSZUG1c&t=523s :
Gofmt’s style is no one’s favorite, yet gofmt is is everyone’s favorite.
At least for my part, I would be happy to use a set of defaults and not think too hard about it if I find the defaults reasonable — even if they’re not a perfect match to what I would have done tabula rasa
*
modulo a few exceptions in formatting choices I find particularly offputting
The other three languages I use are Python (format with black), Go (format with gofmt) and C++ (anarchy )
to be honest it seems unlikely to me that more than a very small number of users would pass up Go solely because they didn’t like some stylistic choices of gofmt.
This is super neat, thank you @fredrikekre for your work on this!
I would like to lend some support to @Tamas_Papp’s suggestion. From a skim of this thread, it seems like I am in a boat that many people are in: all of these defaults you have seem perfectly reasonable, but it’s hard to imagine using this tool myself because I have some of my own weird preferences (for example: I like two spaces instead of four for each indentation).
The biggest appeal of something like this for me is that, should every contributor use it, it will reduce the noise in git diffs and stuff like that. And having a very clean git history is always great. If I were to work on projects that had a significant number of contributors, I would happily adopt this no-configuration formatter, because in some sense it seems fair to pick a standard that doesn’t fit anybody’s exact preferences. But most of my code projects are just me and a small number of collaborators/students/whatever, and for smaller projects like that where maybe 2-3 people could actually reach some consensus on personal and per-project preferences, the sacrifice feels less necessary.
@fredrikekre this is awesome! I have been wanting an opinionated formatter, like black for python, for Julia for a long time. In my company whenever we write python it’s black formatted and whenever we use go it’s of course gofmt. I’ll be changing my neovim config tonight.
Somehow I couldn’t let this thought go and finally I think I got to the bottom of it. Consider
foo(; kw1="bla", kw2="blu", kw2="blub")
vs
foo(; kw1 = "bla", kw2 = "blu", kw2 = "blub")
Written in the second style, the value of a kwarg is actually closer to the key of the following kwarg than to its own (separated by 2 characters vs 3).
Of course this purely visual first impression matters only if you merely glance over it quickly - but still, I feel this is significant.
(A more sustainable option long term would probably be to hook up Runic with the language server formatting but since I am not using VS Code I am not likely to spend time on that in the near future. Perhaps someone wants to contribute it and in that case feel free to reach out.)
I have nothing against Runic.jl, just don’t understand the motivation (but note that I find it totally OK to just write packages without explaining why, no one should have to explain that, I was merely curious).
One can ignore JuliaFormatter’s configuration altogether, ie implicitly just use JuliaFormatter.DefaultStyle.
Given that there are 3 major styles already in JuliaFormatter.jl (YAS, Blue, SciML), I am skeptical about universal acceptance of any new proposal. IMO the most likely outcome is
Having just played around with it, I am quite happy with it. It feels snappy and your readme is exemplary. Ran it over KernelAbstractions and Runic and I seem to mostly agree in style. So big kudos.
Runic can now be (statically) compiled with the juliac compiler driver from JuliaLang/julia#55047 :
Compile the branch from JuliaLang/julia#55047 alternatively get the preview build with juliaup add pr55047 and juliaup default pr55047
Clone the Runic repository
Run make in the juliac subdirectory which compiles the runicc binary
$ ls -lah runicc
-rwxrwxr-x 1 fredrik fredrik 2,9M sep 5 14:17 runicc
Compiled execution:
$ time ./runicc <../src/Runic.jl >/dev/null
real 0m0,078s
user 0m0,074s
sys 0m0,016s
Regular (precompiled) execution (e.g. julia -e 'using Runic; Runic.main()'):
$ time runic <../src/Runic.jl >/dev/null
real 0m0,328s
user 0m0,314s
sys 0m0,084s
Runic is surprisingly fast even without compiling, but if you use e.g. “format on save” or similar you can sometimes notice a tiny lag for larger files. With the compiled binary you don’t notice it at all.