www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Proposal: Replace __traits and is(typeof(XXX)) with a 'magic namespace'.

reply Don <nospam nospam.com> writes:
[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");
Nov 02 2009
next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Don wrote:
 [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.

I'm all for it. I vote for 'meta'. :) -Lars
Nov 02 2009
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Mon, 02 Nov 2009 11:47:53 -0500, Don <nospam nospam.com> wrote:

 [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");

vote++
Nov 02 2009
prev sibling next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
Don wrote:

 <Good Stuff>

Votes++ Meta, I feel, is a very fitting name as well. -- Simen
Nov 02 2009
parent Justin Johansson <no spam.com> writes:
Simen Kjaeraas Wrote:

 Don wrote:
 
 <Good Stuff>

Votes++ Meta, I feel, is a very fitting name as well. -- Simen

++Votes Justin
Nov 02 2009
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Don wrote:
 [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>).

Another keyword, sigh... And I'll be darned if "static" isn't the perfect fit :o).
 This would give us:
 
 meta.compiles(XXX)
 meta.isArithmetic; // note, property syntax OK if no arguments
 meta.isArithmetic(int*);

isArithmetic is library-implementable. How would the library inject stuff in the meta namespace? Also my alarm goes off when seeing meta.isArithmetic(int*) instead of meta.isArithmetic!(int*), which is what the unwashed masses would have to do if they wanted to implement a similar facility. With time I've acquired a dim view of certain stuff in the language benefiting of untouchable advantages. Andrei
Nov 02 2009
next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Andrei Alexandrescu wrote:

 Don wrote:
 [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>).

Another keyword, sigh...

Which can get rid of at least three keywords ...
 And I'll be darned if "static" isn't the perfect fit :o).
 
 This would give us:
 
 meta.compiles(XXX)
 meta.isArithmetic; // note, property syntax OK if no arguments
 meta.isArithmetic(int*);

isArithmetic is library-implementable. How would the library inject stuff in the meta namespace? Also my alarm goes off when seeing meta.isArithmetic(int*) instead of meta.isArithmetic!(int*), which is what the unwashed masses would have to do if they wanted to implement a similar facility. With time I've acquired a dim view of certain stuff in the language benefiting of untouchable advantages. Andrei

It's not about isArithmetic, it's about __traits(foo) and is(foo).
Nov 02 2009
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 02 Nov 2009 13:17:18 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Don wrote:
 [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>).

Another keyword, sigh...

Wouldn't meta *replace* a keyword? i.e. no more __traits. Maybe I misunderstand the proposal, but that's what I thought. -Steve
Nov 02 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Mon, 02 Nov 2009 13:17:18 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Don wrote:
 [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>).

Another keyword, sigh...

Wouldn't meta *replace* a keyword? i.e. no more __traits. Maybe I misunderstand the proposal, but that's what I thought. -Steve

It would, but all symbols starting with __ are already reserved. Andrei
Nov 02 2009
prev sibling next sibling parent Moritz Warning <moritzwarning web.de> writes:
On Mon, 02 Nov 2009 13:17:36 -0500, Steven Schveighoffer wrote:

 On Mon, 02 Nov 2009 13:17:18 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Don wrote:
 [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>).

Another keyword, sigh...

Wouldn't meta *replace* a keyword? i.e. no more __traits. Maybe I misunderstand the proposal, but that's what I thought. -Steve

__traits is no keyword from a practical viewpoint. It is very unlikely to conflict with other names.
Nov 02 2009
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 Don wrote:
 [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>).

Another keyword, sigh... And I'll be darned if "static" isn't the perfect fit :o).

I suggested 'scope', as well, if you need to minimize keywords. You can get rid of typeid, though, which is a real keyword, by moving it to the same namespace.
 This would give us:

 meta.compiles(XXX)
 meta.isArithmetic; // note, property syntax OK if no arguments
 meta.isArithmetic(int*);

isArithmetic is library-implementable. How would the library inject stuff in the meta namespace?

It could be done from inside traits.c in the compiler. If the function isn't on the list of instrinsics, it can be converted into a function call in the same name. Also my alarm goes off when seeing
 meta.isArithmetic(int*) instead of meta.isArithmetic!(int*), which is 
 what the unwashed masses would have to do if they wanted to implement a 
 similar facility. With time I've acquired a dim view of certain stuff in 
 the language benefiting of untouchable advantages.

Agree, and that's what I see a severe problem with __traits -- nothing in the language looks ANYTHING like it. This is just what you get if you apply the patch as-is, giving you exactly what you get from __traits. There has to be a few special cases -- there's no way of doing .compiles() with existing language features (maybe in the future with macros?) But, by introducing a magic namespace, it's possible to introduce some forward compatibility. There are two fundamental points I'm making with this proposal: (1) we ought to have higher expectations for this part of the language; and (2) considerable improvement can be made with very little effort. The proposal itself is almost immaterial. It's the result of hacking the compiler for twenty minutes. If we can do even better, that'd be fantastic.
Nov 02 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Don wrote:
 Andrei Alexandrescu wrote:
 Don wrote:
 [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>).

Another keyword, sigh... And I'll be darned if "static" isn't the perfect fit :o).

I suggested 'scope', as well, if you need to minimize keywords. You can get rid of typeid, though, which is a real keyword, by moving it to the same namespace.

Well ok. Anyhow, something we need to integrate: one problem with typeid is that it should return the dynamic type for class objects. For example, typeid(this) in an abstract class or an interface should return the TypeInfo for the derived class. I was majorly surprised that that's not the case at all. Walter acknowledged that he's given a few tries at providing decent run-time reflection hooks (typeid, classinfo) but none really work. He agreed that the entire mechanism is due for a thorough review.
 This would give us:

 meta.compiles(XXX)
 meta.isArithmetic; // note, property syntax OK if no arguments
 meta.isArithmetic(int*);

isArithmetic is library-implementable. How would the library inject stuff in the meta namespace?

It could be done from inside traits.c in the compiler. If the function isn't on the list of instrinsics, it can be converted into a function call in the same name. Also my alarm goes off when seeing
 meta.isArithmetic(int*) instead of meta.isArithmetic!(int*), which is 
 what the unwashed masses would have to do if they wanted to implement 
 a similar facility. With time I've acquired a dim view of certain 
 stuff in the language benefiting of untouchable advantages.

Agree, and that's what I see a severe problem with __traits -- nothing in the language looks ANYTHING like it. This is just what you get if you apply the patch as-is, giving you exactly what you get from __traits. There has to be a few special cases -- there's no way of doing .compiles() with existing language features (maybe in the future with macros?) But, by introducing a magic namespace, it's possible to introduce some forward compatibility. There are two fundamental points I'm making with this proposal: (1) we ought to have higher expectations for this part of the language; and (2) considerable improvement can be made with very little effort. The proposal itself is almost immaterial. It's the result of hacking the compiler for twenty minutes. If we can do even better, that'd be fantastic.

I'm (almost) all for it. If it didn't add a keyword, I'd have been 110% for it. Anyhow, the only important part is what Walter thinks. Andrei
Nov 02 2009
next sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Don wrote:
 Andrei Alexandrescu wrote:
 Don wrote:
 [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>).

Another keyword, sigh... And I'll be darned if "static" isn't the perfect fit :o).

I suggested 'scope', as well, if you need to minimize keywords. You can get rid of typeid, though, which is a real keyword, by moving it to the same namespace.

is that it should return the dynamic type for class objects. For example, typeid(this) in an abstract class or an interface should return the TypeInfo for the derived class. I was majorly surprised that that's not the case at all.

Isn't that what this.classinfo is for?
 Walter acknowledged that he's given a few tries at
 providing decent run-time reflection hooks (typeid, classinfo) but none
 really work. He agreed that the entire mechanism is due for a thorough
 review.

I think the solution is for classinfo and typeinfo to be templates. I mentioned that here a few days ago, but it was admittedly poorly written, with tons of references to GC hacks. I'll write a clearer proposal tonight. The idea is that, if typeinfo and classinfo were templated on the type that they were providing information about, it would be very easy for anyone to add more information to them--anything that is available at compile time would be available in RTTI with trivial modifications to object.d.
Nov 02 2009
prev sibling next sibling parent Ary Borenszweig <ary esperanto.org.ar> writes:
Andrei Alexandrescu wrote:
 I'm (almost) all for it. If it didn't add a keyword, I'd have been 110% 
 for it. Anyhow, the only important part is what Walter thinks.

Are you word blind? It *replaces* the __traits keyword and also allows to remove some others like typeid.
Nov 03 2009
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
rmcguire wrote:
 It makes a lot of sense to just say to someone "if you want to do something at
 
 compile time, just check the 'static' documentation".

I agree. And goes with static if too. Andrei
Nov 03 2009
parent Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 rmcguire wrote:
 It makes a lot of sense to just say to someone "if you want to do 
 something at  compile time, just check the 'static' documentation".

I agree. And goes with static if too. Andrei

Unfortunately static if, static variables, and static member functions don't seem to have much in common with each other. You have to be quite imaginative to find a common theme.
Nov 03 2009
prev sibling next sibling parent Justin Johansson <no spam.com> writes:
 I really like 'static' as the namespace, it would be awesome if it did not
just 
 contain 'meta' stuff.
 
 Could we lose 'pragma', 'typeof', unary 'is', 'typeid', '__traits'.
 
 It makes a lot of sense to just say to someone "if you want to do something at
 
 compile time, just check the 'static' documentation".

"just check the static documentation" Either very punny or Nirvana; imagine the language not being a moving target and Andrei not having to update TDPL every few weeks. Then again, I don't like giving the language critics a possible play on words: "just check the stagnant documentation" Justin :-)
Nov 03 2009
prev sibling parent Justin Johansson <no spam.com> writes:
Robert Jacques Wrote:

 On Tue, 03 Nov 2009 13:10:26 -0500, Bill Baxter <wbaxter gmail.com> wrote:
 
 On Tue, Nov 3, 2009 at 7:47 AM, Leandro Lucarella <llucax gmail.com>  
 wrote:
 rmcguire, el  3 de noviembre a las 15:11 me escribiste:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 I really like 'static' as the namespace, it would be awesome if it did  
 not just
 contain 'meta' stuff.

 Could we lose 'pragma', 'typeof', unary 'is', 'typeid', '__traits'.

 It makes a lot of sense to just say to someone "if you want to do  
 something at
 compile time, just check the 'static' documentation".

static.if(...) { static.foreach(...) { static.assert(...) { } } } =P

At first I thought this was another joke about how overused "static" is. But actually it does kinda make sense here. --bb

I agree. Though, other keywords could work in this manner just as well (pragma comes to mind), which would reduce static to just member variables and functions.

Good point; reducing 'static' to just member variables and functions would be a positive move. imho, the word is just way too overloaded in current usage. As for the candidate words, my preference is still 'meta'. Justin Johansson
Nov 03 2009
prev sibling next sibling parent rmcguire <rjmcguire gmail.com> writes:
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 
 Don wrote:
 Andrei Alexandrescu wrote:
 Don wrote:
 [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>).

Another keyword, sigh... And I'll be darned if "static" isn't the perfect fit :o).

I suggested 'scope', as well, if you need to minimize keywords. You can get rid of typeid, though, which is a real keyword, by moving it to the same namespace.

Well ok. Anyhow, something we need to integrate: one problem with typeid is that it should return the dynamic type for class objects. For example, typeid(this) in an abstract class or an interface should return the TypeInfo for the derived class. I was majorly surprised that that's not the case at all. Walter acknowledged that he's given a few tries at providing decent run-time reflection hooks (typeid, classinfo) but none really work. He agreed that the entire mechanism is due for a thorough review.
 This would give us:

 meta.compiles(XXX)
 meta.isArithmetic; // note, property syntax OK if no arguments
 meta.isArithmetic(int*);

isArithmetic is library-implementable. How would the library inject stuff in the meta namespace?

It could be done from inside traits.c in the compiler. If the function isn't on the list of instrinsics, it can be converted into a function call in the same name. Also my alarm goes off when seeing
 meta.isArithmetic(int*) instead of meta.isArithmetic!(int*), which is 
 what the unwashed masses would have to do if they wanted to implement 
 a similar facility. With time I've acquired a dim view of certain 
 stuff in the language benefiting of untouchable advantages.

Agree, and that's what I see a severe problem with __traits -- nothing in the language looks ANYTHING like it. This is just what you get if you apply the patch as-is, giving you exactly what you get from __traits. There has to be a few special cases -- there's no way of doing .compiles() with existing language features (maybe in the future with macros?) But, by introducing a magic namespace, it's possible to introduce some forward compatibility. There are two fundamental points I'm making with this proposal: (1) we ought to have higher expectations for this part of the language; and (2) considerable improvement can be made with very little effort. The proposal itself is almost immaterial. It's the result of hacking the compiler for twenty minutes. If we can do even better, that'd be fantastic.

I'm (almost) all for it. If it didn't add a keyword, I'd have been 110% for it. Anyhow, the only important part is what Walter thinks. Andrei

I really like 'static' as the namespace, it would be awesome if it did not just contain 'meta' stuff. Could we lose 'pragma', 'typeof', unary 'is', 'typeid', '__traits'. It makes a lot of sense to just say to someone "if you want to do something at compile time, just check the 'static' documentation". -Rory
Nov 03 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Tue, Nov 3, 2009 at 7:47 AM, Leandro Lucarella <llucax gmail.com> wrote:
 rmcguire, el =A03 de noviembre a las 15:11 me escribiste:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 I really like 'static' as the namespace, it would be awesome if it did n=


 contain 'meta' stuff.

 Could we lose 'pragma', 'typeof', unary 'is', 'typeid', '__traits'.

 It makes a lot of sense to just say to someone "if you want to do someth=


 compile time, just check the 'static' documentation".

static.if(...) { =A0 =A0 =A0 =A0static.foreach(...) { =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0static.assert(...) { =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0} } =3DP

At first I thought this was another joke about how overused "static" is. But actually it does kinda make sense here. --bb
Nov 03 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Tue, Nov 3, 2009 at 8:52 AM, Don <nospam nospam.com> wrote:
 Andrei Alexandrescu wrote:
 rmcguire wrote:
 It makes a lot of sense to just say to someone "if you want to do
 something at =A0compile time, just check the 'static' documentation".

I agree. And goes with static if too. Andrei

Unfortunately static if, static variables, and static member functions do=

 seem to have much in common with each other. You have to be quite
 imaginative to find a common theme.

I think static variables and static member functions (the classic C/C++ statics) would stay as-is. I could go either way, though. I don't particularly care about adding a keyword if it's going to carry it's weight. And I think this one will. meta.if meta.foreach meta.assert all seem ok to me. I also think having a keyword dedicated to compile-time operations sends a clear message that the language is serious about making compile-time a first-class citizen. --bb
Nov 03 2009
prev sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Tue, 03 Nov 2009 13:10:26 -0500, Bill Baxter <wbaxter gmail.com> wrote:

 On Tue, Nov 3, 2009 at 7:47 AM, Leandro Lucarella <llucax gmail.com>  
 wrote:
 rmcguire, el  3 de noviembre a las 15:11 me escribiste:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 I really like 'static' as the namespace, it would be awesome if it did  
 not just
 contain 'meta' stuff.

 Could we lose 'pragma', 'typeof', unary 'is', 'typeid', '__traits'.

 It makes a lot of sense to just say to someone "if you want to do  
 something at
 compile time, just check the 'static' documentation".

static.if(...) { static.foreach(...) { static.assert(...) { } } } =P

At first I thought this was another joke about how overused "static" is. But actually it does kinda make sense here. --bb

I agree. Though, other keywords could work in this manner just as well (pragma comes to mind), which would reduce static to just member variables and functions.
Nov 03 2009
prev sibling next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
This would help so much, I do hope it will make it in D2. 
Nov 02 2009
prev sibling next sibling parent Max Samukha <spambox d-coding.com> writes:
On Mon, 02 Nov 2009 17:47:53 +0100, Don <nospam nospam.com> wrote:

[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*);

I like the proposed syntax and I like the "meta" keyword. Though I'm using "meta" name for a templated function returning runtime meta-objects, I can change it to something else. However, I think semantic limitations of __traits are more important (introspecting function overloads, telling apart static and instance functions, etc.) Also, IMO, "meta" should provide only minimal functionalily, on which complete introspection can be build in a library. Currently, we have the opposite situation. isArithmetic, isIntegral, isStaticArray and the likes definitely belong to the library.
Nov 02 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Mon, Nov 2, 2009 at 8:47 AM, Don <nospam nospam.com> wrote:
 [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.

I don't understand what you are proposing to replace "is()" with. I also don't understand what it means to call meta.isArithmetic with no argument. But I agree that meta.blah() looks more like part of an intentional design than __traits(blah, ...). Even meta(blah, ...) would be a significant improvement. I already see people trying to heap on other refactorings and redesigns on top of this proposal. While certainly more could be done, I think it's worth while to go ahead with just making the syntax not look hideous. If you try to roll this in with a more global reform, it's just going to get bogged down like 95% of the other conversations that start up here and go anywhere. Let's take it one step at a time. Do the renaming first, then we can work on the next step after the first step is taken. --bb
Nov 02 2009
prev sibling next sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Don (nospam nospam.com)'s article
 [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
 <snip>

I like the basic idea, though I think there are some details to be hammered out. Why don't you post it to the DIP page on the wiki so that it's in a form that's a little longer-lived than this newsgroup and conversations about it don't eat into more general discussion here? Also, I'll soon be posting a DIP for enhancing runtime introspection, which is similarly a bit of a rat's nest right now. Perhaps considering them in parallel would be a good idea.
Nov 02 2009
prev sibling next sibling parent Moritz Warning <moritzwarning web.de> writes:
On Mon, 02 Nov 2009 17:47:53 +0100, Don wrote:

 [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.
 

I like your proposal. __traits is a rats-hole. An artificial name-space is a nice place for compiler build-in methods (maybe smth. other than meta then?). But I hope it will be able to implement it in the library in the future. Anyway, it's visual appealing and does look less like a hack.
Nov 02 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 02 Nov 2009 11:47:53 -0500, Don <nospam nospam.com> wrote:

 [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.

According to Andrei's reply, __traits is not a keyword (or at least does not have the downside of using a likely variable name) since __ symbols are reserved, so your assertion that less keywords isn't technically correct. But IMO, something this important deserves a keyword, and I *hate* the less keywords is unequivocally better POV. Also, I was under the impression that __traits was a placeholder until both 1) __traits proved to be a useful feature (and it has) and 2) a good name could be found, is this not the case? I'm not sure you need to get ride of typeid. The benefits to deprecating a keyword don't seem very apparent to me, you still most likely need to keep the keyword for backwards compatibility. I agree with you on is() expressions, but you need to replace them all, not just the is(typeof(XXX)) form. And I agree with you on the whole. I'd say the best thing to do is implement the feature (it seems you have a good grasp on what needs to be done) and take a particularly nasty __traits-using module, and show how it looks with the new style :) Hell, even doing the second part may be enough to convince Andrei/Walter. vote++ -Steve
Nov 02 2009
prev sibling next sibling parent Leandro Lucarella <llucax gmail.com> writes:
Don, el  2 de noviembre a las 20:19 me escribiste:
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>).

Another keyword, sigh... And I'll be darned if "static" isn't the perfect fit :o).

I suggested 'scope', as well, if you need to minimize keywords. You can get rid of typeid, though, which is a real keyword, by moving it to the same namespace.

I think typeof can be moved there too, maybe pragma too (or completely replace pragma with meta: meta.msg("hello"), meta.lib("mylib"), meta.startaddress(foo)). There might be even more.
This would give us:

meta.compiles(XXX)
meta.isArithmetic; // note, property syntax OK if no arguments
meta.isArithmetic(int*);

isArithmetic is library-implementable. How would the library inject stuff in the meta namespace?

It could be done from inside traits.c in the compiler. If the function isn't on the list of instrinsics, it can be converted into a function call in the same name. Also my alarm goes off when seeing
meta.isArithmetic(int*) instead of meta.isArithmetic!(int*), which
is what the unwashed masses would have to do if they wanted to
implement a similar facility. With time I've acquired a dim view
of certain stuff in the language benefiting of untouchable
advantages.

Agree, and that's what I see a severe problem with __traits -- nothing in the language looks ANYTHING like it.

I don't know if you're talking about the __ or the syntax, but pragma follows the same syntax pattern, and do compile-time stuff, so I guess it's a good candidate for meta too. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Un paracaidista, que no deja de caer. Lo que me lleva hacia arriba, es lo que me tira hacia abajo.
Nov 02 2009
prev sibling next sibling parent Leandro Lucarella <llucax gmail.com> writes:
rmcguire, el  3 de noviembre a las 15:11 me escribiste:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 I really like 'static' as the namespace, it would be awesome if it did not
just 
 contain 'meta' stuff.
 
 Could we lose 'pragma', 'typeof', unary 'is', 'typeid', '__traits'.
 
 It makes a lot of sense to just say to someone "if you want to do something at
 
 compile time, just check the 'static' documentation".

static.if(...) { static.foreach(...) { static.assert(...) { } } } =P -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- PITUFO ENRIQUE ATEMORIZA CATAMARCA, AMPLIAREMOS -- Crónica TV
Nov 03 2009
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 02 Nov 2009 17:47:53 +0100, Don wrote:


 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>).

Thank you Don for this "voice of reason". A specific keyword for the concept of compile-time activity/functionality is totally justified. "meta" is very suitable. Short and to the point. "compiler" I could live with. "traits" is unsuitable, as it is too limiting a concept. "scope" is unsuitable, as it is already too highly overloaded with semantics. "static" is extremely unsuitable. This word should, at best, be only used for things that do not change value or location during run-time. ... and slightly off topic ... now if only we could get the 'bang' out of template instantiation syntax as well. When I see the '!' in something like "Foo!(X)()", my mind first says "we are about to negate something" and then has to switch tracks "oh no, this actually means we are using a template this time". I'm *so* over the amount of symbol and keyword overloading that goes on in D and C-like languages. It's as if they were devised by academics during the days when data transmission times were slow and only they looked at source code. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Nov 03 2009
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Bill Baxter wrote:
 On Tue, Nov 3, 2009 at 1:27 PM, Derek Parnell <derek psych.ward> wrote:
 On Mon, 02 Nov 2009 17:47:53 +0100, Don wrote:


 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>).

concept of compile-time activity/functionality is totally justified. "meta" is very suitable. Short and to the point.

Shortness is key. In compile-time code this keyword is going to appear a lot. So if it's going to be a new keyword, I vote for this one.
 "compiler" I could live with.

 "traits" is unsuitable, as it is too limiting a concept.

 "scope" is unsuitable, as it is already too highly overloaded with
 semantics.

 "static" is extremely unsuitable. This word should, at best, be only used
 for things that do not change value or location during run-time.

A type doesn't change whether it "isArithmetic" at runtime. A "static if" doesn't change the branch it takes at run-time. So by your explanation static is exactly the right thing to use.
 ... and slightly off topic ...
 now if only we could get the 'bang' out of template instantiation syntax as
 well. When I see the '!' in something like "Foo!(X)()", my mind first says
 "we are about to negate something" and then has to switch tracks "oh no,
 this actually means we are using a template this time".

It does make template code in D look noisy, but I don't think there's much chance it's going away. I think if I were making a new language, I'd seriously consider going with () for both indexing and function calls, and use [] for template arguments. --bb

Aka, Scala. /* D */ T some_func (T : int) (T a, T b) { ... } U[] another (U) (U a, U[] b) { ... } some_func!int(1, 2) /* Scala */ def some_func [T <:Int] (a: T, b: T) = ... def another [U] (a: U, b: Seq[U]): Seq[U] = ... some_func[Int] (1, 2) -- Chris Nicholson-Sauls
Nov 04 2009
prev sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Tue, Nov 3, 2009 at 1:27 PM, Derek Parnell <derek psych.ward> wrote:
 On Mon, 02 Nov 2009 17:47:53 +0100, Don wrote:


 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>).

Thank you Don for this "voice of reason". A specific keyword for the concept of compile-time activity/functionality is totally justified. "meta" is very suitable. Short and to the point.

Shortness is key. In compile-time code this keyword is going to appear a lot. So if it's going to be a new keyword, I vote for this one.
 "compiler" I could live with.

 "traits" is unsuitable, as it is too limiting a concept.

 "scope" is unsuitable, as it is already too highly overloaded with
 semantics.

 "static" is extremely unsuitable. This word should, at best, be only used
 for things that do not change value or location during run-time.

A type doesn't change whether it "isArithmetic" at runtime. A "static if" doesn't change the branch it takes at run-time. So by your explanation static is exactly the right thing to use.
 ... and slightly off topic ...
 now if only we could get the 'bang' out of template instantiation syntax as
 well. When I see the '!' in something like "Foo!(X)()", my mind first says
 "we are about to negate something" and then has to switch tracks "oh no,
 this actually means we are using a template this time".

It does make template code in D look noisy, but I don't think there's much chance it's going away. I think if I were making a new language, I'd seriously consider going with () for both indexing and function calls, and use [] for template arguments. --bb
Nov 03 2009