While working on owlkettle I stumbled over this warning repeatedly. It turns out owlkettle used {.locks: 0.} rather liberally (21 times from what I could find). A lot of those places are for procs where owlkettle accepts user defined procs as parameters and this is just to deliberately limit those procs in their ability to enforce a bit more correctness (aka a "You shouldn't do this here" kind of thing, I think).
This is there to ensure that no lock is ever acquired in this code, based on: > Lock level 0 means that no lock is acquired at all. Source: https://nim-lang.org/1.6.12/manual_experimental.html#guards-and-locks-lock-levels
Reading through the same section in the new docs (https://nim-lang.org/docs/manual.html#guards-and-locks) I can't find a similar way to have such an enforcement mechanism. I asked about this in the discord and Rika stated that expressing such a thing should no longer be necessary.
I don't quite see why that would be the case though, since the desire to enforce that "This code should not access some locked shared mutable memory" seems to me like it would be something that is relevant regardless of what the syntax for locks looks like. Or is that something that shouldn't have been used in the first place?
Note that I myself have very little multi-threading code experience in nim. I'm aware of how to use locks, but that's about it. So I can't quite figure out the relevance of guaranteeing no-lock-operations or not.
There is no replacement mechanism, except maybe passing the lock around explicitly via parameters and then using callbacks that lack the parameter so that callbacks cannot acquire the lock.
The lock levels mechanism wasn't used much, further complicated the type system and I'm not aware of a single realworld case where it actually prevented a deadlock at compile-time.
Don't we still have tag/effects tracking? I think that is supposed to solve a similar problem (telling the developer to not exhibit certain prohibited behaviors somewhere.)
Though that requires various APIs properly tag the functions and I do not believe most of them do.
Theoretically yes, in this usecase it wouldn't be a gain. This is for a framework that accepts procs from a user, so you do not control what kind of proc gets passed in there.
An effect is basically not being validated there, or rather there's no validation beyond the user applying said effect-pragma to their proc which they may do blindly. At that point the effects system is nothing more than an annoyance to the user, so you may as well leave it out.
For larger applications where you control multiple sides of the equation (or if we had some standard effect-types in the nim-ecosystem for e.g. this kind of scenario) I think this is still valuable. Just not in this scenario.