-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
std.fs: split Dir into IterableDir
#12060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
cb8bc1f to
5c228b2
Compare
andrewrk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like the main benefit of this change is so that calling intoIterable gives an assert in safe modes, so that when testing on an operating systems which allow all dirs to iterate, the programmer will not incorrectly believe that it works when it will fail on a different operating system that needs the iterable flag to be correct.
This benefit could be achieved more simply by adding the safety flag to Dir instead of introducing IterableDir as a new type.
I'm a bit concerned here with the added clunkiness of the API; having two types associated with the same resource. It does prevent a certain kind of mistake from being made, but it also causes confusion about which type has which methods and makes usage sites more convoluted.
We had a similar pattern earlier with mutexes. It used to be:
var held = mutex.acquire();
defer held.release();
...which was a nice way to help the user not forget to call unlock(). However it ended up being really annoying and actually more error prone any time the API needed to be wrapped, and we ended up just going back to the more straightforward:
mutex.lock();
defer mutex.unlock();
How do you feel about my counter proposal of adding the safety field directly to Dir?
lib/std/fs.zig
Outdated
| /// Convert `self` into an iterable directory. | ||
| /// Asserts that `self` was opened with `iterate = true`. | ||
| pub fn intoIterable(self: Dir) IterableDir { | ||
| if (builtin.mode == .Debug) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (builtin.mode == .Debug) { | |
| if (std.debug.runtime_safety) { |
lib/std/fs.zig
Outdated
| fd: os.fd_t, | ||
| iterable: @TypeOf(iterable_safety) = iterable_safety, | ||
|
|
||
| const iterable_safety = if (builtin.mode == .Debug) false else {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const iterable_safety = if (builtin.mode == .Debug) false else {}; | |
| const iterable_safety = if (std.debug.runtime_safety) false else {}; |
I don't think the main benefit here is
I think the separation between the types is quite clear here,
I don't think this situation is comparable. |
|
Just rounding up comments made about this on Discord:
|
Removing the ability to easily go between the different types causes a lot of unnecessary repetition or loss of type information via the use of |
|
You've said this a number of times, but could you please provide an actual example of this? There is no case in which going from If a function needs to iterate on a directory, it should take Have you thought this through? |
This is not the point you were making earlier or at least you couldn't be bothered to make it clear. This I could agree on.
That is exactly how |
|
@Vexu Would you maybe consider omitting the components of this PR that would allow for conversion from Otherwise, I think it'll turn out to be far more harmful for people to unwittingly take a |
Couldn't be bothered?? 🙄 This is my entire criticism I've been making of your PR: that One of my concerns is that, for example, someone has an already-written function which takes a
But you can only call |
And yet, I though you wanted to remove the conversion in both directions which is why I was emphasizing how it would lead to repetition of code.
Not directly, but all it takes is a little comptime logic: fn iterableOrNotIDontCare(dir: anytype) void {
// non iterating operations on `dir`..
if (some_comptime_condition) iterableOnly(dir);
// more non iterating operations on `dir`..
}(This of course is only when |
Oh I see why you could have thought that lol. Glad we're on the same page now, then! |
|
A similar pattern can be drawn with passing |
I do also, but if we're to add a check for iterability, I think it's probably best to try a comptime, type-based solution first. |
Also adds safety check for attempting to iterate directory not opened with `iterate = true`.
|
For a real-world example, here's how this change affects zigup: As I was moving to the new API, I forgot to change one of my opens to |
|
I've seen mixed feedback on this change. There are people who are very unhappy with it, proclaiming it "pointless" and a terrible API, and then you with the benefit that you know your code will be correct when it compiles. I'm not sure where we should go with this, whether we should revert and use a runtime check or stick with it. Maybe worth giving it more time? |
|
I am on the fence with this change. If you look at the updated |
|
This change makes using If Zig had a way to do interfaces/"inheritance"/traits/etc without adding an extra layer of nesting (instead of |
|
After running with this change for about a year now, I have to say that I strongly don't like it and I would like to revert it. In fact, I'm sorry @Vexu but I am very confident in this decision and will use my BDFL veto powers to make the call here. It's going to be reverted. |
* zig std had removed meta.trait ps: this change need set minimum zig build version to 0.12.0-dev.1686+d5e21a4f1 * std.fs: split Dir into IterableDir ziglang/zig#12060 * rework std.atomic ziglang/zig#18085 * set minimum build version to 0.12.0-dev.1710+2bffd8101 * Update binned_allocator.zig * build.zig.zon: Update `known-folders` --------- Co-authored-by: nullptrdevs <[email protected]>
* std.fs.Dir/IterableDir separation was reverted in https://www.github.com/ziglang/zig/pull/18076 , fix breaks ability to compile with Zig 0.11.0. It was planned since at least October, 16th: ziglang/zig#12060 (comment) . Signed-off-by: Eric Joldasov <[email protected]>
walkanditerateare moved to a new typeIterableDir.Dirreceives a newopenIterableDirfunction which returns anIterableDirand also anintoIterablefunction which converts theDirinto anIterableDirasserting that it was opened withiterate = true.Closes #12007