Thread overview
IFTI - first impressions
Mar 08, 2006
Oskar Linde
Mar 08, 2006
Oskar Linde
Mar 09, 2006
Don Clugston
Mar 08, 2006
Sean Kelly
Mar 09, 2006
Oskar Linde
March 08, 2006
Hello,

With the new IFTI support, I just had to do some quick tests. It turns out it works perfectly given its limitations. I had to rewrite some templates to be more IFTI-friendly. One example:

Before:

template filter(T:T[]) {
	T[] filter(T[] arr, bool function func(T)) {
		...
	}
}

After:

template filter(ArrTy, FuncTy) {
	ArrTy filter(ArrTy arr, FunTy fun) {
		...
	}
}

With a simple map and filter template, the following code works:

const int[] data = [1,2,3,76,2,1,3,45,2];
writefln("data = ", data);

auto squared = map(data, function int(int x) { return x*x; });
writefln("squared = ", squared);

auto sqrooted = map(data, function double(int x) { return
sqrt(cast(float)x); });
writefln("sqrooted = ", sqrooted);

auto even = filter(data, function bool(int x) { return (x&1) == 0; });
writefln("even = ", even);

auto odd = filter(data, function bool(int x) { return (x&1) == 1; });
writefln("odd = ", odd);

And prints:

data = [1,2,3,76,2,1,3,45,2]
squared = [1,4,9,5776,4,1,9,2025,4]
sqrooted = [1,1.41421,1.73205,8.7178,1.41421,1,1.73205,6.7082,1.41421]
even = [2,76,2,2]
odd = [1,3,1,3,45]

In conclusion, I'm very pleased.
I've attached the full 50-line source code if anyone is interested.

/Oskar


March 08, 2006
Oskar Linde skrev:

> const int[] data = [1,2,3,76,2,1,3,45,2];
> writefln("data = ", data);
> 
> auto squared = map(data, function int(int x) { return x*x; });
> writefln("squared = ", squared);
> 
> auto sqrooted = map(data, function double(int x) { return sqrt(cast(float)x); });
> writefln("sqrooted = ", sqrooted);
> 
> auto even = filter(data, function bool(int x) { return (x&1) == 0; });
> writefln("even = ", even);
> 
> auto odd = filter(data, function bool(int x) { return (x&1) == 1; });
> writefln("odd = ", odd);

I just noticed that with implicit array member functions, you can even write the last one as:

auto odd = data.filter(function bool(int x) { return (x&1) == 1; });
writefln("odd = ", odd);

Isn't this even better?

You can also make a:

template stable_sort(ArrTy) {
	ArrTy stable_sort(ArrTy arr) {
		...
	}
}

and make a library alternative to the built in sort:

a.stable_sort();

The only difference to the built in sort is the tailing parenthesis. I wish we could get rid of those or force .sort to be called as .sort(). Then we could make .sort a pure library implementation together with other array functions.

/Oskar
March 08, 2006
Oskar Linde wrote:
> Hello,
> 
> With the new IFTI support, I just had to do some quick tests. It turns out it works perfectly given its limitations. I had to rewrite some templates to be more IFTI-friendly. One example:
> 
> Before:
> 
> template filter(T:T[]) {
>     T[] filter(T[] arr, bool function func(T)) {
>         ...
>     }
> }
> 
> After:
> 
> template filter(ArrTy, FuncTy) {
>     ArrTy filter(ArrTy arr, FunTy fun) {
>         ...
>     }
> }

This should only be a temporary measure.  Once IFTI matures a bit, your original function should work as expected.  In fact, the first form is necessary in some cases to make sure the proper overload is called.


Sean
March 09, 2006
Oskar Linde wrote:
> Oskar Linde skrev:
> 
>> const int[] data = [1,2,3,76,2,1,3,45,2];
>> writefln("data = ", data);
>>
>> auto squared = map(data, function int(int x) { return x*x; });
>> writefln("squared = ", squared);
>>
> 
> auto odd = data.filter(function bool(int x) { return (x&1) == 1; });
> writefln("odd = ", odd);
>

Nifty IFTI!
It makes sense to start writing D template libraries, now.
I'm looking forward to seeing what is produced.
March 09, 2006
Sean Kelly wrote:
> Oskar Linde wrote:
>> Hello,
>>
>> With the new IFTI support, I just had to do some quick tests. It turns out it works perfectly given its limitations. I had to rewrite some templates to be more IFTI-friendly. One example:
>>
>> Before:
>>
>> template filter(T:T[]) {
>>     T[] filter(T[] arr, bool function func(T)) {
>>         ...
>>     }
>> }
>>
>> After:
>>
>> template filter(ArrTy, FuncTy) {
>>     ArrTy filter(ArrTy arr, FunTy fun) {
>>         ...
>>     }
>> }
> 
> This should only be a temporary measure.  Once IFTI matures a bit, your original function should work as expected.  In fact, the first form is necessary in some cases to make sure the proper overload is called.

A quick way to make many cases of template specializations to work is to write a template wrapper function:

template func(A,B) {
	void func(A a, B b) {
		func_imp!(A,B)(a,b);
	}
}

But it doesn't cover all cases of course...

/Oskar