www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Specifying eponymous template "internal parameter"

reply "monarch_dodra" <monarchdodra gmail.com> writes:
Sometimes (especially in phobos), one defines a parametrized 
template, that resolves to a templated function.

This is a nifty trick, because it allows specifying a vararg 
before the current type parameter, eg:

//----
auto r = [1, 2, 3];
auto m = map!("++a", "--a")(r);
//----

As you can see, the template guessed the type of r, even though 
we used a vararg. This would not have worked with a single 
template function.

My question though: I have a similar use case, but I NEED to be 
able to explicitly specify the type of r: as such:

//----
auto m = fun!("++a", "--a", ubyte)(1);
auto m = fun!("++a", "--a")!(ubyte)(1);
auto m = fun!("++a", "--a").fun!ubyte(1);
//----
None of them work. In this specific case, I *need* to specify 
that 1 is of type ubyte, but I really can't do it :/

Simplified example: in my use case, it is a "immutable(int[])": 
Failure to specify the type means the compiler strips tail 
immutability...

The only workaround I can find to make such a thing, is to *not* 
use eponymous temples, and explicitly call an inner function. 
This is ugly as sin, and it makes specifying the internal 
parameter mandatory.

Any thoughts?
Jan 08 2013
next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2013-55-08 09:01, monarch_dodra <monarchdodra gmail.com> wrote:

 Sometimes (especially in phobos), one defines a parametrized template,  
 that resolves to a templated function.

 This is a nifty trick, because it allows specifying a vararg before the  
 current type parameter, eg:

 //----
 auto r = [1, 2, 3];
 auto m = map!("++a", "--a")(r);
 //----

 As you can see, the template guessed the type of r, even though we used  
 a vararg. This would not have worked with a single template function.

 My question though: I have a similar use case, but I NEED to be able to  
 explicitly specify the type of r: as such:

 //----
 auto m = fun!("++a", "--a", ubyte)(1);
 auto m = fun!("++a", "--a")!(ubyte)(1);
 auto m = fun!("++a", "--a").fun!ubyte(1);
 //----
 None of them work. In this specific case, I *need* to specify that 1 is  
 of type ubyte, but I really can't do it :/

 Simplified example: in my use case, it is a "immutable(int[])": Failure  
 to specify the type means the compiler strips tail immutability...

 The only workaround I can find to make such a thing, is to *not* use  
 eponymous temples, and explicitly call an inner function. This is ugly  
 as sin, and it makes specifying the internal parameter mandatory.

 Any thoughts?
A non-eponymous template is currently the only way to do this. Strangely, this works: alias fun2 = fun!("++a", "--a"); auto m = fun2!(ubyte)(1); -- Simen
Jan 08 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 8 January 2013 at 09:59:26 UTC, Simen Kjaeraas wrote:
 On 2013-55-08 09:01, monarch_dodra <monarchdodra gmail.com> 
 wrote:

 Sometimes (especially in phobos), one defines a parametrized 
 template, that resolves to a templated function.

 This is a nifty trick, because it allows specifying a vararg 
 before the current type parameter, eg:

 //----
 auto r = [1, 2, 3];
 auto m = map!("++a", "--a")(r);
 //----

 As you can see, the template guessed the type of r, even 
 though we used a vararg. This would not have worked with a 
 single template function.

 My question though: I have a similar use case, but I NEED to 
 be able to explicitly specify the type of r: as such:

 //----
 auto m = fun!("++a", "--a", ubyte)(1);
 auto m = fun!("++a", "--a")!(ubyte)(1);
 auto m = fun!("++a", "--a").fun!ubyte(1);
 //----
 None of them work. In this specific case, I *need* to specify 
 that 1 is of type ubyte, but I really can't do it :/

 Simplified example: in my use case, it is a 
 "immutable(int[])": Failure to specify the type means the 
 compiler strips tail immutability...

 The only workaround I can find to make such a thing, is to 
 *not* use eponymous temples, and explicitly call an inner 
 function. This is ugly as sin, and it makes specifying the 
 internal parameter mandatory.

 Any thoughts?
A non-eponymous template is currently the only way to do this. Strangely, this works: alias fun2 = fun!("++a", "--a"); auto m = fun2!(ubyte)(1);
Nice! And now, for the 1M$ question: Can I rely on this behavior, or is this an accepts invalid...?
Jan 08 2013
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2013-16-08 11:01, monarch_dodra <monarchdodra gmail.com> wrote:

 On Tuesday, 8 January 2013 at 09:59:26 UTC, Simen Kjaeraas wrote:
   alias fun2 = fun!("++a", "--a");
   auto m = fun2!(ubyte)(1);
Nice! And now, for the 1M$ question: Can I rely on this behavior, or is this an accepts invalid...?
You can rely on it. -- Simen
Jan 08 2013
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 8 January 2013 at 11:09:58 UTC, Simen Kjaeraas wrote:
 On 2013-16-08 11:01, monarch_dodra <monarchdodra gmail.com> 
 wrote:

 On Tuesday, 8 January 2013 at 09:59:26 UTC, Simen Kjaeraas 
 wrote:
  alias fun2 = fun!("++a", "--a");
  auto m = fun2!(ubyte)(1);
Nice! And now, for the 1M$ question: Can I rely on this behavior, or is this an accepts invalid...?
You can rely on it.
Thank you.
Jan 08 2013
prev sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Jan 8, 2013 at 10:58 AM, Simen Kjaeraas <simen.kjaras gmail.com>wrote:

    alias fun2 = fun!("++a", "--a");
Wait wait wait. Since when is this a valid alias syntax? Is that another Easter egg hidden in 2.061?
Jan 08 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 8 January 2013 at 16:56:05 UTC, Philippe Sigaud wrote:
 On Tue, Jan 8, 2013 at 10:58 AM, Simen Kjaeraas 
 <simen.kjaras gmail.com>wrote:

    alias fun2 = fun!("++a", "--a");
Wait wait wait. Since when is this a valid alias syntax? Is that another Easter egg hidden in 2.061?
Oh. New alias syntax. Nice ain't it? It works for everything except "alias something this". Not that it can't be done, but there were discussions for another syntax specific to alias this.
Jan 08 2013
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Jan 8, 2013 at 5:59 PM, monarch_dodra <monarchdodra gmail.com>wrote:

 Oh. New alias syntax. Nice ain't it?
Yes nice. Why was it not announced somewhere? At least, the grammar was updated: *AliasDeclaration*: *alias* *BasicType*<http://dlang.org/declaration.html#BasicType> *Declarator* <http://dlang.org/declaration.html#Declarator> *alias* * AliasInitializerList*<http://dlang.org/declaration.html#AliasInitializerList> *AliasInitializerList*: *AliasInitializer*<http://dlang.org/declaration.html#AliasInitializer> *AliasInitializer* <http://dlang.org/declaration.html#AliasInitializer> *,* *AliasInitializerList* *AliasInitializer*: *Identifier* *=* *Type<http://dlang.org/declaration.html#Type> * *AliasDeclaration*: *alias* *BasicType*<http://dlang.org/declaration.html#BasicType> *Declarator* <http://dlang.org/declaration.html#Declarator> *alias* * AliasInitializerList*<http://dlang.org/declaration.html#AliasInitializerList> *AliasInitializerList*: *AliasInitializer*<http://dlang.org/declaration.html#AliasInitializer> *AliasInitializer* <http://dlang.org/declaration.html#AliasInitializer> *,* *AliasInitializerList* *AliasInitializer*: *Identifier* *=* *Type*<http://dlang.org/declaration.html#Type> *AliasDeclaration*: *alias* *BasicType*<http://dlang.org/declaration.html#BasicType> *Declarator* <http://dlang.org/declaration.html#Declarator> *alias* * AliasInitializerList*<http://dlang.org/declaration.html#AliasInitializerList> *AliasInitializerList*: *AliasInitializer*<http://dlang.org/declaration.html#AliasInitializer> *AliasInitializer* <http://dlang.org/declaration.html#AliasInitializer> *,* *AliasInitializerList* *AliasInitializer*: *Identifier* *=* *Type*<http://dlang.org/declaration.html#Type> AliasDeclaration: alias BasicType Declarator alias AliasInitializerList AliasInitializerList: AliasInitializer AliasInitializer , AliasInitializerList AliasInitializer: Identifier = Type I'll have to update my grammar and generated parser. Hmm. Why the limitation to Type? The examples still all use the old syntax, but oh well.
 It works for everything except "alias something this". Not that it can't
 be done, but there were discussions for another syntax specific to alias
 this.
The grammar says: *AliasThisDeclaration*: *alias* *Identifier* *this* *alias* *this* *=* * Identifier* AliasThisDeclaration: alias Identifier this alias this = Identifier Nice nice nice.
Jan 08 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 8 January 2013 at 18:40:55 UTC, Philippe Sigaud wrote:
 On Tue, Jan 8, 2013 at 5:59 PM, monarch_dodra
 It works for everything except "alias something this". Not 
 that it can't
 be done, but there were discussions for another syntax 
 specific to alias
 this.
The grammar says: *AliasThisDeclaration*: *alias* *Identifier* *this* *alias* *this* *=* * Identifier* AliasThisDeclaration: alias Identifier this alias this = Identifier Nice nice nice.
Ah: There it is: https://github.com/D-Programming-Language/dmd/pull/1413 The plan was to kill it before it made it into 2.061, but I guess it made it. Anyways, the details are there if you want details. I don't know which way it'll go.
Jan 08 2013
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Jan 8, 2013 at 8:39 PM, monarch_dodra <monarchdodra gmail.com>wrote:

 Anyways, the details are there if you want details. I don't know which way
 it'll go.
OK. I'll wait for a stabilized syntax for alias this. But the new `alias newSym = oldSym;` is implemented, right?
Jan 08 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 8 January 2013 at 20:48:24 UTC, Philippe Sigaud wrote:
 On Tue, Jan 8, 2013 at 8:39 PM, monarch_dodra 
 <monarchdodra gmail.com>wrote:

 Anyways, the details are there if you want details. I don't 
 know which way
 it'll go.
OK. I'll wait for a stabilized syntax for alias this. But the new `alias newSym = oldSym;` is implemented, right?
Definitely.
Jan 08 2013
prev sibling parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Tuesday, 8 January 2013 at 20:48:24 UTC, Philippe Sigaud wrote:
 On Tue, Jan 8, 2013 at 8:39 PM, monarch_dodra wrote:
 Anyways, the details are there if you want details. I don't 
 know which way it'll go.
OK. I'll wait for a stabilized syntax for alias this. But the new `alias newSym = oldSym;` is implemented, right?
As far as I can tell, Yes. I'll still be using 'alias oldSym newSym;' for a long time most likely, unless there's a big reason to switch.
Jan 08 2013
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Jan 8, 2013 at 9:53 PM, Era Scarecrow <rtcvb32 yahoo.com> wrote:

 On Tuesday, 8 January 2013 at 20:48:24 UTC, Philippe Sigaud wrote:

  On Tue, Jan 8, 2013 at 8:39 PM, monarch_dodra wrote:

  Anyways, the details are there if you want details. I don't know which
 way it'll go.
OK. I'll wait for a stabilized syntax for alias this. But the new `alias newSym = oldSym;` is implemented, right?
As far as I can tell, Yes. I'll still be using 'alias oldSym newSym;' for a long time most likely, unless there's a big reason to switch.
When I stop D for a few weeks and come back to it, I'm sometimes confused as to which is the old symbol and which is the new one. For a declaration: type newSym = oldSym; is standard. alias nemSym = oldSym; will be easy to get used to
Jan 08 2013