Okay, what happened to my literal strings?
Regan Heath
regan at netmail.co.nz
Mon Sep 10 01:45:23 PDT 2007
Bill Baxter wrote:
> Burton Radons wrote:
>>
>> "Walter Bright" <newshound1 at digitalmars.com> wrote in message
>> news:fbq3d5$1j0j$1 at digitalmars.com...
>>> 1) It opens the door to functional programming. This means that
>>> function calls can be automatically parallelized, which is going to
>>> become an increasingly big deal as people try to figure out how to
>>> use their multicore processors.
>>>
>>> Note that C++ const CANNOT do FP, and Java CANNOT do const. This will
>>> open up a huge advantage for D.
>>
>> But you can't do any serious optimisations (like SIMD) unless if you
>> have the function body, in which case proving it's procedural (or
>> where the output is defined based on hermetic input) is relatively
>> simple and completely foolproof.
>>
>> C-type languages have too much of a fetish for becoming undefined. If
>> my function is declared const or invariant, but it's not (which the
>> language rules allow), it's undefined and the worst kind of undefined
>> - the kind which works initially, and might even work with -O. But
>> then one day it doesn't because of new optimisations or because the
>> file is compiled in a different environment or even because the
>> operating system has been upgraded or the same code is executed on a
>> different processor or the code is moved into a different context or
>> it or a dependency has been slightly modified. This can cause major
>> damage to older code and forces dozens of discrete optimisation flags
>> to try to get it to compile properly with a little more speed.
>>
>> If the language could not be put into an undefined state (but could be
>> put into an erroneous state which could be detected in debug
>> compilations) then you'd be free to implement any compliant
>> optimisation without worrying about how much code it breaks.
>> "Aggressive optimisation" wouldn't be a bad thing in that context.
>>
>>> 2) People who work on large projects with several teams modifying the
>>> code tell me unequivocably that they need some sort of const to
>>> enforce modularity.
>>
>> I don't think you believe it's adequate to do that. I'd expect that to
>> be a good situation for programmers using const incorrectly, because
>> they might need to cast const off code which they're not in control
>> of, particularly when the internal rule is "you should const anything
>> you don't modify" (which is an easy trap) instead of "you should const
>> anything you /shouldn't/ modify".
>>
>>> 3) Const improves the self-documentation of interfaces.
>>
>> In this context, const is being used to describe a contract with the
>> user. But contracts of this sort are impossible to reduce to a
>> combination of keywords and unenforcable in all contexts by the
>> compiler; there are too many subtleties. This belongs in the
>> documentation itself.
>>
>> A good example is "char* strchr (const char*, char)" from C. That
>> implies that the return value is not a pointer to an index of the
>> first argument, but it is, it's just not declared that way because the
>> argument itself may not be const. So the signature misses the subtlety
>> of the true contract. If the user uses this signature as
>> self-documentation then they could easily make an error. If it were
>> instead "const char* strchr (const char*, char)" then the contract
>> goes beyond what is strictly required because it's so blunt, and
>> interpreted as self-documentation requires the user to make a copy
>> before any modifications of the return value (and makes it impossible
>> to do certain operations). If we decide that we don't want to lie then
>> we can declare it as "char* strchr (char*, char)", which implies that
>> the function modifies the string (because of the absence of const),
>> when it never does; interpreted as self-documentation you'd always
>> call it with mutable data. There's no happy medium: in any case the
>> self-documentation is wrong and harms the user.
>>
>> This could be "fixed" through a complex set of attributes, in this
>> case something like "argument (a) strchr (const char*a, char)", so the
>> compiler could assume that if it calls it with a non-const argument
>> then it gets a non-const argument in return and vice versa, and the
>> function can be implemented without casting off const. But even
>> keeping these literate contracts to const there are many variations
>> that would require the user to learn a new language to interpret them
>> when simple human-interpreted language more than suffices.
>>
>
> I think the actual "fix" in C++ would be just to define a version of
> strchr overloaded on const. So you have both:
>
> const char* strchr(const char*, char);
> and
> char* strchr(char*, char);
>
> If you pass it a char* that can be modified, it'll give you back one
> that can be modified. Otherwise it won't.
And in D we can use a template as the body of the function is the same
for const or non-const data, eg.
S[] strchr(S : S[], C)(S[], C);
Two types S and C are required because sometimes you want to pass a
char[] for the first and invariant(char) for the 2nd.
Regan
More information about the Digitalmars-d
mailing list