www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 6756] New: Idea about std.stdio.chunks and std.range.chunks


           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

--- Comment #0 from bearophile_hugs 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:


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);

It gives:

test.d(3): Error: std.stdio.chunks at ...\dmd2\src\phobos\std\stdio.d(2038)
conflicts with std.range.chunks(Source) at

So you have to write:

import std.stdio, std.range;
void main() {
    auto ch = std.range.chunks(iota(15), 2);

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]);

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

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