February 12, 2004
J Anderson wrote:
>
> Sean Kelly wrote:
> 
>> So there's no way for a caller to ensure he's safe from side-effects when passing a class to a function?  I didn't think this was typical even for GC languages.
> 
> I'm not 100% sure, but I think it's the same in Java. Although it would be nice to have a read only in D.  You could always make a copy of A before you pass it (or after) if you want to modify without side effect.  You can also use design by contracts.

I thought a bit more about this last night and decided the D way is good.  Adding const qualifiers for parameter passing would require the existence of const qualifiers for member functions, a mutable qualifier, etc.  And then there's the issue of some classes which just plain aren't copyable: streams and other complex objects with state information.

I think this is one thing I'm just going to have to get used to. Document the cases where a side-effect may occur and allow the user to make a copy before passing if it's an issue.  And I checked the Java spec last night and I think you're right--I could find no mention of by value vs. by reference passing.

The fact that structs are copied makes me wonder though.  Is it enough just to rely on the optimizer for keeping such operations efficient? I'm inclined to think so.  Also, I imagine that using the inout qualifier on POD types will pass them by reference?


Sean

February 12, 2004
Sean Kelly wrote:
> J Anderson wrote:
>  >
> 
>> Sean Kelly wrote:
>>
>>> So there's no way for a caller to ensure he's safe from side-effects when passing a class to a function?  I didn't think this was typical even for GC languages.
>>
>>
>> I'm not 100% sure, but I think it's the same in Java. Although it would be nice to have a read only in D.  You could always make a copy of A before you pass it (or after) if you want to modify without side effect.  You can also use design by contracts.
> 
> 
> I thought a bit more about this last night and decided the D way is good.  Adding const qualifiers for parameter passing would require the existence of const qualifiers for member functions, a mutable qualifier, etc.  And then there's the issue of some classes which just plain aren't copyable: streams and other complex objects with state information.
> 
> I think this is one thing I'm just going to have to get used to. Document the cases where a side-effect may occur and allow the user to make a copy before passing if it's an issue.  And I checked the Java spec last night and I think you're right--I could find no mention of by value vs. by reference passing.

Java doesn't have the distinction. It passes all by quasi-value, which makes integers, characters and floats/doubles (ie primitive types) pass by value, everything else is a class (even if the fact is partially hidden from the user) and thus passes by reference.

In general, functions should be written in a safe manner, like the copy-on-write string examples from the manual.

> The fact that structs are copied makes me wonder though.  Is it enough just to rely on the optimizer for keeping such operations efficient? I'm inclined to think so.  Also, I imagine that using the inout qualifier on POD types will pass them by reference?

I don't know how a current implementation decides it, but your struct is admittably tiny - everything not larger than 8 bytes is faster to pass by value than by reference. I would guess that implementation decides how to actually pass. However, value pass semantics stays - this can be done e.g. by detecting whether any change is being made, and if there is, then make a local copy in the beginning of the function.

If i remember correctly, Delphi had 2 access modifiers, const and var. Var was the same as inout, const was to disallow any change. While this looks elegant, it has still at least one problem: you can *never* reasonably detect a change on an object, unlike a struct. There are deep reasons to that, if you like i could explain, or you simply may guess them. So i must say i'm satisfied with D solution. Especiall, it doesn't break common code e.g. from Java.

And yes, inout on structs makes them definately pass by reference, but you shouldn't do that for performance reasons. Do this only if you actually modify the struct and need the inout semantics.

-eye

February 12, 2004
Ilya Minkov wrote:
>
> If i remember correctly, Delphi had 2 access modifiers, const and var. Var was the same as inout, const was to disallow any change. While this looks elegant, it has still at least one problem: you can *never* reasonably detect a change on an object, unlike a struct. There are deep reasons to that, if you like i could explain, or you simply may guess them. So i must say i'm satisfied with D solution.

This was my conclusion last night.  Once I gave it some thought I realized the complexity involved and decided it wasn't worth the hassle.  The D method now makes sense.

> And yes, inout on structs makes them definately pass by reference, but you shouldn't do that for performance reasons. Do this only if you actually modify the struct and need the inout semantics.

Agreed.  I was mostly curious for academic reasons as I'm still getting the hang of this language.


Sean

February 23, 2004
"Sean Kelly" <sean@ffwd.cx> wrote in message news:c0e6jd$sr0$1@digitaldaemon.com...
> J Anderson wrote:
>  >
> > Nar, it's by-design.  You see objects in D are references (pointers) themselves. Structs however aren't.
>
> So there's no way for a caller to ensure he's safe from side-effects when passing a class to a function?  I didn't think this was typical even for GC languages.

Sounds completely typical for GC languages.



February 23, 2004
"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c0e6rk$t00$1@digitaldaemon.com...
> Sean Kelly wrote:
>
> > J Anderson wrote:
> > >
> >
> >> Nar, it's by-design.  You see objects in D are references (pointers) themselves. Structs however aren't.
> >
> >
> > So there's no way for a caller to ensure he's safe from side-effects when passing a class to a function?  I didn't think this was typical even for GC languages.
>
> I'm not 100% sure, but I think it's the same in Java. Although it would be nice to have a read only in D.  You could always make a copy of A before you pass it (or after) if you want to modify without side effect.  You can also use design by contracts.

No, this is an area where C/C++ got it right, and D/.NET/Java have it quite wrong.

Alas Walter is influenced by the practical breakability of C/C++'s const - by casts - and its conceptual splendour seems to have skipped him.

But this argument is long gone, and we lost. D will have to be broken in this regard.

btw, DBC is *quite* the wrong tool for this - it's a compile time thing. Alas, because we are denied the const (or "readonly", which makes much more sense) keyword, it is our only tool. :(



February 23, 2004
"Sean Kelly" <sean@ffwd.cx> wrote in message news:c0ea34$136o$1@digitaldaemon.com...
> J Anderson wrote:
>  >
> > IMHO, for such a task DBC is more work with marking it read-only.
>
> And how would DBC work in this case anyway?  Say I have a function I want to gurantee will not alter its parameters:
>
>
> class A {}
>
> void func( int i, A a )
> in
> {
>      A ain = new A( a )
> }
> out
> {
>      assert( a == ain );
> }
> body
> {
> ...
> }
>
>
> This doesn't work for two reasons.  First, A doesn't have a copy ctor, so I can't create a new A in this way.  Second, ain expires when the in block completes.  To make matters worse, if func is a template function and A might be either a primitive or object type, I need to be more careful about how I generate the copy.  And all this just to produce a "const" equivalent.  There has to be a better way.

It's called const / readonly. :-(



February 23, 2004
"Sean Kelly" <sean@ffwd.cx> wrote in message news:c0g9td$17gl$1@digitaldaemon.com...
> J Anderson wrote:
>  >
> > Sean Kelly wrote:
> >
> >> So there's no way for a caller to ensure he's safe from side-effects when passing a class to a function?  I didn't think this was typical even for GC languages.
> >
> > I'm not 100% sure, but I think it's the same in Java. Although it would be nice to have a read only in D.  You could always make a copy of A before you pass it (or after) if you want to modify without side effect.  You can also use design by contracts.
>
> I thought a bit more about this last night and decided the D way is good.  Adding const qualifiers for parameter passing would require the existence of const qualifiers for member functions, a mutable qualifier, etc.  And then there's the issue of some classes which just plain aren't copyable: streams and other complex objects with state information.

Nooooooooooooooo! Don't believe the hype.

It's bad, bad, bad. This is one important area in which the hunt for compiler simplicity is a specious one.

> I think this is one thing I'm just going to have to get used to. Document the cases where a side-effect may occur and allow the user to make a copy before passing if it's an issue.  And I checked the Java spec last night and I think you're right--I could find no mention of by value vs. by reference passing.

Everything is passed by value in Java, including references. A copy of a reference is another reference to the same object. Since the only distinguishing aspect of a refernece is its referent, it looks as if pass-by-reference is being used for references, but it's not. :-)

> The fact that structs are copied makes me wonder though.  Is it enough just to rely on the optimizer for keeping such operations efficient? I'm inclined to think so.  Also, I imagine that using the inout qualifier on POD types will pass them by reference?

We can but hope!



February 23, 2004
Matthew wrote:

>"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message
>news:c0e6rk$t00$1@digitaldaemon.com...
>  
>
>>Sean Kelly wrote:
>>
>>    
>>
>>>J Anderson wrote:
>>>      
>>>
>>>>Nar, it's by-design.  You see objects in D are references (pointers)
>>>>themselves. Structs however aren't.
>>>>        
>>>>
>>>So there's no way for a caller to ensure he's safe from side-effects
>>>when passing a class to a function?  I didn't think this was typical
>>>even for GC languages.
>>>      
>>>
>>I'm not 100% sure, but I think it's the same in Java. Although it would
>>be nice to have a read only in D.  You could always make a copy of A
>>before you pass it (or after) if you want to modify without side
>>effect.  You can also use design by contracts.
>>    
>>
>
>No, this is an area where C/C++ got it right, and D/.NET/Java have it quite
>wrong.
>  
>
Where is that no referring to. No it's not the same in java? No it wouldn't be nice to have a read-only in D?
No you can't  make a copy before/after passing it?

>Alas Walter is influenced by the practical breakability of C/C++'s const -
>by casts - and its conceptual splendour seems to have skipped him.
>
>But this argument is long gone, and we lost. D will have to be broken in
>this regard.
>
>btw, DBC is *quite* the wrong tool for this - it's a compile time thing.
>Alas, because we are denied the const (or "readonly", which makes much more
>sense) keyword, it is our only tool. :(
>  
>
I completely agree, I was just trying to be practical.

-- 
-Anderson: http://badmama.com.au/~anderson/
February 23, 2004
"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c1c89p$54m$1@digitaldaemon.com...
> Matthew wrote:
>
> >"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c0e6rk$t00$1@digitaldaemon.com...
> >
> >
> >>Sean Kelly wrote:
> >>
> >>
> >>
> >>>J Anderson wrote:
> >>>
> >>>
> >>>>Nar, it's by-design.  You see objects in D are references (pointers) themselves. Structs however aren't.
> >>>>
> >>>>
> >>>So there's no way for a caller to ensure he's safe from side-effects when passing a class to a function?  I didn't think this was typical even for GC languages.
> >>>
> >>>
> >>I'm not 100% sure, but I think it's the same in Java. Although it would be nice to have a read only in D.  You could always make a copy of A before you pass it (or after) if you want to modify without side effect.  You can also use design by contracts.
> >>
> >>
> >
> >No, this is an area where C/C++ got it right, and D/.NET/Java have it
quite
> >wrong.

It was no to DBC (in this case)



February 23, 2004
Matthew wrote:

> "Sean Kelly" <sean@ffwd.cx> wrote in message
> news:c0g9td$17gl$1@digitaldaemon.com...
>
>>I thought a bit more about this last night and decided the D way is
>>good.  Adding const qualifiers for parameter passing would require the
>>existence of const qualifiers for member functions, a mutable qualifier,
>>etc.  And then there's the issue of some classes which just plain aren't
>>copyable: streams and other complex objects with state information.
> 
> Nooooooooooooooo! Don't believe the hype.
> 
> It's bad, bad, bad. This is one important area in which the hunt for
> compiler simplicity is a specious one.

I'll admit that I would like consts, but I can understand that it's far more than just adding a "const" qualifier to parameters.  but with "const" missing, I'd like to add a *strong* recommendation that creators of classes supply a copy ctor.

> Everything is passed by value in Java, including references. A copy of a
> reference is another reference to the same object. Since the only
> distinguishing aspect of a refernece is its referent, it looks as if
> pass-by-reference is being used for references, but it's not. :-)

But it amounts to the same thing.  This raises some interesting issues regarding exception safety and "const" gurantees.  Can a function writer ever be sure that an object he is passed will be returned in an unaltered state?  I'm inclined to think not, unless he always created a copy of any passed object before doing *anything* with it.  This is an idea I'm still warming up to.  I think I'll have to write some serious code in D before I decide whether this is an issue I'm happy with.


Sean