April 22, 2005
On Thu, 21 Apr 2005 21:25:36 -0400, Ben Hinkle wrote:

>>  class Foo
>>  {
>>      void Value(Bar x) { ... }
>>  }
>>
>>  class Bar
>>  {
>>      void Value(Foo x) { ... }
>>  }
>>
>>  Foo f = new Foo;
>>  Bar b = new Bar;
>>
>>  Foo.Value = b;
>>  Bar.Value = f;
> 
> Without knowing anything about the context, would using toFoo and toBar work? I use toFoo to "cast" to other types much like toString takes the object and returns a string.

Yes it would work, but I use templates a lot, and there are more classes than just two, so that might be a problem. The syntax "<id>.Value = <id>" is a bit more generic.

> Note the original example Foo.Value = b doesn't compile - I assume you meant something like f.Value = b.

Oops! Just coding from the hip ;-)

-- 
Derek
Melbourne, Australia
22/04/2005 11:27:39 AM
April 22, 2005
"Regan Heath" <regan@netwin.co.nz> wrote in message news:opspln2nhw23k2f5@nrage.netwin.co.nz...
> On Thu, 21 Apr 2005 12:44:35 -0400, Ben Hinkle <ben.hinkle@gmail.com> wrote:
>> "TechnoZeus" <TechnoZeus@PeoplePC.com> wrote in message news:d48iic$9se$1@digitaldaemon.com...
>>> It's a big thread... that might have been in it somewhere.
>>> This branch of it deals with adding ":=" as a separate operator in
>>> addition to the "=" operator,
>>> and having ":=" act as a value assignment operator such that...
>>> a := b;
>>> anways results in (a == b) being true, but never makes (a is b) become
>>> true.
>>>
>>> Not related to overloading the "=" operator.
>>>
>>> TZ
>>
>> hehe. Sorry but it sounds funny to say an operator called := with
>> overload
>> opAssign is not related to overloading assignment. I would bet no matter
>> what the symbol is and the overload name Walter's objections would still
>> apply.
>
> But they don't as far as I can see. Reading: http://www.digitalmars.com/d/faq.html#assignmentoverloading
>
> and remembering he mentioned something along the lines of "overloading = causes subtle behaviour which is a source of bugs for little gain".
>
> 1. := is a new operator, so no subtle behaviour for = is added.
>
> 2. You could argue := has the subtle behaviour, but I argue it isn't subtle because if you use := you're asking for that behaviour.

I agree it's a matter of opinion what counts as subtle and what doesn't. The fact that users would know := can be subtle still makes it subtle. The argument that := isn't like = is too subtle for me ;-)

> 3. The copy constructor argument is on the surface valid, but consider intrinsics which have no constructors at all.
>
> 4. Lastly .dup does not solve the whole problem, the original intent was to make this possible:
>
> class A{}
> class B{}
>
> A a = new A();
> B b;
>
> b = a;
>
> construct a A using an A.
>
> So while you can write a copy constructor:
>
> class A {
>  this(B b) {}
> }
>
> intrinsics don't have constructors so in a template:
>
> template(T) { void foo(T t) {
>   B b = new B();
>   T t;
>
>   t = new T(b);
> }}
>
> it doesn't work when T is 'int' etc.

I think I need more context - I am missed the point.

> .dup does not solve the above as:
>   t = b.dup
>
> returns a B not a T.
>
>
> However := solves both problems neatly.
>
> t := b;
>
> calls opAssign for type T (for intrinsics it would do what it currently does on assignment).

I don't really get the point so correct me if I'm wrong but I think your example is getting at converting a B into a T while copying the value. I agree dup only concerns itself with duplicating a value and not with casting it or converting it to something else. For that one needs other mechanisms and I would agree it's hard to write generic code in D that does conversions. The opCast is clunky because you can't overload it. Personally I'm not convinced := is the right way to solve the casting problem, though. Consider if D got something that let you say "t = cast(T)b". That would be cleaner than introducing := IMO. If a copy of the value is needed it could be "t = cast(T)b.dup".


April 22, 2005
On Thu, 21 Apr 2005 21:40:45 -0400, Ben Hinkle <ben.hinkle@gmail.com> wrote:
> I don't really get the point so correct me if I'm wrong but I think your
> example is getting at converting a B into a T while copying the value.

Yes. Derek originally wanted to overload opCast by return type or something along those lines.

After some thought I figured casting is actually just "copying the 'value' using some predefined method", i.e. casting from int to float copies the 'value' be it 5, 9 etc but uses some method to arrange the value in 'float' form.

I also remembered a while back someone wanting a way to deep copy things.

It occured to me a deep copy is also "copying the 'value' using some predefined method" where the source type is the same as the destination type.

So then I figured, why not combine all these ideas into one thing, an operator that copies the 'value' from the RHS into the LHS, thus ":=".

> I agree dup only concerns itself with duplicating a value and not with casting it or converting it to something else. For that one needs other mechanisms and I would agree it's hard to write generic code in D that does
> conversions. The opCast is clunky because you can't overload it.

Correct.

> Personally I'm not convinced := is the right way to solve the casting problem, though.

I am not adverse to other suggestions...

> Consider if D got something that let you say "t = cast(T)b". That would be cleaner than introducing := IMO.

Maybe. This would call some variant of opCast or something similar. Then you'd write a dup method when LHS and RHS are the same type. So you have opCast and dup methods, instead of opAssign methods. The latter just seems .. cleaner to me.

> If a copy of the value is needed it could be "t = cast(T)b.dup".

Wouldn't "t = cast(T)b" have to copy anyway?

Regan
April 22, 2005
"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d48l9l$cb7$1@digitaldaemon.com...
>
> "TechnoZeus" <TechnoZeus@PeoplePC.com> wrote in message news:d48iic$9se$1@digitaldaemon.com...
> > It's a big thread... that might have been in it somewhere.
> > This branch of it deals with adding ":=" as a separate operator in
> > addition to the "=" operator,
> > and having ":=" act as a value assignment operator such that...
> > a := b;
> > anways results in (a == b) being true, but never makes (a is b) become
> > true.
> >
> > Not related to overloading the "=" operator.
> >
> > TZ
>
> hehe. Sorry but it sounds funny to say an operator called := with overload opAssign is not related to overloading assignment. I would bet no matter what the symbol is and the overload name Walter's objections would still apply.
>
> ps - I should have asked you to do my taxes :-)
>
>

Yes, you're right.  If that had been what we were saying, it would have sounded funny.

TZ


April 22, 2005
Using := as a value assignment operator would have more uses than just those related to casting.

Yes, it is true that there could be advantages in that area, but they would be "emergent advantages" and would surface as a function of the implementation.

TZ


April 22, 2005
The problem isn't a lack of understanding.
The problem in comming to a uniform agreement is mostly in the idea that there is only one right way to do something.
A few people who are comfortable with the way things are oppose the addition of an alternative way of doing things because they see it as "not needed" since they personally don't need it.

It's unfortunately an all too common way of looking at the world,
and if that way of thinking were to be applied across the board,
then since some people never program at all,
we could consider any programming language to be completely useless,
and since some people never use computers,
we could consider all computers to be useless as well.

In fact, if the only thing it takes for something to be useless is that "someone" fails to see the use for it, then by that logic, there is nothing in this world that is of any use at all.

Personally, I favor looking at the world from a less egocentric point of view. If it's useful to "someone" then it is of value.

The := operator would "obviously" be of use to "many" people, even if there are a few people who just don't see it.

TZ


"Georg Wrede" <georg.wrede@nospam.org> wrote in message news:42682A29.8090300@nospam.org...
> brad beveridge wrote:
> > Vladimir wrote:
> > <snip>
> > Vladimir - that is a fantastic example of the disconnect between
> > reference types and value types, and how screwed up you could
> > potentially get with templates.  You've also illustrated that the :=
> > operator doesn't really cut it in terms of making life better.
> > Can we come up with something that fixes this?
>
> This post essentially sums up what I've been talking about for some time.
>
> 1) It is obvious that the difference between reference and value
> assignment does cause head aches. (For the non-gurus anyway. :-) )
>
> 2) All of the discussion about "=" vs "==" (etc.) has actually been
> about this single issue (whether all the participants have realised it,
> or not.)
>
> 3) There seems not to exist an obvious solution, at least as far as we've got so far.
>
> 4) For all I know, there might not even exist a problem here. (!) OTOH, this does seem to be a thing that gets peoples' attention, and does seem to disturb people -- even if they come from C++ or Java. (Those coming from other languages, I'd _expect_ to get stuck with this issue.)
>
> 5) Considering that D is a "metal near language" (in the spirit of C),
> and a high level language (in the spirit of C++ and Java -- but not ever
> aspiring to the level of Lisp), it is natural, that this distinction is
> prominent in the language -- after all, the distinction is very visible
> in assembler and C. (And in processor architecture.)
>
> 6) As a side effect of this, the discussion of .value and .reference, as
> well as (a part of) the discussion of comparability vs. equality, has
> arisen.
>
> On the surface, there would exist a number of "solutions".
>
>   - Create two distinct assignment operators.
>
>     - := and =.
>
>       - Have each do its part, and only then default to the other.
>
>       - Have each do its part, and fail when applied wrong.
>
>       - Have a war about which does which.
>
>   - Somehow else separate value and reference assignment.
>
>       - Using & or some other syntactic means.
>
>       - Rely on the lvalue accepting only either.
>
> I could go on with this list, as anybody else could, too. But what I see here is, a lack of a common understanding and thorough insight between the two. Therefore, I suggest that we refrain from "Calling Walter" for quite some time with this issue.
>
> We really need to get to the bottom of this. (We might find nothing of value -- whence the existing status quo would suffice. Or, we might find something else, but then we'd know exactly what we want! By that time it would be "a piece of cake" to ask Walter to pay attention.)
>
> So far, however, this discussion (excuse me, everybody) hasn't turned up anything "new". Hey, I'm not putting any single person down, or the entire discussion. I'm just (like a referee, this time) "lifting the cat on the table" as we say in Finland, or writing the obvious on the wall.
>
> -----
>
> I do (whaddayaknow) humbly admit here, that I haven't got a clear picture of the issue, so far. Somehow I "feel" that the distinction between value and reference, is, eh, unsharp. (Not as a concept, but as it is implemented in the _syntax_ (or, more to the point, the _semantics_) of quite a few languages, including D.)
>
> On one hand, I'd love a situation where there were two separate assignment operators (for example := and =), where neither would accept the "wrong" kind of rvalue nor lvalue.
>
> On the other hand, I feel that this would make programming cumbersome, introduce gratuituous obstacles, steer folks' attention to undeserving detail, and appear low-level upon the whole.
>
> -----
>
> The distinction between value and reference is (to my (this time) not so
> humble opinion), very much less clear to the newcomer in D, as it is in
> C. The same problem occurred to me when initially learning Pascal.
> (Where it was actually less opaque than in D.)
>
> While people hate pointers and references in C, at least they are consistent (in _this_ respect, not necessarily in general).
>
> So, this discussion does carry some merit, IMHO.
>
>    But let's not assume this is for D 1.0!!!
>
>    Let's all accept that this discussion is about
>    something bigger, and more fundamental, and
>    therefore we'd be stupid to ecxpect that we'd
>    reach the required level of common (or even
>    individual) understanding before D 1.0
>    has been out for a long time.
>
> While I'm not suggesting that we get rid of imports or the need to write the main function (for the illiterate, see other thread), I do think that this issue is worth some serious study.


April 22, 2005
xs0 wrote:

> 
>>>Hmm, isn't there a problem that if you do
>>>
>>>func(T a)
>>>{
>>>     T b:=a;
>>>}
>>>
>>>b is null if T is reference-type, so it can't even have the value assigned? You can't explicitly new it, because that wouldn't work with primitive types again.
>>>
>>>It could get automatically allocated, but that'd require the class to have a zero-parameter constructor, which may again break, and in fact, calling it may cause unforeseen effects.
>> 
>> Please, look at my post in different branch of this thread: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22165
> 
> With .init on classes:
> - all uninitialized vars of a class will point to the same object
> - using := with any of them will change all the others
> - so, even trivial code like
Yes, you are right and I was wrong.
Possible solution is to allow .init property to return new instance of
class:

class A {
        static A init() {
                // return new A object with reasonable state
                return new A(0,0);
                // default is return null;
        }
}

so for now
A a,b;
a == b - true
a is b - false

> func(T a, T b)
> {
> T c:=a+b;
> T d:=a*b;
> 
> return c/d;
> }
> 
> will totally not work, because after the second line, c will have the same value as d, so the result will always be the same (1, assuming some normal numeric class). In a multithreaded app, things will get even uglier, because c and d may get modified from outside, which is not the case with =.
> 
> 


-- 
          Vladimir
April 22, 2005
As it turns out, the .dup member function returns a reference, rather than a value (at least in arrays, as I have tested it), and so does not qualify as a substitute for directly working the a value rather than a reference.  The := reference operator is still needed.

TZ

"pragma" <pragma_member@pathlink.com> wrote in message news:d48rjc$ibp$1@digitaldaemon.com...
> In article <d48pet$g4d$1@digitaldaemon.com>, Vladimir says...
> >
> >> Not that I think it's a good idea, but you could use something like '@' to mean 'value-of' (which would be akin to '&' meaning 'address-of').
> >>
> >> { return @a; }
> >>
> >> This isn't too bad, but it still lands us in "create a new operator territory".
> >But what is so fundamental difference between "create a new property for fundamental data type" and "create a new operator" ?
>
> Largely, the compiler impact is the biggest difference; a universal dup() property won't require anything new in the lexer and will likely be easily attached to the property evaluation bits already present.  Adding a ':=' operator requires changes to the lexer, and a expression handling branch, with quirks and rules all its own.  IMO, adding ':=' would be much more work to do, and not worth it since D has already (partially) sovled the problem.
>
> There is a smaller impact to D's grammar is a close second as ':=' is somewhat ambiguous when applied to certain cases; I'm welcome to be wrong about that. Regardless, .dup() is wholly unambiguous and meshes well with the present design.
>
> >
> >>
> >> I still think .dup() is the way to go.
> >For me it's just harder to type that @.
> >The only thing is that having @ operator it's too big tempting to allow T@
> >for creating class-value-type, which Walter will never accept, wont
> >he ? :-)
>
> Probably not.  Again, I'd be willing to bet that extending .dup to everything would be cake to implement by comparison.
>
> - EricAnderton at yahoo


April 22, 2005
oops... brain thought one thing, and hands typed another.

that last line should have read...

The := value assignment operator is still needed.

TZ

"TechnoZeus" <TechnoZeus@PeoplePC.com> wrote in message news:d4adkr$21p6$1@digitaldaemon.com...
> As it turns out, the .dup member function returns a reference, rather than a value (at least in arrays, as I have tested it), and so does not qualify as a substitute for directly working the a value rather than a reference.  The := reference operator is still needed.
>
> TZ
>
> "pragma" <pragma_member@pathlink.com> wrote in message news:d48rjc$ibp$1@digitaldaemon.com...
> > In article <d48pet$g4d$1@digitaldaemon.com>, Vladimir says...
> > >
> > >> Not that I think it's a good idea, but you could use something like '@' to mean 'value-of' (which would be akin to '&' meaning 'address-of').
> > >>
> > >> { return @a; }
> > >>
> > >> This isn't too bad, but it still lands us in "create a new operator territory".
> > >But what is so fundamental difference between "create a new property for fundamental data type" and "create a new operator" ?
> >
> > Largely, the compiler impact is the biggest difference; a universal dup() property won't require anything new in the lexer and will likely be easily attached to the property evaluation bits already present.  Adding a ':=' operator requires changes to the lexer, and a expression handling branch, with quirks and rules all its own.  IMO, adding ':=' would be much more work to do, and not worth it since D has already (partially) sovled the problem.
> >
> > There is a smaller impact to D's grammar is a close second as ':=' is somewhat ambiguous when applied to certain cases; I'm welcome to be wrong about that. Regardless, .dup() is wholly unambiguous and meshes well with the present design.
> >
> > >
> > >>
> > >> I still think .dup() is the way to go.
> > >For me it's just harder to type that @.
> > >The only thing is that having @ operator it's too big tempting to allow T@
> > >for creating class-value-type, which Walter will never accept, wont
> > >he ? :-)
> >
> > Probably not.  Again, I'd be willing to bet that extending .dup to everything would be cake to implement by comparison.
> >
> > - EricAnderton at yahoo
>
>


April 22, 2005
Actually, it's not ambiguous at all.  At least, not to me... and I'm guessing not to other people who see the advantages of a := value assignment operator.  There is a clear distinction between working with values and working with identities.  If you interpret "a+7" as an identity operation, then that interpretation obviously can't be assigned using a value assignment operator.  If you interpret it as a value operation, then the results would be a value.  You don't need to look for the value stored at the location pointed to by the identity referenced to specify the value.  That's recursive, and serves only to cause an invinite loop.

b := a+7;

would mean that the value "7" is added to the value stored in "a" and then the value of b is set to the resulting value.  No ambiguity.  That's the idea.

TZ

"pragma" <pragma_member@pathlink.com> wrote in message news:d48osb$fgg$1@digitaldaemon.com...
> I should've double-checked before posting.
>
> by 'lvalue', I actually mean 'rvalue'.  Sorry for the confusion.
>
> -EricAnderton at yahoo
>
> In article <d48nr3$ejr$1@digitaldaemon.com>, pragma says...
> >
> >In article <d48je6$arv$1@digitaldaemon.com>, TechnoZeus says...
> >>
> >>If the programmer wants to be sure that they are assigning values, and not changing the address of somehting, then the ":=" operator would be used...
> >>
> >>int a := 5;
> >>int b;
> >>int c;
> >>b := a+7;
> >>c := b;
> >>
> >>No ambiguity there.  Notice that with this convention, one would know what "a := b" is supposed to do, even without knowing what "a" and "b" represent.  The same can not be said of "a = b" in D.
> >>
> >
> >The problem with your example in this argument is that it's ambiguous.
> >
> >b := a+7
> >
> >Does it mean "take the actual value of the lvalue"?
> >
> >b = (a+7).opValue;
> >
> >.. or "take the actual value of all the distinct portions of the lvalue"?
> >
> >b = a.opValue + 7.opValue;
> >
> >Which is correct?  Also, keep in mind, that with either interpretation, will limit its percieved utility:
> >
> >T a,b,c,d;
> >a := b + c + d;
> >
> >To obtain the opvalue of just one of b,c or d, i need to use more than one expression; regardless of the actual interpretation of ':='.  To side-step the limitations of the operator.  This is in sharp contrast to operators like good ol' '=' or even '&', which are much more explicit.
> >
> >With an explicit syntax like '.dup' there's no question as to what's going on.
> >
> >- EricAnderton at yahoo
>
>