Jump to page: 1 2 3
Thread overview
opValue()
Apr 06, 2005
Derek Parnell
Apr 06, 2005
Ben Hinkle
Apr 06, 2005
Derek Parnell
Apr 06, 2005
Regan Heath
Apr 06, 2005
Ben Hinkle
Apr 06, 2005
Derek Parnell
Apr 06, 2005
Regan Heath
Apr 06, 2005
Derek Parnell
Apr 06, 2005
Derek Parnell
Apr 06, 2005
Regan Heath
Apr 06, 2005
Derek Parnell
Apr 06, 2005
Regan Heath
Apr 06, 2005
Derek Parnell
Apr 06, 2005
Georg Wrede
Apr 06, 2005
xs0
Apr 06, 2005
Derek Parnell
Apr 06, 2005
xs0
Apr 06, 2005
brad
Apr 07, 2005
Regan Heath
Apr 07, 2005
Derek Parnell
Apr 07, 2005
brad
Apr 07, 2005
Regan Heath
Apr 07, 2005
xs0
Apr 08, 2005
brad
Apr 06, 2005
Ben Hinkle
Apr 06, 2005
David Medlock
Apr 06, 2005
Derek Parnell
Apr 07, 2005
Vladimir
April 06, 2005
Walter (and anyone else),

AAAARRRRRGGGGGHHHH!!!!! (Sorry about that. I'm getting a little frustrated at the hoops D is putting me through).

Here's an idea to kick around...

In the construct

    a = <expression>;

when 'a' is an aggregate, it is equivalent to coding

    a.opValue(<expression>);

This would make my coding life *so* much easier. It is one way of providing a natural coding style for implicit conversion of classes and structs.

Here is some sample code to explain what I'd like ...
<code>
import std.stdio;
class A
{
    private int aa;
    this() { aa = 2; }
    A opValue(B y)
    {
        aa = y.bb + 1; // 'convert' a B to an A
        return this;
    }
}
class B
{
    private int bb;
    this() { bb = 4; }
    B opValue(A y)
    {
        bb = y.aa - 10;  // 'convert' an A to a B
        return this;
    }
}

void main()
{
    A a = new A;
    B b = new B;

    writefln("Before %d %d", a.aa, b.bb);

    a.opValue(b); // aka: a = b;
    b.opValue(a); // aka: b = a;

    writefln("After  %d %d", a.aa, b.bb);
}
</code>

-- 
Derek Parnell
Melbourne, Australia
http://www.dsource.org/projects/build/ v1.19 released 04/Apr/2005
http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage
6/04/2005 10:45:52 AM
April 06, 2005
"Derek Parnell" <derek@psych.ward> wrote in message news:9wvklcksh1nr.n1xvda56jdpe$.dlg@40tude.net...
> Walter (and anyone else),
>
> AAAARRRRRGGGGGHHHH!!!!! (Sorry about that. I'm getting a little frustrated at the hoops D is putting me through).

no problem.

> Here's an idea to kick around...
>
> In the construct
>
>    a = <expression>;
>
> when 'a' is an aggregate, it is equivalent to coding
>
>    a.opValue(<expression>);
>
> This would make my coding life *so* much easier. It is one way of
> providing
> a natural coding style for implicit conversion of classes and structs.

I'm confused. By aggregate I assume you mean either a struct or class type. But with a class a.opValue will seg-v if a is null so how does one initialize a? See http://www.digitalmars.com/d/archives/23623.html for a thread including a message from Walter explaining why D doens't allow assignment to be overloaded.

More context about what you are actually trying to do would help, too.

> Here is some sample code to explain what I'd like ...
> <code>
> import std.stdio;
> class A
> {
>    private int aa;
>    this() { aa = 2; }
>    A opValue(B y)
>    {
>        aa = y.bb + 1; // 'convert' a B to an A
>        return this;
>    }
> }
> class B
> {
>    private int bb;
>    this() { bb = 4; }
>    B opValue(A y)
>    {
>        bb = y.aa - 10;  // 'convert' an A to a B
>        return this;
>    }
> }
>
> void main()
> {
>    A a = new A;
>    B b = new B;
>
>    writefln("Before %d %d", a.aa, b.bb);
>
>    a.opValue(b); // aka: a = b;
>    b.opValue(a); // aka: b = a;
>
>    writefln("After  %d %d", a.aa, b.bb);
> }
> </code>

What's wrong with writing a.opValue(b) or a.copyFrom(b) or something? Why is "=" needed? Are you using templates?


April 06, 2005
On Tue, 5 Apr 2005 21:48:54 -0400, Ben Hinkle wrote:

> "Derek Parnell" <derek@psych.ward> wrote in message news:9wvklcksh1nr.n1xvda56jdpe$.dlg@40tude.net...

>> Here's an idea to kick around...
>>
>> In the construct
>>
>>    a = <expression>;
>>
>> when 'a' is an aggregate, it is equivalent to coding
>>
>>    a.opValue(<expression>);
>>
>> This would make my coding life *so* much easier. It is one way of
>> providing
>> a natural coding style for implicit conversion of classes and structs.
> 
> I'm confused. By aggregate I assume you mean either a struct or class type.

Yep.

> But with a class a.opValue will seg-v if a is null so how does one initialize a?

Huh? Did I mention initializing? See example code below. Classes would still be initialized as normal, with the 'new' keyword. I'm talking about assigning value to a (existing) class/struct based on the value of an expression. Nothing to do with constructors, etc...

> See http://www.digitalmars.com/d/archives/23623.html for a thread including a message from Walter explaining why D doens't allow assignment to be overloaded.

Yes, I remember this discussion. It was mainly dealing with constructors for structs and deep vs shallow copying.

The primary reason (I think) for Walter not liking that, is what happens when assigning class instances between related classes. Eg...

  class C {}
  class B:C {}
  class A:B {}

  C c;
  A a;

  c = a; // This is legal and useful.

> More context about what you are actually trying to do would help, too.

See code below ;-)

My emphasis is on making life easier for coders and readers. So sure there is a 'work around', namely explicitly calling opValue(), but I argue that doing so is not as intuitive as the commonly used '=' symbol.

So here is a more fuller description of what I think would make coding in D a more pleasant experience.

__________________________
 In the construct

    a = <expression>;

when 'a' is an aggregate *and* it contains the member function 'opValue', it is equivalent to coding

    a.opValue(<expression>);

otherwise the construct behaves as with the current semantics. __________________________

The idea, is to have a nice way in which a class designer can invent built-in conversion routines for explicit data types, and have people use those conversion routines in a standard, clean and intuitive manner.

>> Here is some sample code to explain what I'd like ...
>> <code>
>> import std.stdio;
>> class A
>> {
>>    private int aa;
>>    this() { aa = 2; }
>>    A opValue(B y)
>>    {
>>        aa = y.bb + 1; // 'convert' a B to an A
>>        return this;
>>    }
>> }
>> class B
>> {
>>    private int bb;
>>    this() { bb = 4; }
>>    B opValue(A y)
>>    {
>>        bb = y.aa - 10;  // 'convert' an A to a B
>>        return this;
>>    }
>> }
>>
>> void main()
>> {
>>    A a = new A;
>>    B b = new B;
>>
>>    writefln("Before %d %d", a.aa, b.bb);
>>
>>    a.opValue(b); // aka: a = b;
>>    b.opValue(a); // aka: b = a;
>>
>>    writefln("After  %d %d", a.aa, b.bb);
>> }
>> </code>
> 
> What's wrong with writing a.opValue(b) or a.copyFrom(b) or something? Why is "=" needed?

To make writing and reading coding a more pleasant experience.

Imaging being able to doing something like this ...

  Circle c;
  Square s;
  Triangle t;
  . . .
  c = s; // Convert the square to a circle.
  t = c; // Convert the circle to a triangle.
  . . .


In my current project, I need to convert between various classes and structs, and currently it involves lots of white-noise coding. A cleaner, clearer, method of coding this would be appreciated.

> Are you using templates?

Yes, and that too. That fact that you must use different syntax depending on whether you are using a class, a struct, an array or an intrinsic data type is a real PITA.

-- 
Derek Parnell
Melbourne, Australia
http://www.dsource.org/projects/build/ v1.19 released 04/Apr/2005
http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage
6/04/2005 12:54:43 PM
April 06, 2005
On Wed, 6 Apr 2005 12:57:00 +1000, Derek Parnell <derek@psych.ward> wrote:
>> But with a class a.opValue will seg-v if a is null so how does one
>> initialize a?
>
> Huh? Did I mention initializing? See example code below. Classes would
> still be initialized as normal, with the 'new' keyword. I'm talking about
> assigning value to a (existing) class/struct based on the value of an
> expression. Nothing to do with constructors, etc...

I think what Ben was trying to say here is that:

(assume A is a class)
A a = new A();

*is* assigning a value to 'a' so would call "opValue(A a)" in A, if it existed.

Regan.
April 06, 2005
"Regan Heath" <regan@netwin.co.nz> wrote in message news:opsosivfu423k2f5@nrage.netwin.co.nz...
> On Wed, 6 Apr 2005 12:57:00 +1000, Derek Parnell <derek@psych.ward> wrote:
>>> But with a class a.opValue will seg-v if a is null so how does one initialize a?
>>
>> Huh? Did I mention initializing? See example code below. Classes would still be initialized as normal, with the 'new' keyword. I'm talking about assigning value to a (existing) class/struct based on the value of an expression. Nothing to do with constructors, etc...
>
> I think what Ben was trying to say here is that:
>
> (assume A is a class)
> A a = new A();
>
> *is* assigning a value to 'a' so would call "opValue(A a)" in A, if it existed.
>
> Regan.

Yes, that's what I was thinking. To put it another way, the code
A a;
will initialize a to null and so when you try to run
a = b;
it will try to run a.opValue(b) which will seg-v. This is slightly different
than
A a = new A;
but basically I'm wondering how a.opValue works when a is null or during
initialization.


April 06, 2005
On Wed, 06 Apr 2005 15:05:29 +1200, Regan Heath wrote:

> On Wed, 6 Apr 2005 12:57:00 +1000, Derek Parnell <derek@psych.ward> wrote:
>>> But with a class a.opValue will seg-v if a is null so how does one initialize a?
>>
>> Huh? Did I mention initializing? See example code below. Classes would still be initialized as normal, with the 'new' keyword. I'm talking about assigning value to a (existing) class/struct based on the value of an expression. Nothing to do with constructors, etc...
> 
> I think what Ben was trying to say here is that:
> 
> (assume A is a class)
> A a = new A();
> 
> *is* assigning a value to 'a' so would call "opValue(A a)" in A, if it existed.

Why? Doesn't the 'new' keyword mean 'call the this() member function'?

-- 
Derek
Melbourne, Australia
6/04/2005 1:25:31 PM
April 06, 2005
On Tue, 5 Apr 2005 23:17:53 -0400, Ben Hinkle wrote:

> "Regan Heath" <regan@netwin.co.nz> wrote in message news:opsosivfu423k2f5@nrage.netwin.co.nz...
>> On Wed, 6 Apr 2005 12:57:00 +1000, Derek Parnell <derek@psych.ward> wrote:
>>>> But with a class a.opValue will seg-v if a is null so how does one initialize a?
>>>
>>> Huh? Did I mention initializing? See example code below. Classes would still be initialized as normal, with the 'new' keyword. I'm talking about assigning value to a (existing) class/struct based on the value of an expression. Nothing to do with constructors, etc...
>>
>> I think what Ben was trying to say here is that:
>>
>> (assume A is a class)
>> A a = new A();
>>
>> *is* assigning a value to 'a' so would call "opValue(A a)" in A, if it existed.
>>
>> Regan.
> 
> Yes, that's what I was thinking. To put it another way, the code
> A a;
> will initialize a to null and so when you try to run
> a = b;
> it will try to run a.opValue(b) which will seg-v. This is slightly different
> than
> A a = new A;
> but basically I'm wondering how a.opValue works when a is null or during
> initialization.

In my way of thinking, when a class is initialized it calls the constructor routine 'this' and so it wouldn't attempt calling opValue. Also, if the class instance is not initialized (ie still null), then opValue couldn't be called.

Why are you guys thinking that I'm talking about initialization? I'm just trying to invent a nice way to implement customized data conversions. That is, converting data from an evaluated expression to an instance of a class/struct.

class C {
   C opValue(int x)
   { . . . return this; }
}

 . . .

 C myC = new C;
 . . .

 myC = 42; // i.e. myC.opValue(42);


-- 
Derek
Melbourne, Australia
6/04/2005 2:03:28 PM
April 06, 2005
On Wed, 6 Apr 2005 13:26:15 +1000, Derek Parnell <derek@psych.ward> wrote:
> On Wed, 06 Apr 2005 15:05:29 +1200, Regan Heath wrote:
>
>> On Wed, 6 Apr 2005 12:57:00 +1000, Derek Parnell <derek@psych.ward> wrote:
>>>> But with a class a.opValue will seg-v if a is null so how does one
>>>> initialize a?
>>>
>>> Huh? Did I mention initializing? See example code below. Classes would
>>> still be initialized as normal, with the 'new' keyword. I'm talking about
>>> assigning value to a (existing) class/struct based on the value of an
>>> expression. Nothing to do with constructors, etc...
>>
>> I think what Ben was trying to say here is that:
>>
>> (assume A is a class)
>> A a = new A();
>>
>> *is* assigning a value to 'a' so would call "opValue(A a)" in A, if it
>> existed.
>
> Why? Doesn't the 'new' keyword mean 'call the this() member function'?

Well I'm no expert on how this works, but I imagine...

A a = new A();

RHS: "new A()" means allocate some memory on the heap, and calls "this" for A in it.
<at this stage we have an A class in heap memory assigned to nothing)

LHS: "A a"
<at this stage we have a null reference to an A on the stack called 'a'>

"=" means assign RHS to LHS.
<the A in memory is assigned to the 'a' on the stack>

Ben's other question is perhaps more important.

A a;
a = b; <- a is null, this calls a.opValue(b).

Does that seg-v or.. ?

Regan
April 06, 2005
On Wed, 6 Apr 2005 14:09:43 +1000, Derek Parnell <derek@psych.ward> wrote:
> On Tue, 5 Apr 2005 23:17:53 -0400, Ben Hinkle wrote:
>
>> "Regan Heath" <regan@netwin.co.nz> wrote in message
>> news:opsosivfu423k2f5@nrage.netwin.co.nz...
>>> On Wed, 6 Apr 2005 12:57:00 +1000, Derek Parnell <derek@psych.ward> wrote:
>>>>> But with a class a.opValue will seg-v if a is null so how does one
>>>>> initialize a?
>>>>
>>>> Huh? Did I mention initializing? See example code below. Classes would
>>>> still be initialized as normal, with the 'new' keyword. I'm talking about
>>>> assigning value to a (existing) class/struct based on the value of an
>>>> expression. Nothing to do with constructors, etc...
>>>
>>> I think what Ben was trying to say here is that:
>>>
>>> (assume A is a class)
>>> A a = new A();
>>>
>>> *is* assigning a value to 'a' so would call "opValue(A a)" in A, if it
>>> existed.
>>>
>>> Regan.
>>
>> Yes, that's what I was thinking. To put it another way, the code
>> A a;
>> will initialize a to null and so when you try to run
>> a = b;
>> it will try to run a.opValue(b) which will seg-v. This is slightly different
>> than
>> A a = new A;
>> but basically I'm wondering how a.opValue works when a is null or during
>> initialization.
>
> In my way of thinking, when a class is initialized it calls the constructor
> routine 'this' and so it wouldn't attempt calling opValue. Also, if the
> class instance is not initialized (ie still null), then opValue couldn't be
> called.
>
> Why are you guys thinking that I'm talking about initialization?

Because as a general rule what you're suggesting appeared to me to effect initialization (after I read Bens response). So, I wanted clarification as to how you thought it would work with initialization, which you've just given above. Some comments:

> In my way of thinking, when a class is initialized it calls the constructor
> routine 'this' and so it wouldn't attempt calling opValue.

My take on this, from my other post:

<quote>
Well I'm no expert on how this works, but I imagine...

A a = new A();

RHS: "new A()" means allocate some memory on the heap, and calls "this" for A in it.
<at this stage we have an A class in heap memory assigned to nothing)

LHS: "A a"
<at this stage we have a null reference to an A on the stack called 'a'>

"=" means assign RHS to LHS.
<the A in memory is assigned to the 'a' on the stack>
</quote>

> Also, if the
> class instance is not initialized (ie still null), then opValue couldn't be
> called.

Correct, so what happens? Isn't this like saying:
  if (a == b)

when a is a null reference? which casues a seg-v.

Regan
April 06, 2005
On Wed, 6 Apr 2005 14:09:43 +1000, Derek Parnell wrote:

> On Tue, 5 Apr 2005 23:17:53 -0400, Ben Hinkle wrote:
> 
>> "Regan Heath" <regan@netwin.co.nz> wrote in message news:opsosivfu423k2f5@nrage.netwin.co.nz...
>>> On Wed, 6 Apr 2005 12:57:00 +1000, Derek Parnell <derek@psych.ward> wrote:
>>>>> But with a class a.opValue will seg-v if a is null so how does one initialize a?
>>>>
>>>> Huh? Did I mention initializing? See example code below. Classes would still be initialized as normal, with the 'new' keyword. I'm talking about assigning value to a (existing) class/struct based on the value of an expression. Nothing to do with constructors, etc...
>>>
>>> I think what Ben was trying to say here is that:
>>>
>>> (assume A is a class)
>>> A a = new A();
>>>
>>> *is* assigning a value to 'a' so would call "opValue(A a)" in A, if it existed.
>>>
>>> Regan.
>> 
>> Yes, that's what I was thinking. To put it another way, the code
>> A a;
>> will initialize a to null and so when you try to run
>> a = b;
>> it will try to run a.opValue(b) which will seg-v. This is slightly different
>> than
>> A a = new A;
>> but basically I'm wondering how a.opValue works when a is null or during
>> initialization.
> 
> In my way of thinking, when a class is initialized it calls the constructor routine 'this' and so it wouldn't attempt calling opValue. Also, if the class instance is not initialized (ie still null), then opValue couldn't be called.
> 
> Why are you guys thinking that I'm talking about initialization? I'm just trying to invent a nice way to implement customized data conversions. That is, converting data from an evaluated expression to an instance of a class/struct.
> 
> class C {
>    C opValue(int x)
>    { . . . return this; }
> }
> 
>  . . .
> 
>  C myC = new C;
>  . . .
> 
>  myC = 42; // i.e. myC.opValue(42);

We might actually need an opValue_r() routine too.

  void opValue_r(inout int x)
  {
     . . .
     x = ... ;
  }

  . . .

  int y;

  y = myC; // i.e. myC.opValue_r(y);

And if you are concerned by opValue_r not returning anything, (damn C's
heritage) you can still do " while ( (y = myC, y) > 0) ... "  :D

[offtopic:
  Q. How much of B and BPCL did Richie & Kernighan jettison?
   A. Enough.
  Q. How much of C and C++ did Walters jettison?
   A. Not enough (yet?)
]

-- 
Derek
Melbourne, Australia
6/04/2005 2:12:00 PM
« First   ‹ Prev
1 2 3