-
Notifications
You must be signed in to change notification settings - Fork 395
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
RFC - Annotations #807
RFC - Annotations #807
Conversation
Support because this means inlining could be added and inlining could actually be useful to reduce the overhead of calls on simple statements such as: @inline
local function GetCatNameFromAge(cat)
return if cat.age >= 1 then "cat" else "kitten"
end |
I believe this is really poorly fleshed out.
Inlining should not be the motivating scenario given it's already a feature that the compiler already performs. Additionally, why should we give valuable syntax to something that could be more concisely expressed as a comment? eg: -- allow unused variable
local x = 1
local x = {
-- allow undefined variable
notDefined,
} I just believe there is a better use for this syntax, such as annotating tables, that users could benefit from. |
Similar RFC: #824 |
I'd be interested to know what you mean by annotating tables in this case. I'm not able to think of a case where this syntax isn't usable for both annotating functions and tables, but I'm open to it if an example can be provided. That said, comments aren't a good alternative to this syntax because having to parse comments to control language features is bad. It works for directives at the moment, but they have to be the first tokens in the file and it complicates things dramatically to peek at every comment in a file. |
@Dekkonot thanks for your response! Sorry for the long delay—Here are my thoughts:
My apologies, I was unnecessarily vague there. I believe that this syntax can be used for better semantics than switching on/off type checker features. I’ve included some examples in my (competing) RFC here. Basically, the gist of it is a rip-off of ECMA Decorators, which are generally praised by the JS community and actively used to enhance previously-imperative code with declarative constructs. Here’s an example of it being used to enhance defining schemas with a JavaScript ORM. This C# project uses Attributes (Similar to ECMA decorators, but different semantics) to allow developers to easily automate creating protobuf-like schemas for C# classes.
Why is it bad? Comments are frequently used to store structured information (eg, jsdoc, xmldoc), so why is it bad for the type checker to use comments too? The way I see it, it’s already used by the typechecker in a much more limited sense—so it’s positioned well to provide even more annotations to the typechecker in the future.
Luau currently reads and lists all “hot” ( |
I'm a bit of a rust nut so I would prefer Rust's way of doing annotations but this definitely wont work with Lua syntax, the best approach honestly is to just extend upon the already existing --!inline
local function isOdd(n)
return bit32.band(n, 1) == 1
end If thats done, typecheck mode could probably be changed to be per-function instead of over the entire script --!nocheck
local function obviouslyBadType(x: string): number
return x * 2
end
-- implicitly inferred as nonstrict
... I guess the issue with that is how you diferentiate setting |
This RFC specifically does not indicate what it will be used for. It specifically states "[t]his RFC does not propose any annotations, just that the syntax be reserved for future use cases." Whether they end up being annotations or decorators is ultimately irrelevant to this RFC, which is why it's being done; we don't have to agree on the details, just that it should take this syntax. Let's not get caught up bike-shedding quite yet.
As I said before, I would prefer language features not be controlled by comments! It's fine at the moment because the type checker and optimization level don't impact the runtime of any code. Poorly typed code will still compile to the same code and the behavior should be the same between If a comment began altering runtime behavior, it would mean any parser or compiler that disregards comments would be wrong. At the moment, disregarding comments for stuff like a linter has no consequences. It may end up being a problem if they became significant, so I can't support it. |
I think it would be nice to have two different types of annotations. Although this may make it more confusing, it does enable it to be more powerful. One would simple add information and nothing else onto an object of either type table or function. (e.g. The other would instead pass the object as the first argument to a function and then keep the return value. (like In essence: type @somedecorator(text: string, number: number) -- example syntax
@somedecorator("abc",123)
function foo()
-- blah blah blah...
end
print(getannotation(foo, "somedecorator")) -- "abc", 123
print(getannotations(foo)) -- {"somedecorator"}
-----
function wrapperdecorator(f, initial: any)
return function(...)
f(initial, ...)
end
end
@wrapperdecorator(123)
function myCustomFunction(...)
print(...)
end
print(myCustomFunction("hello")) -- Output: 123, hello |
|
I also explicitly am avoiding having this RFC make any comment about how user-implemented annotations might work, or even if they are a necessity at all. Putting your idea into the RFC complicates it significantly more, as we now must talk about how to handle ambiguities, stack tracing, etc. I want to keep this very straightforward. |
Maybe |
I agree with Dekkonot that comments should not alter runtime behavior, which annotations very well should have the ability to do. |
What are examples of ehat they potentislly would modify runtime behavior. Like how mich is the runtime behavior affected by them? |
This RFC intentionally does not request any specific annotations, but annotations changing runtime behavior is something that very much should be possible. Off the cuff ideas purely for the sake of example are things like force inlining or memory tracking. |
I think you should add something to the RFC telling that annotations shouldn't be used in a way that they totally change the semantics of a function. That is, they should only be used for things that do not radically change or alter the semantics of the function. Force inlining and memory tracking are fine, because they don't really change the semantics of the function. (Although inlining is already done by the compiler so the usefulness of force inlining is not quite clear) |
I don't want to put any limitations on what annotations theoretically can do, especially since user defined annotations are a reasonable future development. |
Worth noting that there could theoretically be use cases where you want to attach an attribute to all returns of a function, or attach an attribute on the module itself, etc, e.g. C# This makes me think that we should reserve syntax that uses an opening and closing delimiter for the sake of future proofing, otherwise we run into the usual ambiguities at the tail end of the syntax. It's also why extending Luau with new syntax without causing breaking changes is a nontrivial problem, the lack of |
@alexmccord What do you think about something like |
How about Edit: oh wait, local x = t
[...]
function f() ... end |
I'm more in favor of That said, I can see some people being unhappy with using |
I feel like this discussion has just been bikeshedding about the specific syntax to be used rather than the actual semantics and use cases. We don’t need to make an RFC “reserving” this syntax since it isn’t valid Luau syntax anyways. I’d prefer if instead we discussed how these annotations would be defined, how these would be used, and what the API surface would look like for user-defined ones, if we choose to support that. |
The entire point of this RFC is to settle the question of syntax. It isn't "bikeshedding" for a committee to gather and discuss the color of a bike shed when that is what the meeting was for. The entire point of this discussion is to have a back and forth over syntax; it is not to have a back and forth over how they should work, how they'll be implemented, if/how they should be defined by users, what specific annotations would be implemented, whether these should be "decorators" or "annotations", or anything else you can think of that is not about syntax. If you wish to argue semantics, you should do so in a different RFC that is intended to settle that question. But please do not attempt to derail this RFC into something it is explicitly not about. |
The syntax truly does not matter. Both @ and # are easily accessed on most keyboard layouts around the world. People won’t look at this and go “I won’t use it because it’s an @ and not a #!”
I have! Check out #824. But you’re still over here arguing about how you’d type it out. …And because we have no solid foundation on how these objects should be treated (such as whether or not they can be typed or indexable, and where they can appear) we don’t actually know whether or not the syntax we’ve settled on is legal, intuitive, or ambiguous (eg, So now we’ve spent four months looking at the same proposal that still has gotten no serious traction or progress because we’re stuck up arguing on what color the bike is and not whether or not it will actually have wheels. |
I would except it's tagged as a draft still. That usually indicates something isn't ready for review. 🙂 |
Alright, I've gone ahead and readied it for review since I'm fairly confident in it for the time being. Didn't realize that would be a blocker, thanks! |
@Mooshua Any form of annotations needs to have the right syntax, so the conversation is going to happen at some point anyway. Better to get it done in a dedicated thread for it. Otherwise, an RFC for affixing behavior to annotations is going to be half-syntax and half-behavior discussions, which is a lot harder to follow and more likely to produce suboptimal results for one and/or the other. |
This PR is closed as part of RFC migration; please see #1074 (comment) for context. Additional context: I think it's inevitable that we will end up with this syntax, or a similar syntax. I would recommend using Off the top of my head, a few things I could see using attributes for in the future:
|
Rendered
Proposes reserving
@name
and co for statements and expressions, to pave the way for features like: