-
Notifications
You must be signed in to change notification settings - Fork 1
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
syntax for declaring fields #3
Comments
I'd think a |
You could put I also like that This could however be a benefit -- i.e., multiple |
I have a pretty negative reaction to the We've also talked from time to time about allowing method declarations within struct declarations, as a shorthand for writing inherent impl blocks. Presumably we'd run into all the same problems there, but not have I'm a bit surprised that |
I think the idea is that the "matching binding" is the assignment in the trait Foo {
let f: T;
let g: U;
}
impl Foo for Bar {
let f = self.x;
let g = self.y;
} It is "specified before it is used" in the sense that if there is no matching (FWIW I'm personally torn between the |
You could use I fine |
I like the I think using a contextual keyword like trait Foo {
type Tf1: Bar;
type Tf2: Baz;
field f1: Tf1;
field f2: Tf2;
} |
True. Though last time I floated this, there was a lot of negative reaction.
Well, we could in principle permit One complication I can see would be trait Foo {
fn bar() where A: B + C, // <-- is this `,` terminating the list of where-clauses, or the item?
fn baz()
} |
I guess it would make sense to flesh out the various syntax options more concretely. There is definitely a diversity of opinion on this topic. I think one particularly important knob is how they would support "shared-only" fields. |
let
syntax for declaring fields
ok, I updated the main text to reflect various alternatives. Let me know if anything is unclear or different from how you would have expected it. |
+1 for |
I was thinking on this a bit more. I think part of the reason I sort of like I am a bit nervous about |
I strongly prefer the trait Foo {
struct {
bar: u32,
baz: u64,
}
} For several reasons:
trait Optional<T> {
enum {
Yes(T),
No,
}
} To which you can then define a mapping which we will check for exclusivity & exhaustiveness. I know Niko also has a different idea for how pattern abstraction could work inspired by extractor classes in Scala. |
I suspect Niko's custom disjointness rules favor using If
It kinda looks like |
Having let this sit for a while, I think I've come around to the "anonymous" trait Foo {
struct { (mut? field: Type),* }
}
impl Foo for T {
struct { (field: value),* }
} There would be at most one There are some advantages:
It's not perfect -- in particular, I think we probably still want fields to be "read-only" by default, and hence the syntax between traits and structs is mildly asymmetric: trait Foo {
struct {
mut f: u32
}
} However, it seems better to me than inventing a keyword like (That said, I personally still find |
I think |
I was fond of I'm coming around to |
@lxrec
Note that we could eventually loosen this, if we get some way for (e.g.) enums to have common fields. But then we are saying "this trait acts like a struct" -- and, perhaps, implementing types must have some "struct-like subset" of them. So it still works. I couldn't quite get the tone of your comment. Seems like you used to dislike I feel like we have to unblock on this point, in any case. Certainly before stabilization we could also revisit this question as we gain more experience, though it's the kind of thing you'd prefer to get right to start. |
Would more finer-grained disjointness rules be expressed by grouping or something else? If grouping, then you could omit the
|
I shouldn't really have mentioned that, I think. It's hard to know what's the best design here and I don't really want to spend too much time thinking about it, because I see it as fairly orthogonal from this RFC. I think I agree with your broader point that |
Well, I guess in this respect there is one slight advantage to |
I'd think some well considered contextual keyword would be best "pedagogically", maybe not In fact, one could always separate methods into a different block with any syntax, like say You guys could go with |
I would like to propose another option: "super type", analogy to "super trait". struct Foo1 {
f1: u32
}
struct Foo2 {
f2: u32
}
trait Bar: Foo1 + mut Foo2 {
fn call(&self) {
self.f2 += 1;
let x = self.f1 + self.f2;
...
}
}
impl Bar for T {
struct Foo1 { f1 : member1 }
struct Foo2 { f2 : member2 }
fn call(&self) {
let x = self.member1 + self.member2;
...
}
} I'm not saying it's better or not. This option seems not mentioned by anyone. |
@F001 That might be a confusing name, as terminologically it would be a form of subtyping AFAIK. |
The existing RFC text proposes a struct-like syntax:
This is nice in some respects, but awkward in others. For example, a
;
is required to separate fields from methods. There are a few alternatives floating about.requirements
I think it's important to plan out how we will support shared-only fields (#5)
current proposal
Upsides:
mut
keyword is notDownsides:
mut g: U
is inconsistent with struct declarationthe
let
keyword (or other contextual keyword)One alternative is to use
let
:This no longer mirrors struct syntax, but it has some advantages:
let mut f: T
to indicate (potentially) mutable fields.Downside:
let
suggests (to some, at least) "lexically scoped variables"Alternative:
inner
struct
Advantages:
Disadvantages:
mut
part is not consistent with structsOther interactions
Foo { f: 22, g: 44 }
might instantiate the trait above. This would be equivalent to declaring, basically, a local struct with those fields. This can still work withlet
syntax, but does it feel weirder in some way? I guess not.The text was updated successfully, but these errors were encountered: