Jump to page: 1 2
Thread overview
Reversing a string
Jan 11, 2019
AndreasDavour
Jan 11, 2019
rikki cattermole
Jan 11, 2019
JN
Jan 11, 2019
AndreasDavour
Jan 11, 2019
Seb
Jan 11, 2019
bauss
Jan 11, 2019
AndreasDavour
Jan 11, 2019
Mike James
Jan 11, 2019
bauss
Jan 11, 2019
AndreasDavour
Jan 11, 2019
JN
Jan 11, 2019
Adam D. Ruppe
Jan 11, 2019
0xEAB
Jan 11, 2019
AlCaponeJr
Jan 13, 2019
Seb
January 11, 2019
Hi.

I've just started to learn some D, so maybe this question is extremely stupid, but please bear with me.

I have been trying to reverse a string, and through some googling found the std.algorithm.mutation.reverse method. But, when I try to use it I get some very verbose errors that just makes my eyes glaze over. What on earth do they mean? How do I reverse a string, really?

This is my code:
----------------------------
import std.stdio;
import std.algorithm;

void main() {
  auto test = "This is my text";
  string next_test = reverse(test);

  writeln(test);
  writeln(next_test);
}
----------------------------

This is my error:
----------------------------
[ante@tiny ~/src/D/tutorial]$ rdmd string4.d
/usr/home/ante/src/dmd2/freebsd/bin64/../../src/phobos/std/algorithm/mutation.d(2513): Error: template `std.algorithm.mutation.reverse` cannot deduce function from argument types `!()(immutable(ubyte)[])`, candidates are:
/usr/home/ante/src/dmd2/freebsd/bin64/../../src/phobos/std/algorithm/mutation.d(2485):        `std.algorithm.mutation.reverse(Range)(Range r) if (isBidirectionalRange!Range && (hasSwappableElements!Range || hasAssignableElements!Range && hasLength!Range && isRandomAccessRange!Range || isNarrowString!Range && isAssignable!(ElementType!Range)))`
/usr/home/ante/src/dmd2/freebsd/bin64/../../src/phobos/std/algorithm/mutation.d(2521): Error: template `std.algorithm.mutation.reverse` cannot deduce function from argument types `!()(immutable(ubyte)[])`, candidates are:
/usr/home/ante/src/dmd2/freebsd/bin64/../../src/phobos/std/algorithm/mutation.d(2485):        `std.algorithm.mutation.reverse(Range)(Range r) if (isBidirectionalRange!Range && (hasSwappableElements!Range || hasAssignableElements!Range && hasLength!Range && isRandomAccessRange!Range || isNarrowString!Range && isAssignable!(ElementType!Range)))`
string4.d(6): Error: template instance `std.algorithm.mutation.reverse!string` error instantiating
Failed: ["/usr/home/ante/src/dmd2/freebsd/bin64/dmd", "-v", "-o-", "string4.d", "-I."]
------------------------------

Can some unpack that for me, please?

I might add that the most intuitive way to reverse a string, I think, would be to consider it a range and just do "newstring = oldstring[$ .. 0]" but that gives an error about being out of bounds, so I guess the compiler expect values to increase from left to right, and does not want to increment beyond $. Makes sense, but that syntax would be very neat.

January 11, 2019
So strings in D are Unicode. This is both a great thing and a horrible thing.
To reverse a Unicode string correctly you need to take into account BiDi and graphemes, in other words it gets rather complex. However I suspect that this isn't what you want.

Now a (w/d)string is defined as:

alias string  = immutable(char)[];
alias wstring = immutable(wchar)[];
alias dstring = immutable(dchar)[];

Note the immutable, it means you cannot modify individual values. Which is a problem for reverse because it modifies in place.

Which means:

writeln("Hello D".reverse);

Won't work, but:

writeln("Hello D".dup.reverse);

Will. A simple duplication (char[]) makes it work.

Finally, arrays in D are absolutely brilliant. They are what we call slices. A slice is a pointer + a length. That is it. Hence they cannot be reversed in place. Of course this is great for interacting with e.g. C, since its just a matter of slicing any data back to get your bounds checking ext.
January 11, 2019
On Friday, 11 January 2019 at 08:05:39 UTC, AndreasDavour wrote:
> Hi.
>
> I've just started to learn some D, so maybe this question is extremely stupid, but please bear with me.
>
> [...]

Use .retro - it is also lazy and won't allocate:

https://run.dlang.io/is/A6bjrC
January 11, 2019
On Friday, 11 January 2019 at 08:15:01 UTC, rikki cattermole wrote:
> Note the immutable, it means you cannot modify individual values. Which is a problem for reverse because it modifies in place.
>

The error message is kind of unfortunate. This is a simple usecase and the error message is undecipherable already. It'd be cool if the compiler could try to strip immutability, and if the type matches then, throw an error something like "Cannot pass immutable char[] to reverse, did you mean char[]?".
January 11, 2019
On Friday, 11 January 2019 at 08:45:12 UTC, JN wrote:
> On Friday, 11 January 2019 at 08:15:01 UTC, rikki cattermole wrote:
>> Note the immutable, it means you cannot modify individual values. Which is a problem for reverse because it modifies in place.
>>
>
> The error message is kind of unfortunate. This is a simple usecase and the error message is undecipherable already. It'd be cool if the compiler could try to strip immutability, and if the type matches then, throw an error something like "Cannot pass immutable char[] to reverse, did you mean char[]?".

That would help a lot, as I got "rikki cattermole"'s answer at once, when my eyes were brought to the "immutable" part.

I come from the lisp world, so I'm kind of familiar with the idea of copying and/or modifying in place to limit consing. I guess I should I have realised this would be a perfect example of that kind of situation.
January 11, 2019
On Friday, 11 January 2019 at 08:25:41 UTC, Seb wrote:
> On Friday, 11 January 2019 at 08:05:39 UTC, AndreasDavour wrote:
>> Hi.
>>
>> I've just started to learn some D, so maybe this question is extremely stupid, but please bear with me.
>>
>> [...]
>
> Use .retro - it is also lazy and won't allocate:
>
> https://run.dlang.io/is/A6bjrC

What a terrible name.
January 11, 2019
On Friday, 11 January 2019 at 09:41:30 UTC, bauss wrote:
> On Friday, 11 January 2019 at 08:25:41 UTC, Seb wrote:
>> On Friday, 11 January 2019 at 08:05:39 UTC, AndreasDavour wrote:
>>> Hi.
>>>
>>> I've just started to learn some D, so maybe this question is extremely stupid, but please bear with me.
>>>
>>> [...]
>>
>> Use .retro - it is also lazy and won't allocate:
>>
>> https://run.dlang.io/is/A6bjrC
>
> What a terrible name.

Well, it was not the first one I would have searched for, no.

Good to know it exists as well, though. Thanks!
January 11, 2019
On Friday, 11 January 2019 at 09:41:30 UTC, bauss wrote:
> On Friday, 11 January 2019 at 08:25:41 UTC, Seb wrote:
>> On Friday, 11 January 2019 at 08:05:39 UTC, AndreasDavour wrote:
>>> Hi.
>>>
>>> I've just started to learn some D, so maybe this question is extremely stupid, but please bear with me.
>>>
>>> [...]
>>
>> Use .retro - it is also lazy and won't allocate:
>>
>> https://run.dlang.io/is/A6bjrC
>
> What a terrible name.

Check out the origin :-)

https://forum.dlang.org/thread/hl8345$2b1q$1@digitalmars.com?page=1


-=mike=-
January 11, 2019
On Friday, 11 January 2019 at 11:15:05 UTC, Mike James wrote:
> On Friday, 11 January 2019 at 09:41:30 UTC, bauss wrote:
>> On Friday, 11 January 2019 at 08:25:41 UTC, Seb wrote:
>>> On Friday, 11 January 2019 at 08:05:39 UTC, AndreasDavour wrote:
>>>> Hi.
>>>>
>>>> I've just started to learn some D, so maybe this question is extremely stupid, but please bear with me.
>>>>
>>>> [...]
>>>
>>> Use .retro - it is also lazy and won't allocate:
>>>
>>> https://run.dlang.io/is/A6bjrC
>>
>> What a terrible name.
>
> Check out the origin :-)
>
> https://forum.dlang.org/thread/hl8345$2b1q$1@digitalmars.com?page=1
>
>
> -=mike=-

I wish I could live my life peacefully, but apparently not.

January 11, 2019
On Friday, 11 January 2019 at 11:15:05 UTC, Mike James wrote:
> On Friday, 11 January 2019 at 09:41:30 UTC, bauss wrote:
>> On Friday, 11 January 2019 at 08:25:41 UTC, Seb wrote:
>>> On Friday, 11 January 2019 at 08:05:39 UTC, AndreasDavour wrote:
>>>> Hi.
>>>>
>>>> I've just started to learn some D, so maybe this question is extremely stupid, but please bear with me.
>>>>
>>>> [...]
>>>
>>> Use .retro - it is also lazy and won't allocate:
>>>
>>> https://run.dlang.io/is/A6bjrC
>>
>> What a terrible name.
>
> Check out the origin :-)
>
> https://forum.dlang.org/thread/hl8345$2b1q$1@digitalmars.com?page=1
>
>
> -=mike=-


Look at that.

Incidentally, I kind of like "foreach(i; 99 .. 0 : -1)".
« First   ‹ Prev
1 2