www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - reduce string ranges

reply Brian Myers <bmyers harryanddavid.com> writes:
I'd like to be able to use the reduce template on a range of strings. The
following:

int main(char[][] args)
{
    string[] tstarr = ["one", "two", "three"];
    writefln(reduce!("a ~ b")("", tstarr));
}

gives the following error message:

c:\dmd\bin\..\src\phobos\std\algorithm.d(289): Error: functions cannot return
static array invariant(char[0u])

Is there another way to do this? I've tried both the ~ operator and the +
operator.

Brian
Jun 03 2008
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Brian Myers:
 I'd like to be able to use the reduce template on a range of strings. The
following:
 int main(char[][] args)
 {
     string[] tstarr = ["one", "two", "three"];
     writefln(reduce!("a ~ b")("", tstarr));
 }

Don't do that, probably it's a slow way to join an array of strings. In the std.string module you can use the join("") function, or you can use joinArr() function from the d.string module of mine. (I have like a dejavu, isn't this discussion happened already?) Bye, bearophile
Jun 03 2008
parent Brian Myers <bmyers harryanddavid.com> writes:
Well yes and no. I have posted about the map and reduce templates before a few
days ago, but this is with a different function -- string concatenation.

I'm just exploring how well D supports the functional paradigm. 2.0 is bringing
in a lot of functional features, and I'm trying to get a feel for the
boundaries.

Brian

bearophile Wrote:

 Brian Myers:
 I'd like to be able to use the reduce template on a range of strings. The
following:
 int main(char[][] args)
 {
     string[] tstarr = ["one", "two", "three"];
     writefln(reduce!("a ~ b")("", tstarr));
 }

Don't do that, probably it's a slow way to join an array of strings. In the std.string module you can use the join("") function, or you can use joinArr() function from the d.string module of mine. (I have like a dejavu, isn't this discussion happened already?) Bye, bearophile

Jun 04 2008
prev sibling parent reply Christian Kamm <kamm-incasoftware removethis.de> writes:
Brian Myers wrote:
 The following:
 
 int main(char[][] args)
 {
     string[] tstarr = ["one", "two", "three"];
     writefln(reduce!("a ~ b")("", tstarr));
 }
 
 gives the following error message:
 
 c:\dmd\bin\..\src\phobos\std\algorithm.d(289): Error: functions cannot
 return static array invariant(char[0u])

This is just the old problem that string literals are static arrays. Reduce expects its return type to have the same type as the first argument, which is invariant(char[0]) in your case. Replace "" by ""[] and the code compiles.
Jun 04 2008
parent reply "Nick Sabalausky" <a a.a> writes:
"Christian Kamm" <kamm-incasoftware removethis.de> wrote in message 
news:g27rd9$1l7d$1 digitalmars.com...
 Brian Myers wrote:
 The following:

 int main(char[][] args)
 {
     string[] tstarr = ["one", "two", "three"];
     writefln(reduce!("a ~ b")("", tstarr));
 }

 gives the following error message:

 c:\dmd\bin\..\src\phobos\std\algorithm.d(289): Error: functions cannot
 return static array invariant(char[0u])

This is just the old problem that string literals are static arrays. Reduce expects its return type to have the same type as the first argument, which is invariant(char[0]) in your case. Replace "" by ""[] and the code compiles.

1. Why does reduce need the seed to be manually specified anyway? Why not just take the first element of the first range as the seed? 2. If it did that, that still wouldn't solve the problem from the original post, would it? I assume you'd need to do something weird like "auto tstarr = ["one"[], "two"[], "three"[]];"? 3. I'm still getting my head around D2's strings so this'll probably sound stupid, but why can't "" be implicitly converted to ""[]? (and how exactly does that solve the original problem anyway)? BTW, ""[] means "a full start-to-end slice of the empty string literal", right? Also, I know arrays and array slices are distict types, but what exactly is the difference? My intuition would tell me that they're both a pointer and a length, and an array slice is simply one that just happens to point to a portion of another array, but lately I've been getting the impression that there's something more to it than that?
Jun 16 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:g371nu$275q$1 digitalmars.com...
 1. Why does reduce need the seed to be manually specified anyway? Why not 
 just take the first element of the first range as the seed?

It could. Some languages/libraries do.
 2. If it did that, that still wouldn't solve the problem from the original 
 post, would it? I assume you'd need to do something weird like "auto 
 tstarr = ["one"[], "two"[], "three"[]];"?

You don't need to put the slice on every element, just the first. That makes the compiler infer the type of the array literal as char[][] instead of char[3][].
 3. I'm still getting my head around D2's strings so this'll probably sound 
 stupid, but why can't "" be implicitly converted to ""[]? (and how exactly 
 does that solve the original problem anyway)?

As said above, the compiler is too dumb to figure out that ["one", "two", "three"] is a char[][] and not a char[3][]. If string literals were dynamic arrays instead of fixed-size, we wouldn't need the [] at the end of the first element.
 BTW, ""[] means "a full start-to-end slice of the empty string literal", 
 right? Also, I know arrays and array slices are distict types, but what 
 exactly is the difference? My intuition would tell me that they're both a 
 pointer and a length, and an array slice is simply one that just happens 
 to point to a portion of another array, but lately I've been getting the 
 impression that there's something more to it than that?

No, they're not different types. At least not yet. Walter was throwing around the idea but it hasn't been implemented yet. There is some ickiness with representing both as the same type. Getting a full slice of a fixed-size array, such as a string literal, gives you a dynamic array reference. Hence why it fixes the array literal.
Jun 16 2008