Jump to page: 1 2
Thread overview
Map and arrays
Nov 28, 2010
Tom
Nov 28, 2010
Jonathan M Davis
Nov 28, 2010
Tom
Nov 28, 2010
bearophile
Nov 28, 2010
Jonathan M Davis
Nov 29, 2010
Tom
Nov 29, 2010
Jonathan M Davis
Nov 29, 2010
Tom
Nov 29, 2010
Jonathan M Davis
Nov 28, 2010
bearophile
Nov 28, 2010
spir
Nov 28, 2010
Tom
November 28, 2010
Hi,

I wonder how to solve this kind of stuff...

void foo(string[] sarray) {
    // do something with sarray
}

void bar(int[] iarray) {
    auto sarray = map!(to!string)(iarray);
    foo(sarray);
}

And get...

foo (string[] sarray) is not callable using argument types (Map!(to,int[]))

What should I do? Is there some way to get the original array type?

Thanks in advance,
Tom;
November 28, 2010
On Saturday 27 November 2010 22:48:28 Tom wrote:
> Hi,
> 
> I wonder how to solve this kind of stuff...
> 
> void foo(string[] sarray) {
>      // do something with sarray
> }
> 
> void bar(int[] iarray) {
>      auto sarray = map!(to!string)(iarray);
>      foo(sarray);
> }
> 
> And get...
> 
> foo (string[] sarray) is not callable using argument types (Map!(to,int[]))
> 
> What should I do? Is there some way to get the original array type?

Many functions in std.algorithm return range types specific to that function. A number of these do lazy evaluation, so the actual work of the function is done when iterating over the resulting range. map happens to be one of those.

For all such functions, if you want an array out of the deal, what you do is pass the result to std.array.array(). That will take an arbitrary range and return its contents as an array - which also forces the processing of the range in the case of lazy evaluation like you get with map. So, if you want to delay the evaluation at all, or if it's really only go to make sense that some of the range be processed, you may not want to actually put it in an array. The combination of auto and templates can avoid making you actually turn it into an array in many cases. But if you do want an array, std.array.array() is what you're looking for.

- Jonathan M Davis
November 28, 2010
Tom:

> What should I do? Is there some way to get the original array type?

This code shows two ways to solve your problem:


import std.stdio: writeln;
import std.algorithm: map;
import std.conv: to;
import std.traits: ForeachType;
import std.array: array;

void foo(Range)(Range srange) if (is(ForeachType!Range == string)) {
     writeln(srange);
}

void bar(string[] sarray) {
     writeln(sarray);
}

void main() {
    int[] arr = [1, 2, 3];
    auto srange = map!(to!string)(arr);
    foo(srange);
    string[] sarr = array(srange);
    bar(sarr);
}


They are good for different purposes, but in many cases the foo() version is good.

If you want to simplify your code a little you may define a helper template like this:

template IsIterableType(Range, T) {
    enum bool IsIterableType = is(ForeachType!Range == T);
}

void foo2(Range)(Range srange) if (IsIterableType!(Range, string)) {
     writeln(srange);
}

Bye,
bearophile
November 28, 2010
On Sun, 28 Nov 2010 06:19:00 -0500
bearophile <bearophileHUGS@lycos.com> wrote:

> Tom:
> 
> > What should I do? Is there some way to get the original array type?
> [...]
> void foo(Range)(Range srange) if (is(ForeachType!Range == string)) {
>      writeln(srange);
> }
> [...]
> If you want to simplify your code a little you may define a helper template like this:
> 
> template IsIterableType(Range, T) {
>     enum bool IsIterableType = is(ForeachType!Range == T);
> }
> 
> void foo2(Range)(Range srange) if (IsIterableType!(Range, string)) {
>      writeln(srange);
> }

I was just thinking that all the complication about is() (or un-intuitiveness) may be replaced by a proper use of interfaces. Possibly with a simple operator like 'isa'. Maybe:
void foo2(Range)(Range srange) if (Range isa Iterable(string)) {
     writeln(srange);
}
or in this case
void foo2(Range!T)(Range!T srange) if (T == string && Range isa Iterable) {
     writeln(srange);
}
...which is a bit strange because Range exists precisely to be iterable (so that "Range isa Iterable" is nearly synonym of "Range isa Range"), so this may reduce to
void foo2(Range!T)(Range!T srange) if (T == string) {
     writeln(srange);
}

(Sure, we may find better idioms.)
After all, isn't the whole point of interfaces to tell that a given type has a given capability?

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

November 28, 2010
El 28/11/2010 04:11, Jonathan M Davis escribió:
> On Saturday 27 November 2010 22:48:28 Tom wrote:
>> Hi,
>>
>> I wonder how to solve this kind of stuff...
>>
>> void foo(string[] sarray) {
>>       // do something with sarray
>> }
>>
>> void bar(int[] iarray) {
>>       auto sarray = map!(to!string)(iarray);
>>       foo(sarray);
>> }
>>
>> And get...
>>
>> foo (string[] sarray) is not callable using argument types (Map!(to,int[]))
>>
>> What should I do? Is there some way to get the original array type?
>
> Many functions in std.algorithm return range types specific to that function. A
> number of these do lazy evaluation, so the actual work of the function is done
> when iterating over the resulting range. map happens to be one of those.
>
> For all such functions, if you want an array out of the deal, what you do is
> pass the result to std.array.array(). That will take an arbitrary range and
> return its contents as an array - which also forces the processing of the range
> in the case of lazy evaluation like you get with map. So, if you want to delay
> the evaluation at all, or if it's really only go to make sense that some of the
> range be processed, you may not want to actually put it in an array. The
> combination of auto and templates can avoid making you actually turn it into an
> array in many cases. But if you do want an array, std.array.array() is what
> you're looking for.
>
> - Jonathan M Davis

Thank you very much.

Is there some documentation (besides digitalmars ddoc's, which I find very chaotic for a starting point) that explains these structures, when to use them (instead of arrays), and how they interact with arrays? It's very difficult to find that kind of documentation, if there's such.

Also I wish to point out that the layout and presentation of some of phobos ddoc pages are, IMHO and as I said before, a little bit of a mess. Wish they could look more like javadoc, or at least more organized.

Kind regards.
Tom;



November 28, 2010
El 28/11/2010 08:19, bearophile escribió:
> Tom:
>
>> What should I do? Is there some way to get the original array type?
>
> This code shows two ways to solve your problem:
>
>
> import std.stdio: writeln;
> import std.algorithm: map;
> import std.conv: to;
> import std.traits: ForeachType;
> import std.array: array;
>
> void foo(Range)(Range srange) if (is(ForeachType!Range == string)) {
>       writeln(srange);
> }
>
> void bar(string[] sarray) {
>       writeln(sarray);
> }
>
> void main() {
>      int[] arr = [1, 2, 3];
>      auto srange = map!(to!string)(arr);
>      foo(srange);
>      string[] sarr = array(srange);
>      bar(sarr);
> }
>
>
> They are good for different purposes, but in many cases the foo() version is good.
>
> If you want to simplify your code a little you may define a helper template like this:
>
> template IsIterableType(Range, T) {
>      enum bool IsIterableType = is(ForeachType!Range == T);
> }
>
> void foo2(Range)(Range srange) if (IsIterableType!(Range, string)) {
>       writeln(srange);
> }
>
> Bye,
> bearophile

Thank's, I'll take a look...

Tom;
November 28, 2010
Tom:

> Also I wish to point out that the layout and presentation of some of phobos ddoc pages are, IMHO and as I said before, a little bit of a mess. Wish they could look more like javadoc, or at least more organized.

D docs will surely need improvements, but I don't think they will look like javadoc because Walter follows the typical engineering principle of "brutal simplicity" :-)

Bye,
bearophile
November 28, 2010
On Sunday 28 November 2010 11:37:26 Tom wrote:
> El 28/11/2010 04:11, Jonathan M Davis escribió:
> > On Saturday 27 November 2010 22:48:28 Tom wrote:
> >> Hi,
> >> 
> >> I wonder how to solve this kind of stuff...
> >> 
> >> void foo(string[] sarray) {
> >> 
> >>       // do something with sarray
> >> 
> >> }
> >> 
> >> void bar(int[] iarray) {
> >> 
> >>       auto sarray = map!(to!string)(iarray);
> >>       foo(sarray);
> >> 
> >> }
> >> 
> >> And get...
> >> 
> >> foo (string[] sarray) is not callable using argument types
> >> (Map!(to,int[]))
> >> 
> >> What should I do? Is there some way to get the original array type?
> > 
> > Many functions in std.algorithm return range types specific to that function. A number of these do lazy evaluation, so the actual work of the function is done when iterating over the resulting range. map happens to be one of those.
> > 
> > For all such functions, if you want an array out of the deal, what you do is pass the result to std.array.array(). That will take an arbitrary range and return its contents as an array - which also forces the processing of the range in the case of lazy evaluation like you get with map. So, if you want to delay the evaluation at all, or if it's really only go to make sense that some of the range be processed, you may not want to actually put it in an array. The combination of auto and templates can avoid making you actually turn it into an array in many cases. But if you do want an array, std.array.array() is what you're looking for.
> > 
> > - Jonathan M Davis
> 
> Thank you very much.
> 
> Is there some documentation (besides digitalmars ddoc's, which I find very chaotic for a starting point) that explains these structures, when to use them (instead of arrays), and how they interact with arrays? It's very difficult to find that kind of documentation, if there's such.

Typically the point is _not_ to care about them. You use auto, so you don't care what the type actually is. If you want to pass them to a function, you have it be a templated function. Perhaps it has a template constraint to verify that the range is a particular type of range (such as std.range.isForwardRange!()) rather than a totally arbitrary type, but you're not supposed to have to care that map returns a Map object. Heck, exactly what type of range it is depends on what type of range the one you gave to map was (e.g. if you gave map a random access range - such as an array - than map returns a version of Map which is random access range, whereas if you fed it a range which isn't a random access range, then it isn't a random access range). You're not supposed to have to care. So, to some extent at least, the documentation tries to bury it (which is definitely better than telling you all of its gory details which is more along the lines of what it did in the past).

If you want to know what the return type of a function is, use typeof. And if you _really_ want to know what that return type actually looks like, then you need to look at the source code (which would be in dmd2/src/phobos/std/algorithm.d in the after you unzip the dmd zip file). But you're just not supposed to have to care. I'm sure that the documentation could be improved, but it is better than it used to be, and auto removes most of the need to worry about what the exact type a return value is.

> Also I wish to point out that the layout and presentation of some of phobos ddoc pages are, IMHO and as I said before, a little bit of a mess. Wish they could look more like javadoc, or at least more organized.

It's better than it used to be. I'm sure that it will improve more in the future. But there are higher priorities (like bug fixing), so it's not something that's likely to happen right away - certainly not massive change. I don't expect that it will ever look quite like javadoc does, but it should be getting better eventually. In theory, ddoc output can be made to look like pretty much anything (javadoc included) - and what's up on the site is definitely better than what you get by default - but that means that someone has to do the work to make it look like whatever looks really good (which is one of those things which is highly subjective). It's improving, but slowly.

- Jonathan M Davis
November 29, 2010
El 28/11/2010 20:37, Jonathan M Davis escribió:
> On Sunday 28 November 2010 11:37:26 Tom wrote:
>> El 28/11/2010 04:11, Jonathan M Davis escribió:
>>> On Saturday 27 November 2010 22:48:28 Tom wrote:
>>>> Hi,
>>>>
>>>> I wonder how to solve this kind of stuff...
>>>>
>>>> void foo(string[] sarray) {
>>>>
>>>>        // do something with sarray
>>>>
>>>> }
>>>>
>>>> void bar(int[] iarray) {
>>>>
>>>>        auto sarray = map!(to!string)(iarray);
>>>>        foo(sarray);
>>>>
>>>> }
>>>>
>>>> And get...
>>>>
>>>> foo (string[] sarray) is not callable using argument types
>>>> (Map!(to,int[]))
>>>>
>>>> What should I do? Is there some way to get the original array type?
>>>
>>> Many functions in std.algorithm return range types specific to that
>>> function. A number of these do lazy evaluation, so the actual work of
>>> the function is done when iterating over the resulting range. map
>>> happens to be one of those.
>>>
>>> For all such functions, if you want an array out of the deal, what you do
>>> is pass the result to std.array.array(). That will take an arbitrary
>>> range and return its contents as an array - which also forces the
>>> processing of the range in the case of lazy evaluation like you get with
>>> map. So, if you want to delay the evaluation at all, or if it's really
>>> only go to make sense that some of the range be processed, you may not
>>> want to actually put it in an array. The combination of auto and
>>> templates can avoid making you actually turn it into an array in many
>>> cases. But if you do want an array, std.array.array() is what you're
>>> looking for.
>>>
>>> - Jonathan M Davis
>>
>> Thank you very much.
>>
>> Is there some documentation (besides digitalmars ddoc's, which I find
>> very chaotic for a starting point) that explains these structures, when
>> to use them (instead of arrays), and how they interact with arrays? It's
>> very difficult to find that kind of documentation, if there's such.
>
> Typically the point is _not_ to care about them. You use auto, so you don't care
> what the type actually is. If you want to pass them to a function, you have it
> be a templated function. Perhaps it has a template constraint to verify that the
> range is a particular type of range (such as std.range.isForwardRange!()) rather
> than a totally arbitrary type, but you're not supposed to have to care that map
> returns a Map object. Heck, exactly what type of range it is depends on what
> type of range the one you gave to map was (e.g. if you gave map a random access
> range - such as an array - than map returns a version of Map which is random
> access range, whereas if you fed it a range which isn't a random access range,
> then it isn't a random access range). You're not supposed to have to care. So,
> to some extent at least, the documentation tries to bury it (which is definitely
> better than telling you all of its gory details which is more along the lines of
> what it did in the past).
>
> If you want to know what the return type of a function is, use typeof. And if
> you _really_ want to know what that return type actually looks like, then you
> need to look at the source code (which would be in
> dmd2/src/phobos/std/algorithm.d in the after you unzip the dmd zip file). But
> you're just not supposed to have to care. I'm sure that the documentation could
> be improved, but it is better than it used to be, and auto removes most of the
> need to worry about what the exact type a return value is.
>
>> Also I wish to point out that the layout and presentation of some of
>> phobos ddoc pages are, IMHO and as I said before, a little bit of a
>> mess. Wish they could look more like javadoc, or at least more organized.
>
> It's better than it used to be. I'm sure that it will improve more in the
> future. But there are higher priorities (like bug fixing), so it's not something
> that's likely to happen right away - certainly not massive change. I don't
> expect that it will ever look quite like javadoc does, but it should be getting
> better eventually. In theory, ddoc output can be made to look like pretty much
> anything (javadoc included) - and what's up on the site is definitely better than
> what you get by default - but that means that someone has to do the work to make
> it look like whatever looks really good (which is one of those things which is
> highly subjective). It's improving, but slowly.
>
> - Jonathan M Davis

I'm not criticizing ddoc color or fonts. I mean, for example, in the index of symbols at the beginning of every ddoc page, there are functions, constants, classes, and templates, all mixed and each next to the other. It doesn't even have an alphabetic ordering. It was difficult to me at first sight to understand where to look for things. Maybe it's not that important as bugfixes, but when new programmers get close to D2 (even old D1 fans, like myself), I'm afraid that more than one could feel some frustration.

Tom;


November 29, 2010
On Sunday 28 November 2010 19:53:36 Tom wrote:
> I'm not criticizing ddoc color or fonts. I mean, for example, in the index of symbols at the beginning of every ddoc page, there are functions, constants, classes, and templates, all mixed and each next to the other. It doesn't even have an alphabetic ordering. It was difficult to me at first sight to understand where to look for things. Maybe it's not that important as bugfixes, but when new programmers get close to D2 (even old D1 fans, like myself), I'm afraid that more than one could feel some frustration.

Oh, I agree, as do many others. But someone has to come up with a better way of doing it and be motivated enough to figure out what has to be done with regards to macros and css and whatever else about generating the html files needs to be tweaked. Some folks have done work on it, but no one has presented a better solution yet. And the main devs for dmd, druntime, and Phobos are generally working on code fixes rather than documentation fixes. I'm sure that it'll be improved eventually, but someone has to want to do it, get it done, and get the main devs to approve it. That hasn't happened yet.

- Jonathan M Davis
« First   ‹ Prev
1 2