-
Notifications
You must be signed in to change notification settings - Fork 0
Attributes #24
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
base: main
Are you sure you want to change the base?
Attributes #24
Conversation
Signed-off-by: Nick Cameron <nrc@ncameron.org>
|
||
Proposed changes: | ||
|
||
- Inner vs outer attribute semantics |
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.
Instead of inner and outer, could we call them item attributes and scope attributes, respectively? Seems clearer.
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 like item attr, but I find 'scope' a bit ambiguous. I was hoping to not use either terminology in user-facing docs, just named/unnamed and explain how they apply
item ::= ... | fn_decl | const_decl | import | inner_attr | outer_attr item | ||
stmt ::= ... | const_decl | outer_attr stmt | ||
|
||
inner_attr ::= `@` `(` (annot_item,)* `)` |
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.
The lack of identifier after the @
for inner attributes makes it awkward to use many, unrelated attributes for an item. Instead of them looking like function calls, they would need to be differentiated by keyword arguments. An example I'm thinking about would be in Rust #[derive(Clone, Serialize)]
and #[serde(rename_all = "camelCase")]
on a struct. How would you do the equivalent here?
@(derive = [Clone, Serialize], serde = { rename_all = camelCase })
I know KCL is very different from Rust, so the specifics don't apply. But in most languages that have item attributes, it's common to want to apply multiple, unrelated attributes to the same declaration.
I think I'd prefer a different token or tokens the way Rust does it with #
vs. #!
.
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 was thinking like:
@(derive = [Clone, Serialize])
@(serde = { rename_all = camelCase })
So, the logic here is that the name after the @
for inner attrs is showing the target of the attribute, whereas with outer attrs the target is always the following item
|
||
## Issues | ||
|
||
- "Attributes" or "annotations"? I prefer the former, we've been using a mix, but mostly the latter. Other languages use either or both, no consensus. |
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 think I'd choose attributes too. It's pretty arbitrary, as long as we stick with one. The only theme I've seen maybe hinted at is that annotations have no runtime effect by default. But it's all just metadata.
- Syntax overlap with `@` for 'self' | ||
- Remove `@` on self-arg once we've finished the kwarg migration |
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.
Can we remove the @
? I thought someone said that we needed a way to distinguish between a regular function and one that has a "self" parameter.
An alternative is how Python does it with a separator between positional and named parameters. I don't particularly like this, but it's optimized so that in the common case, the separator is rarely needed at all. For KCL, it would potentially allow us to free up the token.
If we need to keep it, couldn't we use basically any other token?
@outer
@!inner
fn foo(!positional: Plane, named: string): Sketch {}
// Attribute on the positional parameter.
fn foo(@!inner !positional: Plane, named: string): Sketch {}
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 thought someone said that we needed a way to distinguish between a regular function and one that has a "self" parameter." - hmm, yeah
"If we need to keep it, couldn't we use basically any other token?" - yes
Design doc for attributes (
@settings
, etc).