Skip to content

Create Static Enough Metaprogramming proposal #4374

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

mraleph
Copy link
Member

@mraleph mraleph commented May 14, 2025

This moves content from #4271 into a markdown file in the repository to make discussion and revisions easier.

I have incorporated some of the feedback from discussions on the issue - but I continue to maintain focus on this as a toolchain feature. I have added some remarks that analyzer can't constant fold everything anyway because it does not have access to the compilation environment.

I would like to collect a few rounds of feedback and then rejuvenate the prototype implementation to get something experimental working across all platforms in the SDK so that we can have an idea of how well this could work in a real world.

Copy link
Member

@eernstg eernstg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. (Very interesting indeed!)

I could suggest the addition of 'a' or 'the' in many locations, but decided that this wouldn't be the top priority at this time.

Dart source code generation or which are supported by macro systems in other
programming languages. For example the following capabilities are out of scope:

- injecting new declarations into the program;
Copy link
Contributor

@jakemac53 jakemac53 May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This definitely does drastically simplify the proposal - but it also makes it a lot less useful. Ultimately trying to accomplish this was the downfall of the original macros proposal though.

But, I think it is important to look at the original motivations for macros, and which of those use cases are covered by this.

Ultimately, I think you can end up with some fairly decent solutions for automatic encoding/decoding, equality, toString, etc. But not copyWith or constructors due to the signatures being dependent on the shape of the class (you could generate the bodies of these but that's only half the boilerplate).

Edit: I see you have an interesting copyWith idea using records, that is fairly reasonable actually.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a section trying to cover some of the use cases mentioned peaked from an old spreadsheet I managed to find.

I could not exactly figure out what some of those entail, could you help me a bit (look for TODO: unclear what this means. and if you have context please add it in the comment). I am interested about auto listenable and render accessors. I think union types (ala freezed) means more concise way of declaring sealed class hierarchies - which I think should just be its own feature (paired with primary constructors).

I think a number of use cases require property wrappers and/or ability to redirect methods - this should probably be its own feature. If property wrappers are available then @konst can be used to handle the boilerplate.

Finally some cases (e.g. proxies, functional widgets and reduced widget classes boilerplate) require ability to create class declarations. I think it is actually an okay feature to give via @konst reflection. As long as classes are anonymous and are otherwise not visible.

- Average code size overhead per class: 270 bytes
- Average JIT kernel generation overhead per-class: 0.2ms (cost of producing
specialized functions using Kernel-to-Kernel AST transformation)
- Average AOT compilation overhead per-class: 2.6ms
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the baseline?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have numbers right now but I can try to revive the prototype and update this later.

code:

```dart
mixin DataClass<@konst T> {
Copy link
Contributor

@jakemac53 jakemac53 May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be 🔥 (and help a lot with the reduction of boilerplate)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it would be useful in many places. Also it would solve a performance problem we occasionally encounter where inheritance or generics cause polymorphism and severely reduce performance.

@mraleph
Copy link
Member Author

mraleph commented May 16, 2025

I have made some updates based on comments. PTAL.

Copy link
Member

@munificent munificent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still have the same reservations as before, but landing this in the repo so we can discuss more sounds great. It's a very solid well-thought out proposal and the background information it provides is really helpful for any metaprogramming-related features we might do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants