Thread overview
Value-based function overloading - Three is Lucky
May 20, 2005
Nod
May 20, 2005
Kyle Furlong
May 20, 2005
Nod
May 20, 2005
It's that time again - value-based overloading part three is here. This time I touch on inner functions, classes, and templates.

Here are the first two drafts for reference:
1) http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/23796
2) http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/23897

/****************************************
* Inner functions
***/
Inner scopes relates to outer scopes in the same way that the base module
relates to an imported module (see draft 2). Value-based overloads are allowed,
and one can override a function in an outer scope by using the override keyword.
If no original function is found in the immediately enclosing scope, the next
enclosing scope is searched.

This is useful when debugging, as it enables us to: wrap an outer function, for only specific values, in only the current block of code, touching neither the function nor the function invocations. In the wrapper, one may wish to print a message, alter the parameters, or somesuch.

Example:
:void foo(char c) { ... }
:int main()
:{
:  override void foo(char c in "@#%")
:  {
:    printf("Invalid char %c\n", c);
:    .foo(c);  // call outer
:  }
:  /++ ... lots of foo invocations here ... ++/
:}

Without the override keyword only the current scope is searched for overloads.

/****************************************
* Classes
***/
In classes we find a symbol clash due to me using the override keyword for my
own mischievous purposes *snigger*. Astonishingly however, my definition of the
keyword fits perfectly, and won't even break old code. As I am making this up as
I write, this was utterly surprising :)

So once again, derived classes relates to its base class in the same way that a base module relates to its imported module (see draft 2). Hmm... Nice consistency here. Neat.

Any class method may be value-overloaded. Constructors too.

/****************************************
* Templates
***/
Both types and ranges can be used in templates.

Example:
:template TFoo (T, R) { foo(T in R) { ... } }
:int main()
:{
:  TFoo bar = new TFoo!(int, 0..10);  // legal
:  TFoo baz = new TFoo!(char[], ["fi","fy","fo"]);  // legal
:  TFoo bah = new TFoo!(char[], 0..10);  // kaputt
:  bar.foo(5);  // legal
:  bar.foo(15);  // illegal
:  baz.foo("fo");  // legal
:  baz.foo("fum");  // illegal
:}

My mind cannot find a use for this. Maybe it can be used as some kind of algorithm factory? It looks rather snazzy though - clearly belongs in a 21st century programming language :)

Value-based template specialization:
On a related but technically different note, value-based overloading extends
also to the specialization of templates. It should probably be called
value-based template specialization in this context.

Example:
:template TFoo (T, int Size in 0..256) { ... }
:template TFoo (T, int Size in 256..int.max) { ... }
:int main()
:{
:  TFoo foo = new TFoo!(double, 8192);  // instanciates the second one
:}

This makes it possible, for example, to use different data structure templates for different data sizes, and also to add further optimized versions without touching any code which uses the template.

/****************************************
* Phew.
***/
I am starting to think that the working name of this feature isn't general
enough. Perhaps "implicit flow control" would be more suiting. Ah well.

Feel free to sanitize, scrutinize or vandalize the above ideas at your leisure. -Nod-


May 20, 2005
Nod wrote:
> It's that time again - value-based overloading part three is here. This time I
> touch on inner functions, classes, and templates.
> 
> Here are the first two drafts for reference:
> 1) http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/23796
> 2) http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/23897
> 
> /****************************************
> * Inner functions
> ***/
> Inner scopes relates to outer scopes in the same way that the base module
> relates to an imported module (see draft 2). Value-based overloads are allowed,
> and one can override a function in an outer scope by using the override keyword.
> If no original function is found in the immediately enclosing scope, the next
> enclosing scope is searched.
> 
> This is useful when debugging, as it enables us to: wrap an outer function, for
> only specific values, in only the current block of code, touching neither the
> function nor the function invocations. In the wrapper, one may wish to print a
> message, alter the parameters, or somesuch.
> 
> Example:
> :void foo(char c) { ... }
> :int main()
> :{
> :  override void foo(char c in "@#%")
> :  {
> :    printf("Invalid char %c\n", c);
> :    .foo(c);  // call outer :  }
> :  /++ ... lots of foo invocations here ... ++/
> :}
> 
> Without the override keyword only the current scope is searched for overloads.
> 
> /****************************************
> * Classes
> ***/
> In classes we find a symbol clash due to me using the override keyword for my
> own mischievous purposes *snigger*. Astonishingly however, my definition of the
> keyword fits perfectly, and won't even break old code. As I am making this up as
> I write, this was utterly surprising :)
> 
> So once again, derived classes relates to its base class in the same way that a
> base module relates to its imported module (see draft 2). Hmm... Nice
> consistency here. Neat.
> 
> Any class method may be value-overloaded. Constructors too.
> 
> /****************************************
> * Templates
> ***/
> Both types and ranges can be used in templates.
> 
> Example:
> :template TFoo (T, R) { foo(T in R) { ... } }
> :int main()
> :{
> :  TFoo bar = new TFoo!(int, 0..10);  // legal
> :  TFoo baz = new TFoo!(char[], ["fi","fy","fo"]);  // legal
> :  TFoo bah = new TFoo!(char[], 0..10);  // kaputt
> :  bar.foo(5);  // legal
> :  bar.foo(15);  // illegal
> :  baz.foo("fo");  // legal
> :  baz.foo("fum");  // illegal
> :}
> 
> My mind cannot find a use for this. Maybe it can be used as some kind of
> algorithm factory? It looks rather snazzy though - clearly belongs in a 21st
> century programming language :)
> 
> Value-based template specialization:
> On a related but technically different note, value-based overloading extends
> also to the specialization of templates. It should probably be called
> value-based template specialization in this context.
> 
> Example:
> :template TFoo (T, int Size in 0..256) { ... }
> :template TFoo (T, int Size in 256..int.max) { ... }
> :int main()
> :{
> :  TFoo foo = new TFoo!(double, 8192);  // instanciates the second one
> :}
> 
> This makes it possible, for example, to use different data structure templates
> for different data sizes, and also to add further optimized versions without
> touching any code which uses the template.
> 
> /****************************************
> * Phew.
> ***/
> I am starting to think that the working name of this feature isn't general
> enough. Perhaps "implicit flow control" would be more suiting. Ah well.
> 
> Feel free to sanitize, scrutinize or vandalize the above ideas at your leisure.
> -Nod-
> 
> 

Very good work again Nod, looks like a sure thing, as soon as we get Walter's opinion.
May 20, 2005
In article <d6k0iv$abp$1@digitaldaemon.com>, Kyle Furlong says...
>
>>
>> <snip>
>> 
>
>Very good work again Nod, looks like a sure thing, as soon as we get Walter's opinion.

Thanks!

I wouldn't be so sure though. Implementation and philosophical details are so far sorely lacking from the drafts. Mostly because I can't speak on those topics with very much authority. Ho hum. The hammer of Walter is pending.

-Nod-