Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
July 20, 2004 Filter composition is here. :-) | ||||
---|---|---|---|---|
| ||||
Just wanted to let the faithful (and the faithless) know that I'm getting there. I've just got the following code to compile: foreach(int i; cont.select1!(DivisibleBy)(new DivisibleBy(3)).reject(&isEven)) { printf("%d ", i); } printf("\n"); yielding: -9 -3 3 9 from a List containing [-20, 20) DivisibleBy is a functor, and isEven is a plain function |
July 20, 2004 Re: Filter composition is here. :-) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | Hmm, just had an idea. Can I use a class (static) opCall on a functor to create it, without clashing with the member (non-static) opCall? It's only a small saving, but it'd trim cont.select1!(DivisibleBy)(new DivisibleBy(3)).reject(&isEven)) down to cont.select1!(DivisibleBy)(DivisibleBy(3)).reject(&isEven)) Ah, if only we have implicit instantiation ... ;) "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:cdi01n$vo4$1@digitaldaemon.com... > Just wanted to let the faithful (and the faithless) know that I'm getting there. I've just got the following code to compile: > > foreach(int i; cont.select1!(DivisibleBy)(new > DivisibleBy(3)).reject(&isEven)) > { > printf("%d ", i); > } > printf("\n"); > > yielding: > > -9 -3 3 9 > > from a List containing [-20, 20) > > DivisibleBy is a functor, and isEven is a plain function > > |
July 20, 2004 Re: Filter composition is here. :-) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | Is there a description/spec somewhere for select, reject, etc? What are the use cases? What are the advantages/disadvantages of using them as opposed to foreach(int i, cont) { if (!isEven(i) && (i%3 == 0)) printf("%d ",i); } If these things are delaying the rest of DTL and they are driving fairly big compiler changes I'd like to know more about them. Call me a party-pooper but I'm not convinced right now that they are that big of a deal. Personally I find the basic foreach to be much more readable. "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:cdi01n$vo4$1@digitaldaemon.com... > Just wanted to let the faithful (and the faithless) know that I'm getting there. I've just got the following code to compile: > > foreach(int i; cont.select1!(DivisibleBy)(new > DivisibleBy(3)).reject(&isEven)) > { > printf("%d ", i); > } > printf("\n"); > > yielding: > > -9 -3 3 9 > > from a List containing [-20, 20) > > DivisibleBy is a functor, and isEven is a plain function > > |
July 20, 2004 Re: Filter composition is here. :-) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | In article <cdj7b4$1h6f$1@digitaldaemon.com>, Ben Hinkle says... > >Is there a description/spec somewhere for select, reject, etc? What are the use cases? What are the advantages/disadvantages of using them as opposed to > foreach(int i, cont) { > if (!isEven(i) && (i%3 == 0)) > printf("%d ",i); > } >If these things are delaying the rest of DTL and they are driving fairly big compiler changes I'd like to know more about them. Call me a party-pooper but I'm not convinced right now that they are that big of a deal. Personally I find the basic foreach to be much more readable. It might actually be kind of nice if we could do something like this: int main() { int[char[]] map; map["a"] = 1; map["b"] = 2; map["c"] = 3; foreach( int value; map["a".."b"] ) { printf( "%d\n", value ); } return 0; } The opSlice extension would largely remove the need for this select() method. Sean |
July 20, 2004 Re: Filter composition is here. :-) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | "Sean Kelly" <sean@f4.ca> wrote in message news:cdjgfc$1li3$1@digitaldaemon.com... > In article <cdj7b4$1h6f$1@digitaldaemon.com>, Ben Hinkle says... > > > >Is there a description/spec somewhere for select, reject, etc? What are the > >use cases? What are the advantages/disadvantages of using them as opposed to > > foreach(int i, cont) { > > if (!isEven(i) && (i%3 == 0)) > > printf("%d ",i); > > } > >If these things are delaying the rest of DTL and they are driving fairly big > >compiler changes I'd like to know more about them. Call me a party-pooper but I'm not convinced right now that they are that big of a deal. Personally > >I find the basic foreach to be much more readable. > > It might actually be kind of nice if we could do something like this: > > int main() > { > int[char[]] map; > map["a"] = 1; > map["b"] = 2; > map["c"] = 3; > foreach( int value; map["a".."b"] ) > { > printf( "%d\n", value ); > } > return 0; > } > > The opSlice extension would largely remove the need for this select() method. > > > Sean Associative arrays don't have any defined ordering to the entries - which I assume is what you are requesting. Using the C++ terminology a "map" is a sorted associative array. In the "minimal template library" I just started your code would work fine if map is declared as type Map!(char[].int) instead of int[char[]]. Eventually I'd also like to add the equivalent to Java's LinkedHashMap, which is a hashtable that uses the insertion order for slicing and foreach (the usual Map implementation use trees which have O(log(n)) behavior instead of a hashtable's O(1)). One wrinkle about slicing with keys: the slice includes the last key. This contrasts with the usual D array slicing behavior where x[1..5] doesn't include x[5] in the slice. So your example above would print 1 and 2. I went with this behavior since 1) it would be a pain for users to have to get the next key after the last one in the slice and 2) what is the key that means "one after the last key in the map?" For slicing Lists and Maps I went with the rule that any integer slicing uses the regular D style of excluding the right endpoint but for non-integer slicing it includes the right endpoint. |
July 20, 2004 Re: Filter composition is here. :-) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | In article <cdjmbj$1o2i$1@digitaldaemon.com>, Ben Hinkle says... > > >"Sean Kelly" <sean@f4.ca> wrote in message news:cdjgfc$1li3$1@digitaldaemon.com... >> In article <cdj7b4$1h6f$1@digitaldaemon.com>, Ben Hinkle says... >> > >> >Is there a description/spec somewhere for select, reject, etc? What are >the >> >use cases? What are the advantages/disadvantages of using them as opposed >to >> > foreach(int i, cont) { >> > if (!isEven(i) && (i%3 == 0)) >> > printf("%d ",i); >> > } >> >If these things are delaying the rest of DTL and they are driving fairly >big >> >compiler changes I'd like to know more about them. Call me a party-pooper but I'm not convinced right now that they are that big of a deal. >Personally >> >I find the basic foreach to be much more readable. >> >> It might actually be kind of nice if we could do something like this: >> >> int main() >> { >> int[char[]] map; >> map["a"] = 1; >> map["b"] = 2; >> map["c"] = 3; >> foreach( int value; map["a".."b"] ) >> { >> printf( "%d\n", value ); >> } >> return 0; >> } >> >> The opSlice extension would largely remove the need for this select() >method. >> >> >> Sean > >Associative arrays don't have any defined ordering to the entries - which I assume is what you are requesting. Using the C++ terminology a "map" is a sorted associative array. In the "minimal template library" I just started your code would work fine if map is declared as type Map!(char[].int) instead of int[char[]]. Yup. I had thought that the implementation might be something like: int[] opSlice( char[] from, char[] to ) { char[] keys = map.keys; keys.sort(); // binary search for 'from' // binary search for 'to' // construct and return the requested range [from..to] } The obvious problem is that the range wouldn't be a slice of the actual map, but rather a copy. And sadly, I can't think of an easy way around this. >One wrinkle about slicing with keys: the slice includes the last key. This contrasts with the usual D array slicing behavior where x[1..5] doesn't include x[5] in the slice. So your example above would print 1 and 2. Good point. And there's no easy way around this for associative arrays. >I went with this behavior since >1) it would be a pain for users to have to get the next key after the last >one in the slice and >2) what is the key that means "one after the last key in the map?" Yup. Without begin and end properties we're kind of stuck in this regard. And I guess since the built-in contaners are really hash maps, asking for a sorted range is kind of silly anyway. And I suppose we could get away with something like this for a tree-based map: class Map { size_t length(); key_type key( int pos ); value_type value( int pos ); value_type[] opSlice( int b, int e ); } Thus faking it a bit by using indexes as iterators. Sean |
July 20, 2004 Re: Filter composition is here. :-) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | > Yup. I had thought that the implementation might be something like: > > int[] opSlice( char[] from, char[] to ) > { > char[] keys = map.keys; > keys.sort(); > // binary search for 'from' > // binary search for 'to' > // construct and return the requested range [from..to] > } > > The obvious problem is that the range wouldn't be a slice of the actual map, but > rather a copy. And sadly, I can't think of an easy way around this. Actually as I have it now the slice of a Map!(K,V) has type Map!(K,V). A Map has a pointer to the root, a left and right node pointer and a compare function. This is a pretty big struct but I think it is worth it. The relevant parts of Map are: struct Map(K,V) { Node!(K,V) root, begin, end; CompareFcn cmp; Map opSlice(K a, K b) { Map res; ... look up the node for a and b and fill in res ... return res; } int opApply(int delegate(inout V val) dg) { ... loop from this.begin to this.end (with null checks) and apply dg ... } } I also have opSlice and opIndex with integer indices but it is slower since to find the Nth node it crawls over the tree from left to right. > >One wrinkle about slicing with keys: the slice includes the last key. This > >contrasts with the usual D array slicing behavior where x[1..5] doesn't include x[5] in the slice. So your example above would print 1 and 2. > > Good point. And there's no easy way around this for associative arrays. > > >I went with this behavior since > >1) it would be a pain for users to have to get the next key after the last > >one in the slice and > >2) what is the key that means "one after the last key in the map?" > > Yup. Without begin and end properties we're kind of stuck in this regard. And > I guess since the built-in contaners are really hash maps, asking for a sorted > range is kind of silly anyway. And I suppose we could get away with something > like this for a tree-based map: > > class Map { > size_t length(); > key_type key( int pos ); > value_type value( int pos ); > value_type[] opSlice( int b, int e ); > } > > Thus faking it a bit by using indexes as iterators. > > > Sean > > |
July 30, 2004 Re: Filter composition is here. :-) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:cdj7b4$1h6f$1@digitaldaemon.com... > Is there a description/spec somewhere for select, reject, etc? What are the > use cases? What are the advantages/disadvantages of using them as opposed to > foreach(int i, cont) { > if (!isEven(i) && (i%3 == 0)) > printf("%d ",i); > } I've borrowed the terminology from Ruby. I don't really care what they're called in the long run, just using them for now. > If these things are delaying the rest of DTL and they are driving fairly big compiler changes I'd like to know more about them. Call me a party-pooper but I'm not convinced right now that they are that big of a deal. Personally I find the basic foreach to be much more readable. You're right, and I intend to release 0.1 with minimal bells and whistles this weekend. > > "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:cdi01n$vo4$1@digitaldaemon.com... > > Just wanted to let the faithful (and the faithless) know that I'm getting there. I've just got the following code to compile: > > > > foreach(int i; cont.select1!(DivisibleBy)(new > > DivisibleBy(3)).reject(&isEven)) > > { > > printf("%d ", i); > > } > > printf("\n"); > > > > yielding: > > > > -9 -3 3 9 > > > > from a List containing [-20, 20) > > > > DivisibleBy is a functor, and isEven is a plain function > > > > > > |
Copyright © 1999-2021 by the D Language Foundation