March 30, 2011
Ary Manzana:

> Why make *anything* hard to use if you can do it in an easier way?

I agree. On the other hand is the :: syntax easy compared to a "meta." namespace? The meta name is more readable. I suggest to try to invent few more alternative syntaxes before choosing.

Bye,
bearophile
March 30, 2011
On Mar 31, 11 06:32, Ary Manzana wrote:
> On 3/30/11 5:52 PM, KennyTM~ wrote:
>> On Mar 31, 11 04:19, Alix Pexton wrote:
>>> On 30/03/2011 20:45, KennyTM~ wrote:
>>>> This is confusing as :: is used to separate scopes in C++ (and PHP
>>>> too).
>>>
>>> The first thing it reminded me of was Lua, where a single colon makes
>>> the left hand side into the first argument of the function on the right.
>>>
>>> foo:bar(x) ==> bar.(foo, x)
>>>
>>> So it felt kinda familiar to me ^^
>>>
>>> A...
>>
>> That is almost like UFCS in D.
>>
>> int foo(string x, int y) { return x.length - y; }
>>
>> assert (foo("testing", 3) == 4);
>> assert ("testing".foo(3) == 4);
>>
>> But OP's proposal is restricted to __traits only.
>>
>> __traits is a relatively advanced part of the language, plus many of its
>> features has already been exposed via the library std.traits, e.g.
>> std.traits.hasMember!(S, "m"), I don't think it really needs a very
>> short syntax.
>
> Look, metaprogramming in Ruby is a relatively advanced part of the
> language. And you know why it is heavily used and everyone can jump and
> start using it in a matter of seconds and build the most amazing things?
> Because it's very, very, very, (add 1000 very words here), very easy to
> use.
>

We're talking about __traits, a feature for compile-time reflection where most of its capability is already wrapped up to std.traits. It isn't comparable with the whole metaprogramming capability in another language.

You know, metaprogramming is also heavily used in D, because of a sensible template system, mixins and CTFE, not __traits.

> Why make *anything* hard to use if you can do it in an easier way?

Is

  meta.hasMember(S, "m")

or even

  import std.traits;
  ...
  hasMember!(S, "m")

really that hard to use?

I think the 'meta' namespace is enough. 'A::B' is too much for such a low-level feature.
March 30, 2011
How about not inventing new syntaxes? Leave that to C++7xFF.
March 30, 2011
Andrej Mitrovic:

> How about not inventing new syntaxes? Leave that to C++7xFF.

Sorry for not being clear, by "alternative syntaxes" I meant something like the "meta" namespace too.

Bye,
bearophile
March 31, 2011
On 03/30/2011 09:28 PM, Ary Manzana wrote:
> I think :: is not used in the language.
>
> In a recent article about D I saw:
>
> mixin(__traits(identifier, T) ~ " " ~
> to!string(tolower(__traits(identifier, T)[0])) ~
> __traits(identifier, T)[1..$] ~ ";");
>
> What if foo::bar were an alias for __traits(foo, bar) ?
>
> The code would look like this:
>
> mixin(T::identifier ~ " " ~
> to!string(tolower(T::identifier[0])) ~
> T::identifier[1..$] ~ ";");
>
> What do you think?
>
> Another uses:
>
> __traits(int, isArithmetic) ==> int::isArithmetic
> __traits(C, isAbstractClass) ==> C::isAbstractClass
>
> __traits(hasMember, S, "m") ==> S::hasMember("m")
>
> Well, you get the idea...
>
> :: might be applied to other compile time uses, but I just came up with this...

Waow, this /is/ syntactic sugar ;-)

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

March 31, 2011
I just hate it when you have to write too much to get simple things done.

Does this type have a member? Current approach:

1. import std.traits;
2. invoke hasMember!(S, "m")

Another approach:

1. I have the type, let's ask it: S::hasMember("m")

Map's thought to code.

My problem is that when you start using D's cool features you end up with a really hard to understand and obscure code...
March 31, 2011
On 03/30/2011 09:45 PM, KennyTM~ wrote:
> On Mar 31, 11 03:28, Ary Manzana wrote:
>> I think :: is not used in the language.
>>
>> In a recent article about D I saw:
>>
>> mixin(__traits(identifier, T) ~ " " ~
>> to!string(tolower(__traits(identifier, T)[0])) ~
>> __traits(identifier, T)[1..$] ~ ";");
>>
>> What if foo::bar were an alias for __traits(foo, bar) ?
>>
>> The code would look like this:
>>
>> mixin(T::identifier ~ " " ~
>> to!string(tolower(T::identifier[0])) ~
>> T::identifier[1..$] ~ ";");
>>
>> What do you think?
>>
>> Another uses:
>>
>> __traits(int, isArithmetic) ==> int::isArithmetic
>> __traits(C, isAbstractClass) ==> C::isAbstractClass
>>
>
> You've got the order wrong.

?

>> __traits(hasMember, S, "m") ==> S::hasMember("m")
>>
>> Well, you get the idea...
>>
>> :: might be applied to other compile time uses, but I just came up with
>> this...
>
> -1.
>
> This is confusing as :: is used to separate scopes in C++ (and PHP too). e.g.

D is not C++. D precisely exists to make things differently, ie its own way.

> struct A {
> int x;
> bool isSame(const A other) pure const { return x == other.x; }
> }
>
> void main () {
> A a = A(2), b = A(2);
> assert ( a.isSame(b)); // ok
> assert (! a::isSame(b)); // ???
> }
>
> (How about that 'meta' namespace proposal? meta.hasMember(S, "m") )

This is no improvement about __traits. I'm all for a meta namespace, but it should be syntactically attractive. There is no contradiction between Ary's proposal meta, though the exact optimal syntax may not be that one.

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

March 31, 2011
On Mar 31, 11 09:42, Ary Manzana wrote:
> I just hate it when you have to write too much to get simple things
> done.
>
> Does this type have a member? Current approach:
>
> 1. import std.traits;
> 2. invoke hasMember!(S, "m")
>
> Another approach:
>
> 1. I have the type, let's ask it: S::hasMember("m")
>
> Map's thought to code.
>
> My problem is that when you start using D's cool features you end up
> with a really hard to understand and obscure code...

How often do you really needs feature in __traits? I've grepped my code which uses a lot of templates and CTFE, and it only appears in 2 lines

    else static if (__traits(isScalar, T)) {
        static if (__traits(compiles, T.init.re))

Therefore I oppose the use of :: just for __traits, because it's so rare.

Now I have a counter-proposal,

    T::ident(x, y, z, ...)  <=>  ident!(T, x, y, z, ...)

then hasMember can be invoked as

    import std.traits;
    ...
    S::hasMember("m")

Isn't it better than reserving :: just for __traits?

March 31, 2011
On 2011-03-30 19:38, KennyTM~ wrote:
> On Mar 31, 11 09:42, Ary Manzana wrote:
> > I just hate it when you have to write too much to get simple things done.
> > 
> > Does this type have a member? Current approach:
> > 
> > 1. import std.traits;
> > 2. invoke hasMember!(S, "m")
> > 
> > Another approach:
> > 
> > 1. I have the type, let's ask it: S::hasMember("m")
> > 
> > Map's thought to code.
> > 
> > My problem is that when you start using D's cool features you end up with a really hard to understand and obscure code...
> 
> How often do you really needs feature in __traits? I've grepped my code which uses a lot of templates and CTFE, and it only appears in 2 lines
> 
>      else static if (__traits(isScalar, T)) {
>          static if (__traits(compiles, T.init.re))
> 
> Therefore I oppose the use of :: just for __traits, because it's so rare.
> 
> Now I have a counter-proposal,
> 
>      T::ident(x, y, z, ...)  <=>  ident!(T, x, y, z, ...)
> 
> then hasMember can be invoked as
> 
>      import std.traits;
>      ...
>      S::hasMember("m")
> 
> Isn't it better than reserving :: just for __traits?

I use __traits(compiles, ) all the time, and a few of the others in __traits, though I probably use std.traits more than __traits.

I don't mind the meta proposal (__traits _is_ kind of ugly), but I _definitely_ don't like the :: proposal. I don't find it to be clear at all, and it's one more operator to remember. Not to mention, it might cause problems when porting C++ code.

- Jonathan M Davis
March 31, 2011
On Mar 31, 11 10:38, KennyTM~ wrote:
> On Mar 31, 11 09:42, Ary Manzana wrote:
>> I just hate it when you have to write too much to get simple things
>> done.
>>
>> Does this type have a member? Current approach:
>>
>> 1. import std.traits;
>> 2. invoke hasMember!(S, "m")
>>
>> Another approach:
>>
>> 1. I have the type, let's ask it: S::hasMember("m")
>>
>> Map's thought to code.
>>
>> My problem is that when you start using D's cool features you end up
>> with a really hard to understand and obscure code...
>
> How often do you really needs feature in __traits? I've grepped my code
> which uses a lot of templates and CTFE, and it only appears in 2 lines
>
> else static if (__traits(isScalar, T)) {
> static if (__traits(compiles, T.init.re))
>
> Therefore I oppose the use of :: just for __traits, because it's so rare.
>
> Now I have a counter-proposal,
>
> T::ident(x, y, z, ...) <=> ident!(T, x, y, z, ...)
>
> then hasMember can be invoked as
>
> import std.traits;
> ...
> S::hasMember("m")
>
> Isn't it better than reserving :: just for __traits?
>

PS. I don't mean to push this proposal. This is just to show that instead of using :: for __traits, there is a better alternative.