[swift-evolution] User Defined Attributes/Annotations

Akiva Leffert aleffert at gmail.com
Wed Dec 9 23:40:08 CST 2015

I’m interested in adding user defined annotations. For example,

	@MyAnnotation func foo() {

This would help enable third party linting and behavioral documentation. This is useful in its own right, but it can also help inform the future direction of static checks within the language.

I’ve started hacking on this (adding a new “Annotation” attribute and associated declaration), but I figured before I went too far I should get some feedback.


I imagine you would declare one of these in the following way:
	annotation MyAnnotation

and use it as above, using a qualified path if necessary: ``@MyModule.MyClass.MyAnnotation``.

You could also imagine just having a single extendable attribute that takes a string, similar to how C compilers do it, ``@Annotate(“whatever”)`` but that seems error prone and really only works in C because you #define it once and count on the preprocessor to avoid typos. It also doesn’t help prepare for more interesting annotation usage later.

As such, this would introduce a new keyword “annotation”. I think these are sufficiently useful - especially if they end up tying into a macro system - that they deserve a keyword. However, an alternate approach is to overload the existing attribute syntax:


	@annotation MyAnnotation
	To me this seems awkward, as it does not match the style of any other declarations, but adding a new keyword is a big deal, so there’s an obvious trade off.

This proposal does not include annotations with arguments nor does it ascribe any dynamic behavior to those annotations. The static content is limited to checking whether the annotation is already defined.

I deliberately skipped arguments for annotations since there are a lot of questions about defining the types of those arguments, but it's an obvious future extension.

Other possible extensions this proposal needs to not prevent:

1. Providing annotations that actually do things like:
	- Evaluate macros
	- Connect to a protocol or class in some way a la java
	- Python style decorators
2. Limiting annotations to certain syntactic classes.
3. New built in attributes.
4. <Insert your feature idea here>

This initial version is sufficiently minimal that I don’t think any of those would be blocked by it*.

It’s not obvious to me what is the right way to scope user annotations vs new compiler ones. A simple namespace might be best, forcing the compiler to use “_” or lowercase or something like that, but that would involve further migration for existing code.

Anyway, I’m happy to write this up into a proper proposal if there’s general interest.

-Akiva Leffert

* Strawman examples of being compatible with possible extensions

// arguments
annotation Foo(A, B, C)

// macros
annotation macro Bar(A, B, C) {
	… do stuff ...

// decorators
annotation func Baz(f : Int -> String) -> (Int -> String) {
	… do stuff ...

// only certain syntactic classes
annotation Foo { usage { func, decl, struct, class } }

More information about the swift-evolution mailing list