-
Notifications
You must be signed in to change notification settings - Fork 15
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
Change the syntax of traits from 'is foo(val)' to '@Foo(val)', and let them precede the thing they annotate #257
Comments
It just struck me that one issue with this change is that it delays how soon we can know which type of statement (or class member, etc) we're parsing. Basically, it goes against the grain of Perl 6's idea of having a "declarative prefix" in each rule after which you know what rule you're parsing. |
On second thought, it's not quite that hopeless. If we parse traits alongside statements in the |
I can't find it right now, but somewhere I had quite a complicated Anyway, that'd be problematic if we reverse the order of traits and parameters. At least, we'd have to find some other way to achieve the same effect. I'd like to find that |
Another small argument in favor of this syntax change: I find it somewhat easier to read this syntax:
Than this syntax:
|
Coming back to it, I feel this was a valid objection to have, but it's by no means a show-stopper. Labels are much the same, in that they can precede many different types of statement and we don't know which one until we've finished parsing the label. Maybe it'd be worth it to explore the dangers of allowing arbitrary expressions inside the |
Working on this in a branch. Realizing we'll probably need an issue where we also nail down the semantics of decorators. They're interesting beasts. The ones for precedence and associativity will be driving in this, and they are mostly "metadata decorators" in the sense that they want to end up being attached to the declaration somehow, so that the parser can query them when it needs the information. There are more "business rules" connected to them than I remembered, for example (but not exhaustive):
It's an interesting question how much of that needs to be code, and how much can be captured declaratively somehow in the declaration of the decorators themselves. |
Simple question: how should the Qtree look for statements with decorators? (Hint: I don't know.) |
I think the former can be easily captured using a The latter sounds like a "business rule" to me, and should most likely be handled by whatever thing consumes those parser-targeting decorators. (That is, they should be handled by the parser.) By the way, the solution I've struck upon with the 007 parser in Perl 6 is to carry that information from where the decorators are parsed to where the statement they're decorating is parsed, by using a dynamic variable. This, in some sense, feels like a sane solution. I could also imagine it being handled by using some sort of "parser state" — as long as the stack-like aspect of it all is still captured. (A previous comment hints at decorators occurring inside decorators via declarations. The dynamic variable handles this well, by storing its data essentially "in the call stack". A "parser state" solution would need to handle it as well.) In passing, I note that I'm suddenly writing decorators with lowerCamelCase, like in Python, not with UpperCamelCase, like in Java. I have no idea why. |
Decorators can be
|
What's the Simplest Possible Thing That Could Possibly Work? From my vantage point, it's a special statement that contains a decorator and an inner statement. That is, a composite. |
...or maybe that's to general. Maybe a decorator captures what we want here? (That can't be a coincidence, can it?) |
Let's hold off on that one. First, because we don't have enums yet in the language. Second, because it's kind of an exception, and I don't fully understand yet. With just functions/macros in the mix, the rule is simple: a decorator desugars to a call. That is,
desugars to
or something very much like it. In general, a decorator is always a function or a macro with an extra first parameter, which is the wrapped function-or-macro. (Or, if the decorator itself is a macro, its Qnode.) As to "marker decorators", I think on second thought that all decorators are potential marker decorators. But specifically, if one leaves their implementation empty (or identity function), that's probably because they are meant to be used as markers. |
Following Python and Java's lead. Even TypeScript and ES.next, and (modulo a slight difference in syntax) C#.
Not sure I can fully motivate why I want to make this change, but (a) it feels a little bit more robust in some way, and (b) it's becoming clear that we can have use for traits on a number of things besides subs/macros:
An example of the former:
@Abstract
; instead of making it a keyword. An example of the latter:@Readonly
. Maybe@Lazy
too.The text was updated successfully, but these errors were encountered: