Replies: 31 comments 4 replies
-
While I do like the idea since there are alot of structs that could easily be constants how can the compiler be sure the constructor doesnt do anything that might violate that? Any kind of code could be in there. I see the constructor seems to be implicitly generated in your example? Is this how you would solve the above problem? Only allow it to be a constant if you do not specify a constructor? Expanding this to allow enums to support more than just long, int, short, byte etc is only logical after this is implemented |
Beta Was this translation helpful? Give feedback.
-
Why is status-readonly insufficient for this purpose? |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi What do you mean? At first I was try include a suggestion that struct of blittable member should also be blittable. But that was already have it's own proposal. However my idea generally is when a struct contain member that share any kind of property, that struct should also inherit that property too, as I said above, if all member is integer it should be integer too, if all member is primitive it should be primitive too, if all member is blittable it should be blittable too And so struct that contain only struct that was integer will also be integer all the way up in any level, same go for any property @Barsonax If we really implement this feature. Compiler would just inline constructor at the call site. And so if the constructor using any function that was impossible to be inline as constant, it should just throw a compile error |
Beta Was this translation helpful? Give feedback.
-
I'm not sure i understand what that means. If i contain 4 int32s, that doesn't make me an int32. Nor does it make me an int128. Just because i contain values with properties doesn't mean those properties inherently 'lift' onto me in any meaningful way. For example, how would add work on this combined int? If i had |
Beta Was this translation helpful? Give feedback.
-
What does it man to be "integer all the way up in any level"? |
Beta Was this translation helpful? Give feedback.
-
@Thaina I think we should drop the 'integer' in this feature request as this feature is much broader than just that as it also applies to byte, short, long, float etc. It should be more like this 'a constant struct is a struct that is made up of structs that can be constants themselves'. @CyrusNajmabadi from what I understood this feature request is about being able to use a custom struct as a constant. Currently this is only possible with build in primitives which are getting some kind of special treatment. This would enable these custom structs to be used as default parameters for instance. As a extension on top of that one could allow these custom structs to be also used in enums. Ofcourse the tricky point here is that constructor that can fire off arbitrary logic. |
Beta Was this translation helpful? Give feedback.
-
Can you explain why this is a benefit? I.e. why an enum is a preferred concept here over what is already possible with a struct? Thanks! |
Beta Was this translation helpful? Give feedback.
-
In other words, when i hear a request for "can we make feature X much more like feature Y" my common reaction is simply: why not just use 'feature Y' since it's already here and does what you seem to want. :) |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi readonly is not the same as constant. Readonly doesnt do much more than disallow you to write code that changes that field outside of constructors. The actual value of that field is still determined at runtime. Constants values are defined at compile time and are inlined at all places that use them. Some things readonly cannot do but constants can: |
Beta Was this translation helpful? Give feedback.
-
I'd actually like a real world example where this has been measured to matter.
I don't think that's necessarily a virtue that is worth extending beyond primitive values.
That is something that could be weakened by updating the rules on default-parameters. It doesn't necessitate introducing new constant types. I'd be far more amenable to that approach vs adding more constants myself.
I'm really iffy on hte "much safer" bit. At best, it seems marginal. And certainly not enough so to me to warrant introducing a new sort of constant. |
Beta Was this translation helpful? Give feedback.
-
There is actualy a blog post about readonly getting copied alot and reducing performance:
Build in primitives types have a special 'constant' privilege which is hidden and cannot be used for other types. This feature is not about adding a new kind of constant but its rather about to allow this privilege to be applied to more than just the build in primitives. Currently even if you define a struct in a way that it could be a constant the compiler refuses to do so and will throw a error.
Its not marginal. The enum is there so we don't have to work with for instance just ints and remember what all the numbers actually mean. On top of that the compiler will prevent you from defining a invalid value which gives you some safety. Also like I said there is no 'new sort of constant' its just taking the existing 'constant' and making it more flexible so it can be used on custom structs as well. |
Beta Was this translation helpful? Give feedback.
-
Note: that has been addressed with readonly structs. Previously, the compiler had to assume (non-well-known) structs might be mutable, and thus any instance operation might mutate it. So it needed to make a defensive copy in order to prevent violating the "readonly"-ness of the field. With 'readonly structs' that's not the case. Because the compiler sees that it is declared to not mutate, it can avoid that copy. |
Beta Was this translation helpful? Give feedback.
-
I get that. But, for me, i need compelling cases around 'allow[ing] this privilege'. So far, the only thing that seems interesting is "to allow use in 'default'". but i'd much rather just relax that specific restriction rather than trying to spread hte constant concept. |
Beta Was this translation helpful? Give feedback.
-
How? you can cast any integral value to an enum without any problem. Indeed, that's one of their "virtues", they really are just basically ints. If you want actual protection, you create a type. |
Beta Was this translation helpful? Give feedback.
-
Which is already something that's happening as part of Record types. |
Beta Was this translation helpful? Give feedback.
-
I understand but the point is there was many approach when we do something. And I prefer this way while you prefer another First problem is default parameter. We can relax restriction on default parameter. Or we relax restriction on constant to struct. We can just choose one then it solve the same problem As for me I prefer to have generalized approach as much as possible. Relaxing |
Beta Was this translation helpful? Give feedback.
-
I'm curious how you envision this proposal being implemented. The limitations as to what can be a default value or a constant are imposed by the CLR and what it can embed as a BLOB in metadata. The C# and VB.NET compilers have some tricks for faking constants via attributes that can capturing their specific representation. That's something that I don't think can be extended to general-purpose structs. |
Beta Was this translation helpful? Give feedback.
-
@HaloFour hasnt constant structs been discussed before in the context of ‘blittable’? |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
How would that actually work? if i have: struct TwoInts {
int int1, int2;
} How can i make an enum inherit from this? Like what actual mechanism makes this possible? |
Beta Was this translation helpful? Give feedback.
-
My issue with this is: you called this "integer all the way up". Except, this sort of 'pairwise application of operations' is definitely not how integers work. I gave simple examples of that above. The presumption that the pairwise math holds as you compose primitive values up doesn't hold. I could see there maybe being 1-2 cases where this might be valuable to someone. But since htat is so staggeringly rare, having people just write their own If we put this in the language it would be because there was significant value to be had. i.e. you had tons of libraries and code that composed structs out of other structs and wanted to commonly 'lift' the operators to the composed structs. That's extremely unlikely, and so it doesn't warrant language changes. |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi Well, bit by bit that is actually int64. It could be the same as It's actually about that enum should just use bit block in arbitrary size if all of member was integer
It's about our focus on the word integer is not the same. When I said integer in this proposal I just means primitive types except float, bool and string which is the constraint for used in enum. But I don't mean we need to treat this integer struct as the actual number itself And yes, it reasonable to allow writing custom overload operator. It just that we could let default behavior work like vector from the start. If people don't satisfied with that then they can write their own overload operator normally And if using |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi On the other hand, We then could write |
Beta Was this translation helpful? Give feedback.
-
Yes, like i said: I could see there maybe being 1-2 cases where this might be valuable That's just not good enough. If it was the case that most structs composed of other types did want to lift applicable operators of their constituent parts up to themselves, tehn i would feel differently. But that's not the case. So spending the time and effort on a feature like this which does not make sense for most types doesn't make sense to me. |
Beta Was this translation helpful? Give feedback.
-
What about people that don't want the operator at all? Now you need a way to say "do not lift the operator up to this composed struct". |
Beta Was this translation helpful? Give feedback.
-
Sorry, i meant in the general sense. i.e. 3 ints, 4 ints, etc. etc. How would that actually work? |
Beta Was this translation helpful? Give feedback.
-
As I said
|
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi Another use case for const structs is being able to use them as Attribute parameters. |
Beta Was this translation helpful? Give feedback.
-
Agree with @spixy. @CyrusNajmabadi @FurkanKambay came here from the closed #1466 (finding that from #124). I think this also ties into the new #5354 proposal (at least for my scenario below)? We have a case where we want to pass in a simple structure as an array/params of an Attribute (a pair of strings). Was hoping new records could do it or a tuple, but nope... So this would be really nice to let us do something like: // Desired usage
[MultiChoiceOption("TextForeground", title: "Text foreground",
("Teal", "#0ddc8c"),
("Sand", "#e7a676"),
("Dull green", "#5d7577")]
// Attribute constructor
public MultiChoiceOption(string name, string title, params (string Label, string Value)[] options) { } Everything should just be a constant, so would be nice for this to work. Right now I think the closest we can get is: [MultiChoiceOption("TextForeground", title: "Text foreground",
labels: new string[] { "Teal", "Sand", "Dull green" },
values: new string[] { "#0ddc8c", "#e7a676", "#5d7577" }] Though this leads to not having nicely aligned string pairs or mismatching them. It also requires all the |
Beta Was this translation helpful? Give feedback.
-
I think that inlining is pretty weak argument because 1) the struct would need to contain only constants 2) the compiler would need to unwrap/unpack (or deconstruct) the variables which means the target now needs to accept the variables as multiple arguments as opposed as a single argument 3) inlining isn't the magic word or silver bullet to performance; however, I agree that it would be nice to support structs as constants for the application of pattern matching and attributes. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Primitive type such as
string
andint
have a special ability. Such as make itconst
, use it on default parameter (because it is const). Integer type also able to be base class of enumI think it useful if we could have
struct
that contain only primitive type also being primitiveAnd if it contains only integer it should also be integer
This issue was ported from dotnet/roslyn#16095
Also this could cover record enum types dotnet/roslyn#6739
And if we could recursively see
enum
type as integer type so we could havestruct
containsenum
can be base class of anotherenum
this feature would also cover dotnet/roslyn#16193Like this
This should also cope with Tuple and other generic struct. If its generic contains only primitive it would became primitive
Beta Was this translation helpful? Give feedback.
All reactions