July 03, 2005
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da9k9n$2201$1@digitaldaemon.com...
>
> "Walter" <newshound@digitalmars.com> wrote in message news:da9dc2$1r5s$2@digitaldaemon.com...
>>
>> "Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:da9b6j$1ouo$1@digitaldaemon.com...
>>> Perhaps dstyle.html should say functions with a leading 'to' should not modify their inputs. There are several toFoo functions in phobos and it would be nice to keep that style consistent.
>>
>> That's a good idea. There are also the 'is' prefix functions.
>>
>>
>
> I beleive that next will be a proposal to use 'c' as a first
> char of parameter name and all this will end up with
> Polish Notation and the like... Poor man type system to be short.
>
> Gentlemen, array and immutable slice are two *distinct* types with their own set of operations. The same for pointers - immutable pointer cannot be dereferenced to l-value.
>
> And please don't cover holes in type system by inventing naming conventions. This is not honest.
>
> Andrew.

Nothing is preventing someone from writing
  void upper(char[] str);
  char[] toUpper(char[] str);
I see no reason to abuse the already-established conventions with the "to"
prefix. Multiple versions of toUpper might seem natural to you and your team
but it isn't "typical" D code. Even if all your proposals were accepted I
would still argue a function named toUpper should not modify its input.
That isn't saying your general point is wrong - just that the example you
gave using the name "toUpper" isn't one that should be encouraged.


July 03, 2005
In article <da8ivk$12cm$1@digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...
>
>Stefan Zobel wrote:
>
>> For what it's worth, that String isn't immutable in Java/C# sense, is it? Every time you hand out a char[], you give the caller a reference to your internal member. Should be a "return str.dup;" :-(
>
>This goes for most implementations of toString(), I guess ? This actually would be the key issue we are debating here...
>

Yep, exactly.

>The char[] that is given out *is* read-only, there's just no way of indicating that - except for the Gentlemen's Agreement.
>

I understand the "philosophical" point here. I was just pointing out that, technically (current D), it is not.

>
>And, no, it should NOT be a dup (as my "StringBuffer" did do that).
>It's _supposed_ to return a reference to the (immutable) contents.
>

Hhm, "_supposed_". Not sure, if I can follow you here, but that may be because english is not my mother tongue (also didn't take a look at StringBuffer). The fact remains, that (to be really immutable) it must be a dup in D as it is right now.

>And you could still peek and poke it by casting to char* and changing the memory inside, but that's besides the point here.
>

void main ()
{
String mutableString = new String("immutable!");
writefln(mutableString);
char[] ref = mutableString.toString();
ref[9] = '?';
writefln(mutableString);
}

No "peeking and poking" here, just a realistic use case. But I'm convinced you know that. So, presumably I simply didn't get your point?


>
>I don't think that D needs a string class, but "something else" ? (as in Java and C#, the class internals are protected by the VM)
>
>I like the current strings, it's just that they are (or: could be) a little dangerous - just like a raw char* in C could be, I guess.
>
>
>But for C/C++ there is "const" - D needs something similar, but better.
>
>--anders


Agreed, we wouldn't need a string class (could save on all that duping)
if we had a way to declare const/immutable/... references in D. Just wanted
to remark that String.d isn't immutable, nothing more. No offense intended :)

Kind regards,
Stefan



July 03, 2005
"Dave" <Dave_member@pathlink.com> wrote in message news:da9jup$21h4$1@digitaldaemon.com...
> "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da9g47$1tfc$1@digitaldaemon.com...
>>
>> "Dave" <Dave_member@pathlink.com> wrote in message news:da95on$1jff$1@digitaldaemon.com...
>>>
>>> The whole problem is, with the C++ rules, the optimizations cannot even be done by the code generator - you may think you've optimized something with const, but in reality the code generator cannot make use of it because of how const is implimented in C++ and the compiler cannot figure out 100% for certain what is being done with referenced data.
>>
>> Again I am willing to write to functions which provided together will give an optimal choice:
>>
>> void toUpper( in char[] strbuf ) // inplace
>> char[] toUpper( in const char[] str ) // return brand new.
>>
>
> I understand - I think we're all looking for some way to implement "constness" in a way that is better, for at least the majority of cases, than how C++ does it. From Walter's earlier post, it appears that overloading based on some type of "const" storage modifier is not going to happen, so I'll take what I can get in this regard, especially if it helps compiler implementors do their job better because then I get better tools.

'"const" storage modifier is not going to happen,...'

Then page http://www.digitalmars.com/d/comparison.html
needs to be updated by features which are impossible
to implement in D in principle. Just for the sake of truth.

>
> Walter wants D's "constness" to be taken as a semantic guarantee of some value, and I agree with him on that, because then it's of more value to both the compiler and someone debugging code (const the way it is in C++ can actually hide bugs). I also agree with the notion that C++ constness is a mess and that is one of the major reasons why I want D to succeed, so I don't have to deal with that as it is.
>
> I take it you basically want C++ constness in D - I just have to disagree with that because that's one of the things I think needs to be done better.

The ultimate const protection can be done only on hardware level (I mean without compromises) which is not the case for D.

About stylistic:

I will repeat again: the best way (near ideal) is to be able
to say something like this:

type[def] string: char[]
{
   private opIndexAssign(...) // disabled
   public string opSlice() // returns immutable slice....
   ... etc...
}

It is more universal but significantly more complex.
But I am pretty sure it is a future - to be able
to fine tune type redefinitions of primitives.

For a while I propose to introduce
typedef#[] as an immutable version of typedef[]
and typedef#* ...


>
>> I am free to chose optimal function for particular case.
>> And while implementing it compiler will not allow
>> me to change *accidentally* value of str.
>>
>>>
>>> private and package methods can't be virtual, so there are some optimizations having to do with inlining and the vtable that can be (and are) done by the compiler, because 'private' or 'package' guarantees that those are not virtual methods.
>>
>> I think that you a wrong here as following:
>>
>> import std.stdio;
>>
>> class One
>> {
>>  package int foo() { return 1; }
>> }
>>
>> class Two: One
>> {
>>  override package int foo() { return 2; }
>> }
>>
>> int main()
>> {
>> Two t = new Two;
>> return t.foo();
>> }
>>
>> compiles just fine.
>>
>>
>
> Try this:
>
> # dmd -version=_package pt.d
> # ./pt
> 1
> 1
>
> vs. this:
>
> # dmd pt.d
> # ./pt
> 2
> 1
>
> ;---
> import std.stdio;
>
> class One
> {
> version(_package)
>  package int foo() { return 1; }
> else
>  public int foo() { return 1; }
> }
>
> class Two: One
> {
> version(_package)
>  override package int foo() { return 2; }
> else
>  override public int foo() { return 2; }
> }
>
> void main()
> {
> Two t = new Two;
> writefln((cast(One)t).foo());
> One o = new One;
> writefln("%d\n",(cast(One)o).foo());
> }
>
>

Nice! Just perfect!

And those people are telling me that
const hides possible errors? :-)))




July 03, 2005
"AJG" <AJG_member@pathlink.com> wrote in message news:da9ig8$1vpg$1@digitaldaemon.com...
> >> Once again, what if pointers are not considered, would this make things
> >easier?
> >> If you take out pointers, couldn't the compiler detect if you were
sending
> >the
> >> same variable to multiple differently-accessable parameters?
> >
> >The compiler cannot detect it in the general case, as a function may
receive
> >a non-const reference to the same data by an arbitrarilly complex path.
>
> I know I'm pushing it here, but can't the compiler follow that arbitrarily complex path (excluding pointers)?

If it could, the program could be executed at compile time rather than run time <g>.


> >What you're suggesting is different from C++ "const" - you're suggesting that const actually mean "constant". This is definitely more interesting that C++ const, but then there's the problem of undefined behavior and trying to detect it.
>
> Hm... perhaps. Ok, first let me see if I understand your point:
>
> You say: C++ const, which is semantic only, is useless for optimizations. You say: Implementing C++ const in D would be equally useless re:
optimizations.
> I say:   const should be _always_ about semantics ("correctness"), and _if
> possible_ provide optimizations.
> You say: That is not good enough, we need correctness and optimization.
>
> Is that correct?

From correctness comes the optimizations. C++ doesn't implement correctness, as my example showed.

> If not syntactically, could it be done via whole-program static analysis?

No.


July 03, 2005
"Walter" <newshound@digitalmars.com> wrote in message news:da99t5$1net$1@digitaldaemon.com...
>
> "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da95gq$1j4t$1@digitaldaemon.com...
>> 1) How in will solve this:
>>
>> class Record
>> {
>>     Field[] fields()
>>     {
>>         return m_fields.dup; // this is not needed, isn't it?
>>                                      // but it must be here in current D.
>>     }
>> }
>
> It won't, but then again, I don't see that the .dup is necessary there, as fields() is a producer of a value, not a consumer.
>
>> 2) 'In' does not allow to distinguish cases:
>>
>> void toUpper(in char[] str_in_place);
>> char[] toUpper(in const char[] str);
>>
>> and select optimal implementation.
>
> That's correct, there would be no overloading based on const-ness. I know
> this is commonplace in C++, but frankly I think it's poor design. A
> function
> overloaded on const implicitly has significantly different behavior, and
> so
> should have a different name.

1 ) There are situations when you just cannot use different names. E.g. template specializations.

2) "overloaded on const implicitly has significantly different behavior"
This apply also to all cases of function overloading.
E.g. foo(int i) and foo(char[] s) might have a significantly different
behavior, isn't it?

3) "should have a different name" - someone will consider
D as language forcing "name pollution" then.
Following this statement all toString() shall be rewritten as
toStringFromXXX( XXX x );

>
>
>> > volatile/volatile in/volatile out/volatile inout - 'volatile',
>> > 'volatile
>> > in', 'volatile out' and 'volatile inout' params. would basically
>> > operate
>> > exactly as they do now. Just like other statements in any other scope,
>> > a
>> > "volatile" param. would mean "inhibit optimizations on the variable
>> > that
>> > may effect memory reads/writes". Not even a new keyword..
>> >
>> > The whole justification for these new defaults is because the cases
> where
>> > "volatile" would have to be used for the code to operate correctly are
>> > a
>> > small minority, so shouldn't the default go with what benefits the
>> > great
>> > majority of cases?
>> >
>> > Also, the same justification goes for making the default [none] and
>> > 'in'
>> > operate the same way w.r.t. the new proposal - majority of cases rules.
>> > Another big plus would be not having to litter code with 'in' (like C++
>> > code is littered with 'const').
>> >
>>
>> "littered with 'const'"....
>>
>> well, it depends.... If European will see Stone Garden in Japan he will find it littered by stones.
>>
>> For me personally code which is not using const looks non-prefessional and written by young hacker in 'fire-n-forget' mode. Non maintainable, non reliable, non optimized.
>>
>> Someone can tell that:
>>
>> private int something1
>> public int something2
>>
>> is littered with private and public.
>> Does it *really* mean that it is littered?
>
> The idea is that the most common case should be the default. Would you
> agree
> that for the vast majority of function parameters, they are read only?
> That
> mutable ones are relatively rare? If so, then it makes sense to have the
> uncommon ones need the extra syntax.
>
> As for myself, since most parameters in C++ code are const, the const everywhere tends to visually clutter up the code, obscuring the other stuff.
>

Yep, as I meantioned above:
alias const char[] string;
will help.




July 03, 2005
"Nick" <Nick_member@pathlink.com> wrote in message news:da9dfv$1r9p$1@digitaldaemon.com...
> In article <da7pp5$i06$1@digitaldaemon.com>, Walter says...
> >
> >Yet the value can change anyway. Another reference can change it, and another thread can change it. It isn't "constant" at all, and cannot be relied on to be constant, even if your program is 100% "const-correct".
>
> That is true, but also in fact completly irrelevant. I think you might
have
> misunderstood the intention of the const keyword in C++. It's not meant to
be,
> and has never been meant to be, a guarantee to the internals of the
function
> that "this value will not change". It's not supposed to protect the INSIDE
of
> the function from the outside world, but quite the opposite. It's a
guarantee
> (or contract, if you will) with the code OUTSIDE the function (ie. the
caller)
> that "THIS function will never change this value." What happens in other
threads
> and other references has no relevance to this contract. Also, your example
with
> foo(a,a) is ok, since when you (the caller) send 'a' as the second
(non-const)
> parameter, the function is 'allowed' to change it. Thus the function has
not
> broken the contract.
>
> I am not arguing for or against const in D here. My experience with it in
C++
> has been pretty much the same as yours, and so I am not really convinced
of it's
> usefulness. But your argument really attacks a use of 'const' that was
never
> intended, and thus is not a very good argument.

You do make a good point.


July 03, 2005
"Walter" <newshound@digitalmars.com> wrote in message news:da9dc2$1r5s$1@digitaldaemon.com...
>
> "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da97g2$1l30$1@digitaldaemon.com...
>>
>> "Walter" <newshound@digitalmars.com> wrote in message news:da888e$rhs$1@digitaldaemon.com...
>> >
>> > "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da818n$md2$1@digitaldaemon.com...
>> >>
>> >> "Walter" <newshound@digitalmars.com> wrote in message news:da7u7k$kkh$1@digitaldaemon.com...
>> >> >
>> >> > "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da7s6r$jcd$1@digitaldaemon.com...
>> >> >> "I'll give you my slice and don't forget to dup it as it is not
>> >> >> yours."
>> >> >> This does not work in serious programming as
>> >> >> slice creation happens in one place and its consuming
>> >> >> in galaxy far far away and code of three developers
>> >> >> happens in between. It is EXTREMELY difficult to debug.
>> >> >> I know. It happened to me once in Harmonia and I wasted
>> >> >> almost three days to catch it. Sigh...
>> >> >> And I was designing it by myself - not even in team...
>> >> >
>> >> > The COW rule for when to .dup is:
>> >> >
>> >> >    When you're going to change the data, and you're not *sure*
>> >> > you're
>> > the
>> >> > sole handle to it.
>> >>
>> >> In real projects and in real life this *not sure* is almost always.
>> >
>> > True, but it's also true that most of the time, one doesn't care
>> > because
>> > one
>> > has no need to modify the data.
>>
>> Absolutely true. This is why e.g. string literals
>> shall have type const char[] and not just a char[] by default.
>> This is stupid design mistake in C++:
>> "hello"[0] = 0;
>> will compile and run on one machines and will not on others.
>
> It is an error in C++ to do that, though it is allowed by some compilers
> for
> backwards compatibility. In C++, string literals are const char*.
>
>> Walter, need of const appears together with raw pointers. It is critical to have pointers (slices included) together with const.
>>
>> If some language takes ++ from C but not pointers then
>> it does not need const so much.
>>
>> There is no language in active use which has raw pointers and has no concept of pointers to const data.
>
> I don't know of any language that even allows raw pointers other than C,
> C++
> and D!

Delphi:

function CopyStr(const aSourceString : string; aStart, aLength : Integer) : string;



>
>> > I agree with you that C++ has a culture of "const is good".
>> >
>> > I'd like to find something better, something that works (i.e. that
>> > gives
>> > useful semantic information).
>> >
>> > I also am not understanding how const would help with COW mistakes.
>>
>> What are the "COW mistakes"? I don't understand this exactly....
>
> A COW mistake would be, for example, modifying a reference when you aren't sure you're the owner of it.

See, I even don't know about these errors as I am using

void foo(const char[] s)
{
  s[0] = 0; // here compiler rises an error - warnig me....
}

Is it bad?


>
>> Anyway....
>>
>> void  toLower(in char[] str)
>> char[]  toLower(in const char[] str)
>>
>>
>> Having them both is a matter of optimization.
>> First does transformation in place, second allocates
>> new string.
>>
>> Do these two together make sense? Definitely, yes.
>
> See my comments on this example in another post here.
>
> 


July 03, 2005
On Sun, 3 Jul 2005 15:05:20 -0700, Walter <newshound@digitalmars.com> wrote:
> "Nick" <Nick_member@pathlink.com> wrote in message
> news:da9dfv$1r9p$1@digitaldaemon.com...
>> In article <da7pp5$i06$1@digitaldaemon.com>, Walter says...
>> >
>> >Yet the value can change anyway. Another reference can change it, and
>> >another thread can change it. It isn't "constant" at all, and cannot be
>> >relied on to be constant, even if your program is 100% "const-correct".
>>
>> That is true, but also in fact completly irrelevant. I think you might
> have
>> misunderstood the intention of the const keyword in C++. It's not meant to
> be,
>> and has never been meant to be, a guarantee to the internals of the
> function
>> that "this value will not change". It's not supposed to protect the INSIDE
> of
>> the function from the outside world, but quite the opposite. It's a
> guarantee
>> (or contract, if you will) with the code OUTSIDE the function (ie. the
> caller)
>> that "THIS function will never change this value." What happens in other
> threads
>> and other references has no relevance to this contract. Also, your example
> with
>> foo(a,a) is ok, since when you (the caller) send 'a' as the second
> (non-const)
>> parameter, the function is 'allowed' to change it. Thus the function has
> not
>> broken the contract.
>>
>> I am not arguing for or against const in D here. My experience with it in
> C++
>> has been pretty much the same as yours, and so I am not really convinced
> of it's
>> usefulness. But your argument really attacks a use of 'const' that was
> never
>> intended, and thus is not a very good argument.
>
> You do make a good point.

This is the same point I've tried to make in the past. To me 'in' is part of the function contract stating I will only 'read' this parameter.

I had a DBC style idea for detecting modification to 'in' parameters, it went:

import std.stdio;
import std.string;
import std.c.stdlib;

void main()
{
	char[] a = "regan";
	foo(a);
}

void* cmp = null;

void foo(char[] string)
in {
	cmp = realloc(cmp,string.sizeof);
	memcpy(cmp,&string,string.sizeof);
}
out {
	assert(memcmp(cmp,&string,string.sizeof) == 0);
}
body {
      //this causes the assert, remove it, no assert.
	string.length = 20;
}

The compiler could concievably insert these checks itself.

Of course, this only detects changes to the variable itself be it a reference, pointer, int etc.

It does not address the other desire, to protect the data referenced by the variable.

Regan
July 03, 2005
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da9jf7$210d$1@digitaldaemon.com...
> most cases are strings I believe. So do

I'm afraid not. Take a look at the STL source code :-( Go into \dm\stlport\stlport\stl and do a grep for "const".


July 03, 2005
"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:da9lak$23de$1@digitaldaemon.com...
>
> "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:da9k9n$2201$1@digitaldaemon.com...
>>
>> "Walter" <newshound@digitalmars.com> wrote in message news:da9dc2$1r5s$2@digitaldaemon.com...
>>>
>>> "Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:da9b6j$1ouo$1@digitaldaemon.com...
>>>> Perhaps dstyle.html should say functions with a leading 'to' should not modify their inputs. There are several toFoo functions in phobos and it would be nice to keep that style consistent.
>>>
>>> That's a good idea. There are also the 'is' prefix functions.
>>>
>>>
>>
>> I beleive that next will be a proposal to use 'c' as a first
>> char of parameter name and all this will end up with
>> Polish Notation and the like... Poor man type system to be short.
>>
>> Gentlemen, array and immutable slice are two *distinct* types with their own set of operations. The same for pointers - immutable pointer cannot be dereferenced to l-value.
>>
>> And please don't cover holes in type system by inventing naming conventions. This is not honest.
>>
>> Andrew.
>
> Nothing is preventing someone from writing
>  void upper(char[] str);
>  char[] toUpper(char[] str);
> I see no reason to abuse the already-established conventions with the "to"
> prefix. Multiple versions of toUpper might seem natural to you and your
> team but it isn't "typical" D code. Even if all your proposals were
> accepted I would still argue a function named toUpper should not modify
> its input.
> That isn't saying your general point is wrong - just that the example you
> gave using the name "toUpper" isn't one that should be encouraged.
>

Ben, am I propsing to abuse naming conventions? No.
'to' works in some places and for someone - fine.
But how this related to const?

OT: this 'to' in Russian is one letter and sometimes looks funny combined with camelCase.