View mode: basic / threaded / horizontal-split · Log in · Help
October 25, 2008
internal/local template memebers
A number of times while working with template code I have found that I need 
a variable inside a template but don't want the side effects of doing so. 
Specifically 1) having a tmp variable results in having to explicitly reference 
template members rather than being able to use the default member rule and 
2) the extra symbols seem to result in a substantial increases in the compile 
time memory usage.

The idea I'm floating would be to have a "local" storage class (or whatever 
keyword is chosen) that would only be accessible from within the template 
it is declared in:


template Foo(char[] str)
{
   local char[] first = str[0..$/2];
   local char[] last = str[$/2..$];

   const char[] Foo = Foo!(first) ~ Foo!(last); // legal; note not "Foo!().Foo"
   // const char[] Foo = Foo!(first).a ~ Foo!(last).a; // error a is not 
accessible
}

During compilation these variables would be computed, used and thrown away 
resulting in no long term memory cost.
October 25, 2008
Re: internal/local template memebers
On Sat, Oct 25, 2008 at 1:05 PM, BCS <ao@pathlink.com> wrote:
> A number of times while working with template code I have found that I need
> a variable inside a template but don't want the side effects of doing so.
> Specifically 1) having a tmp variable results in having to explicitly
> reference template members rather than being able to use the default member
> rule and 2) the extra symbols seem to result in a substantial increases in
> the compile time memory usage.
>
> The idea I'm floating would be to have a "local" storage class (or whatever
> keyword is chosen) that would only be accessible from within the template it
> is declared in:
>
>
> template Foo(char[] str)
> {
>   local char[] first = str[0..$/2];
>   local char[] last = str[$/2..$];
>
>   const char[] Foo = Foo!(first) ~ Foo!(last); // legal; note not
> "Foo!().Foo"
>   // const char[] Foo = Foo!(first).a ~ Foo!(last).a; // error a is not
> accessible
> }
>
> During compilation these variables would be computed, used and thrown away
> resulting in no long term memory cost.

Indeed.  You're resurrecting a classic.  Maybe a good time to do so,
though.  Lots of uses for this suggestion -- internal helper
functions, local aliases for unwieldy types.  I've wished for it many
times, too.

Another way to go would just be to say if you have a symbol with the
same name as the template inside, then it automatically means
everything else is hidden.

---
Another gripe is having to repeat the exact template name over and
over in code like this.

This
template ThisIsTheTemplateNameFoo(char[] str)
{
 const char[] ThisIsTheTemplateName =
ThisIsTheTemplateName!(str[0..$/2]) ~
ThisIsTheTemplateName!(str[$/2..$]);
}

I think "this" for constructors has taught us that not repeating the
name of something when the compiler already knows it is a "honking
great idea".  It should be extended to templates somehow too.

--bb
October 25, 2008
Re: internal/local template memebers
Reply to Bill,

> Indeed.  You're resurrecting a classic.  Maybe a good time to do so,
> though.  Lots of uses for this suggestion -- internal helper
> functions, local aliases for unwieldy types.  I've wished for it many
> times, too.
> 
> Another way to go would just be to say if you have a symbol with the
> same name as the template inside, then it automatically means
> everything else is hidden.

truth be told, that use is not the main reason I want this. The reduced memory 
usage is (when you have compiles that use up >1GB you start to think of these 
things).
October 25, 2008
Re: internal/local template memebers
On Sat, 25 Oct 2008 08:05:41 +0400, BCS <ao@pathlink.com> wrote:

> A number of times while working with template code I have found that I  
> need a variable inside a template but don't want the side effects of  
> doing so. Specifically 1) having a tmp variable results in having to  
> explicitly reference template members rather than being able to use the  
> default member rule and 2) the extra symbols seem to result in a  
> substantial increases in the compile time memory usage.
>
> The idea I'm floating would be to have a "local" storage class (or  
> whatever keyword is chosen) that would only be accessible from within  
> the template it is declared in:
>
>
> template Foo(char[] str)
> {
>     local char[] first = str[0..$/2];
>     local char[] last = str[$/2..$];
>
>     const char[] Foo = Foo!(first) ~ Foo!(last); // legal; note not  
> "Foo!().Foo"
>     // const char[] Foo = Foo!(first).a ~ Foo!(last).a; // error a is  
> not accessible
> }
>
> During compilation these variables would be computed, used and thrown  
> away resulting in no long term memory cost.
>
>


I agree! But I would prefer re-using public/private - they make perfect  
sense here - instead of new internal/local keywords.
October 25, 2008
Re: internal/local template memebers
On Sat, Oct 25, 2008 at 8:48 PM, Denis Koroskin <2korden@gmail.com> wrote:
> On Sat, 25 Oct 2008 08:05:41 +0400, BCS <ao@pathlink.com> wrote:
>
>> A number of times while working with template code I have found that I
>> need a variable inside a template but don't want the side effects of doing
>> so. Specifically 1) having a tmp variable results in having to explicitly
>> reference template members rather than being able to use the default member
>> rule and 2) the extra symbols seem to result in a substantial increases in
>> the compile time memory usage.
>>
>> The idea I'm floating would be to have a "local" storage class (or
>> whatever keyword is chosen) that would only be accessible from within the
>> template it is declared in:
>>
>>
>> template Foo(char[] str)
>> {
>>    local char[] first = str[0..$/2];
>>    local char[] last = str[$/2..$];
>>
>>    const char[] Foo = Foo!(first) ~ Foo!(last); // legal; note not
>> "Foo!().Foo"
>>    // const char[] Foo = Foo!(first).a ~ Foo!(last).a; // error a is not
>> accessible
>> }
>>
>> During compilation these variables would be computed, used and thrown away
>> resulting in no long term memory cost.
>>
>>
>
>
> I agree! But I would prefer re-using public/private - they make perfect
> sense here - instead of new internal/local keywords.

Problem is templates can be mixed in.  And in that case public/private
has meaning in the context of the host.

--bb
October 25, 2008
Re: internal/local template memebers
On Sat, Oct 25, 2008 at 10:08 PM, Bill Baxter <wbaxter@gmail.com> wrote:
> On Sat, Oct 25, 2008 at 8:48 PM, Denis Koroskin <2korden@gmail.com> wrote:
>> On Sat, 25 Oct 2008 08:05:41 +0400, BCS <ao@pathlink.com> wrote:
>>
>>> A number of times while working with template code I have found that I
>>> need a variable inside a template but don't want the side effects of doing
>>> so. Specifically 1) having a tmp variable results in having to explicitly
>>> reference template members rather than being able to use the default member
>>> rule and 2) the extra symbols seem to result in a substantial increases in
>>> the compile time memory usage.
>>>
>>> The idea I'm floating would be to have a "local" storage class (or
>>> whatever keyword is chosen) that would only be accessible from within the
>>> template it is declared in:
>>>
>>>
>>> template Foo(char[] str)
>>> {
>>>    local char[] first = str[0..$/2];
>>>    local char[] last = str[$/2..$];
>>>
>>>    const char[] Foo = Foo!(first) ~ Foo!(last); // legal; note not
>>> "Foo!().Foo"
>>>    // const char[] Foo = Foo!(first).a ~ Foo!(last).a; // error a is not
>>> accessible
>>> }
>>>
>>> During compilation these variables would be computed, used and thrown away
>>> resulting in no long term memory cost.
>>>
>>>
>>
>>
>> I agree! But I would prefer re-using public/private - they make perfect
>> sense here - instead of new internal/local keywords.
>
> Problem is templates can be mixed in.  And in that case public/private
> has meaning in the context of the host.

...But contextual keywords to the rescue!

  private(local) char[] first = str[0..$/2];
  private(local) char[] last = str[$/2..$];

--bb
October 25, 2008
Re: internal/local template memebers
On Sat, 25 Oct 2008 17:08:28 +0400, Bill Baxter <wbaxter@gmail.com> wrote:

> On Sat, Oct 25, 2008 at 8:48 PM, Denis Koroskin <2korden@gmail.com>  
> wrote:
>> On Sat, 25 Oct 2008 08:05:41 +0400, BCS <ao@pathlink.com> wrote:
>>
>>> A number of times while working with template code I have found that I
>>> need a variable inside a template but don't want the side effects of  
>>> doing
>>> so. Specifically 1) having a tmp variable results in having to  
>>> explicitly
>>> reference template members rather than being able to use the default  
>>> member
>>> rule and 2) the extra symbols seem to result in a substantial  
>>> increases in
>>> the compile time memory usage.
>>>
>>> The idea I'm floating would be to have a "local" storage class (or
>>> whatever keyword is chosen) that would only be accessible from within  
>>> the
>>> template it is declared in:
>>>
>>>
>>> template Foo(char[] str)
>>> {
>>>    local char[] first = str[0..$/2];
>>>    local char[] last = str[$/2..$];
>>>
>>>    const char[] Foo = Foo!(first) ~ Foo!(last); // legal; note not
>>> "Foo!().Foo"
>>>    // const char[] Foo = Foo!(first).a ~ Foo!(last).a; // error a is  
>>> not
>>> accessible
>>> }
>>>
>>> During compilation these variables would be computed, used and thrown  
>>> away
>>> resulting in no long term memory cost.
>>>
>>>
>>
>>
>> I agree! But I would prefer re-using public/private - they make perfect
>> sense here - instead of new internal/local keywords.
>
> Problem is templates can be mixed in.  And in that case public/private
> has meaning in the context of the host.
>
> --bb

I don't see how this is a problem:

template Bar
{
    private int value;
    public int getValue() { return value; }
}

class Foo
{
    mixin Bar!();
}

template Square(alias x)
{
    private enum temp = x * x;
    public enum Square = temp;
}

enum x2 = Square!(x);

This is because you usual templates and mixin templates are completely  
different, mixin'ing usual template or instantiating template that is  
intended for being mixed-in makes no sense in the majority of real cases.  
Moreover, I would prefer to separate these terms and so their syntax:

mixin template Bar
{
    private int value;
    public int getValue() { return value; }
}

class Foo
{
    mixin Bar!();
}

int bar = Bar!().getValue(); // Error: can't instantiate mixin template

template Square(alias x)
{
    private enum temp = x * x;
    public enum Square = temp;
}

class Test
{
    mixin Square!(42); // Error: can't mixin non-mixin template
}
October 25, 2008
Re: internal/local template memebers
Bill Baxter wrote:
> On Sat, Oct 25, 2008 at 10:08 PM, Bill Baxter <wbaxter@gmail.com> wrote:
>> On Sat, Oct 25, 2008 at 8:48 PM, Denis Koroskin <2korden@gmail.com> wrote:
>>> On Sat, 25 Oct 2008 08:05:41 +0400, BCS <ao@pathlink.com> wrote:
>>>
>>>> A number of times while working with template code I have found that I
>>>> need a variable inside a template but don't want the side effects of doing
>>>> so. Specifically 1) having a tmp variable results in having to explicitly
>>>> reference template members rather than being able to use the default member
>>>> rule and 2) the extra symbols seem to result in a substantial increases in
>>>> the compile time memory usage.
>>>>
>>>> The idea I'm floating would be to have a "local" storage class (or
>>>> whatever keyword is chosen) that would only be accessible from within the
>>>> template it is declared in:
>>>>
>>>>
>>>> template Foo(char[] str)
>>>> {
>>>>    local char[] first = str[0..$/2];
>>>>    local char[] last = str[$/2..$];
>>>>
>>>>    const char[] Foo = Foo!(first) ~ Foo!(last); // legal; note not
>>>> "Foo!().Foo"
>>>>    // const char[] Foo = Foo!(first).a ~ Foo!(last).a; // error a is not
>>>> accessible
>>>> }
>>>>
>>>> During compilation these variables would be computed, used and thrown away
>>>> resulting in no long term memory cost.
>>>>
>>>>
>>>
>>> I agree! But I would prefer re-using public/private - they make perfect
>>> sense here - instead of new internal/local keywords.
>> Problem is templates can be mixed in.  And in that case public/private
>> has meaning in the context of the host.
> 
> ...But contextual keywords to the rescue!
> 
>    private(local) char[] first = str[0..$/2];
>    private(local) char[] last = str[$/2..$];
> 
> --bb

Sweet, suddenly contextual keywords become a viable solution to 
everything; first the new member functions, now this :). Why no one had 
suggested it before?

(Although private(local) sounds like unnecessary redundancy here.)
October 25, 2008
Re: internal/local template memebers
On Sat, Oct 25, 2008 at 10:34 PM, Denis Koroskin <2korden@gmail.com> wrote:
> On Sat, 25 Oct 2008 17:08:28 +0400, Bill Baxter <wbaxter@gmail.com> wrote:
>
>> On Sat, Oct 25, 2008 at 8:48 PM, Denis Koroskin <2korden@gmail.com> wrote:
>>>
>>> On Sat, 25 Oct 2008 08:05:41 +0400, BCS <ao@pathlink.com> wrote:
>>>
> This is because you usual templates and mixin templates are completely
> different, mixin'ing usual template or instantiating template that is
> intended for being mixed-in makes no sense in the majority of real cases.

Good point.  I can't think of any case where something I've written as
a mixin would be useful as a stand-alone template.
I usually end up calling my mixin templates something with "Mix" in the name.

But it does seem like it would be tricky for the compiler to determine
which case you meant.   Unless you told it which case... which is
exactly what you suggest next.

> Moreover, I would prefer to separate these terms and so their syntax:
>
> mixin template Bar

That sounds quite reasonable to me.  (Though it's 4am and I just woke
up, so I may not be at my peak right now)
I would also appreciate templates being distict from mixin templates
too.  If you actually did run into some need for a template that can
be either, then just mixin the mixin into a template!

mixin template BarMix(T)
{
  ...
}
template Bar(T)
{
   mixin BarMix!(T);
}

--bb
October 25, 2008
Re: internal/local template memebers
On Sun, Oct 26, 2008 at 3:54 AM, Bill Baxter <wbaxter@gmail.com> wrote:
> On Sat, Oct 25, 2008 at 10:34 PM, Denis Koroskin <2korden@gmail.com> wrote:
>> On Sat, 25 Oct 2008 17:08:28 +0400, Bill Baxter <wbaxter@gmail.com> wrote:
>>
>>> On Sat, Oct 25, 2008 at 8:48 PM, Denis Koroskin <2korden@gmail.com> wrote:
>>>>
>>>> On Sat, 25 Oct 2008 08:05:41 +0400, BCS <ao@pathlink.com> wrote:
>>>>
>> This is because you usual templates and mixin templates are completely
>> different, mixin'ing usual template or instantiating template that is
>> intended for being mixed-in makes no sense in the majority of real cases.
>
> Good point.  I can't think of any case where something I've written as
> a mixin would be useful as a stand-alone template.
> I usually end up calling my mixin templates something with "Mix" in the name.
>
> But it does seem like it would be tricky for the compiler to determine
> which case you meant.   Unless you told it which case... which is
> exactly what you suggest next.
>
>> Moreover, I would prefer to separate these terms and so their syntax:
>>
>> mixin template Bar
>
> That sounds quite reasonable to me.  (Though it's 4am and I just woke
> up, so I may not be at my peak right now)

Actually, I realized I do actually have some code that I use as either
mixin or standalone.
It's a template full of utility functions.  Sometimes it's convenient
just to mix all those utility functions into a class directly rather
than having to go through the GeomUtil!(PointType) template.  But it's
a convenient set of functions that doesn't particularly need to be
mixed in to be useful.

--bb
Top | Discussion index | About this forum | D home