[Issue 6756] New: Idea about std.stdio.chunks and std.range.chunks
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sat Oct 1 18:52:12 PDT 2011
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 at puremagic.com
ReportedBy: bearophile_hugs at eml.cc
--- Comment #0 from bearophile_hugs at eml.cc 2011-10-01 18:51:32 PDT ---
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: -------
More information about the Digitalmars-d-bugs
mailing list