July 25, 2006
Wolfgang Draxinger skrev:
> Andrei Khropov wrote:
> 
>> Looks like we have only '@' symbol to use.
> 
> Looks nice, too.
>  
>> What you are talking about is actually more powerful
>> metaprogramming. I'm afraid it's postponed to D 2.0.
> 
> Sad, that would have made my engine's source code, especially in
> the renderer part a lot of shorter and readable.
> 
> But may I make a suggestion for D 1.0 here, that would at least
> allow usage as I have in mind, i.e. using template mixins as a
> stock function generator, by adding following rule to templates:
> 
> If a template only contains functions of the name of the
> template, and the function declarations adhere the overloading
> rules the template is a multifunction template.

Exactly this has been suggested several times before:

Eg:

http://www.digitalmars.com/d/archives/digitalmars/D/30234.html

and

http://www.digitalmars.com/d/archives/digitalmars/D/38389.html

It is a minor change, but would break existing code, so getting it before 1.0 would be preferred.

> Example:
> 
> template Foo (T, V, U)
> {
>         void Foo(T t,V v){...}
>         V    Foo(T t){...}
>         U    Foo(V v){...}
> };
> 
> mixin Foo!(int, bool, float) bar; // ok, no ambiguties
> 
> bar(1, 2.0);
> bool a = bar(2);
> float b = bar(true);
> 
> minxin Foo!(int, int, bool) foobar; // error: T and V conflict in
> // ambigue function parameters, that can't overload.
July 25, 2006
Oskar Linde wrote:

> It is a minor change, but would break existing code, so getting it before 1.0 would be preferred.

Could you give me an example of breakage? I don't see a reason (yet), why that would break something. I'd have said, that my suggestion is a superset of the old behaviour and backwards compatible, but seem's I was wrong.

Wolfgang Draxinger
-- 
E-Mail address works, Jabber: hexarith@jabber.org, ICQ: 134682867 GPG key FP: 2FC8 319E C7D7 1ADC 0408 65C6 05F5 A645 1FD3 BD3E
July 25, 2006
Wolfgang Draxinger skrev:
> Oskar Linde wrote:
> 
>> It is a minor change, but would break existing code, so getting
>> it before 1.0 would be preferred.
> 
> Could you give me an example of breakage? I don't see a reason
> (yet), why that would break something. I'd have said, that my
> suggestion is a superset of the old behaviour and backwards
> compatible, but seem's I was wrong.

Currently, when a template contains several functions, they are not implicit template properties and must be called as func!().func(...). If the proposed change was introduced, they would be required to be called as func!()(...). Example:

struct Foo { int foo; }

template foo() {
	Foo foo() { Foo r; return r; }
	Foo foo(int x) { Foo r; return r; }
}

void main() {
	auto x = foo!().foo;
	// with current behavior, typeof(x) == Foo,
	// with proposed behavior, typeof(x) == int.
}

I still think the change is worthwhile.

/Oskar
July 25, 2006
Oskar Linde skrev:
> Wolfgang Draxinger skrev:
>> Oskar Linde wrote:
>>
>>> It is a minor change, but would break existing code, so getting
>>> it before 1.0 would be preferred.
>>
>> Could you give me an example of breakage? I don't see a reason
>> (yet), why that would break something. I'd have said, that my
>> suggestion is a superset of the old behaviour and backwards
>> compatible, but seem's I was wrong.
> 
> Currently, when a template contains several functions, they are not implicit template properties and must be called as func!().func(...). If the proposed change was introduced, they would be required to be called as func!()(...). Example:

Another proposal that I made before in conjunction with the above is to make implicit template properties explicit via the /this/ keyword. It would work analogous to how /this/ is used to denote class constructors.

template myfunc(T) {
	T this() {...}
	T this(int x) {...}
	T this(double x) {...}
}

and:

template IsSomethingOrWhatever(T) {
	const this = ...;
}

The advantages would be that implicit template properties would become explicit. It would in many cases save some typing and leave only one instead of two places to update when a template is renamed. The somewhat dubious rule of special handling when the template and template member name are the same could be removed.

One could also imagine private template members in conjunction with implicit template properties. Something that isn't possible today:

template myfync(T) {
	private alias Something!(T) SomeType;

	SomeType this() { ... }
	SomeType this(int x) { ... }
	SomeType this(double x) { ... }
}

which would both improve readability and save typing. Not only for the case with several polymorphic template functions:

template foo(T1,T2) {
	private alias ALongExpression!(Involving!(T1).and!(T2)) RetType;

	RetType this(T1 a, T2 b) {
		RetType ret;
		...
		return ret;
	}
}

With todays templates, the above becomes less readable.

/this/ would be shadowed by locally defined classes, just like /this/ currently gets shadowed by inner classes.

/Oskar

July 25, 2006
Oskar Linde wrote:

> Another proposal that I made before in conjunction with the above is to make implicit template properties explicit via the /this/ keyword. It would work analogous to how /this/ is used to denote class constructors.

I like that, and it would be just logical.

Also I don't see a reason, why the multifunction template proposal would break existing code, if adding some rules: If such a template is instanciated "annonymously" and not used in an assignment, the local scope should be implicitly considerd the the L value of a "silent" assignment.

Example

template foo(T) {
        int foo(T){...}
        T foo(int){...}
}

foo!(bool);
foo!(float) bar;
auto fbr = foo!(char[]);
auto bfo = foo!(void*);

// typeof(foo(true))==int;
// typeof(foo(1))==bool;

// typeof(bar.foo(false))==int;
// typeof(bar.foo(0))==float;

// typeof(fbr.foo(""))==int;
// typeof(fbr.foo(2))==char[];

// typeof(bfp.foo(NULL))==int;
// typeof(bfp.foo(3))==void*;

However I'm not sure if that would be context free, but I think it probably is.

Wolfgang Draxinger
-- 
E-Mail address works, Jabber: hexarith@jabber.org, ICQ: 134682867 GPG key FP: 2FC8 319E C7D7 1ADC 0408 65C6 05F5 A645 1FD3 BD3E
July 25, 2006
Oskar Linde wrote:
> Oskar Linde skrev:
>> Wolfgang Draxinger skrev:
>>> Oskar Linde wrote:
>>>
>>>> It is a minor change, but would break existing code, so getting
>>>> it before 1.0 would be preferred.
>>>
>>> Could you give me an example of breakage? I don't see a reason
>>> (yet), why that would break something. I'd have said, that my
>>> suggestion is a superset of the old behaviour and backwards
>>> compatible, but seem's I was wrong.
>>
>> Currently, when a template contains several functions, they are not implicit template properties and must be called as func!().func(...). If the proposed change was introduced, they would be required to be called as func!()(...). Example:
> 
> Another proposal that I made before in conjunction with the above is to make implicit template properties explicit via the /this/ keyword. It would work analogous to how /this/ is used to denote class constructors.
> 
> template myfunc(T) {
>     T this() {...}
>     T this(int x) {...}
>     T this(double x) {...}
> }
> 
> and:
> 
> template IsSomethingOrWhatever(T) {
>     const this = ...;
> }

I like it.


Sean
July 25, 2006
Oskar Linde wrote:
> Wolfgang Draxinger skrev:
>> Andrei Khropov wrote:
>>
>>> Looks like we have only '@' symbol to use.
>>
>> Looks nice, too.
>>  
>>> What you are talking about is actually more powerful
>>> metaprogramming. I'm afraid it's postponed to D 2.0.
>>
>> Sad, that would have made my engine's source code, especially in
>> the renderer part a lot of shorter and readable.
>>
>> But may I make a suggestion for D 1.0 here, that would at least
>> allow usage as I have in mind, i.e. using template mixins as a
>> stock function generator, by adding following rule to templates:
>>
>> If a template only contains functions of the name of the
>> template, and the function declarations adhere the overloading
>> rules the template is a multifunction template.
> 
> Exactly this has been suggested several times before:
> 
> Eg:
> 
> http://www.digitalmars.com/d/archives/digitalmars/D/30234.html
> 
> and
> 
> http://www.digitalmars.com/d/archives/digitalmars/D/38389.html
> 
> It is a minor change, but would break existing code, so getting it before 1.0 would be preferred.

This may make IFTI much more achievable in the short-term, as overloading template functions basically doesn't work at all now.  I think mixing the two might be more complicated for the compiler to sort out:

template fn( T )
{
    void fn( T[] x ) {}
    void fn( T x ) {}
}

template fn( T : int[] )
{
    void fn( T[] x ) {}
}

template fn( T : int )
{
    void fn( T x ) {}
}

But I suppose that's up to Walter to decide.


Sean
July 25, 2006
Sean Kelly wrote:

> This may make IFTI much more achievable in the short-term, as overloading template functions basically doesn't work at all now.  I think mixing the two might be more complicated for the compiler to sort out:
> 
> template fn( T )
> {
>      void fn( T[] x ) {}
>      void fn( T x ) {}
> }
> 
> template fn( T : int[] )
> {
>      void fn( T[] x ) {}
> }
> 
> template fn( T : int )
> {
>      void fn( T x ) {}
> }

Umm, even me, being not a compiler, wouldn't know how to decide which of those templates to use. That's a highly ambiguos example of code and no sane compiler would process that.

Wolfgang Draxinger
-- 
E-Mail address works, Jabber: hexarith@jabber.org, ICQ: 134682867 GPG key FP: 2FC8 319E C7D7 1ADC 0408 65C6 05F5 A645 1FD3 BD3E
July 25, 2006
Wolfgang Draxinger wrote:
> Sean Kelly wrote:
> 
>> This may make IFTI much more achievable in the short-term, as
>> overloading template functions basically doesn't work at all
>> now.  I think mixing the two might be more complicated for the
>> compiler to sort out:
>>
>> template fn( T )
>> {
>>      void fn( T[] x ) {}
>>      void fn( T x ) {}
>> }
>>
>> template fn( T : int[] )
>> {
>>      void fn( T[] x ) {}
>> }
>>
>> template fn( T : int )
>> {
>>      void fn( T x ) {}
>> }
> 
> Umm, even me, being not a compiler, wouldn't know how to decide
> which of those templates to use. That's a highly ambiguos
> example of code and no sane compiler would process that.

It's perfectly legal.  Since the most specialized overload is chosen, the last two functions would be called for int arrays or int parameters, and the first two functions would be called for arrays and non-arrays otherwise.


Sean
July 25, 2006
Sean Kelly wrote:

> It's perfectly legal.  Since the most specialized overload is chosen, the last two functions would be called for int arrays or int parameters, and the first two functions would be called for arrays and non-arrays otherwise.

Didn't knew that. You never stop learning.

Wolfgang Draxinger
-- 
E-Mail address works, Jabber: hexarith@jabber.org, ICQ: 134682867 GPG key FP: 2FC8 319E C7D7 1ADC 0408 65C6 05F5 A645 1FD3 BD3E