Jump to page: 1 2
Thread overview
Template question
Oct 04, 2006
Chad J
Oct 04, 2006
Sean Kelly
Oct 04, 2006
Chad J
Oct 05, 2006
Thomas Kuehne
Oct 05, 2006
Chad J
Oct 05, 2006
BCS
Oct 05, 2006
Reiner Pope
Oct 05, 2006
Chad J
Oct 05, 2006
Don Clugston
Oct 05, 2006
Derek Parnell
Oct 05, 2006
Markus Dangl
Oct 06, 2006
rm
Oct 06, 2006
Markus Dangl
Oct 06, 2006
rm
Oct 08, 2006
Markus Dangl
Oct 09, 2006
Don Clugston
October 04, 2006
I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.  Here is some code I tried, but it doesn't work:

import std.stdio;

template GetUID()
{
    const ulong accumulator;

    static if ( ++accumulator != 0 )
        const ulong GetUID = accumulator;
    else
        static assert(0);
}

void main()
{
    writefln( GetUID!() ); // should print 1
    writefln( GetUID!() ); // should print 2
}

Hopefully that gives a good idea of what I am shooting for.
October 04, 2006
Chad J > wrote:
> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.

I don't think this is possible.  Once a template is evaluated that's it.  Future references to a template do not cause a re-evaluation.


Sean
October 04, 2006
Sean Kelly wrote:
> Chad J > wrote:
> 
>> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.
> 
> 
> I don't think this is possible.  Once a template is evaluated that's it.  Future references to a template do not cause a re-evaluation.
> 
> 
> Sean

Oh, bummer.  Is there another way to do what I want to do at compile-time, besides just manually writing the numbers in?
October 05, 2006
Chad J schrieb am 2006-10-04:
> Sean Kelly wrote:
>> Chad J > wrote:
>> 
>>> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.
>> 
>> 
>> I don't think this is possible.  Once a template is evaluated that's it.
>>  Future references to a template do not cause a re-evaluation.
>> 
>> 
>> Sean
>
> Oh, bummer.  Is there another way to do what I want to do at compile-time, besides just manually writing the numbers in?

Here is a kludge(limitation: only UID instantiation per line and file allowed):

#
# template UID(char[] file, int line){
#     const uint UID = line * Hash!(file);
# }
#
# template Hash(char[] seed){
#     static if(seed.length == 1){
#         const uint Hash = seed[0];
#     }else{
#         const uint Hash = Hash!(seed[1 .. $]) * 9 + seed[0];
#     }
# }
#
# const x = UID!(__FILE__, __LINE__);
# const y = UID!(__FILE__, __LINE__);
#

Thomas


October 05, 2006
Chad J > wrote:
> Sean Kelly wrote:
> 
>> Chad J > wrote:
>>
>>> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.
>>
>>
>>
>> I don't think this is possible.  Once a template is evaluated that's it.  Future references to a template do not cause a re-evaluation.
>>
>>
>> Sean
> 
> 
> Oh, bummer.  Is there another way to do what I want to do at compile-time, besides just manually writing the numbers in?

It would require a new feature but...

<code>
enum Root{}

enum foo : Root{a}	
// a is distinct from all values in types deriving from Root
foo.a;

enum bar : Root{a}
// a is distinct from all values in types deriving from Root
bar.a
</code>

Implementing this would be a pain though (putting the enums in different  files...)  :P
October 05, 2006
Chad J > wrote:
> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.  Here is some code I tried, but it doesn't work:
The reason this sort of thing is not supported with templates is that it creates ambiguities. Template evaluation is lazy, meaning (a) it is only done when it is required, and (b) it can be done in any order. This is really the obvious way to do it.

For example, consider the following code:

void foo()
{
  writefln( GetUID!() );
}

void bar()
{
  writefln( GetUID!() );
}

void main()
{
  bar();
  foo();
}

Which one prints 1, and which one prints 2? I can think of two arbitrary rules which resolve the ambiguity:
1. evaluate all templates from the top of the source code down; or
2. evaluate all templates according to execution order.

The problem is that 1. is arbitrary and contradicts the assumption and aim the rearranging the order of functions won't change anything, and 2. is not always decidable, vis a vis the halting problem.


I don't actually have an idea of what you are trying to accomplish, though. If just simple accumulator, then write it as actual D code and let the optimizer inline and pre-evaluate it without your assistance. If you want something else, I'm sure there is a way to do it within the template system -- you'll probably find Thomas and BCS's suggestions the right sort of thing.

Cheers,

Reiner
October 05, 2006
Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Chad J schrieb am 2006-10-04:
> 
>>Sean Kelly wrote:
>>
>>>Chad J > wrote:
>>>
>>>
>>>>I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.
>>>
>>>
>>>I don't think this is possible.  Once a template is evaluated that's it. 
>>> Future references to a template do not cause a re-evaluation.
>>>
>>>
>>>Sean
>>
>>Oh, bummer.  Is there another way to do what I want to do at compile-time, besides just manually writing the numbers in?
> 
> 
> Here is a kludge(limitation: only UID instantiation per line and file allowed):
> 
> #
> # template UID(char[] file, int line){
> #     const uint UID = line * Hash!(file);
> # }
> # # template Hash(char[] seed){
> #     static if(seed.length == 1){
> #         const uint Hash = seed[0];
> #     }else{
> #         const uint Hash = Hash!(seed[1 .. $]) * 9 + seed[0];
> #     }
> # }
> # # const x = UID!(__FILE__, __LINE__);
> # const y = UID!(__FILE__, __LINE__);
> #
> 
> Thomas
> 
> 
> -----BEGIN PGP SIGNATURE-----
> 
> iD8DBQFFJF8MLK5blCcjpWoRArtDAJ42K2nEhKcEWNvpp3q+LjHVdBzAfwCfa8dT
> rS6sQyT7s1XUic1TLz3Y2+A=
> =+5nW
> -----END PGP SIGNATURE-----

Maybe I'm wrong, but it seems like it can't guarantee uniqueness due to hashing of the files.  Anyhow, it's a useful template to keep in mind.

Thanks for that!
October 05, 2006
Reiner Pope wrote:
> Chad J > wrote:
> 
>> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.  Here is some code I tried, but it doesn't work:
> 
> The reason this sort of thing is not supported with templates is that it creates ambiguities. Template evaluation is lazy, meaning (a) it is only done when it is required, and (b) it can be done in any order. This is really the obvious way to do it.
> 
> For example, consider the following code:
> 
> void foo()
> {
>   writefln( GetUID!() );
> }
> 
> void bar()
> {
>   writefln( GetUID!() );
> }
> 
> void main()
> {
>   bar();
>   foo();
> }
> 
> Which one prints 1, and which one prints 2? I can think of two arbitrary rules which resolve the ambiguity:
> 1. evaluate all templates from the top of the source code down; or
> 2. evaluate all templates according to execution order.
> 
> The problem is that 1. is arbitrary and contradicts the assumption and aim the rearranging the order of functions won't change anything, and 2. is not always decidable, vis a vis the halting problem.
> 
> 
> I don't actually have an idea of what you are trying to accomplish, though. If just simple accumulator, then write it as actual D code and let the optimizer inline and pre-evaluate it without your assistance. If you want something else, I'm sure there is a way to do it within the template system -- you'll probably find Thomas and BCS's suggestions the right sort of thing.
> 
> Cheers,
> 
> Reiner

I see.  I was kind of expecting arbitrary order of evaluation, but didn't care really.  This one was mostly just a learning excercise for me to get a better feel for templates.

In a way it would be nice if there was some sort of tutorial type resource for D templates; hopefully something that doesn't rely on C++ background.  For a long time I just ignored them because they were scary :)

Anyhow, thanks for the info!
October 05, 2006
On Wed, 04 Oct 2006 15:52:01 -0400, Chad J wrote:

> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.

This does not answer your question, but I was wondering why you need this functionality at compile time. I do something similar but it happens at application initialization time and is simple to code.

 import util.series;
 import std.stdio;

 Series UID; // Declare the series.
 static this()
 {
   UID.Next = 1; // Set first value to one.
 }

 void main()
 {
     writefln( UID.Next ); // should print 1
     writefln( UID.Next ); // should print 2
 }

Where series.d is

// ------------------
module util.series;

struct Series
{
    private
    {
        ulong mValue;
        ulong mIncr;
    }

    ulong Next()
    {
        ulong lCV;

        lCV = mValue;
        mValue += (mIncr+1);
        return lCV;
    }

    void Next(ulong pInit)
    {
        mValue = pInit;
    }

    ulong Current()
    {
        return mValue;
    }

    ulong Prev()
    {
        return mValue - (mIncr+1);
    }

    void Increment(ulong pInit = 1)
    {
        mIncr = pInit-1;
    }

}


unittest
{
    Series a;
    assert( a.Next == 0);
    assert( a.Next == 1);
    assert( a.Next == 2);
    assert( a.Current == 3);
    a.Increment = 2;
    assert( a.Next == 3);
    assert( a.Next == 5);
    assert( a.Prev == 5);
    a.Next = 100;
    assert( a.Current == 100);
    assert( a.Next == 100);
    assert( a.Next == 102);
}

// ------[ end of file ]-----------------


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
5/10/2006 2:15:46 PM
October 05, 2006
Chad J > wrote:
> Reiner Pope wrote:
>> Chad J > wrote:
>>
>>> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.  Here is some code I tried, but it doesn't work:
>>
>> The reason this sort of thing is not supported with templates is that it creates ambiguities. Template evaluation is lazy, meaning (a) it is only done when it is required, and (b) it can be done in any order. This is really the obvious way to do it.
>>
>> For example, consider the following code:
>>
>> void foo()
>> {
>>   writefln( GetUID!() );
>> }
>>
>> void bar()
>> {
>>   writefln( GetUID!() );
>> }
>>
>> void main()
>> {
>>   bar();
>>   foo();
>> }
>>
>> Which one prints 1, and which one prints 2? I can think of two arbitrary rules which resolve the ambiguity:
>> 1. evaluate all templates from the top of the source code down; or
>> 2. evaluate all templates according to execution order.
>>
>> The problem is that 1. is arbitrary and contradicts the assumption and aim the rearranging the order of functions won't change anything, and 2. is not always decidable, vis a vis the halting problem.
>>
>>
>> I don't actually have an idea of what you are trying to accomplish, though. If just simple accumulator, then write it as actual D code and let the optimizer inline and pre-evaluate it without your assistance. If you want something else, I'm sure there is a way to do it within the template system -- you'll probably find Thomas and BCS's suggestions the right sort of thing.
>>
>> Cheers,
>>
>> Reiner
> 
> I see.  I was kind of expecting arbitrary order of evaluation, but didn't care really.  This one was mostly just a learning excercise for me to get a better feel for templates.
> 
> In a way it would be nice if there was some sort of tutorial type resource for D templates; hopefully something that doesn't rely on C++ background.  For a long time I just ignored them because they were scary :)

A tutorial would be nice. I started writing one a while ago, but then the language changed so much, it became completely obsolete!
And as recently as DMD 0.166, Oskar's patches for member templates have changed the rules again. Although some 'best practices' are now well understood, some 'how-tos' are still unknown by everyone. Nobody has more than 35 days experience with the current D templates. Not even Walter.
<g>
« First   ‹ Prev
1 2