www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Annoyances with traits

reply "F i L" <witte2008 gmail.com> writes:
I find myself using __traits(hasMember, T, "member") a lot.
It's really basic feature of meta-programming.

I'm not a fan of the "__usedByCompiler" syntax, but that's a
whole different discussion. __traits() is fine (besides the fact
that first-argument-as-function is syntactically inconsistent to
the rest of the language), but std.traits doesn't wrap it
correctly; and, because it's globally available anyways & so
often used, shouldn't have to be imported to use in the first
place, IMO.

What I would like to see happen: Have a traits.d which replaces
std.traits and is always included (like object.d) which properly
wraps __trait functions.

so in traits.d:

      // use alias T, so we can pass "laser.x" to it
      // without having to pass typeof(laser.x). Just like
      // we can with using __traits(hasMember, ...)

      template hasMember(alias T, string member) {
          enum hasMember = __traits(hasMember, T, member);
      }

we can then write:

      auto laser = ship.fire();
      static if(traits.hasMember!(laser.x, "isProp") ...;

which feels syntactically consistent. Because traits are in their
own module, we could emit the "traits." and just call
"hasMember()". Even better, if UFCS allows, we could simply write:

      static if(laser.x.hasMember!("isProp")) ...;


my 2 cents.
Mar 27 2012
next sibling parent Manu <turkeyman gmail.com> writes:
--485b397dce8383773904bc494724
Content-Type: text/plain; charset=UTF-8

On 28 March 2012 07:29, F i L <witte2008 gmail.com> wrote:

 I find myself using __traits(hasMember, T, "member") a lot.
 It's really basic feature of meta-programming.

 I'm not a fan of the "__usedByCompiler" syntax, but that's a
 whole different discussion. __traits() is fine (besides the fact
 that first-argument-as-function is syntactically inconsistent to
 the rest of the language), but std.traits doesn't wrap it
 correctly; and, because it's globally available anyways & so
 often used, shouldn't have to be imported to use in the first
 place, IMO.

 What I would like to see happen: Have a traits.d which replaces
 std.traits and is always included (like object.d) which properly
 wraps __trait functions.

 so in traits.d:

     // use alias T, so we can pass "laser.x" to it
     // without having to pass typeof(laser.x). Just like
     // we can with using __traits(hasMember, ...)

     template hasMember(alias T, string member) {
         enum hasMember = __traits(hasMember, T, member);
     }

 we can then write:

     auto laser = ship.fire();
     static if(traits.hasMember!(laser.x, "isProp") ...;

 which feels syntactically consistent. Because traits are in their
 own module, we could emit the "traits." and just call
 "hasMember()". Even better, if UFCS allows, we could simply write:

     static if(laser.x.hasMember!("isProp"**)) ...;


 my 2 cents.

I was rummaging through exactly the same stuff yesterday, and reached a similar conclusion. My code became borderline impossible to understand very fast with all the references to __traits(getMember, instanceOf, member) and friends. Something like you suggest would go a long way to making it readable again. One thing I noticed recurring, __traits(getMember, T, member) can be aliased, but __traits(getMember, instanceOfT, member) can not really be aliased, since D doesn't have references. Is there a practical way to do this? Granted, it's not so necessary if the syntax to do that wasn't so long and cumbersome. The other thing I found was within a few functions I was desperately wanting user attributes. I was interacting with a database, and without being able to attribute row structure items, it's very messy and hacky to specify which item was the primary key, which items should be relational references, mask items which should be ignored, etc. --485b397dce8383773904bc494724 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 28 March 2012 07:29, F i L <span dir=3D"ltr">= &lt;<a href=3D"mailto:witte2008 gmail.com">witte2008 gmail.com</a>&gt;</spa= n> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b= order-left:1px #ccc solid;padding-left:1ex"> I find myself using __traits(hasMember, T, &quot;member&quot;) a lot.<br> It&#39;s really basic feature of meta-programming.<br> <br> I&#39;m not a fan of the &quot;__usedByCompiler&quot; syntax, but that&#39;= s a<br> whole different discussion. __traits() is fine (besides the fact<br> that first-argument-as-function is syntactically inconsistent to<br> the rest of the language), but std.traits doesn&#39;t wrap it<br> correctly; and, because it&#39;s globally available anyways &amp; so<br> often used, shouldn&#39;t have to be imported to use in the first<br> place, IMO.<br> <br> What I would like to see happen: Have a traits.d which replaces<br> std.traits and is always included (like object.d) which properly<br> wraps __trait functions.<br> <br> so in traits.d:<br> <br> =C2=A0 =C2=A0 // use alias T, so we can pass &quot;laser.x&quot; to it<br> =C2=A0 =C2=A0 // without having to pass typeof(laser.x). Just like<br> =C2=A0 =C2=A0 // we can with using __traits(hasMember, ...)<br> <br> =C2=A0 =C2=A0 template hasMember(alias T, string member) {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 enum hasMember =3D __traits(hasMember, T, memb= er);<br> =C2=A0 =C2=A0 }<br> <br> we can then write:<br> <br> =C2=A0 =C2=A0 auto laser =3D ship.fire();<br> =C2=A0 =C2=A0 static if(traits.hasMember!(laser.x, &quot;isProp&quot;) ...= ;<br> <br> which feels syntactically consistent. Because traits are in their<br> own module, we could emit the &quot;traits.&quot; and just call<br> &quot;hasMember()&quot;. Even better, if UFCS allows, we could simply write= :<br> <br> =C2=A0 =C2=A0 static if(laser.x.hasMember!(&quot;isProp&quot;<u></u>)) ...= ;<br> <br> <br> my 2 cents.<br> </blockquote></div><br><div>I was rummaging through exactly the same stuff = yesterday, and reached a similar conclusion.</div><div>My code became borde= rline impossible to understand very fast with all the references to __trait= s(getMember, instanceOf, member) and friends. Something like you suggest wo= uld go a long way to making it readable again.</div> <div><br></div><div>One thing I noticed recurring, __traits(getMember, T, m= ember) can be aliased, but __traits(getMember, instanceOfT, member) can not= really be aliased, since D doesn&#39;t have references. Is there a practic= al way to do this? Granted, it&#39;s not so necessary if the syntax to do t= hat wasn&#39;t so long and cumbersome.</div> <div><br></div><div>The other thing I found was within a few functions I wa= s desperately wanting user attributes. I was interacting with a database, a= nd without being able to attribute row structure items, it&#39;s very messy= and hacky to specify which item was the primary key, which items should be= relational references, mask items which should be ignored, etc.</div> --485b397dce8383773904bc494724--
Mar 28 2012
prev sibling next sibling parent Johannes Pfau <nospam example.com> writes:
Am Wed, 28 Mar 2012 06:29:30 +0200
schrieb "F i L" <witte2008 gmail.com>:

 I find myself using __traits(hasMember, T, "member") a lot.
 It's really basic feature of meta-programming.
 

We already had this discussion 3 years ago, there's even a bug report: http://d.puremagic.com/issues/show_bug.cgi?id=3702 http://www.digitalmars.com/d/archives/digitalmars/D/Proposal_Replace_traits_and_is_typeof_XXX_with_a_magic_namespace_._99914.html And related: http://forum.dlang.org/thread/in00fa$4fa$1 digitalmars.com?page=1 I think someone just has to implement that 'meta' namespace and start a pull request, I doubt there will be a big resistance against it.
Mar 28 2012
prev sibling next sibling parent "RivenTheMage" <riven-mage id.ru> writes:
My proposal:
http://www.digitalmars.com/d/archives/digitalmars/D/Yet_another_compile-time_reflection_revisited_proposal_150309.html
Mar 28 2012
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--20cf303b42d30093fb04bc550f42
Content-Type: text/plain; charset=UTF-8

On 28 March 2012 20:01, RivenTheMage <riven-mage id.ru> wrote:

 My proposal:
 http://www.digitalmars.com/d/**archives/digitalmars/D/Yet_**
 another_compile-time_**reflection_revisited_proposal_**150309.html<http://www.digitalmars.com/d/archives/digitalmars/D/Yet_another_compile-time_reflection_revisited_proposal_150309.html>

Yes please! :) Although I'm not sure why you distinguish 'metainfo' from 'meta'? These proposals all look basically the same, more or less. I'm curious to know why it wasn't done that way in the first place? It seems the obvious approach... --20cf303b42d30093fb04bc550f42 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 28 March 2012 20:01, RivenTheMage <span dir= =3D"ltr">&lt;<a href=3D"mailto:riven-mage id.ru">riven-mage id.ru</a>&gt;</= span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e= x;border-left:1px #ccc solid;padding-left:1ex"> My proposal:<br> <a href=3D"http://www.digitalmars.com/d/archives/digitalmars/D/Yet_another_= compile-time_reflection_revisited_proposal_150309.html" target=3D"_blank">h= ttp://www.digitalmars.com/d/<u></u>archives/digitalmars/D/Yet_<u></u>anothe= r_compile-time_<u></u>reflection_revisited_proposal_<u></u>150309.html</a><= /blockquote> <div><br></div><div>Yes please! :)</div><div>Although I&#39;m not sure why = you distinguish &#39;metainfo&#39; from &#39;meta&#39;?</div><div><br></div=
<div>These proposals all look basically the same,=C2=A0more or less.</div>=

I&#39;m curious to know why it wasn&#39;t done that way in the first place?= It seems the obvious approach...</div></div> --20cf303b42d30093fb04bc550f42--
Mar 28 2012
prev sibling next sibling parent "F i L" <witte2008 gmail.com> writes:
On Wednesday, 28 March 2012 at 17:01:50 UTC, RivenTheMage wrote:
 My proposal:
 http://www.digitalmars.com/d/archives/digitalmars/D/Yet_another_compile-time_reflection_revisited_proposal_150309.html

I like this idea more than the one I purposed.
Mar 28 2012
prev sibling next sibling parent "RivenTheMage" <riven-mage id.ru> writes:
On Wednesday, 28 March 2012 at 22:23:51 UTC, Manu wrote:

 Although I'm not sure why you distinguish 'metainfo' from 
 'meta'?

To me, it's consistent with .typeinfo and .classinfo properties.
Mar 28 2012
prev sibling next sibling parent "F i L" <witte2008 gmail.com> writes:
I'd like to add to what I suggested earlier. Conversion between
types is a common and expected behavior. Because std.conv is
small, and the new UFCS is here, I think object.d could benefit.
Hear what I had in mind:

+ Move std.conv functionality to object.d
+ Move Object.toString() from the base class, to free space.
+ Make toString() simply wrap to!string() and depreciate it.
+ Replace parse!() with a more intelligent to!()/string

+ emplace!() would be handy to always have around :)
+ idk what to do with text!() :/

Now we can convert types as a language feature, and toString()
still works, but universally on any type that defines opCall().
Also, like I said, toString() might just wrap to!string() and be
marked as depreciated (since we already have .stringof).

      auto name = "Jacque Fresco";
      auto age = 96;

      writeln("Hi, I'm ", name, ".");
      writeln("I'm ", age.text(), " years old");
      writeln("This shit's got to go!"); // ;)

      writeln("How old are you?");

      auto line = readln();
      auto theirAge = line.to!int();
Mar 29 2012
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--f46d0444ef4322235c04bc6869a1
Content-Type: text/plain; charset=UTF-8

On 29 March 2012 20:07, F i L <witte2008 gmail.com> wrote:

     auto name = "Jacque Fresco";
     auto age = 96;

     writeln("Hi, I'm ", name, ".");
     writeln("I'm ", age.text(), " years old");
     writeln("This shit's got to go!"); // ;)

Hah! Nicely played ;) --f46d0444ef4322235c04bc6869a1 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 29 March 2012 20:07, F i L <span dir=3D"ltr">= &lt;<a href=3D"mailto:witte2008 gmail.com">witte2008 gmail.com</a>&gt;</spa= n> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b= order-left:1px #ccc solid;padding-left:1ex"> =C2=A0 =C2=A0 auto name =3D &quot;Jacque Fresco&quot;;<br> =C2=A0 =C2=A0 auto age =3D 96;<br> <br> =C2=A0 =C2=A0 writeln(&quot;Hi, I&#39;m &quot;, name, &quot;.&quot;);<br> =C2=A0 =C2=A0 writeln(&quot;I&#39;m &quot;, age.text(), &quot; years old&q= uot;);<br> =C2=A0 =C2=A0 writeln(&quot;This shit&#39;s got to go!&quot;); // ;)<br></= blockquote><div><br></div><div>Hah!</div><div>Nicely played ;)</div></div> --f46d0444ef4322235c04bc6869a1--
Mar 29 2012
prev sibling parent "F i L" <witte2008 gmail.com> writes:
On Thursday, 29 March 2012 at 21:29:04 UTC, Manu wrote:
 On 29 March 2012 20:07, F i L <witte2008 gmail.com> wrote:

     auto name = "Jacque Fresco";
     auto age = 96;

     writeln("Hi, I'm ", name, ".");
     writeln("I'm ", age.text(), " years old");
     writeln("This shit's got to go!"); // ;)

Hah! Nicely played ;)

XD I was hoping someone would get that reference.
Mar 29 2012