www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Value-based function overloading - Three is Lucky

reply Nod <Nod_member pathlink.com> writes:
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()
:{

:  {
:    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 19 2005
parent reply Kyle Furlong <ky220 umail.ucsb.edu> writes:
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()
 :{

 :  {
 :    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 19 2005
parent Nod <Nod_member pathlink.com> writes:
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-
May 20 2005