July 20, 2006
xs0 wrote:
> Craig Black wrote:
>> Sounds like a great idea to me.  Easy to implement, improves correctness and performance.  What are we waiting for?
> 
> Personally, I'm waiting/hoping for Walter to see the proposal and say what he thinks :)
> 
> I'm also wondering whether the "overwhelming" response to the proposal is because
> - I didn't write "proposal" in the subject
> - it's from me (I used to argue in a bad way too much, I'm sure I'm being filtered at least by some people :)
> - it's so bad it's not even worth a comment
> - it's so good everybody is already waiting for Walter to say yes ;)

Maybe you just need some better terminology. How about

arr.clone
to replace arr with a writable copy of arr (instead of "needToWrite").
(you don't care if its the original arr, or a dup)
and turn it into a proposal about a more efficient dup.

Modify Only One Copy On Write.
(MOO COW).
<g>.
July 20, 2006
xs0 wrote:
> Andrew Fedoniouk wrote:
>> b) does not solve compile verification of readonlyness and
> 
> I said so myself :P But, the question is whether compile-time verification is better or not. In some cases it definitely isn't;
> 
> int[] cowFoo(int[] a) { if (whatever) { a=a.dup; a[0] = 5; } }
> int[] cowBar(int[] a) { if (something) { a=a.dup; a[1] = 10; } }
> 
> int[] result=cowFoo(cowBar(whatever));
> 
> How can a compile-time check ever help you avoid the (unnecessary) second .dup when both funcs decide to modify the data?
> 

For that case (how to avoid the unnecessary dups):

  int[] cowFoo(int[] a) { if (whatever) { a[0] = 5; return a; } }
  int[] cowBar(int[] a) { if (something) { a[1] = 10; return a; } }

  int[] result=cowFoo(cowBar(someintar));

What's the a.dup for? Do you realize that if the parameter (a) is non-const then that means the function is allowed to change it? Perhaps you meant a different use case?


-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 20, 2006
"Don Clugston" <dac@nospam.com.au> wrote in message news:e9nvee$2h4m$1@digitaldaemon.com...
> xs0 wrote:
>> Craig Black wrote:
>>> Sounds like a great idea to me.  Easy to implement, improves correctness and performance.  What are we waiting for?
>>
>> Personally, I'm waiting/hoping for Walter to see the proposal and say what he thinks :)
>>
>> I'm also wondering whether the "overwhelming" response to the proposal is
>> because
>> - I didn't write "proposal" in the subject
>> - it's from me (I used to argue in a bad way too much, I'm sure I'm being
>> filtered at least by some people :)
>> - it's so bad it's not even worth a comment
>> - it's so good everybody is already waiting for Walter to say yes ;)
>
> Maybe you just need some better terminology. How about
>
> arr.clone
> to replace arr with a writable copy of arr (instead of "needToWrite").
> (you don't care if its the original arr, or a dup)
> and turn it into a proposal about a more efficient dup.
>
> Modify Only One Copy On Write.
> (MOO COW).
> <g>.

Don, I think that reference counting (MOO COW) has the
same set of "civil rights" as GC so probably it makes sense
to look on this from language design perspective in more universal
fashion. RefCounting of arrays is only one particular thing I mean -
language shall support this idiom with the same quality as GC.

In fact for typical and effective refcounting implementation it is
enough to have ctors/dtors/assignement in structs.
Having them MOO COW can be implemented easily without
need of runtime model changes.

And MOO COW is somehow orthogonal to constness.

Again, I would try to find here more universal solution rather than particular array problem.

I beleive that "smart pointer" as an entity will cover
MOO COW cases. But D does not have facilities
now for smart pointers at all.


Andrew Fedoniouk.
http://terrainformatica.com















July 21, 2006
Andrew Fedoniouk wrote:
> Don, I think that reference counting (MOO COW) has the
> same set of "civil rights" as GC so probably it makes sense
> to look on this from language design perspective in more universal
> fashion. RefCounting of arrays is only one particular thing I mean -
> language shall support this idiom with the same quality as GC.

I agree that something more universal would be better. But there's a really interesting feature: when you have GC, you don't need full reference counting, because you don't need deterministic destruction. You only need a single bit. (I think this is correct, but it needs more thought).

> In fact for typical and effective refcounting implementation it is
> enough to have ctors/dtors/assignement in structs.

I don't quite agree with this. I think that arrays in D are fundamentally different from arrays in C/C++. In C, they're little more than syntactic sugar for pointers, whereas in D, they are more like very important, built-in structs. If refcounting were more integral in the language, it would need to be available for built-in arrays.

> Having them MOO COW can be implemented easily without
> need of runtime model changes.
> 
> And MOO COW is somehow orthogonal to constness.

Yes, that's the point I was trying to make. I thought it was an interesting proposal, but doesn't have much to do with compile-time constness, except insofar as it reduces the need for full const.

> Again, I would try to find here more universal solution
> rather than particular array problem.
> 
> I beleive that "smart pointer" as an entity will cover
> MOO COW cases. But D does not have facilities
> now for smart pointers at all.

Walter seems to have vehement opposition to operator =. I wonder if it is really necessary. Maybe a single opXXX() function could do the job, if the compiler had some extra intelligence. (Much as opCmp does all of the >,<, >=, <=. Every op= and copy constructor I've ever seen in C++ was  very tedious, I wonder if that design pattern could be factored into a single function).
July 21, 2006
"Don Clugston" <dac@nospam.com.au> wrote in message news:e9qb6h$2r4m$1@digitaldaemon.com...
> Andrew Fedoniouk wrote:
>> Don, I think that reference counting (MOO COW) has the
>> same set of "civil rights" as GC so probably it makes sense
>> to look on this from language design perspective in more universal
>> fashion. RefCounting of arrays is only one particular thing I mean -
>> language shall support this idiom with the same quality as GC.
>
> I agree that something more universal would be better. But there's a really interesting feature: when you have GC, you don't need full reference counting, because you don't need deterministic destruction. You only need a single bit. (I think this is correct, but it needs more thought).

"But there's a really interesting feature: when you have GC, you don't need
full
reference counting, because you don't need deterministic destruction."

Theoretically, yes. Practically... I would change it to "when you have perfect GC".

And about GC:

Here is the sample I know pretty well:
There is no HTML rendering engine in the wild based on GC  memory
management ( http://en.wikipedia.org/wiki/List_of_layout_engines )

I've seen attempts to do them in Java or C# - not even close. (In Harmonia I've decided to do not use GC heap for the DOM too)

Deterministic memory management has one and big benefit - it is manageable and predictable.


>
>> In fact for typical and effective refcounting implementation it is enough to have ctors/dtors/assignement in structs.
>
> I don't quite agree with this. I think that arrays in D are fundamentally different from arrays in C/C++. In C, they're little more than syntactic sugar for pointers, whereas in D, they are more like very important, built-in structs. If refcounting were more integral in the language, it would need to be available for built-in arrays.
>
>> Having them MOO COW can be implemented easily without
>> need of runtime model changes.
>>
>> And MOO COW is somehow orthogonal to constness.
>
> Yes, that's the point I was trying to make. I thought it was an interesting proposal, but doesn't have much to do with compile-time constness, except insofar as it reduces the need for full const.

There is a string struct in Harmonia using such bit (string.d):

struct tstring(CHAR)
{
  CHAR[]  chars;
  bit     mutable = true; // by default empty string is mutable
  ......
}

and this is exactly wat was propsed (except of placement of the bit)

Without constness and ability to define methods it worth nothing for arrays.

>
>> Again, I would try to find here more universal solution rather than particular array problem.
>>
>> I beleive that "smart pointer" as an entity will cover
>> MOO COW cases. But D does not have facilities
>> now for smart pointers at all.
>
> Walter seems to have vehement opposition to operator =. I wonder if it is
> really necessary. Maybe a single opXXX() function could do the job, if the
> compiler had some extra intelligence. (Much as opCmp does all of the >,<,
>  >=, <=. Every op= and copy constructor I've ever seen in C++ was  very
> tedious, I wonder if that design pattern could be factored into a single
> function).

operator "="  IS really necessary.  As there is no method in D currently to guard assignment to variable (memory location). Again without it good chunk of RAII methods and smart pointers are not implementable in D.

In HTMLayout SDK I have dom::element object which is wrapper
around internal DOM element handler. It is in C++.
I physically cannot write something close and so easy to use in D.

**DOM element.*/

    class element
    {
    protected:
      HELEMENT he;
      void use(HELEMENT h) { he = (HTMLayout_UseElement(h) == HLDOM_OK)? h:
0; }
      void unuse() { if(he) HTMLayout_UnuseElement(he); he = 0; }
      void set(HELEMENT h) { unuse(); use(h); }
    public:
      element(): he(0) { }
      element(HELEMENT h)       { use(h); }
      element(const element& e) { use(e.he); }
      operator HELEMENT() const { return he; }
      ~element()                { unuse(); }
      element& operator = (HELEMENT h) { set(h); return *this; }
      element& operator = (const element& e) { set(e.he); return *this; }
      ....
}



















July 21, 2006
>
>operator "="  IS really necessary.  As there is no method in D currently to guard assignment to variable (memory location). Again without it good chunk of RAII methods and smart pointers are not implementable in D.
>

It is impossible to allow operator "=" to be overloaded without totally killing
the way D works because D uses references.
Example:
ClassA a = new ClassA();
ClassA b = a; // b now refers to a
b.mutate(); // both 'b' and 'a' are changed since they refer to the same object

What is possible is to define a new operator (such as ":=") that means copy assignment, but I don't see how this differs from creating a method that does the same thing.


July 21, 2006
"Ben Phillips" <Ben_member@pathlink.com> wrote in message news:e9rc1u$1g71$1@digitaldaemon.com...
> >
>>operator "="  IS really necessary.  As there is no method in D currently to guard assignment to variable (memory location). Again without it good chunk of RAII methods and smart pointers are not implementable in D.
>>
>
> It is impossible to allow operator "=" to be overloaded without totally
> killing
> the way D works because D uses references.
> Example:
> ClassA a = new ClassA();
> ClassA b = a; // b now refers to a
> b.mutate(); // both 'b' and 'a' are changed since they refer to the same
> object
>

I think that operator= shall be available only for structs and probably
other value types.
So it will be no conflict with current situation.

> What is possible is to define a new operator (such as ":=") that means
> copy
> assignment, but I don't see how this differs from creating a method that
> does
> the same thing.

method is not an option at all.
operator= is a guard of memory loacation and method, well, is method.

struct guard {
   int v;
   void opAssign(int nv) {  alarm("value 'v' is about to change"); v =
v;  }
}

guard gv;
gv = 12;

As you may see operator= guards memory location allowing you to intercept
all assignments into the variable. Too many things (RAII, smart pointers)
were built
around this in C++.

Method of the struct will not help you here in principle.

Andrew Fedoniouk.
http://terrainformatica.com















July 22, 2006
On Sat, 22 Jul 2006 06:27:24 +1000, Andrew Fedoniouk <news@terrainformatica.com> wrote:

>
> "Ben Phillips" <Ben_member@pathlink.com> wrote in message
> news:e9rc1u$1g71$1@digitaldaemon.com...
>> >
>>> operator "="  IS really necessary.  As there is no method in D
>>> currently to guard assignment to variable (memory location).
>>> Again without it good chunk of RAII methods and smart pointers
>>> are not implementable in D.
>>>
>>
>> It is impossible to allow operator "=" to be overloaded without totally
>> killing
>> the way D works because D uses references.
>> Example:
>> ClassA a = new ClassA();
>> ClassA b = a; // b now refers to a
>> b.mutate(); // both 'b' and 'a' are changed since they refer to the same
>> object
>>

But some of the side effects of a new operator ':=' would be that it could be used with value types and reference types alike and mean that the information contained in the right-hand side member is copy to the left-hand side member. It would remove the need for ".dup" for example.

  char[] a;
  a := toString(4);


> method is not an option at all.
> operator= is a guard of memory loacation and method, well, is method.
>
> struct guard {
>    int v;
>    void opAssign(int nv) {  alarm("value 'v' is about to change"); v =
> v;  }
> }
>
> guard gv;
> gv = 12;
>
> As you may see operator= guards memory location allowing you to intercept
> all assignments into the variable. Too many things (RAII, smart pointers)
> were built
> around this in C++.
>
> Method of the struct will not help you here in principle.

 struct guard {
    private int _v;
    void v(int nv) {  alarm("value 'v' is about to change"); _v = v;  }
  }
 guard gv;
 gv.v = 12 ;

-- 
Derek Parnell
Melbourne, Australia
July 22, 2006
"Derek Parnell" <derek@psych.ward> wrote in message news:op.tc2lghnq6b8z09@ginger.vic.bigpond.net.au... [skiped]
>> method is not an option at all.
>> operator= is a guard of memory loacation and method, well, is method.
>>
>> struct guard {
>>    int v;
>>    void opAssign(int nv) {  alarm("value 'v' is about to change"); v =
>> v;  }
>> }
>>
>> guard gv;
>> gv = 12;
>>
>> As you may see operator= guards memory location allowing you to intercept
>> all assignments into the variable. Too many things (RAII, smart pointers)
>> were built
>> around this in C++.
>>
>> Method of the struct will not help you here in principle.
>
>  struct guard {
>     private int _v;
>     void v(int nv) {  alarm("value 'v' is about to change"); _v = v;  }
>   }
>  guard gv;
>  gv.v = 12 ;

Consider this:

guard gv, gv1;
gv1.v = 24;
gv.v = 12 ;

gv = gv1; //oops, where is my alarm()?

Again there is no method in "modern D" to catch assignment to the variable.

In my case (wrapper of htmlayout), in following assignment:

dom::element root = dom::element::get_root(hWnd);

operator= calls HTMLayout_useElement of the HELEMENT
returned by get_root. (C++)
And C++ will call destructor for the root at the end of the block.
And in destructor happens HTMLayout_unuseElement.

Such use case allows to hold resources for limited (deterministic) time.  At the end system is more responsive than any GCable one.

There is no way in D to implement this. Sorry, but this is true.

Andrew Fedoniouk.
http://terrainformatica.com







































July 22, 2006
On Sat, 22 Jul 2006 18:03:33 +1000, Andrew Fedoniouk <news@terrainformatica.com> wrote:


> There is no way in D to implement this. Sorry, but this is true.

Agreed.

The ':=' operator could be one solution. I suggest that when applied, it should only copy one level deep and if one needs deeper copies then the opCopy() function could be overloaded to provide that functionality. Of course, we should also have opXXX functionality when using basic types and arrays.  Hopefully, this concept can be seriously considered for v2.0

-- 
Derek Parnell
Melbourne, Australia
1 2 3 4
Next ›   Last »