-
Notifications
You must be signed in to change notification settings - Fork 59
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
Typed metadata (again!) #111
base: master
Are you sure you want to change the base?
Conversation
Why requiring the use of |
proposals/0000-typed-metadata.md
Outdated
@:metadata | ||
@metadataCompileOnly | ||
@metadataRequire(@:metadata _) | ||
function metadataCompileOnly(): haxe.macro.Expr.Function; |
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.
An alternative would be to use @metadata function ...
to define a runtime metadata (@foo
), and @:metadata function ...
for a compile-time one (@:foo
). Requiring to add @metadataCompileOnly
to all compile-time metadata sounds very annoying (also, we have namespaces).
Drawback is that it's easy to make a mistake between @:metadata function
and @metadata function
but that should be caught very easily at use site.
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.
also, we have namespaces
Btw, this seems like a limitation of this proposal to not handle metadata namespaces, which is unfortunate. (edit: I guess it's in concurrence with fully qualified path there..)
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.
(edit: I guess it's in concurrence with fully qualified path there..)
Oh yeah, sorry if I didn't make it as clear in the proposal but you import like normal functions, otherwise you use full path. Like how you would with a normal function call. I kind of touch on it a little here, demonstrating how using module-level vs static function changes how you'd write it with basic module import.
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.
Drawback is that it's easy to make a mistake between
@:metadata function
and@metadata function
but that should be caught very easily at use site.
Yeah, this was certainly a tough thing to find an answer to. Maybe typed metadata should just support being used both ways. But if there's a colon, it doesn't generate rtti? Hmmm...
This was actually my original idea. Instead of The only reason I didn't commit to that in this proposal is I feel like body-less metadata functions are going to be used waaaay more frequently, so you end up writing much more to accommodate the less common use case? Plus nadako's comment seemed kinda popular. And finally, But I'm glad you brought it up cause I thought that might be a better way too, and I'd be interested to hear what others think. |
I don't know, really. All those switch + Speaking of body-less metadata, they seem pretty much useless as-is (unless we enforce typed metadata everywhere which I really doubt we'll do by default) as they don't even really ease reading their data from outside. For example I would assume we could somehow read something like |
That fair. 🤔
I like this a lot. I'll try and incorporate something like this into the proposal in a bit. Would need a way to handle having the same meta used multiple times... so maybe make it an Array in that case? |
I may be wrong but I remember reading something about the metadata function having some way to allow being used multiple times or not? That could potentially be used to allow either
We could have |
Merging typed metadata into the existing syntax seems unlikely to work out. In particular:
Does this mean that virtually all metadata everywhere would be rejected unless the flag is set, especially metadata coming from third-party libraries (which might not update at the same time as the compiler)? Not good… Or is this saying, if the compiler fails to type a metadata, when a function for it exists and is resolved, it will complain? Also bad: a typo in the metadata name (or a forgotten import, etc) will simply be accepted silently. Also: in your proposal you only use the runtime metadata syntax IMO we need separate syntax for this. I think |
Also Simon proposed only allowing classes as metadata providers and disallowing "untyped" metadata starting with an uppercase letter. That handles the separate syntax issue. |
* Provide new suggestion for handling untyped metadata errors. * Add `Array` and `Dynamic` to allowed arguments * Remove `@:metadataCompileOnly`, `@:metadataRequire`, `@:metadataRequire`, `@:metadataPlatforms` * Add options argument to `@:metadata`: ```haxe @:metadata({ allowMultiple: Bool, compileTime: Bool, platforms: [] }) ``` * Replace `MetadataEntryTools` with `typedMeta: StringMap<Dynamic>` field on certain structures. * Added `Context.typeMetadata` function
Updated proposal:
@:metadata({ allowMultiple: Bool }) function author(name: String): Any;
|
|
||
### Reading Arguments | ||
|
||
There needs to be a mechanism for reading metadata arguments. To provide this, a new field `typedMeta: StringMap<Dynamic>` should be added to: |
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.
StringMap<Dynamic>
is very far from my idea of typed metadata :/
Though, well, it's not that easy to express with our type system but shouldn't be impossible.
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.
Ahh, sorry. Could you give a more clear idea? I thought you just meant a Dynamic
originally. How would your system handle the scenario where there are two metadata with the same name? Like in the example: Module1.myMeta
+ Module2.myMeta
?
### Untyped Metadata | ||
|
||
If the Haxe compiler encounters a metadata entry it cannot type, its behavior is currently an [Unresolved Question](0000-typed-metadata.md#unresolved-question). | ||
|
||
For the time being, this proposal suggests throwing an error _unless_ `-D allow-untyped-meta` is defined. | ||
For the time being, this proposal suggests printing an error for each metadata entry that could not be typed (no metadata function could be found for its name/path) ONLY IF within a module that meets the following conditions: |
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 still don't think it's ok as default behavior.
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.
Yeahhh, idk. This is mostly meant to be unresolved until the main question of whether @.
or @CapitalLetter
or some sort of new indicator should be used. Idk, like with a lot of things not married to it, just trying to throw out solutions. 🤔
For the record, I favor the |
What if type checking metadata worked sorta like null safety does? That might give the most flexibility for backwards compatibility without needing to introduce all kinds of new syntax. Make it opt-in per package or even per class, basically. package my.package;
@:metadata({ rtti: true }) function foo(arg:String):Any;
// Could be something like this (at a class-level) or `--macro metadataTypeChecking('my.package', Strict)` (as an
// initialization macro). `Strict` could throw errors, `Warn` could just warn, `Off` could turn it off completely?
@:metadata.typeChecking(Strict)
class Foo {
@foo('ok') final foo:String; // Fine
@bar final bar:String; // Throws an error
// etc.
} Alternatively this could be opt-out, allowing you to turn off type-checking for various packages (but even then maybe only emit a warning by default?). This probably won't work too well with the more ambitious parts of this proposal, but if all we really want is some completion and error checking, maybe it's enough? Heck, even if we go with a new syntax like Edit: |
Some remarks: Metadata targets as return typesThis is a bit too clever. The main problem I see is that we cannot express the targets of something like
|
Another typed metadata proposal.
Similar to previous proposal with relevant discussion here. Relevant wiki content here. Based off of @nadako's comment which seems to be the most popular idea.
Rendered proposal