const and phobos string functions

Regan Heath regan at netmail.co.nz
Thu Aug 2 04:42:55 PDT 2007


Reiner Pope wrote:
> Regan Heath wrote:
>> Kirk McDonald wrote:
>>> I submit the following Python idiom: Functions which mutate their 
>>> arguments should return nothing. That is:
>>>
>>> // Return new string
>>> string tolower(string);
>>> // Mutate argument
>>> void tolower(char[]);
>>>
>>> This rather strictly highlights the difference between char[] and 
>>> string, and makes it essentially impossible to mix up library 
>>> functions differentiated in this way.
>>
>> That's all well and good until you want to write:
>>
>> char[] s;
>> ...
>> foo(tolower(s));
>>
>> If you template tolower in the manner I described it's not possible to 
>> mix it up and call the wrong one anyway (as it selects the correct one 
>> based on the input) so it's a non-problem.
>>
>> Regan
> 
> I think the code you gave here would be misleading. For instance, 
> suppose you had your templated overloads, effectively giving you
> 
>    // copy-on-write
>    string tolower(string);
>    // in-place
>    char[] tolower(char[]);
> 
> Then you would get surprising results if you did this:
> 
> char[] s = "Hello World!".dup;
> int a = howManyLettersDiffer(tolower(s), s);
> assert (a == 2); // assert failed, a is actually 0
> 
> I think avoiding this is exactly why Kirk suggested his overloads.

Good point.

Using Kirk's Python'esque function signatures you'd have:

char[] s = "Hello World!".dup;
tolower(s);
int a = howManyLettersDiffer(s, s);
assert (a == 2); // assert failed, a is actually 0

which is immediately and obviously a pointless operation, requring a 
re-code to:

char[] s = "Hello World!".dup;
char[] s2 = s.dup
tolower(s2);
int a = howManyLettersDiffer(s2, s);
assert (a == 2); // assert failed, a is actually 0

And the 'string' case:

string s = "Hello World!";
int a = howManyLettersDiffer(tolower(s), s);
assert (a == 2); // assert failed, a is actually 0

which would already behave as desired.

It seems that tolower is always going to have to 'copy on write' and 
return that copy.

But, that doesn't stop you templating it so that it returns the copy as 
char[] when you pass char[] (which is all I really wanted in the first 
place) :)

Unfortunately as we cannot overload on return type it would prevent an 
inplace tolower in the form (given by Kirk):

void tolower(char[])

Instead perhaps we need a naming convention for inplace modifying 
functions, options:

void <func>Inplace(<args>)
void <func>IP(<args>)       // "IP" stands for inplace
void <func>M(<args>)        // "M" stands for mutates

or something like those.

Regan



More information about the Digitalmars-d mailing list