-
Notifications
You must be signed in to change notification settings - Fork 72
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
user-defined aggregate types #609
Comments
While I like this idea (and would love to try implementing it when #234 is done), the draft itself definitely needs a few corrections.
Obviously, we can't use
Not sure if this is a good idea. If I understand this correctly, internally
Not sure if this would be possible either, as operators can't have array arguments (except for destructors, but this is so multiple variables could be destroyed with a single destructor call).
The address of
No for both.
I think it must be the first (hidden) argument of a method, as described in #234.
Same as for question 1.
Can you please elaborate, what exactly do you mean by "call-by-value"?
I think we should error when a primitive-tagged single value is overridden with an aggregate-type tag, as we can't convert a single value into an array.
They probably shouldn't be allowed, as arrays can't have a zero length. |
OK, I've not read too carefully yet - I'll get to that. But one thing is that I really don't think that whatever the feature is should hide the size of the data. For example: bool:operator==(Player:a, Player:b) { return a.id == b.id; } There's nothing in the function declaration there to expose the fact that |
Without major reworking, that would print the value of the first field. The same thing that happens with an enum in that case. Anything else would be almost impossible and require |
Something to consider, as a middle-ground between abandoning enums entirely for totally new syntax, and keeping the good parts without issues like name scope: https://www.nextptr.com/tutorial/ta1423015134/scoped-class-enums-fundamentals-and-examples |
If we did have enum const Tag1
{
A, // 0
B, // 1
}
enum const Tag2
{
_NONE, // 0
A, // 1
B, // 2
}
main()
{
new Tag1:a = A; // 0
new Tag2:a = A; // 1
new Tag3:a = A; // Error
} |
Sort of inspired by a hybrid of C++ |
Because C++ Old code: enum E_HOOK_NAME_REPLACEMENT_DATA
{
E_HOOK_NAME_REPLACEMENT_SHORT[16],
E_HOOK_NAME_REPLACEMENT_LONG[16],
E_HOOK_NAME_REPLACEMENT_MIN,
E_HOOK_NAME_REPLACEMENT_MAX
} static stock
YSI_g_sReplacements[MAX_HOOK_REPLACEMENTS][E_HOOK_NAME_REPLACEMENT_DATA]; if ((pos = strfind(name, YSI_g_sReplacements[idx][E_HOOK_NAME_REPLACEMENT_SHORT], false, pos + 1)) == -1)
{
++i,
idx = YSI_g_sReplacementsShortOrder[i];
} New code: enum struct E_HOOK_NAME_REPLACEMENT_DATA
{
E_HOOK_NAME_REPLACEMENT_SHORT[16],
E_HOOK_NAME_REPLACEMENT_LONG[16],
E_HOOK_NAME_REPLACEMENT_MIN,
E_HOOK_NAME_REPLACEMENT_MAX
} static stock
YSI_g_sReplacements[MAX_HOOK_REPLACEMENTS][E_HOOK_NAME_REPLACEMENT_DATA]; if ((pos = strfind(name, YSI_g_sReplacements[idx][E_HOOK_NAME_REPLACEMENT_SHORT], false, pos + 1)) == -1)
{
++i,
idx = YSI_g_sReplacementsShortOrder[i];
} Idiomatic code: enum struct E_HOOK_NAME_REPLACEMENT_DATA
{
SHORT[16],
LONG[16],
MIN,
MAX
} static stock
YSI_g_sReplacements[MAX_HOOK_REPLACEMENTS][E_HOOK_NAME_REPLACEMENT_DATA]; if ((pos = strfind(name, YSI_g_sReplacements[idx][SHORT], false, pos + 1)) == -1)
{
++i,
idx = YSI_g_sReplacementsShortOrder[i];
} 99% of existing tutorials are kept exactly the same. What people know is the same. You can literally upgrade just by adding the word As for the |
Why would we declare in function header if its structure or something else? Its tagged, that tag is used for structure and compiler should figure out that its that exact structure, its members and size. If anything we could use some other and/or additional special character |
Pawn is based on cells. One variable is one cell. Anything more than one cell is an array, using |
You yourself said that in pawn, anything more then one cell is an array, and arrays are passed by reference. That is said in pawn docs and thats how we know that. So why not just expand that documentation and define what structure is, and how its passed? For example, "Structure is custom decorated, named array, that can have one or more cell's called members. Members should be accessed with . operator. Structure can have other structures as members and its size directly depends on its members." That is vague and probably wrong description, but i hope you get my point. All that is needed is to define syntax and its meaning. If we chose By the way, you mentioned confusing syntax, but pawn already has confusing syntax by default. For example, without looking at what function does, how can you tell that it returns array?
|
"There's already confusing syntax" is not a good argument for adding more confusing syntax. |
There's already three different ways to pass a variable by reference. You're proposing a fourth, which is no shorter than any of the others; I just don't think it is worth the overhead at all. |
Another common convention that already exists is using |
Issue description:
Most developers (ab)use
enum
s to create aggregate user-defined types. There are few disadvantages to this method:We can implement a new system to support user-defined aggregate types once in for all. To proceed we need to draft a spec for the syntax and semantics and also have consensus for the feature.
Here is my proposal (ad-hoc and not-well thought) to kick off discussions:
Tags are currently used for user-defined types. We can extend it to allow user-defined aggregate types.
We can have a new class for tags: aggregate-type tag and primitive-type tag. We can use the last but one bit to classify these (the MSB is currently used to mark STRONG and WEAK tags). Tag overrides b/w aggregate types might trigger a warning.
Questions:
this
? What should be the output ofprintf("%d", _:this);
?new Player:a = Player:0;
mean?struct
?We could in principle implement the whole thing as an enum based struct internally and add special handling to prevent identifiers from being spilled out. This would mean passing an object by default would pass by reference.
Bonus: simulate namespaces with static members
While this does simulate a namespace, it uses a
.
instead of the_
convention for naming modules. I don't like this syntax but this is a possibility.Bonus: unions with some tag overrides
We can similarly make variants by having a
type
member variable.Bonus: abuse to support polymorphism (needs more work but it seems to be possible)
Related issues:
The text was updated successfully, but these errors were encountered: