Bumping this. For what I do this is something I struggle with quite often. It’s quite annoying when you want to use an annotation for something, but then need to also have another type to represent the data that should be read off the annotation. Making the type that gets applied AND the type that stores/handles the data, the same type would be .
IMO this would be the most common use case, I still think ideally annotations should work more like:
@[Annotation]
struct MyAnn
end
as opposed to:
annotation MyAnn
end
Essentially this would allow that type (either a class or struct) to be applied via the @[...]
syntax. In macro land the type of MyAnn
would be Annotation
like it is now to allow reading the arguments off the annotation. But, a new method could also be added, like build
or something, that would create an instance of the type based on arguments defined as part of the annotation. For example:
@[Annotation]
record MyAnn, name : String, active : Bool = true
@[MyAnn(name: "foo")
def foo
{{ @def.annotation(MyAnn)[:name] }}
end
foo # => "foo"
@[MyAnn(active: false)
def bar
"bar"
end
bar # => Compile error because `name` wasn't supplied and it's not nilable nor has a default value
@[MyAnn(name: "baz")]
def baz
{{ @def.annotation(MyAnn).build }}
end
baz # => MyAnn(@name="baz", @active=false)
IMO this would be a game changer as it would make annotations less unique, and more like standard types, supporting modules/inheritance etc.