www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - IFTI - first impressions

reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
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
Mar 08 2006
next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
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
Mar 08 2006
parent Don Clugston <dac nospam.com.au> writes:
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.
Mar 09 2006
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
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
Mar 08 2006
parent Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
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
Mar 09 2006