[rust-dev] Deriving keyword

Huon Wilson dbau.pp at gmail.com
Fri Jan 24 01:54:28 PST 2014

On 24/01/14 19:28, Lee Braiden wrote:
> On 24/01/14 04:37, Steven Fackler wrote:
>> The deriving infrastructure is implemented as a procedural macro (or 
>> syntax extension) that's built into the compiler. Historically, _all_ 
>> syntax extensions had to be built in but that is no longer the case: 
>> https://github.com/mozilla/rust/pull/11151. It's now possible to 
>> write something like #[deriving_Drawable] that will implement 
>> Drawable for types but you can't currently add new traits to 
>> #[deriving(..)] to make something like #[deriving(Clone, Drawable)] 
>> work. It would be possible to support that, but it would make 
>> #[deriving(..)] "special" in ways that other syntax extensions aren't 
>> and it's unclear whether or not that's a good idea.
> What exactly is the point of this #[...] syntax, anyway?  I'm sure 
> there's a reason, but I *currently* don't see how #[deriving(...)] is 
> better than simply "deriving", like Haskell has.  Is maintaining a low 
> keyword count really THAT important, that we have to have ugly #[] 
> wrappers around things?  I had thought that #[] represented 
> meta-information, like how to compile/link the file, but if deriving 
> is in there, it's very much involving the language proper, too.
> Also, if it's built into the compiler, that makes it special anyway, 
> in my book.  However, the derivation feature provides such great 
> functionality, that I'd be very OK with it being a keyword. At least, 
> if it could be extended for other types -- i.e., was made to support 
> deriving_Drawable and so forth.
> Finally (and this is more curiosity than suggestion, because it could 
> make the language too dynamic/magic), I wonder what's involved in 
> dropping the "...deriving..." syntax altogether, and automatically 
> deriving functionality for types that implement all the necessary 
> underlying features?  It seems like that's what's done for types that 
> fit POD, for example.

The #[] is just the form of attribute attached to an item[1], and these 
attributes are general annotations that can be used by any part of the 
compilation process (and even by external tools), e.g. #[no_mangle] to 
stop a function's symbol being mangled by the compiler, or 
#[allow(unused_variable)] to stop the 'unused_variable' compiler 
warning, and, syntax extensions (aka procedural macros), which is what 
#[deriving] is: it's just an AST based transformation (which 
unfortunately results in some weird error messages), and users can use 
the functionality added by #11151 to implement their own (e.g. one, if 
they were so inclined, could write a #[getters] syntax extension that 
would automatically create getter method for the fields of a struct).

Also, with some effort, you can *now* write custom derivings using the 
same core code as the real #[deriving] does; the only difference is you 
don't get to call it like #[deriving(Drawable)].

There are a few "kinds"[2] that automatically inherit their properties 
(Pod is among them), but, as Daniel says, it would be incorrect to do it 
for all traits automatically.

[1]: The exact syntax of these may/will be changing, see 

[2]: http://static.rust-lang.org/doc/master/std/kinds/index.html


More information about the Rust-dev mailing list