[I'm moving this from deep inside a TDPL thread, since I think it's
important]
is(typeof(XXX)) is infamously ugly and unintuitive
__traits(compiles, XXX) is more comprehensible, but just as ugly.
They are giving metaprogramming in D a bad name. I think we need to get
rid of both of them.
A very easy way of doing this is to replace them with a 'magic
namespace' -- so that they _look_ as though they're functions in a
normal module.
Names which have been suggested include 'meta', 'traits', 'scope',
'compiler'. Personally I think 'meta' is the nicest (and I suggested two
of the others <g>). This would give us:
meta.compiles(XXX)
meta.isArithmetic; // note, property syntax OK if no arguments
meta.isArithmetic(int*);
Benefits:
* Fewer keywords: __traits -> meta, typeid() -> meta.typeid()
* Get rid of is() expressions, which are the most complicated thing in
the language.
* Some meta.XXX functions could be defined in runtime library code.
* The existing __traits functions could have more useful return values.
* Retain the flexibility of __traits.
These days, I don't propose anything unless I'm prepared to write a
patch to implement it. <g>
If nothing is, this should convince everyone that there's NO REASON to
put up with the ugly metaprogramming syntax we currently have. We can do
much better. Easily.
======================
PATCH against svn 234 (this is just a quick hack for evaluation, it
doesn't fix error messages, etc. But it works as described above. It
allows all existing code to continue to compile).
This allows '__traits' as the magic namespace. The existing __traits
stuff continues to compile. To allow 'meta' as another synonym for the
same magic namespace, add this line to lexer.c, line 2960.
{ "__traits", TOKtraits },
+ { "meta", TOKtraits },
{ "__overloadset", TOKoverloadset },
(Hmm. Didn't know __overloadset was a keyword. The things you find...)
Index: parse.c
===================================================================
--- parse.c (revision 234)
+++ parse.c (working copy)
@@ -4934,6 +4934,20 @@
Objects *args = NULL;
nextToken();
+ if (token.value == TOKdot) {
+ // __traits.identifier(args, ...)
+ nextToken();
+ if (token.value != TOKidentifier)
+ { error("__traits.identifier(args...) expected");
+ goto Lerr;
+ }
+ ident = token.ident;
+ nextToken();
+ if (token.value==TOKlparen)
+ args = parseTemplateArgumentList2();
+ e = new TraitsExp(loc, ident, args);
+ break;
+ }
check(TOKlparen);
if (token.value != TOKidentifier)
{ error("__traits(identifier, args...) expected");