-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Subscript syntax and semantics #1356
Conversation
when `a` is an rvalue, the result can be an lvalue or an rvalue, depending on | ||
which interface the type implements: |
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.
I think this introduces two possibly-significant constraints on the rest of the language design:
- An expression in a generic might be an rvalue where a corresponding expression in a non-generic context (or a generic context with more type information) would be an lvalue. (Specifically, this can happen if we know a type implements
Subscriptable
but do not know whether it implementsSubscriptableAsRValue
.) Therefore we would have a coherence violation if the same operation performed on an lvalue and on an rvalue of the same type are both valid and have different semantics -- providing more type information would change the semantics of the same operation. We would also have a problem if an operation that is valid on an rvalue is not valid on an lvalue, because providing more type information could render a previously-valid operation invalid, but I don't think that's a severe problem. - It must be possible not only for language rules to be able to say "I require that this type implements this interface" during impl validation, but also for them to be able to say "go and have a look at whether this type implements this interface and tell me whether it does; don't reject the program if not". I think that might already be a requirement in order to support things like constrained blanket impls, though.
I think these are probably both fine, but we should make sure we write down at least the first point somewhere, since it seems like this would be an easy trap for future language rules to fall into.
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.
OK, I've added a paragraph at the end of this section spelling out a constraint that I think is equivalent to (1). Let me know if you think (2) needs to be explicitly documented as well.
**Open question:** The spelling of these interface and method names may be | ||
affected by the resolution of #1058. |
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.
#1058 is resolved, so I guess we should try to answer this question.
For the first interface name:
Subscriptable
wouldn't fit in well, given that we've largely moved away from the "able" suffixSub
seems like a possible shortening but doesn't work because that means "subtract" not "subscript"Index
might work, but I think it's likely to be read as a noun rather than a verb unless we're carefulIdx
similarly might workLookup
is a possibility, but not all uses (eg arrays) really "feel like" a lookup, and lookup feels like it should be fallibleSubscript
is a possibility; I think using a typesetting term here for something other than its typesetting meaning is a little odd, but has lots of precedent)
For the second interface name:
- We could use an
AsRValue
suffix or similar. - We could use a name that describes the intended semantics, such as
Slice
orIndirectIdx
For the method names:
- We could use something like
X.Op
with variants of that name for the lvalue and rvalue functions. I don't think that works so well here given that we have three different function names. We could useOp
,LValueOp
,RValueOp
, orOp
,OpAsLValue
,OpAsRValue
I suppose, but I don't really like those so much.Op
,OpL
,OpR
would follow the same terseness asOp
, but aren't all that readable. - We could use
Subscript
/SubscriptAsLValue
/SubscriptAsRValue
, but if the interface is namedSubscript
the name shadowing might be problematic. - We could use
At
orElem
forSubscriptable.Subscript
, andAddr
for the other two functions.
Maybe:
interface IndexWith(T:! Type) {
let Result:! Type;
fn At[me: Self](idx: T) -> Result;
fn Addr[addr me: Self*](idx: T) -> Result*;
}
interface IndirectIndexWith(T:! Type) {
impl as IndexWith(T);
fn Addr[me: Self](idx: T) -> Result*;
}
(I'm not tied to this at all, but I think it fits into our current set of interfaces reasonably well.)
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.
Done.
The source branch is private and I can't make it public, so I'm moving this to #2274 |
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.
Comments are addressed in #2274.
when `a` is an rvalue, the result can be an lvalue or an rvalue, depending on | ||
which interface the type implements: |
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.
OK, I've added a paragraph at the end of this section spelling out a constraint that I think is equivalent to (1). Let me know if you think (2) needs to be explicitly documented as well.
**Open question:** The spelling of these interface and method names may be | ||
affected by the resolution of #1058. |
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.
Done.
Cloned from #1059