digitalmars.D.bugs - [Issue 6756] New: Idea about std.stdio.chunks and std.range.chunks
- d-bugmail puremagic.com (97/97) Oct 01 2011 http://d.puremagic.com/issues/show_bug.cgi?id=6756
http://d.puremagic.com/issues/show_bug.cgi?id=6756 Summary: Idea about std.stdio.chunks and std.range.chunks Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: bearophile_hugs eml.cc I'm finding the recently introduced std.range.chunks quite useful. In Mathematica there is a similar function (but not lazy and even too much powerful) named Partition: http://reference.wolfram.com/mathematica/ref/Partition.html Unfortunately the one in Phobos often causes a name collision in my code: import std.stdio, std.range; void main() { auto ch = chunks(iota(15), 2); writeln(ch); } It gives: test.d(3): Error: std.stdio.chunks at ...\dmd2\src\phobos\std\stdio.d(2038) conflicts with std.range.chunks(Source) at ...\dmd2\src\phobos\std\range.d(5261) So you have to write: import std.stdio, std.range; void main() { auto ch = std.range.chunks(iota(15), 2); writeln(ch); } std.stdio.chunks is a struct with this constructor: struct chunks { private File f; private size_t size; this(File f, size_t size) { ... While std.range.chunks is a helper function: Chunks!(Source) chunks(Source)(Source source, size_t chunkSize) { return typeof(return)(source, chunkSize); } That uses: struct Chunks(Source) if(hasSlicing!Source && hasLength!Source) { this(Source source, size_t chunkSize) { this._source = source; this._chunkSize = chunkSize; } ... } I think you never call std.range.chunks with a File as first argument. The cause of the problem is probably shown in this little test: struct Foo {} void bar(Foo x) {} void bar(T)(T x) if (!is(T == Foo)) {} //void bar(T)(T x) if (is(T == Foo)) {} void main() { bar([1, 2, 3]); bar(Foo()); } test.d(4): Error: template test.bar(T) if (!is(T == Foo)) conflicts with function test.bar at test.d(3) I don't know if in future DMD will allow overloading of functions with templates, but in the meantime a possible solution is to rename the std.stdio.chunks struct to a name that starts with upper case: struct Chunks { private File f; private size_t size; // private string fileName; // Currently, no use this(F f, size_t size) To introduce a lowercase little helper function template with a template constraint that the first template argument must be a File: Chunks chunks(F)(F f, size_t size) if (is(F == File)) { return Chunks(f, size); } (This doesn't cause a code bloat because std.stdio.range gets gets instantiated with only one type for the first argument, so it's like a single regular function.) And then to add a negative template constraint to std.range.chunks: Chunks!(Source) chunks(Source)(Source source, size_t chunkSize) if (!is(Source == File) && hasSlicing!Source && hasLength!Source) { return typeof(return)(source, chunkSize); } I think this solves the name collision problem. By the way, do you know why std.range.Chunks has a template constraint while its helper function std.range.chunks doesn't have it? Most times you call std.range.chunks. So if you call it with wrong arguments you receive a template error inside std.range instead in your code. This is not good. So I think std.range.chunks needs the same template constraint as std.range.Chunks (plus !is(Source == File) at the start if you accept the idea shown here). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 01 2011