Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-09 Thread Nick Treleaven
On Tue, 08 Mar 2011 15:25:27 -0500, Steven Schveighoffer wrote:

 Hey, wouldn't it be cool if I could add a custom allocator to all
 classes!?...
 
 class Collection(T, alloc = DefaultAllocator!T) {
 Collection!(T) add(T t) { ...; return this; } // 20 other now subtly
 incorrect functions like add...
 }
 
 See the problem?

This seems like a good reason to keep allowing the feature. It would be 
nice if it could be documented clearly somewhere, maybe here:

http://www.digitalmars.com/d/2.0/template.html#ClassTemplateDeclaration


Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Andrej Mitrovic
import std.stdio;
import std.traits;
import std.exception;

struct CheckedInt(N) if (isIntegral!N)
{
private N value;

ref CheckedInt opUnary(string op)() if (op == ++)
{
enforce(value != value.max);
++value;
return this;
}

this(N _value)
{
value = _value;
}
}

I didn't know you could define a return type of a templated struct without 
defining the type it is parameterized on. I mean this line:

ref CheckedInt opUnary(string op)() if (op == ++)

I thought for sure I always had to write the parameterized type like so:

ref CheckedInt!(N) opUnary(string op)() if (op == ++)

So I guess this really isn't a question but more of a oh, I didn't know you 
could do that. In fact I rarely see this kind of code in Phobos, most of the 
time the parameterized type is specified in these types of cases. Is this 
feature described somewhere, because I must have missed it if it is?

As a side-note, auto ref is useful in this case, which is pretty cool:
auto ref opUnary(string op)() if (op == ++)


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Steven Schveighoffer

On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none wrote:


import std.stdio;
import std.traits;
import std.exception;

struct CheckedInt(N) if (isIntegral!N)
{
private N value;
   ref CheckedInt opUnary(string op)() if (op == ++)
{
enforce(value != value.max);
++value;
return this;
}
   this(N _value)
{
value = _value;
}
}

I didn't know you could define a return type of a templated struct  
without defining the type it is parameterized on. I mean this line:


ref CheckedInt opUnary(string op)() if (op == ++)

I thought for sure I always had to write the parameterized type like so:

ref CheckedInt!(N) opUnary(string op)() if (op == ++)

So I guess this really isn't a question but more of a oh, I didn't know  
you could do that. In fact I rarely see this kind of code in Phobos,  
most of the time the parameterized type is specified in these types of  
cases. Is this feature described somewhere, because I must have missed  
it if it is?


It is described, but not directly.

Look on this page:

http://www.digitalmars.com/d/2.0/template.html

  From there we have these two descriptions:



If a template has exactly one member in it, and the name of that member is
the same as the template name, that member is assumed to be referred to in
a template instantiation:
template Foo(T)
{
  T Foo;// declare variable Foo of type T
}

void test()
{
  Foo!(int) = 6;// instead of Foo!(int).Foo
}



If a template declares exactly one member, and that member is a class with
the same name as the template:
template Bar(T)
{
  class Bar
  {
T member;
  }
}

then the semantic equivalent, called a ClassTemplateDeclaration can be
written as:
class Bar(T)
{
  T member;
}



Also note that structs have the same description.

So if you think about it, your code is equivalent to:

template CheckedInt(N) if(isIntegral!N)
{
   struct CheckedInt
   {
  ...
   }
}

If you look at it this way, it makes complete sense that within the struct  
that's within the template, the struct can refer to itself without the  
specific instantiation parameters.


I think this should really be laid out properly in the docs.  I discovered  
this trick while writing dcollections by accident and thought it so  
awesome that I changed all my code which self-returned (quite a bit).


-Steve


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread spir

On 03/08/2011 06:20 PM, Steven Schveighoffer wrote:

On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none wrote:


import std.stdio;
import std.traits;
import std.exception;

struct CheckedInt(N) if (isIntegral!N)
{
private N value;
ref CheckedInt opUnary(string op)() if (op == ++)
{
enforce(value != value.max);
++value;
return this;
}
this(N _value)
{
value = _value;
}
}

I didn't know you could define a return type of a templated struct without
defining the type it is parameterized on. I mean this line:

ref CheckedInt opUnary(string op)() if (op == ++)

I thought for sure I always had to write the parameterized type like so:

ref CheckedInt!(N) opUnary(string op)() if (op == ++)

So I guess this really isn't a question but more of a oh, I didn't know you
could do that. In fact I rarely see this kind of code in Phobos, most of the
time the parameterized type is specified in these types of cases. Is this
feature described somewhere, because I must have missed it if it is?


It is described, but not directly.

Look on this page:

http://www.digitalmars.com/d/2.0/template.html

 From there we have these two descriptions:



If a template has exactly one member in it, and the name of that member is
the same as the template name, that member is assumed to be referred to in
a template instantiation:
template Foo(T)
{
T Foo; // declare variable Foo of type T
}

void test()
{
Foo!(int) = 6; // instead of Foo!(int).Foo
}



If a template declares exactly one member, and that member is a class with
the same name as the template:
template Bar(T)
{
class Bar
{
T member;
}
}

then the semantic equivalent, called a ClassTemplateDeclaration can be
written as:
class Bar(T)
{
T member;
}



Also note that structs have the same description.

So if you think about it, your code is equivalent to:

template CheckedInt(N) if(isIntegral!N)
{
struct CheckedInt
{
...
}
}

If you look at it this way, it makes complete sense that within the struct
that's within the template, the struct can refer to itself without the specific
instantiation parameters.

I think this should really be laid out properly in the docs. I discovered this
trick while writing dcollections by accident and thought it so awesome that I
changed all my code which self-returned (quite a bit).

-Steve


I don't share your enthusiasm, Steven, for this feature (which I did not know). 
In fact, I tend to consider it a mis-feature. Yet another syntactic 
special-case for special cases in the language. In this case, there are even 3 
ways to write the same thing:

CheckedInt
CheckedInt!N
CheckedInt!(N)
And note these variants are low-level ones, morphological rather than syntactic 
properly speaking.


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



Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread David Nadlinger

On 3/8/11 8:20 PM, spir wrote:

[…] Yet another
syntactic special-case for special cases in the language. In this case,
there are even 3 ways to write the same thing: […]


I don't quite get how you think this would be a syntactic special case. 
As Steve pointed out, »class Foo(T) {}« is merely syntax sugar for 
»template Foo(T) { class Foo{} }«, and because of this, it would rather 
be a special case *not* to allow referring to Foo using just that name. 
When considering this, don't forget that templates in D are little more 
than parametrized, named scopes.


I guess you could argue that »class Foo(T)« as a shorthand is an 
unnecessary special case, but I very much prefer the benefit in brevity 
here…


David


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Steven Schveighoffer

On Tue, 08 Mar 2011 14:20:40 -0500, spir denis.s...@gmail.com wrote:


On 03/08/2011 06:20 PM, Steven Schveighoffer wrote:
On Tue, 08 Mar 2011 12:06:08 -0500, Andrej Mitrovic n...@none.none  
wrote:



import std.stdio;
import std.traits;
import std.exception;

struct CheckedInt(N) if (isIntegral!N)
{
private N value;
ref CheckedInt opUnary(string op)() if (op == ++)
{
enforce(value != value.max);
++value;
return this;
}
this(N _value)
{
value = _value;
}
}

I didn't know you could define a return type of a templated struct  
without

defining the type it is parameterized on. I mean this line:

ref CheckedInt opUnary(string op)() if (op == ++)

I thought for sure I always had to write the parameterized type like  
so:


ref CheckedInt!(N) opUnary(string op)() if (op == ++)

So I guess this really isn't a question but more of a oh, I didn't  
know you
could do that. In fact I rarely see this kind of code in Phobos, most  
of the
time the parameterized type is specified in these types of cases. Is  
this

feature described somewhere, because I must have missed it if it is?


It is described, but not directly.

Look on this page:

http://www.digitalmars.com/d/2.0/template.html

 From there we have these two descriptions:



If a template has exactly one member in it, and the name of that member  
is
the same as the template name, that member is assumed to be referred to  
in

a template instantiation:
template Foo(T)
{
T Foo; // declare variable Foo of type T
}

void test()
{
Foo!(int) = 6; // instead of Foo!(int).Foo
}



If a template declares exactly one member, and that member is a class  
with

the same name as the template:
template Bar(T)
{
class Bar
{
T member;
}
}

then the semantic equivalent, called a ClassTemplateDeclaration can be
written as:
class Bar(T)
{
T member;
}



Also note that structs have the same description.

So if you think about it, your code is equivalent to:

template CheckedInt(N) if(isIntegral!N)
{
struct CheckedInt
{
...
}
}

If you look at it this way, it makes complete sense that within the  
struct
that's within the template, the struct can refer to itself without the  
specific

instantiation parameters.

I think this should really be laid out properly in the docs. I  
discovered this
trick while writing dcollections by accident and thought it so  
awesome that I

changed all my code which self-returned (quite a bit).

-Steve


I don't share your enthusiasm, Steven, for this feature (which I did not  
know). In fact, I tend to consider it a mis-feature. Yet another  
syntactic special-case for special cases in the language. In this case,  
there are even 3 ways to write the same thing:

CheckedInt
CheckedInt!N
CheckedInt!(N)
And note these variants are low-level ones, morphological rather than  
syntactic properly speaking.


Here's another thing I found in dcollections which caught me off guard,  
and which I was glad to be rid of when I switched to not parameterizing  
the names of self returns:


class Collection(T)
{
   Collection!(T) add(T t) { ...; return this; }
   // 20 other functions like add...
}

Hey, wouldn't it be cool if I could add a custom allocator to all  
classes!?...


class Collection(T, alloc = DefaultAllocator!T)
{
   Collection!(T) add(T t) { ...; return this; }
   // 20 other now subtly incorrect functions like add...
}

See the problem?

-Steve


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Andrej Mitrovic
On 3/8/11, Steven Schveighoffer schvei...@yahoo.com wrote:
 See the problem?

Yup. Btw, does auto ref still suffer from any bugs that I should know
about? I've heard it had issues.


Re: Templated struct doesn't need the parameterized type in return type definitions?

2011-03-08 Thread Jonathan M Davis
On Tuesday, March 08, 2011 15:31:37 Andrej Mitrovic wrote:
 On 3/8/11, Steven Schveighoffer schvei...@yahoo.com wrote:
  See the problem?
 
 Yup. Btw, does auto ref still suffer from any bugs that I should know
 about? I've heard it had issues.

I'm not sure that it works correctly with properties at the moment. It _does_ 
appear in the docs now though.

- Jonathan M Davis