-
Notifications
You must be signed in to change notification settings - Fork 425
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
Should range
be a non-defaulted generic type?
#18215
Comments
This is similar to a decision we made about the The only limitation that I can think of by making Other than that, I think dropping the defaults will make things more permissive, such that you can pass any range to This permissiveness is generally positive for me. However, there has been subtleties with stridable ranges where you'd have to use |
I don't think it's that bad. You can still re-assign But I agree that Question: If we made range only partially defaulted (say we defaulted idxType to var r: range = ...; require the RHS to be an |
I'm taking a look at this, starting by simply removing var r: range = 1..10 by 2;
writeln(r);
writeln(r.type:string); |
Looks like ~100 tests need edits to keep working with a generic
|
#18268 has an implementation for this, though I don't expect this to go into the 1.25 release because I think it's likely that we'll want to do all changes to the range type (likely changing the boundedness enum; reconsidering the name / value of the stridability param) all at once. And because I don't have a vision as to how to make the change gradually. |
The idea of turning What I find missing is a handy way to specify the common-case concrete range type, i.e., today's
Analogously, we can introduce
... as well as |
I'm not a fan of this, it looks "strange" to me (ha ha). Of course, users who liked/wanted type aliases like this could always create them themselves (or type functions). |
range
a non-defaulted generic type?range
be a non-defaulted generic type?
I agree this is not the best name. However, I still believe it will make a difference if we give the users an easy-to-use alias for today's So, to me it comes down to picking a good name. Or perhaps follow int's lead and define |
They could, but I'd argue that it's very common for one to declare Do you have a favorite pattern that demonstrates the utility of having |
I don't think I can find such a pattern that stands out. Using it as the type of a formal, for example? Any use of fully-defaulted This question though led me to the following experiment: how many times do we use I looked at all our module code, as well as
|
I'm not sure I agree with either of those statements. Apart from what you and I are used to from years of working with the language in its current state, it doesn't seem to me that a formal
What do you conclude from this experiment? (I'm curious whether it matches my conclusions). To me, the more interesting experiment is to look at which codes had to change in #18268 and to see whether any of them seem like a significant step backwards. |
I agree that a newbie can perceive I also agree that in some cases today's code that says What I am proposing is a shorthand for the simple range type, so I don't have to spell out Looking at the changes in #18268, if we un-default The great majority of the changes in #18268 replace Also, #18268 makes only ~6 changes in test/studies and no changes in test/release/examples. Which tells me that most of the 54 uses of |
Is there any reason not to make domain the same as range in this regard? That is, if we make
But are these cases using var r: range = 1..10;
var r: range(?) = 1..10;
var r = 1..10;
var r: range(stridable=false) = 1..10; and effectively end up with the same thing. So it seems to me to only really be important in the case of a variable that does not have an initializer.
I don't think this is particularly attractive in its lack of saying what the |
I don't have a good sense of that. I just see that there is some number of cases in the code where the simple-range type is used as the type of a record field, array element, or a tuple component and there is no default value. Another thought is that allowing However, latent bugs come about when such a function assumes stride==1 and some future invocations will pass it range(s) with a non-unit stride. Is this a big deal?
That will make a very good sense, theoretically. Also, applying this a change to our code base will be a good stress-test for how impactful it is. |
Should 'range' become generic, I propose to introduce |
I find the name |
My interpretation: this is the other direction we could choose -- make both // Then we'd need to make |
I'm not following this comment: What's the link between regex and domain/range? (i.e., how would a decision on domain/range affect the design of regex or any other type?)
Do you mean fully concrete, not generic at all? If so, how are you proposing we avoid throwing away performance w.r.t. 1D vs. nD domains, strided vs. unstrided arrays, etc.? |
The link is similarity. My preference that similar things behave in similar ways.
Yes, fully concrete. Just like today I can declare a variable of the type To avoid performance impact, the user would write |
In what way is a range or domain similar to a regex?
Oh, so you don't mean to make the |
Here's a case today that I wrote, the compiler complained about, and then I rewrote, realizing that it was a case where a more generic range would've made it easier to write: var r: range(bool) = ..; |
This specific fact surprised me today, and I've already been caught by and internalized the "domains are generic, ranges aren't" discussion. So I was expecting I could do var d : domain(1) = {1..5 by 1}; but alas I hadn't internalized it as well as I thought. Thankfully it seems there is agreement that |
We decided to keep the generic aspects of This decision resolves this issue. Closing. |
Traditionally, range has been a generic type that is fully defaulted, with:
int
indicesThe argument being that this was the common case and the one we wanted to optimize most for.
However, this has also resulted in a few stumbling blocks:
var r: range = 1..n by 2;
doesn't work and get frustrated at having to change it tovar r = 1..n by 2;
orvar r: range(stridable=false) = 1..n by 2;
: range(?)
rather than: range
to take "any range type", making them asymmetrical withdomain
(which does mean "any domain type" because domains aren't fully defaulted)While reviewing the range type today, @e-kayrakli proposed that perhaps ranges shouldn't have default values. My immediate reaction was "That's ridiculous!" but on reflection, I'm having trouble coming up with arguments for how the defaults are helping us. Just because they're the common case doesn't mean that we rely on the defaults in that way at all (e.g.,
1..n
gets us that same common case without causing pain for anyone else).To that end, this issue proposes we look into making
range
partially or completely non-defaulted in its generic fields to see what the impacts are.This relates somewhat to #18214 due to the asymmetry between
domain
andrange
w.r.t. being fully defaulted.The text was updated successfully, but these errors were encountered: