March 10, 2005
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0nua5$di5$1@digitaldaemon.com...

> class X
> {
> public
>    this(short s)
>    {
>        y = s;
>    } // COMPILE ERROR: explicit member 'z' not explicitly initialised
>
> private:
>    int                y;
>    explicit int    z;
> }

I personally like const, even when flawed.  However your example sounds trivial.  As a library writer you want to make sure that any variable you have gone out of your way to mark 'explicit' then cries foul in your *own* constructors if not set.  Sure it might save a bug or two, but it's not much.  Libraries get vetted quickly enough.

The app writer using your libraries doesn't get squat for all this.  Or as you point out, there is no semantics passed up.  While I'm not used to in, out, inout, and I don't like looking at them, they seem to cover your point about semantics.


March 11, 2005
> I am first and foremost a library writer, and as such see const to
be a
> *hugely* successful idea because (i) it allows me to express highly important semantics to the users of my code


<alert comment="newbie who may not understand the issues">

Seems like your advocated usage of "const" for library routines can be more or less accomplished with "in" parameters?

The "consumer" of your library wouldn't/shouldn't care about other variables that are presumably hidden/private.

</alert>



March 11, 2005
"Lynn Allan" <l_d_allan@adelphia.net> wrote in message news:d0rd7c$128k$1@digitaldaemon.com...
>> I am first and foremost a library writer, and as such see const to
> be a
>> *hugely* successful idea because (i) it allows me to express highly important semantics to the users of my code
>
>
> <alert comment="newbie who may not understand the issues">
>
> Seems like your advocated usage of "const" for library routines can be more or less accomplished with "in" parameters?
>
> The "consumer" of your library wouldn't/shouldn't care about other variables that are presumably hidden/private.
>
> </alert>

Hmmm. I could give several answers, but since I've been somewhat snappish/boorish lately, I'll conjure a nice one <g>:

    "I am flattered that you obviously assume that library writers are
infallible, but unfortunately they're not. Therefore, they are (almost)
as much in need of assistance from compilers as 'normal' programmers."

That ok? :-)


March 11, 2005
Lynn Allan wrote:

> Seems like your advocated usage of "const" for library routines can be
> more or less accomplished with "in" parameters?

Note:
All parameters are "in", unless declared as "out" or "inout"...


The only way that this could apply to, say char[] parameters,
if if they were "extended" to something like "char[out]" or so ?

Currently "in" only applies to the array (or pointer) itself,
and *not* to the actual characters that it is referencing.


The D language at the moment treats all parameters as readonly, and
suggests using the Copy-on-Write 'idiom'. But does not enforce it.

It's a little like with the implicit cast of "bar[]" into "bar*",
it can be convenient and less typing, and it can also hide bugs ?

--anders
March 11, 2005
On Fri, 11 Mar 2005 09:22:55 +0100, Anders F Björklund wrote:

> Lynn Allan wrote:
> 
>> Seems like your advocated usage of "const" for library routines can be more or less accomplished with "in" parameters?
> 
> Note:
> All parameters are "in", unless declared as "out" or "inout"...
> 
> 
> The only way that this could apply to, say char[] parameters, if if they were "extended" to something like "char[out]" or so ?
> 
> Currently "in" only applies to the array (or pointer) itself, and *not* to the actual characters that it is referencing.
> 
> 
> The D language at the moment treats all parameters as readonly, and suggests using the Copy-on-Write 'idiom'. But does not enforce it.
> 
> It's a little like with the implicit cast of "bar[]" into "bar*", it can be convenient and less typing, and it can also hide bugs ?
> 
> --anders

Agreed.

The Copy-on-Write idiom being suggested by Walter, places the responsibility of preserving the referred-to data on the writer of the routine being called. In other words, if one is writing a routine, and that routine can receive reference parameters that are 'in' types, eg. char[], or Class instances, etc...), the one is expected to take a copy of the referred-to data *if* one is going to modify it (for any reason). Except if the *purpose* of the routine is to modify the referred-to data /in place/.

For example, a ToUpperCase() routine might have been designed to change the string in situ. Or it might have been designed to return an modified string but leave the original intact.

However, because one can never be certain that the routine writer has used this idiom, it is 'safer' to pass a reference to a copy of the data instead of a reference to the original data.

It would be nice if we could get the compiler to help us error prone coders. If would just tell the compiler that my intention is to *not* change some referred-to data, then the compiler could alert me to code that actually is known to change the data. This alone would be a great advance in being able to express the coder's intentions and thus reduce mistakes in source code.

I do understand that there are some cases in which the compiler cannot detect that some referred-to data will actually be changed, but I'm happy to live with that because that is exactly what we have now. However, there are times when the compiler *can* detect unintentional attempts to alter 'preserved' data.

Please notice that I have not used the keyword 'const' in the above discussion. That terminology is obvious overloaded, and I hoped instead to just talk in plain simple English.

-- 
Derek Parnell
Melbourne, Australia
11/03/2005 11:12:39 PM
March 11, 2005
[snip]
> However, because one can never be certain that the routine writer has used
> this idiom, it is 'safer' to pass a reference to a copy of the data
> instead
> of a reference to the original data.
>
> It would be nice if we could get the compiler to help us error prone
> coders. If would just tell the compiler that my intention is to *not*
> change some referred-to data, then the compiler could alert me to code
> that
> actually is known to change the data. This alone would be a great advance
> in being able to express the coder's intentions and thus reduce mistakes
> in
> source code.

The compiler/lint can give a warning when a char[], wchar[] or dchar[] "in" parameter is modified in place. The warning would say "modifying string input parameter - possible violation of copy-on-write". They would then search around for copy-on-write in the doc and learn about the "right" way.

[snip]

-Ben


March 11, 2005
On Fri, 11 Mar 2005 07:48:55 -0500, Ben Hinkle wrote:

> [snip]
>> However, because one can never be certain that the routine writer has used
>> this idiom, it is 'safer' to pass a reference to a copy of the data
>> instead
>> of a reference to the original data.
>>
>> It would be nice if we could get the compiler to help us error prone
>> coders. If would just tell the compiler that my intention is to *not*
>> change some referred-to data, then the compiler could alert me to code
>> that
>> actually is known to change the data. This alone would be a great advance
>> in being able to express the coder's intentions and thus reduce mistakes
>> in
>> source code.
> 
> The compiler/lint can give a warning when a char[], wchar[] or dchar[] "in" parameter is modified in place. The warning would say "modifying string input parameter - possible violation of copy-on-write". They would then search around for copy-on-write in the doc and learn about the "right" way.
> 

But how would one tell the lint that my code is intentionally *not* doing a copy-on-write? As in the ToUpperCase() example.

// Modify in place - i.e. Not CoW.
dchar[] ToUpperCase(dchar[] x)
{
    foreach(inout dchar c; x)
        c = Upper(c);

    return x;
}

// Return a new modified string - i.e. CoW
dchar[] ToUpperCase(dchar[] x)
{
    dchar[] y;
    y.length = x.length;
    foreach(int i, inout dchar c; x)
        y[i] = Upper(c);

    return y;
}


-- 
Derek Parnell
Melbourne, Australia
11/03/2005 11:49:35 PM
March 11, 2005
"Derek Parnell" <derek@psych.ward> wrote in message news:1scvmsoj94p35$.1jlrqgw7ijhz2.dlg@40tude.net...
> On Fri, 11 Mar 2005 07:48:55 -0500, Ben Hinkle wrote:
>
>> [snip]
>>> However, because one can never be certain that the routine writer has
>>> used
>>> this idiom, it is 'safer' to pass a reference to a copy of the data
>>> instead
>>> of a reference to the original data.
>>>
>>> It would be nice if we could get the compiler to help us error prone
>>> coders. If would just tell the compiler that my intention is to *not*
>>> change some referred-to data, then the compiler could alert me to code
>>> that
>>> actually is known to change the data. This alone would be a great
>>> advance
>>> in being able to express the coder's intentions and thus reduce mistakes
>>> in
>>> source code.
>>
>> The compiler/lint can give a warning when a char[], wchar[] or dchar[]
>> "in"
>> parameter is modified in place. The warning would say "modifying string
>> input parameter - possible violation of copy-on-write". They would then
>> search around for copy-on-write in the doc and learn about the "right"
>> way.
>>
>
> But how would one tell the lint that my code is intentionally *not* doing
> a
> copy-on-write? As in the ToUpperCase() example.

That's why it's a warning - and given that the standard is cow it would be odd to write a large number of functions that violate cow since users who expect cow (like me) would get confused about how to use those functions. One could also mark the input to ToUpperCase as inout, which would have the effect of forcing it to be an lvalue but has the benefit of informing users and the compiler/lint of the intention.


March 11, 2005
Derek Parnell wrote:

> But how would one tell the lint that my code is intentionally *not* doing a
> copy-on-write?

If "readonly" is the default for arrays, then we would need some kind of
keyword telling that the array in question would be modified in place.


One suggestion that came up was to use the "in" and "out" keywords,
as in: "dchar[in]" (which would be the default) and "dchar[inout]"

In C and C++, there in-place read-write is the default and you use the
oddly named "const" keyword to tell that it's a read-only: const char*


It could be made to work similar in D, just make read-only the default ?
Easier than changing everything else to use "readonly char[]" arguments.

It would also make Object.toString() make more sense, as it would return a readonly string and not a writable buffer tino the objects innards...


> As in the ToUpperCase() example.
> 
> // Modify in place - i.e. Not CoW.
> dchar[] ToUpperCase(dchar[] x)
> {
>     foreach(inout dchar c; x)
>         c = Upper(c);
> 
>     return x;
> }

This could use some keyword telling that it will *not* follow the
standard idiom of using copy-on-write, but will modify in place...
(which would also mean that it would segfault if passed a literal!)

Something like:
	dchar[] ToUpperCase(dchar[inout] x);
or
	dchar[] ToUpperCase(readwrite dchar[] x);


Placing "out" before the array:
	dchar[] ToUpperCase(out dchar[] x);

Just means that you will modify the *slice* (i.e. like length or ptr),
not that you mean to change the actual characters that it points to...
(the very ones it was currently pointing to on function entry, that is)

Examples:
void read(out char[] s);

This means that it will read from the stread into a new buffer, and
then return a slice to this buffer. But *not* that it will change
the characters that s was pointing to, when the function was called.


> // Return a new modified string - i.e. CoW
> dchar[] ToUpperCase(dchar[] x)
> {
>     dchar[] y;
>     y.length = x.length;
>     foreach(int i, inout dchar c; x)
>         y[i] = Upper(c);
> 
>     return y;
> }

You might want to look at std.string.toupper, for the default routine ?
(taking the default string type, char[], as a Copy-on-Write argument,
and optimized both for ASCII strings and for "already uppercase" too)

--anders
1 2
Next ›   Last »