Thread overview
Casting the Result of splitter() into a string array
Jun 17, 2012
GreatEmerald
Jun 17, 2012
Jonathan M Davis
Jun 17, 2012
GreatEmerald
Jun 17, 2012
Jonathan M Davis
Jun 17, 2012
Trass3r
Jun 17, 2012
bearophile
June 17, 2012
A quick and simple question, but I couldn't find the answer to it by myself: how do I cast the return type of std.array.splitter() into a string[]?

According to the compiler, splitter() has a return type Result. How useful... I assume it's a disguised tuple? If I try to simply assign the result to a string array, like this:

  string[] Bits = splitter(" a b");

I get an error "Error: cannot implicitly convert expression (splitter(" a b")) of type Result to string[]". Then if I make an explicit cast, I get "Error: cannot cast from Result to string[]".

So there must be something obvious that I'm missing... I also had the same problem when trying to cast the result of std.algorithm.filter!() to string[].
June 17, 2012
On Sunday, June 17, 2012 13:39:19 GreatEmerald wrote:
> A quick and simple question, but I couldn't find the answer to it by myself: how do I cast the return type of std.array.splitter() into a string[]?
> 
> According to the compiler, splitter() has a return type Result. How useful... I assume it's a disguised tuple? If I try to simply assign the result to a string array, like this:
> 
>    string[] Bits = splitter(" a b");
> 
> I get an error "Error: cannot implicitly convert expression
> (splitter(" a b")) of type Result to string[]". Then if I make an
> explicit cast, I get "Error: cannot cast from Result to string[]".
> 
> So there must be something obvious that I'm missing... I also had the same problem when trying to cast the result of std.algorithm.filter!() to string[].

They're ranges. This is probably the best explanation online at the moment:

http://ddili.org/ders/d.en/ranges.html

If you want to convert a range to an array, use std.array.array, though in the case of a string, to!string(range) will probably work. However, it makes no sense to convert the result of splitter to a string. What's the point of splitting them just to join them?

splitter(" a b ") is going to return a range of strings. If you were to do array(splitter("a b ")), you'd get ["", "a", "b"].

- Jonathan M Davis
June 17, 2012
On Sunday, 17 June 2012 at 11:58:58 UTC, Jonathan M Davis wrote:
> splitter(" a b ") is going to return a range of strings. If you were to do
> array(splitter("a b ")), you'd get ["", "a", "b"].

Aha, that worked! Thanks!

Still makes me wonder how you're supposed to figure out that this type is a range and not anything else from the library documentation, though... Oh well.
June 17, 2012
GreatEmerald:

> A quick and simple question, but I couldn't find the answer to it by myself: how do I cast the return type of std.array.splitter() into a string[]?

splitter(), filter(), etc, are lazy, they return an iterable.

Use split() instead of splitter().

Bye,
bearophile
June 17, 2012
On Sunday, June 17, 2012 14:11:27 GreatEmerald wrote:
> On Sunday, 17 June 2012 at 11:58:58 UTC, Jonathan M Davis wrote:
> > splitter(" a b ") is going to return a range of strings. If you
> > were to do
> > array(splitter("a b ")), you'd get ["", "a", "b"].
> 
> Aha, that worked! Thanks!
> 
> Still makes me wonder how you're supposed to figure out that this type is a range and not anything else from the library documentation, though... Oh well.

The documentation says so in most cases. It certainly does for filter. It is true that it doesn't for spliter though. But pretty much everything in std.algorithm and std.range take and return ranges. And std.array generally takes arrays and returns either arrays or ranges.

- Jonathan M Davis
June 17, 2012
> If you want to convert a range to an array, use std.array.array

This is a constant source of confusion and it also is a crappy design to use a function in a totally different module for this purpose imho.
Can't these Result types get an eval() method and/or be made implicitly convertible to an array where appropriate?

The C++ matrix library Eigen uses this approach and it works out fantastically.
a*b returns an object representing this expression. If I do want to use this I write 'auto c=a*b;'.
If I want the result I can explicitly use its eval() method (which is especially useful inside a bigger expression) or something like 'Matrix c=a*b;' which also evaluates the expression.