Last update November 14, 2009

Language Devel / DIPs / DIP6 / Archive /

DIP6: Annotations

Last Modified:2009-08-21
Author:Ary Borenszweig <ary


Extend the D programming language with annotations. Annotations are metadata attached to declarations and variables that can later be queried at compile-time or runtime. This metadata can't otherwise be expressed except by using boilerplate code or separate files that explicitly state which declaration have which metadata, but the process is ad-hoc and not standarized.

Annotations already exist in other languages:


C# (named "atrributes"):


Annotations will allow several things: reduce the amount of keywords and extend the language more easily.

By reducing the ammount of keywords programmers can use more declarative names for their variables. It also reduces lexer and parser changes when upgrading the language.

The language can be extended more easily just by adding new annotation names instead of new keywords: new keywords might render old code not compilable, while with new annotations that can never happen.

General-purpose attributes allow many other things: specify how serialization should be done, how a field should be stored in a database, how a method maps to an http request, whether a method should do security checks before executing, whether a method should run as a test and what's the thrown exception is.


The idea is to introduce annotations in the D language. As a first stage, users won't be able to define annotations: some well-known annotations will exist and that's it.

Proposed syntax: @annotation(arguments). This is what Java uses. Other syntax can be [annotation(arguments)]. This is what C# uses. Java's syntax has the advantage of having to type less when the annotation has no arguments: @annotation vs. [annotation].

It can be applied to declarations:

int x;

class Foo { }


Annotations could be used for several things now. For example:

struct Foo { }

int foo();

int foo() { }

int foo() { }

int x;

int x;

int x;

class Foo { }

class Foo { }

class Foo {

  void foo() { }

class Foo {

  void foo() { }

And also for new things:

class Foo {

  int x() { ... }

  int x(int value) { ... }


Compiler implementation

At a first stange, the compiler will parse the annotations and attach them to declarations. In the semantic pass the annotations are inspected and actions are taken. For example if the @override property is found in a function, a check is made to see if it indeed overrides a base function. If @deprecated is found and deprecated features are not allowed, a warning/error is issued.

If the annotation is not recognized by the compiler, an error happens (much like what happens with __traits(somehthing, foo) now: if the first argument is not recognized, it is an error). Also at this first stage, a user cannot define new annotations. A user cannot inspect annotations. The first stage will just help introducing annotations, making the language easier to evolve (no need to introduce new keywords for every new functionality). A future DIP should define how annotations evolve from this point once they have been implemented.


This document has been placed in the Public Domain.

FrontPage | News | TestPage | MessageBoard | Search | Contributors | Folders | Index | Help | Preferences | Edit

Edit text of this page (date of last change: November 14, 2009 21:24 (diff))