Thread overview
[your code here]
Jan 15, 2012
Jos van Uden
Jan 15, 2012
bearophile
Jan 15, 2012
bearophile
[OT] Re: [your code here]
Jan 15, 2012
Nick Sabalausky
Jan 15, 2012
Timon Gehr
Jan 15, 2012
Jos van Uden
Feb 11, 2012
Jos van Uden
January 15, 2012
import std.conv, std.traits, std.ascii;

S rot13(S)(S s) if (isSomeString!S) {
    return rot(s, 13);
}

S rot(S)(S s, int key) if (isSomeString!S) {
    dchar[] r = new dchar[s.length];

    foreach (i, dchar c; s) {
        if (isLower(c))
            c = ((c - 'a' + key) % 26 + 'a');
        else if (isUpper(c))
            c = ((c - 'A' + key) % 26 + 'A');
        r[i] = c;
    }
    return to!S(r);
}


---

still learning this stuff, feel free to correct or improve

Jos
January 15, 2012
Jos van Uden:

> still learning this stuff, feel free to correct or improve

Next time I suggest you to use D.learn.

This is a first draft with some changes:

import std.traits, std.string, std.ascii, std.conv, std.range;

// is partial application better here?
dstring rot13(C)(immutable(C[]) s) pure /*nothrow*/
if (isSomeChar!C) {
    return rot(s, 13);
}

// or maybe just use in int key=13 as default argument
// is it right to use a signed int for key?
dstring rot(C)(immutable(C[]) s, in int key) pure /*nothrow*/
if (isSomeChar!C)
in {
    // preconditions here...
    // only ASCII input chars?
    // Are std.ascii.isUpper / isLower working with UTF?
} out(result) {
    // don't use .length here unless the input is verified to contain
    // no past ASCII chars
    assert(walkLength(s) == walkLength(result));
} body {
    auto result = new dchar[s.length];

    foreach (i, dchar c; s) { // not nothrow
        // reassigning c here is not nice
        if (isLower(c))
            result[i] = ((c - 'a' + key) % 26 + 'a');
        else if (isUpper(c))
            result[i] = ((c - 'A' + key) % 26 + 'A');
    }

     return result; // implicit cast, but only dstring output.
     // Otherwise allocate a result with alloca() and copy
     // it at the end with to!S(result)
} unittest {
    // unit tests here...
}

void main() {
    import std.stdio;
    writeln(rot13("hello"));
}

Your little program also shows some of the current D2 problems. You need care to catch a function signature like that that allows implicit cast of the result of the pure function.

Bye,
bearophile
January 15, 2012
On 1/15/12 8:23 AM, Jos van Uden wrote:
> import std.conv, std.traits, std.ascii;
>
> S rot13(S)(S s) if (isSomeString!S) {
> return rot(s, 13);
> }
>
> S rot(S)(S s, int key) if (isSomeString!S) {
> dchar[] r = new dchar[s.length];
>
> foreach (i, dchar c; s) {
> if (isLower(c))
> c = ((c - 'a' + key) % 26 + 'a');
> else if (isUpper(c))
> c = ((c - 'A' + key) % 26 + 'A');
> r[i] = c;
> }
> return to!S(r);
> }
>
>
> ---
>
> still learning this stuff, feel free to correct or improve
>
> Jos

Thanks! Well, we don't have yet the javascript that rotates the examples. Would anyone be interested to work on that?

Andrei
January 15, 2012
Andrei Alexandrescu:

> Thanks! Well, we don't have yet the javascript that rotates the examples. Would anyone be interested to work on that?

Do you want a large amount of D2 "examples"? Have you seen this page? http://rosettacode.org/wiki/Category:D

Bye,
bearophile
January 15, 2012
On 1/15/12 9:26 AM, bearophile wrote:
> Andrei Alexandrescu:
>
>> Thanks! Well, we don't have yet the javascript that rotates the
>> examples. Would anyone be interested to work on that?
>
> Do you want a large amount of D2 "examples"? Have you seen this page?
> http://rosettacode.org/wiki/Category:D
>
> Bye,
> bearophile

Great! For now it would be great to have the code that rotates the script on our homepage.

Andrei
January 15, 2012
On 01/15/2012 03:23 PM, Jos van Uden wrote:
> import std.conv, std.traits, std.ascii;
>
> S rot13(S)(S s) if (isSomeString!S) {
> return rot(s, 13);
> }
>
> S rot(S)(S s, int key) if (isSomeString!S) {
> dchar[] r = new dchar[s.length];
>
> foreach (i, dchar c; s) {
> if (isLower(c))
> c = ((c - 'a' + key) % 26 + 'a');
> else if (isUpper(c))
> c = ((c - 'A' + key) % 26 + 'A');
> r[i] = c;
> }
> return to!S(r);
> }
>
>
> ---
>
> still learning this stuff, feel free to correct or improve
>
> Jos

Your code will fail for narrow strings containing Unicode.
dchar[] r = new dchar[s.length]; // creates a new dchar[] with as many elements as there are code units in the input string

You can use std.range.walkLength to get the number of code points.

Furthermore, that line mentions the type twice.

auto r = new dchar[s.walkLength()];
January 15, 2012
On 15-1-2012 17:26, Timon Gehr wrote:
> On 01/15/2012 03:23 PM, Jos van Uden wrote:
>> import std.conv, std.traits, std.ascii;
>>
>> S rot13(S)(S s) if (isSomeString!S) {
>> return rot(s, 13);
>> }
>>
>> S rot(S)(S s, int key) if (isSomeString!S) {
>> dchar[] r = new dchar[s.length];
>>
>> foreach (i, dchar c; s) {
>> if (isLower(c))
>> c = ((c - 'a' + key) % 26 + 'a');
>> else if (isUpper(c))
>> c = ((c - 'A' + key) % 26 + 'A');
>> r[i] = c;
>> }
>> return to!S(r);
>> }
>>
>>
>> ---
>>
>> still learning this stuff, feel free to correct or improve
>>
>> Jos
>
> Your code will fail for narrow strings containing Unicode.
> dchar[] r = new dchar[s.length]; // creates a new dchar[] with as many
> elements as there are code units in the input string
>
> You can use std.range.walkLength to get the number of code points.
>
> Furthermore, that line mentions the type twice.
>
> auto r = new dchar[s.walkLength()];

Thank you.

---

S rot13(S)(S s) if (isSomeString!S) {
    return rot(s, 13);
}

S rot(S)(S s, int key) if (isSomeString!S) {
    auto r = new dchar[s.walkLength()];

    foreach (i, dchar c; s) {
        if (isLower(c))
            r[i] = ((c - 'a' + key) % 26 + 'a');
        else if (isUpper(c))
            r[i] = ((c - 'A' + key) % 26 + 'A');
    }
    return to!S(r);
}
January 15, 2012
"Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message news:jeuqua$1gfg$3@digitalmars.com...
>
> Thanks! Well, we don't have yet the javascript that rotates the examples. Would anyone be interested to work on that?
>

Speaking of d-p-l.org contributions, #39 has been merged and could use to be put up on the site. Not to nag about it, just a friendly heads-up.


February 11, 2012
> S rot13(S)(S s) if (isSomeString!S) {
> return rot(s, 13);
> }
>
> S rot(S)(S s, int key) if (isSomeString!S) {
> auto r = new dchar[s.walkLength()];
>
> foreach (i, dchar c; s) {
> if (isLower(c))
> r[i] = ((c - 'a' + key) % 26 + 'a');
> else if (isUpper(c))
> r[i] = ((c - 'A' + key) % 26 + 'A');
> }
> return to!S(r);
> }

this is better

S rot13(S)(in S s) if (isSomeString!S) {
    return rot(s, 13);
}

S rot(S)(in S s, in int key) if (isSomeString!S) {
    auto r = new dchar[s.walkLength];

    foreach (i, dchar c; s) {
        if (std.ascii.isLower(c))
            c = ((c - 'a' + key) % 26 + 'a');
        else if (std.ascii.isUpper(c))
            c = ((c - 'A' + key) % 26 + 'A');
        r[i] = c;
    }
    return to!S(r);
}