YACP -- Yet Another Const Proposal
Bruno Medeiros
brunodomedeirosATgmail at SPAM.com
Wed Aug 9 09:27:41 PDT 2006
Reiner Pope wrote:
>>> *3. rocheck*
>>>
>>
>> I haven't read that part of the paper yet, but I think I get a good
>> enough picture from your description.
>> And I think rocheck wouldn't fit well with D, due to the runtime
>> checks and performance penalties, which, like you said, could not be
>> disabled in release builds (as they are not contracts). Also, it would
>> only work with classes, and not any kind of type.
>> (You have an example where you have a "rocheck char[]" variable, how
>> would that work internally?)
> This isn't in the paper. It's my idea, arising from some of the problems
> with getting CoW to work properly. Consider:
>
> char[] /*someCOWFunction*/ foo(char[] input) {}
> char[] /*Also COW*/ bar(char[] input) {}
> char[] /*Also COW*/ bam(char[] input) {}
>
> foo(bar(bam("hello world")));
>
> Each of them would ordinarily duplicate the string if a modification is
> required. However, a maximum of 1 is needed in real life, because no-one
> owns the intermediate copies. So there needs to be some way to know at
> runtime whether the array reference is readonly or not, because if it is
> mutable, then the function would be best advised to modify it in-place.
> That's what rocheck is for. However, in my proposal, it is both:
> -statically verifiable as correct
> -devoid of runtime checking
>
> this is because the mutating methods can only be accessed via the
> ensureWritable() method generated by the compiler, so a correct COW
It is not entirely devoid of runtime checking, since it envolves calling
.ensureWritable() .
> function would look like this:
>
> rocheck char[] capitalizeAllIfFirstLetterIsLowerThenRunBar(rocheck
> char[] input)
> { if (isLowerCase(input[0]))
> { /*mutable*/ char[] modified = input.ensureWritable();
> foreach (inout c; modified)
> { c = makeUpper(c);
> }
> input = modified;
> }
> bar(input);
> }
>
> So in this function, it is clearly const-safe as well as only doing one
> check in the entire function (the call to ensureWritable). This means
> that, although there is a memory cost added to the array reference,
> there is actually a runtime saving because of the avoidance of
> duplications. Additionally, since using this requires a special keyword,
> it will only be used where the memory/speed tradeoff is deemed
> worthwhile by the programmer (however, I recommend that it is used for
> any COW function).
>
Hum. Well, a template version of rocheck can be done already (with or
without const), and it isn't that much worse from the in-language
version: (the code may have some errors)
struct rocheck!(T) {
immutable T elem;
bool writable;
/*mutable*/ Type ensureWritable() {
if (!writable) return cast(mutable) elem;
else return elem.dup;
}
}
// A rocheck caster/constructor
rocheck!(T) asrocheck!(T) (T refval) {
rocheck!(T) rochk;
rochk.elem = refval;
return rochk;
}
rocheck!(char[]) capitalizeEtc(rocheck!(char[]) input)
{
if (isLowerCase(input.elem[0])) {
/*mutable*/ char[] modified = input.ensureWritable();
foreach (inout c; modified) {
c = makeUpper(c);
}
input.elem = modified;
}
bar(input);
return input;
}
...
char[] mystr = "abc";
auto str = capitalizeEtc(filter1(mystr.asrocheck));
The differences are that it is a bit more verbose to declare rocheck
vars, and also you have to explicitly convert from non-rocheck to
rocheck (what asrocheck() does). Other than that I think it works ok.
--
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
More information about the Digitalmars-d
mailing list