Skip to content
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

Proposal: allow direct dereference of comptime-known slices #19447

Open
mlugg opened this issue Mar 27, 2024 · 5 comments
Open

Proposal: allow direct dereference of comptime-known slices #19447

mlugg opened this issue Mar 27, 2024 · 5 comments
Labels
frontend Tokenization, parsing, AstGen, Sema, and Liveness. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@mlugg
Copy link
Member

mlugg commented Mar 27, 2024

At comptime, slices and array pointers are effectively interchangeable. They both have ptr and len fields, both can be sliced, both support indexing, and array pointers coerce to slices. In fact, slice[a..b] yields an array pointer for comptime-known a and b for this reason: it's a more specific type with strictly more functionality.

However, note the "more functionality" part of the equation here. In reality, array pointers have one key capability which slices do not have: you can dereference them, yielding an array. You can't dereference a slice -- that's not a meaningful operation.

...or is it? If the slice is runtime-known, sure, that's definitely not a thing. But what if the slice (and by extension its length) is comptime-known? Then we can easily dereference the memory in question to yield an array of the appropriate length. This operation makes sense because a slice is effectively just a representation of pointer-to-array where the array length may be runtime-known. If the slice is comptime-known, then it represents the exact same thing as the corresponding array pointer.

Thus, I propose to allow direct dereference via .* of comptime-known slices. slice.* would yield a value of type [slice.len:s]T when slice has type [:s]const T (and the obvious analogy when there's no sentinel). This would be equivalent to slice[0..slice.len].* today: the slice operation there is basically a no-op, it just serves to turn the slice into an array pointer. That way of writing it is how you'd do this in status quo, but it's actually pretty confusing if you aren't thinking carefully about the types. The intent and behavior of the proposed slice.* are, IMO, perfectly clear and less confusing.

@mlugg mlugg added proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. frontend Tokenization, parsing, AstGen, Sema, and Liveness. labels Mar 27, 2024
@mlugg mlugg added this to the 0.13.0 milestone Mar 27, 2024
@Rexicon226
Copy link
Contributor

IMO this feels like a shortcut that shouldn't exist. I understand that you cannot use the slice[0..slice.len].* semantic at runtime (obviously), however using this shorthand feels like a second, less obvious way to do it. In the slice[0..slice.len].* you can easily point at the slice.len not being comptime-known and explain how you can defer only slices with a comptime known range, however with slice.* it's less verbose with the implicit "full" range and can be confusing why it isn't allowed at runtime.

TLDR; feels like a less verbose shorthand, and a further split from comptime / runtime Zig.

@rohlem
Copy link
Contributor

rohlem commented Mar 27, 2024

This would be equivalent to slice[0..slice.len].* today

From quick testing it seems that slice[0..].*, which is way shorter, also does the same thing in status-quo.
That being said, I still support using slice.* to reduce noise even further - as long as we appropriately adapt the error message for using it on slices of runtime-known length.

@InKryption
Copy link
Contributor

InKryption commented Mar 27, 2024

This seems like an awkward rule to add. Currently, there's not that many extra rules to remember, just a combination of two: that you can slice with comptime-known indices to get a single-item array pointer, and that you can dereference single-item pointers (to arrays included). Adding this capability seems like adding a rule which requires a write-up in the language reference for the context behind its existence, and another reason for someone needing to debug their knowledge of the language. And as pointed out, with slice[0..].* already yielding the equivalent behaviour at comptime, and again, as a composition of zig's current rule set, this change seems altogether unnecessary.

Edit: I'd also like to add, this seems to be in a similar vein as #5575, which although not rejected, I believe should be, with the advent of #15519.

@mlugg
Copy link
Member Author

mlugg commented Mar 27, 2024

Thanks for the feedback on this one. Usually when I write up a proposal I'm fairly confident that it's the right direction for the language, but I was pretty unsure with this one. I'm still not convinced either way. I'll give a detailed response to the points here later on :)

@Cloudef
Copy link
Contributor

Cloudef commented Apr 1, 2024

Personally I'm worried about the split between comptime and runtime zig. I'm already heavily affected by the #19414 change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
frontend Tokenization, parsing, AstGen, Sema, and Liveness. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

5 participants