V2 string
Bruno Medeiros
brunodomedeiros+spam at com.gmail
Thu Jul 5 04:37:08 PDT 2007
Regan Heath wrote:
> Walter Bright Wrote:
>> Derek Parnell wrote:
>>> However, if I might need to update it ...
>>>
>>> char[] fullpath;
>>>
>>> fullpath = CanonicalPath(shortname).dup;
>>> version(Windows)
>>> {
>>> setLowerCase(fullpath);
>>> }
>>>
>>> The point is that the 'CanonicalPath' function hasn't got a clue what the
>>> calling function is intending to do with the result so it is trying to be
>>> responsible by guarding it against mistakes by the caller.
>> If you write it like this:
>>
>> string fullpath;
>>
>> fullpath = CanonicalPath(shortname);
>> version(Windows)
>> {
>> fullpath = std.string.tolower(fullpath);
>> }
>>
>> you won't need to do the .dup .
>
> Because tolower does it for you, but it still returns string and if for example you need to add something to the end of the path, like a filename you will end up doing yet another dup somewhere.
>
> I think the solution may be to template all functions which return the input string, or part of the input string, eg.
>
> T tolower(T)(T input)
> {
> }
>
> That way if you call it with char[] you get a char[] back, if you call it with string you get a string back.
>
> However...
>
> tolower is an interesting case. As a caller I expect it to modify the string, or perhaps give a modified copy back (both options are valid and should perhaps be supported?).
>
> So, the 'string tolower(string)' version has 2 cases, the first case where it doesn't need to modify the input and can simply return it, no problem.
>
> But case 2, where it does modify it should dup and return char[]. My reasoning being that after it has completed and returned the copy, the caller now 'owns' the string (as it's the only copy in existance and no-one else has a reference to it).
>
Indeed, I think this illustrates that some standard library functions
may not have the correct signature, and I tolower is likely one of them.
The most general case for tolower is:
char[] tolower(const(char)[] s);
Since tolower creates a new array, but does not keep it, it can give
away it's ownership of the the array (ie, return a mutable).
The second case, more specific, is simply syntactic sugar for making
that array invariant:
invariant(char)[] tolowerinv(const(char)[] str) {
return cast(invariant) tolower(str);
}
The current signature:
const(char)[] tolower(const(char)[] str)
is kinda incorrect, because it returns a const reference for an array
that has no mutable references, and that is the same as an invariant
reference, so tolower might as well return invariant(char)[].
> To achieve that we'd need to overload on return type, or something clever... but then, how do we call it?
>
> auto s = tolower(input);
>
> tolower cannot be selected at compile time, and the type of s cannot be known either, so that's an impossible situation, yes?
>
> Regan
The 'something clever' to distinguish both cases is simply naming two
different functions, like tolower or tolowerinv (if the second function
is needed at all).
--
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
More information about the Digitalmars-d
mailing list