Thread overview
internal/local template memebers
Oct 25, 2008
BCS
Oct 25, 2008
Bill Baxter
Oct 25, 2008
BCS
Oct 25, 2008
Denis Koroskin
Oct 25, 2008
Bill Baxter
Oct 25, 2008
Denis Koroskin
Oct 25, 2008
Bill Baxter
Oct 25, 2008
Bill Baxter
Oct 25, 2008
Bill Baxter
Oct 25, 2008
KennyTM~
October 25, 2008
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
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
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
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
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
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
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
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
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
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