www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Javari's Reference Immutability

reply Reiner Pope <reiner.pope gmail.com> writes:
I've read the paper on Javari's reference immutability (thanks to Bruno) 
and it has an interesting idea: a synthesis of dynamic and static 
checking.  This makes it easier to interface const-aware code with 
const-unaware code. It can be demonstrated as follows:

Date a = new Date(); // a mutable date
readonly Date b = a; // A readonly view of a
Date c = (mutable) b; // The compiler bypass static checking, but 
inserts dynamic checks.
a.modify(); // OK
b.modify(); // Compile-time error
c.modify(); // Runtime error


How could you implement the runtime checking? A first thought would be 
to add the following assert to the in contract of every mutating method:

   assert(!isConst);

But that requires that the /class/ knows the const-ness of the reference 
it is accessed through, which I don't think it does.

The other alternative seems to be a much easier one: simply modify the 
vtbl so that all mutating functions point to a single line:

   assert(false, "Trying to modify a class through a readonly view");

The problem with that is that I suspect the vtable is stored with the 
class, not the reference, so modifying the vtable will modify it for all 
other references, even if they aren't readonly.

Clearly, Javari manages such checking, and it claims to manage it in a 
Java-compatible (backwards-compatible) way. How is it done in Javari, 
and how could it be done in D?


Cheers,

Reiner
Jul 24 2006
next sibling parent "Andrei Khropov" <andkhropov nospam_mtu-net.ru> writes:
Reiner Pope wrote:

 The other alternative seems to be a much easier one: simply modify the vtbl
 so that all mutating functions point to a single line:
 
   assert(false, "Trying to modify a class through a readonly view");
 
 The problem with that is that I suspect the vtable is stored with the class,
 not the reference, so modifying the vtable will modify it for all other
 references, even if they aren't readonly.

That problem is easy to solve: Just have 2 vtables per class - one for mutable instances and one for readonly. Cast to readonly will involve changing vtable ptr in the instance then. --
Jul 25 2006
prev sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
I think the question is: what's the point?
Clearly, Java's lack of const didn't prevent it from the having some of 
the best libraries there are.

Reiner Pope wrote:
 I've read the paper on Javari's reference immutability (thanks to Bruno) 
 and it has an interesting idea: a synthesis of dynamic and static 
 checking.  This makes it easier to interface const-aware code with 
 const-unaware code. It can be demonstrated as follows:
 
 Date a = new Date(); // a mutable date
 readonly Date b = a; // A readonly view of a
 Date c = (mutable) b; // The compiler bypass static checking, but 
 inserts dynamic checks.
 a.modify(); // OK
 b.modify(); // Compile-time error
 c.modify(); // Runtime error
 
 
 How could you implement the runtime checking? A first thought would be 
 to add the following assert to the in contract of every mutating method:
 
   assert(!isConst);
 
 But that requires that the /class/ knows the const-ness of the reference 
 it is accessed through, which I don't think it does.
 
 The other alternative seems to be a much easier one: simply modify the 
 vtbl so that all mutating functions point to a single line:
 
   assert(false, "Trying to modify a class through a readonly view");
 
 The problem with that is that I suspect the vtable is stored with the 
 class, not the reference, so modifying the vtable will modify it for all 
 other references, even if they aren't readonly.
 
 Clearly, Javari manages such checking, and it claims to manage it in a 
 Java-compatible (backwards-compatible) way. How is it done in Javari, 
 and how could it be done in D?
 
 
 Cheers,
 
 Reiner

Jul 25 2006
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
But java has immutable strings, right?
http://www.janeg.ca/scjp/pkglang/immutable.html

That in itself is a form of 'const' covering the most common use cases.

Regan

On Tue, 25 Jul 2006 18:21:58 -0600, Hasan Aljudy <hasan.aljudy gmail.com>  
wrote:
 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some of  
 the best libraries there are.

 Reiner Pope wrote:
 I've read the paper on Javari's reference immutability (thanks to  
 Bruno) and it has an interesting idea: a synthesis of dynamic and  
 static checking.  This makes it easier to interface const-aware code  
 with const-unaware code. It can be demonstrated as follows:
  Date a = new Date(); // a mutable date
 readonly Date b = a; // A readonly view of a
 Date c = (mutable) b; // The compiler bypass static checking, but  
 inserts dynamic checks.
 a.modify(); // OK
 b.modify(); // Compile-time error
 c.modify(); // Runtime error
   How could you implement the runtime checking? A first thought would  
 be to add the following assert to the in contract of every mutating  
 method:
    assert(!isConst);
  But that requires that the /class/ knows the const-ness of the  
 reference it is accessed through, which I don't think it does.
  The other alternative seems to be a much easier one: simply modify the  
 vtbl so that all mutating functions point to a single line:
    assert(false, "Trying to modify a class through a readonly view");
  The problem with that is that I suspect the vtable is stored with the  
 class, not the reference, so modifying the vtable will modify it for  
 all other references, even if they aren't readonly.
  Clearly, Javari manages such checking, and it claims to manage it in a  
 Java-compatible (backwards-compatible) way. How is it done in Javari,  
 and how could it be done in D?
   Cheers,
  Reiner


Jul 25 2006
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
Of course, because the string is immutable if you modify it, you actually  
modify a duplicate string. Are they reference counted then? or does it dup  
on every single modification? If so, this would be a very inefficient  
implementation of COW.

Regan

On Wed, 26 Jul 2006 12:40:54 +1200, Regan Heath <regan netwin.co.nz> wrote:
 But java has immutable strings, right?
 http://www.janeg.ca/scjp/pkglang/immutable.html

 That in itself is a form of 'const' covering the most common use cases.

 Regan

 On Tue, 25 Jul 2006 18:21:58 -0600, Hasan Aljudy  
 <hasan.aljudy gmail.com> wrote:
 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some of  
 the best libraries there are.

 Reiner Pope wrote:
 I've read the paper on Javari's reference immutability (thanks to  
 Bruno) and it has an interesting idea: a synthesis of dynamic and  
 static checking.  This makes it easier to interface const-aware code  
 with const-unaware code. It can be demonstrated as follows:
  Date a = new Date(); // a mutable date
 readonly Date b = a; // A readonly view of a
 Date c = (mutable) b; // The compiler bypass static checking, but  
 inserts dynamic checks.
 a.modify(); // OK
 b.modify(); // Compile-time error
 c.modify(); // Runtime error
   How could you implement the runtime checking? A first thought would  
 be to add the following assert to the in contract of every mutating  
 method:
    assert(!isConst);
  But that requires that the /class/ knows the const-ness of the  
 reference it is accessed through, which I don't think it does.
  The other alternative seems to be a much easier one: simply modify  
 the vtbl so that all mutating functions point to a single line:
    assert(false, "Trying to modify a class through a readonly view");
  The problem with that is that I suspect the vtable is stored with the  
 class, not the reference, so modifying the vtable will modify it for  
 all other references, even if they aren't readonly.
  Clearly, Javari manages such checking, and it claims to manage it in  
 a Java-compatible (backwards-compatible) way. How is it done in  
 Javari, and how could it be done in D?
   Cheers,
  Reiner



Jul 25 2006
prev sibling parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Regan Heath wrote:
 But java has immutable strings, right?
 http://www.janeg.ca/scjp/pkglang/immutable.html
 
 That in itself is a form of 'const' covering the most common use cases.

I know. I was commenting on const objects, not arrays. What's the point of Javari?
 Of course, because the string is immutable if you modify it, you
 actually  modify a duplicate string. Are they reference counted then? or
 does it dup  on every single modification? If so, this would be a very
 inefficient  implementation of COW.

No, in Java, you can't modify a string. It's a read only reference <g>. You can modify a StringBuffer in place. However, with String, you can only change what the reference refers to. String concatenation creates a new string: # String x = a + b; Here, (assuming a and b are both, String objects) a new string is created. The original a and b are not changed. I think that's the same with array concatenation in D, no?
 
 Regan
 
 On Tue, 25 Jul 2006 18:21:58 -0600, Hasan Aljudy 
 <hasan.aljudy gmail.com>  wrote:
 
 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some 
 of  the best libraries there are.

 Reiner Pope wrote:

 I've read the paper on Javari's reference immutability (thanks to  
 Bruno) and it has an interesting idea: a synthesis of dynamic and  
 static checking.  This makes it easier to interface const-aware code  
 with const-unaware code. It can be demonstrated as follows:
  Date a = new Date(); // a mutable date
 readonly Date b = a; // A readonly view of a
 Date c = (mutable) b; // The compiler bypass static checking, but  
 inserts dynamic checks.
 a.modify(); // OK
 b.modify(); // Compile-time error
 c.modify(); // Runtime error
   How could you implement the runtime checking? A first thought 
 would  be to add the following assert to the in contract of every 
 mutating  method:
    assert(!isConst);
  But that requires that the /class/ knows the const-ness of the  
 reference it is accessed through, which I don't think it does.
  The other alternative seems to be a much easier one: simply modify 
 the  vtbl so that all mutating functions point to a single line:
    assert(false, "Trying to modify a class through a readonly view");
  The problem with that is that I suspect the vtable is stored with 
 the  class, not the reference, so modifying the vtable will modify it 
 for  all other references, even if they aren't readonly.
  Clearly, Javari manages such checking, and it claims to manage it in 
 a  Java-compatible (backwards-compatible) way. How is it done in 
 Javari,  and how could it be done in D?
   Cheers,
  Reiner



Jul 25 2006
prev sibling next sibling parent reply Reiner Pope <reiner.pope gmail.com> writes:
Hasan Aljudy wrote:
 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some of 
 the best libraries there are.
 

However, it is one of the reasons that Java is so slow. Instead of a proper implementation of reference immutability, anything that needs to be kept constant is either written as a readonly interface, or is simply duplicated. This means either code duplication or data duplication; the former leads to more bugs as everyone knows, and the latter leads to worse speeds. Although lack of speed due to duplication could be seen by some as acceptable, because (a) Java isn't meant for speed and (b) the error-catching achieved by duplication is more important than the speed of not, these arguments are clearly weak, and (more importantly) completely inapplicable for D. Effectively, Java *does* have a const mechanism, just a slow and painful one, because it must be enforced by the coder, not the compiler, and it is slow because it requires duplication. Just because Java manages to have good libraries it doesn't mean ignoring const is the best solution. Remember also that there is a huge company behind Java, so they can afford the extra time required in testing and documenting their libraries by hand for const violations. However, in D, this is not the case, and even if there were such a company, it would be worse for the individuals, who would have trouble competing with the error-checking resources of the company. The benefits of const are: - Machine checking of code, leading to higher-level code (eg 'in', 'out' and 'inout' are much more informative than 'this parameter is a class so it can be modified', 'this parameter is a struct so it won't be modified', etc.) - Saving either developer time or running time. Since most people can't be bothered to spend the time checking for const-violations by hand, they will tend to create const-safety through duplicates. If they are truly masochistic, then they can ensure by hand that it is safe, but this is unreliable, and requires extra work. - If the const mechanism is trustworthy, other optimizations could be explored, such as those possible in functional languages due to the lack of side effects (ie, everything being const): in a functional language, a = sin(1); b = sin(1); would only evaluate sin(1) once, and cache the answer. In D, however, it would be calculated twice, slowing it down. For any argument that this could be optimized away by a Sufficiently Smart Compiler, you can make arbitrarily hard optimizations that const would fix but the compiler would not. Cheers, Reiner
Jul 26 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Reiner Pope wrote:
 Hasan Aljudy wrote:
 
 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some 
 of the best libraries there are.

However, it is one of the reasons that Java is so slow. Instead of a proper implementation of reference immutability, anything that needs to be kept constant is either written as a readonly interface, or is simply duplicated. This means either code duplication or data duplication; the former leads to more bugs as everyone knows, and the latter leads to worse speeds. Although lack of speed due to duplication could be seen by some as acceptable, because (a) Java isn't meant for speed and (b) the error-catching achieved by duplication is more important than the speed of not, these arguments are clearly weak, and (more importantly) completely inapplicable for D. Effectively, Java *does* have a const mechanism, just a slow and painful one, because it must be enforced by the coder, not the compiler, and it is slow because it requires duplication.

Actually java provides a StringBuffer which can eliminate most of the unnecessary string duplication when one needs to modify a string.
 
 Just because Java manages to have good libraries it doesn't mean 
 ignoring const is the best solution. Remember also that there is a huge 
 company behind Java, so they can afford the extra time required in 
 testing and documenting their libraries by hand for const violations. 
 However, in D, this is not the case, and even if there were such a 
 company, it would be worse for the individuals, who would have trouble 
 competing with the error-checking resources of the company.

There are alot of third-party libraries for Java, and they're still very good. I mean, compare any library that has a version for C++ and a version for Java; I bet you the Java version will always be much much better. ICU is a good example of this, I think.
 
 The benefits of const are:

 

No no .. don't give me theory. Tell me what's the point of const in Javari. Show me real life examples that prove Javari to be superior to Java.
 Cheers,
 
 Reiner

Jul 26 2006
parent reply Reiner Pope <reiner.pope gmail.com> writes:
Hasan Aljudy wrote:
 
 
 Reiner Pope wrote:
 Hasan Aljudy wrote:

 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some 
 of the best libraries there are.

However, it is one of the reasons that Java is so slow. Instead of a proper implementation of reference immutability, anything that needs to be kept constant is either written as a readonly interface, or is simply duplicated. This means either code duplication or data duplication; the former leads to more bugs as everyone knows, and the latter leads to worse speeds. Although lack of speed due to duplication could be seen by some as acceptable, because (a) Java isn't meant for speed and (b) the error-catching achieved by duplication is more important than the speed of not, these arguments are clearly weak, and (more importantly) completely inapplicable for D. Effectively, Java *does* have a const mechanism, just a slow and painful one, because it must be enforced by the coder, not the compiler, and it is slow because it requires duplication.

Actually java provides a StringBuffer which can eliminate most of the unnecessary string duplication when one needs to modify a string.

important because Java doesn't have it. I then rebutted that by explaining the various evils of the Java library: it has pseudo const checking which is slow (ie immutable strings). Your example, StringBuffer, is actually a case for my side: it allows unprotected access, yet it isn't used anywhere near as much as the immutable version: java.lang.String. Can you tell me why, if const-ness is so useless?
 Just because Java manages to have good libraries it doesn't mean 
 ignoring const is the best solution. Remember also that there is a 
 huge company behind Java, so they can afford the extra time required 
 in testing and documenting their libraries by hand for const 
 violations. However, in D, this is not the case, and even if there 
 were such a company, it would be worse for the individuals, who would 
 have trouble competing with the error-checking resources of the company.

There are alot of third-party libraries for Java, and they're still very good. I mean, compare any library that has a version for C++ and a version for Java; I bet you the Java version will always be much much better. ICU is a good example of this, I think.
 The benefits of const are:


No no .. don't give me theory. Tell me what's the point of const in Javari. Show me real life examples that prove Javari to be superior to Java.

Cheers, Reiner
Jul 27 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Reiner Pope wrote:
 Hasan Aljudy wrote:
 
 Reiner Pope wrote:

 Hasan Aljudy wrote:

 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some 
 of the best libraries there are.

However, it is one of the reasons that Java is so slow. Instead of a proper implementation of reference immutability, anything that needs to be kept constant is either written as a readonly interface, or is simply duplicated. This means either code duplication or data duplication; the former leads to more bugs as everyone knows, and the latter leads to worse speeds. Although lack of speed due to duplication could be seen by some as acceptable, because (a) Java isn't meant for speed and (b) the error-catching achieved by duplication is more important than the speed of not, these arguments are clearly weak, and (more importantly) completely inapplicable for D. Effectively, Java *does* have a const mechanism, just a slow and painful one, because it must be enforced by the coder, not the compiler, and it is slow because it requires duplication.

Actually java provides a StringBuffer which can eliminate most of the unnecessary string duplication when one needs to modify a string.

important because Java doesn't have it. I then rebutted that by explaining the various evils of the Java library: it has pseudo const checking which is slow (ie immutable strings). Your example, StringBuffer, is actually a case for my side: it allows unprotected access, yet it isn't used anywhere near as much as the immutable version: java.lang.String. Can you tell me why, if const-ness is so useless?

Calm down please. I'm not saying const is totally useless (not that I use or need it anyway). The biggest argument in favor of const has been that writing good libraries requires some constness guarantess. However, as I see it, the only constness needed is one for arrays. Java has immutable String class, thus it covers that area. As we all know, Java has one of the best libraries around. You say that Java's String class implies alot of copying, therefor it's bad. However, you fail to realize that copying when modifying is exactly what COW stands for. COW is a kind of honor-system protocol implemented by phobos. Everytime phobos thinks it needs to modify a string which it doesn't own, it makes a copy first to keep the original string intact. In Java, this can be done by creating a StringBuffer from the String (which creates a copy), after that, any modification you make to StringBuffer happens in-place; no needless copying.
 
 Just because Java manages to have good libraries it doesn't mean 
 ignoring const is the best solution. Remember also that there is a 
 huge company behind Java, so they can afford the extra time required 
 in testing and documenting their libraries by hand for const 
 violations. However, in D, this is not the case, and even if there 
 were such a company, it would be worse for the individuals, who would 
 have trouble competing with the error-checking resources of the company.

There are alot of third-party libraries for Java, and they're still very good. I mean, compare any library that has a version for C++ and a version for Java; I bet you the Java version will always be much much better. ICU is a good example of this, I think.
 The benefits of const are:

<sbip>

No no .. don't give me theory. Tell me what's the point of const in Javari. Show me real life examples that prove Javari to be superior to Java.


Well it's your call. Right now, I think Javari is a useless extension.
Jul 27 2006
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 27 Jul 2006 18:39:29 -0600, Hasan Aljudy <hasan.aljudy gmail.com>  
wrote:
 You say that Java's String class implies alot of copying, therefor it's  
 bad. However, you fail to realize that copying when modifying is exactly  
 what COW stands for. COW is a kind of honor-system protocol implemented  
 by phobos. Everytime phobos thinks it needs to modify a string which it  
 doesn't own, it makes a copy first to keep the original string intact.  
 In Java, this can be done by creating a StringBuffer from the String  
 (which creates a copy), after that, any modification you make to  
 StringBuffer happens in-place; no needless copying.

Sure. But are you trying to tell me that this.. String foo(String a) { .. return modified a .. } String bar(String a) { .. return modified a .. } String baz(String a) { .. return modified a .. } String bob(String a) { .. return modified a .. } String s = foo(bar(baz(bob("test")))); Will result in _no_ needless copying? Regan
Jul 27 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Regan Heath wrote:
 On Thu, 27 Jul 2006 18:39:29 -0600, Hasan Aljudy 
 <hasan.aljudy gmail.com>  wrote:
 
 You say that Java's String class implies alot of copying, therefor 
 it's  bad. However, you fail to realize that copying when modifying is 
 exactly  what COW stands for. COW is a kind of honor-system protocol 
 implemented  by phobos. Everytime phobos thinks it needs to modify a 
 string which it  doesn't own, it makes a copy first to keep the 
 original string intact.  In Java, this can be done by creating a 
 StringBuffer from the String  (which creates a copy), after that, any 
 modification you make to  StringBuffer happens in-place; no needless 
 copying.

Sure. But are you trying to tell me that this.. String foo(String a) { .. return modified a .. } String bar(String a) { .. return modified a .. } String baz(String a) { .. return modified a .. } String bob(String a) { .. return modified a .. } String s = foo(bar(baz(bob("test")))); Will result in _no_ needless copying? Regan

Same thing will happen will happen with phobos COW P.S. Are you (or Reiner Pope) saying that Javari provides a better solution to this? <g>
Jul 27 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 27 Jul 2006 20:27:06 -0600, Hasan Aljudy <hasan.aljudy gmail.com>  
wrote:
 Regan Heath wrote:
 On Thu, 27 Jul 2006 18:39:29 -0600, Hasan Aljudy  
 <hasan.aljudy gmail.com>  wrote:

 You say that Java's String class implies alot of copying, therefor  
 it's  bad. However, you fail to realize that copying when modifying is  
 exactly  what COW stands for. COW is a kind of honor-system protocol  
 implemented  by phobos. Everytime phobos thinks it needs to modify a  
 string which it  doesn't own, it makes a copy first to keep the  
 original string intact.  In Java, this can be done by creating a  
 StringBuffer from the String  (which creates a copy), after that, any  
 modification you make to  StringBuffer happens in-place; no needless  
 copying.

String foo(String a) { .. return modified a .. } String bar(String a) { .. return modified a .. } String baz(String a) { .. return modified a .. } String bob(String a) { .. return modified a .. } String s = foo(bar(baz(bob("test")))); Will result in _no_ needless copying? Regan

Same thing will happen will happen with phobos COW

At present. This is the 'problem' I'd like to solve somehow.
 P.S. Are you (or Reiner Pope) saying that Javari provides a better  
 solution to this? <g>

No. I was just pointing out that Java's solution doesn't work for all cases. The reason it doesn't work is that String and StringBuffer are seperate types. I think we need a single type (or 2 types which can be passed as an argument of the same name, perhaps 2 types where one is implicitly convertable to the other). Either way, we need to know whether we need to .dup or not. Regan
Jul 27 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Regan Heath wrote:
 On Thu, 27 Jul 2006 20:27:06 -0600, Hasan Aljudy 
 <hasan.aljudy gmail.com>  wrote:
 
 Regan Heath wrote:

 On Thu, 27 Jul 2006 18:39:29 -0600, Hasan Aljudy  
 <hasan.aljudy gmail.com>  wrote:

 You say that Java's String class implies alot of copying, therefor  
 it's  bad. However, you fail to realize that copying when modifying 
 is  exactly  what COW stands for. COW is a kind of honor-system 
 protocol  implemented  by phobos. Everytime phobos thinks it needs 
 to modify a  string which it  doesn't own, it makes a copy first to 
 keep the  original string intact.  In Java, this can be done by 
 creating a  StringBuffer from the String  (which creates a copy), 
 after that, any  modification you make to  StringBuffer happens 
 in-place; no needless  copying.

Sure. But are you trying to tell me that this.. String foo(String a) { .. return modified a .. } String bar(String a) { .. return modified a .. } String baz(String a) { .. return modified a .. } String bob(String a) { .. return modified a .. } String s = foo(bar(baz(bob("test")))); Will result in _no_ needless copying? Regan

Same thing will happen will happen with phobos COW

At present. This is the 'problem' I'd like to solve somehow.
 P.S. Are you (or Reiner Pope) saying that Javari provides a better  
 solution to this? <g>

No. I was just pointing out that Java's solution doesn't work for all cases. The reason it doesn't work is that String and StringBuffer are seperate types. I think we need a single type (or 2 types which can be passed as an argument of the same name, perhaps 2 types where one is implicitly convertable to the other). Either way, we need to know whether we need to .dup or not. Regan

Well, for D, this can be solved with a non-COW versions of foo,baz, etc. For Java, there is a possible solution that revolves around the same idea: If a function is supposed to change the input string, and it's obvious (for example, if it's called toLower, toUpper .. etc), then it should take a StringBuffer, modify it in-place, and return it (as a StringBuffer). If a String is passed, it can be implicitly converted to a StringBuffer (duplicated). (Ok, maybe this is not the current Java behaviour, but it's my porposed solution) If a StringBuffer is passed, then it's all good. This eliminates duplications in the given case. However, it creates a problem if the user expects a String return type: StringBuffer foo(StringBuffer arg) { ... } .. String a = "hi"; String b = foo(a); this creates 2 duplicates: first duplicate a, then duplicate the returned string from foo. (converting a StringBuffer to a String should create a duplicate, no?)
Jul 27 2006
next sibling parent Reiner Pope <reiner.pope gmail.com> writes:
I'll make all my replies in this post.

Hasan Aljudy wrote:
 The biggest argument in favor of const has been that writing good libraries
requires some constness guarantess.

_easier_. The important thing about const is, as I said earlier, that it saves development time, because it avoids the need for code duplication. It is undeniable that all constness guarantees can be emulated by hand, but there is clearly a difference between what is needed and what is useful. Neither static typing nor unit testing add any efficiency to the actual code-/writing/ stage, but they save time on bug-hunting. A similar argument is true for const.
 However, as I see it, the only constness needed is one for arrays.

an array-wrapping pair of classes which emulate constness, as Java has indeed done for String (readonly form) and StringBuffer (read/write form). However, right in my first post which you still seem to have ignored, I outlined the trouble with this: duplicate code. An this is not theory, but practice, because code is indeed duplicated, as in Java's String and StringBuffer classes which are effectively two versions of the same thing: char[].
 
 Java has immutable String class, thus it covers that area.
 As we all know, Java has one of the best libraries around.

fundamentals. Your assertion: Java has one of the best libraries around. My assertion: it is not as good as all that, because of the unnecessary copying required. I am not saying that Javari fixes that problem (because it doesn't) but rather that looking to the knowledge there can provide some insight into avoiding that problem in D. As you may have seen from various other proposals for const in D, I have in fact found a way to avoid this duplication.
 P.S. Are you (or Reiner Pope) saying that Javari provides a better  
 solution to this? <g>



some of my other posts, you'll see the solution. Cheers, Reiner
Jul 27 2006
prev sibling parent reply Ary Manzana <asterite gmail.com> writes:
Hasan Aljudy wrote:
 
 
 Regan Heath wrote:
 On Thu, 27 Jul 2006 20:27:06 -0600, Hasan Aljudy 
 <hasan.aljudy gmail.com>  wrote:

 Regan Heath wrote:

 On Thu, 27 Jul 2006 18:39:29 -0600, Hasan Aljudy  
 <hasan.aljudy gmail.com>  wrote:

 You say that Java's String class implies alot of copying, therefor  
 it's  bad. However, you fail to realize that copying when modifying 
 is  exactly  what COW stands for. COW is a kind of honor-system 
 protocol  implemented  by phobos. Everytime phobos thinks it needs 
 to modify a  string which it  doesn't own, it makes a copy first to 
 keep the  original string intact.  In Java, this can be done by 
 creating a  StringBuffer from the String  (which creates a copy), 
 after that, any  modification you make to  StringBuffer happens 
 in-place; no needless  copying.

Sure. But are you trying to tell me that this.. String foo(String a) { .. return modified a .. } String bar(String a) { .. return modified a .. } String baz(String a) { .. return modified a .. } String bob(String a) { .. return modified a .. } String s = foo(bar(baz(bob("test")))); Will result in _no_ needless copying? Regan

Same thing will happen will happen with phobos COW

At present. This is the 'problem' I'd like to solve somehow.
 P.S. Are you (or Reiner Pope) saying that Javari provides a better  
 solution to this? <g>

No. I was just pointing out that Java's solution doesn't work for all cases. The reason it doesn't work is that String and StringBuffer are seperate types. I think we need a single type (or 2 types which can be passed as an argument of the same name, perhaps 2 types where one is implicitly convertable to the other). Either way, we need to know whether we need to .dup or not. Regan

Well, for D, this can be solved with a non-COW versions of foo,baz, etc. For Java, there is a possible solution that revolves around the same idea: If a function is supposed to change the input string, and it's obvious (for example, if it's called toLower, toUpper .. etc), then it should take a StringBuffer, modify it in-place, and return it (as a StringBuffer). If a String is passed, it can be implicitly converted to a StringBuffer (duplicated). (Ok, maybe this is not the current Java behaviour, but it's my porposed solution) If a StringBuffer is passed, then it's all good. This eliminates duplications in the given case. However, it creates a problem if the user expects a String return type: StringBuffer foo(StringBuffer arg) { ... } .. String a = "hi"; String b = foo(a); this creates 2 duplicates: first duplicate a, then duplicate the returned string from foo. (converting a StringBuffer to a String should create a duplicate, no?)

The classes String and StringBuffer implements CharSequence, so declaring a function to recieve a CharSequence can handle both scenarios. If the function modifies the "string", it can create a String Buffer from it and return it as a CharSquence. CharSquence foo(CharSequence arg) { ... } Ary
Jul 28 2006
parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Ary Manzana wrote:
 Hasan Aljudy wrote:
 
 Regan Heath wrote:

 On Thu, 27 Jul 2006 20:27:06 -0600, Hasan Aljudy 
 <hasan.aljudy gmail.com>  wrote:

 Regan Heath wrote:

 On Thu, 27 Jul 2006 18:39:29 -0600, Hasan Aljudy  
 <hasan.aljudy gmail.com>  wrote:

 You say that Java's String class implies alot of copying, 
 therefor  it's  bad. However, you fail to realize that copying 
 when modifying is  exactly  what COW stands for. COW is a kind of 
 honor-system protocol  implemented  by phobos. Everytime phobos 
 thinks it needs to modify a  string which it  doesn't own, it 
 makes a copy first to keep the  original string intact.  In Java, 
 this can be done by creating a  StringBuffer from the String  
 (which creates a copy), after that, any  modification you make to  
 StringBuffer happens in-place; no needless  copying.

Sure. But are you trying to tell me that this.. String foo(String a) { .. return modified a .. } String bar(String a) { .. return modified a .. } String baz(String a) { .. return modified a .. } String bob(String a) { .. return modified a .. } String s = foo(bar(baz(bob("test")))); Will result in _no_ needless copying? Regan

Same thing will happen will happen with phobos COW

At present. This is the 'problem' I'd like to solve somehow.
 P.S. Are you (or Reiner Pope) saying that Javari provides a better  
 solution to this? <g>

No. I was just pointing out that Java's solution doesn't work for all cases. The reason it doesn't work is that String and StringBuffer are seperate types. I think we need a single type (or 2 types which can be passed as an argument of the same name, perhaps 2 types where one is implicitly convertable to the other). Either way, we need to know whether we need to .dup or not. Regan

Well, for D, this can be solved with a non-COW versions of foo,baz, etc. For Java, there is a possible solution that revolves around the same idea: If a function is supposed to change the input string, and it's obvious (for example, if it's called toLower, toUpper .. etc), then it should take a StringBuffer, modify it in-place, and return it (as a StringBuffer). If a String is passed, it can be implicitly converted to a StringBuffer (duplicated). (Ok, maybe this is not the current Java behaviour, but it's my porposed solution) If a StringBuffer is passed, then it's all good. This eliminates duplications in the given case. However, it creates a problem if the user expects a String return type: StringBuffer foo(StringBuffer arg) { ... } .. String a = "hi"; String b = foo(a); this creates 2 duplicates: first duplicate a, then duplicate the returned string from foo. (converting a StringBuffer to a String should create a duplicate, no?)

The classes String and StringBuffer implements CharSequence, so declaring a function to recieve a CharSequence can handle both scenarios. If the function modifies the "string", it can create a String Buffer from it and return it as a CharSquence. CharSquence foo(CharSequence arg) { ... } Ary

Ah, yes. I forgot about CharSequence and interfaces! :D
Jul 28 2006
prev sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Hasan Aljudy wrote:
 
 
 Reiner Pope wrote:
 Hasan Aljudy wrote:

 Reiner Pope wrote:

 Hasan Aljudy wrote:

 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having 
 some of the best libraries there are.

However, it is one of the reasons that Java is so slow. Instead of a proper implementation of reference immutability, anything that needs to be kept constant is either written as a readonly interface, or is simply duplicated. This means either code duplication or data duplication; the former leads to more bugs as everyone knows, and the latter leads to worse speeds. Although lack of speed due to duplication could be seen by some as acceptable, because (a) Java isn't meant for speed and (b) the error-catching achieved by duplication is more important than the speed of not, these arguments are clearly weak, and (more importantly) completely inapplicable for D. Effectively, Java *does* have a const mechanism, just a slow and painful one, because it must be enforced by the coder, not the compiler, and it is slow because it requires duplication.

Actually java provides a StringBuffer which can eliminate most of the unnecessary string duplication when one needs to modify a string.

important because Java doesn't have it. I then rebutted that by explaining the various evils of the Java library: it has pseudo const checking which is slow (ie immutable strings). Your example, StringBuffer, is actually a case for my side: it allows unprotected access, yet it isn't used anywhere near as much as the immutable version: java.lang.String. Can you tell me why, if const-ness is so useless?

Calm down please. I'm not saying const is totally useless (not that I use or need it anyway). The biggest argument in favor of const has been that writing good libraries requires some constness guarantess. However, as I see it, the only constness needed is one for arrays.

I doubt anyone has said exactly that. First, const/immutability is not strictly "required", but it helps or improves the quality of a library. Second, it is not just for libraries, it is for any kind of code. Third, what is a "good" library depends on the language. Many things are good and acceptable for Java, but are not for D. (see below) Also, going back to the second point, the kind of code that a const/immutability mechanism helps particularly more is domain logic code, or better said: code which handles domain objects (or abstract data types). A library, particularly a system/language library has little domain objects (or ADTs) and as such, for many parts of the library it will make little difference whether a const mechanism exists or not. For example, a Thread, Stream, File, etc. classes are not "domain" types, rather they are "handle" types which manage a resource which exists outside of the data the class itself holds. There is not much sense for there to be readonly views of these objects as they are not changed in the same way "domain" types are. Now what are the "domain" types in Java's lib? It's String (and it's corresponding StringBuffer), and also List and the whole Collection classes, and maybe some more I don't recall or know right now. These types have all some sort of const/immutability mechanism since such mechanism is very important (in the case of Java, a custom, "user"-made one, not natural to the language). In the case of String, you have two classes for each const/nonconst version. In the case of a List or other Collections such attribute is part of the object state, and a check is made at runtime. Here's an example of usage of a const and a non-const Collection: List<Object> lst = new ArrayList<Object>(); List<Object> lst2 = Collections.unmodifiableList(lst); lst.add("ddd"); lst2.add("ddd"); // Runtime error: UnsupportedOperationException The first point pro a const/immutability mechanism (as a language construct) is that it saves work of creating the const mechanism on a custom, per user class basis. (if you're just using a code/library already done, it won't matter, but it doesn't invalidate the point) The second point pro a const/immutability mechanism (as a language construct), especially if it as compile time one, is that of efficiency. Those custom, user-made mechanisms are all slower than a compile time one, since they require extra duping of objects, and/or runtime constness data and checks. Of course one can /not/ implement these custom mechanism at all, but then you are less safe from ownership violations. For more info see the "2. Motivation" section in the Javari paper.
 Java has immutable String class, thus it covers that area.
 As we all know, Java has one of the best libraries around.
 
 You say that Java's String class implies alot of copying, therefor it's 
 bad. However, you fail to realize that copying when modifying is exactly 
 what COW stands for. COW is a kind of honor-system protocol implemented 
 by phobos. Everytime phobos thinks it needs to modify a string which it 
 doesn't own, it makes a copy first to keep the original string intact. 
 In Java, this can be done by creating a StringBuffer from the String 
 (which creates a copy), after that, any modification you make to 
 StringBuffer happens in-place; no needless copying.
 

What is good, best, acceptable, etc. for one language may not be for another language. Java's solution (COW) is acceptable for Java because Java is not meant to be fast, but it is not acceptable/good for D. Note: when I say COW is acceptable for Java, I mean for small types like strings, or a Collection proxy, etc, because for large, complex types, even for Java it will burdensome to duplicate indiscriminately.
 Just because Java manages to have good libraries it doesn't mean 
 ignoring const is the best solution. Remember also that there is a 
 huge company behind Java, so they can afford the extra time required 
 in testing and documenting their libraries by hand for const 
 violations. However, in D, this is not the case, and even if there 
 were such a company, it would be worse for the individuals, who 
 would have trouble competing with the error-checking resources of 
 the company.

There are alot of third-party libraries for Java, and they're still very good. I mean, compare any library that has a version for C++ and a version for Java; I bet you the Java version will always be much much better. ICU is a good example of this, I think.
 The benefits of const are:

<sbip>

No no .. don't give me theory. Tell me what's the point of const in Javari. Show me real life examples that prove Javari to be superior to Java.


Well it's your call. Right now, I think Javari is a useless extension.

Reiner is right, dismissing points like that is lame and foolish. Plus, your request for examples ("Show me real life examples that prove Javari to be superior to Java") is flawed. First Javari is *very* recent (from years 2004-2005), and is an "academic", proof-of-concept language, so it is not in mainstream use and maybe not meant for it. Second, the lack of a const mechanism is not as harmful to Java as it for a language of the likes of D, for the reasons explained above. So you if want an example, it should be one of the same kind as D, so will give quite a good one: C++ -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 29 2006
prev sibling parent reply "Andrei Khropov" <andkhropov nospam_mtu-net.ru> writes:
Hasan Aljudy wrote:

 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some of the
 best libraries there are.

This doesn't mean Java is superb as a language. It means that Sun just invested tons of money in writing Java libraries with lots of features. --
Jul 26 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Andrei Khropov wrote:
 Hasan Aljudy wrote:
 
 
I think the question is: what's the point?
Clearly, Java's lack of const didn't prevent it from the having some of the
best libraries there are.

This doesn't mean Java is superb as a language. It means that Sun just invested tons of money in writing Java libraries with lots of features.

It's not just Sun! http://www-306.ibm.com/software/globalization/icu/index.jsp Compare the C++ version with the Java version.
Jul 27 2006
parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Hasan Aljudy wrote:
 
 
 Andrei Khropov wrote:
 Hasan Aljudy wrote:


 I think the question is: what's the point?
 Clearly, Java's lack of const didn't prevent it from the having some 
 of the
 best libraries there are.

This doesn't mean Java is superb as a language. It means that Sun just invested tons of money in writing Java libraries with lots of features.

It's not just Sun! http://www-306.ibm.com/software/globalization/icu/index.jsp Compare the C++ version with the Java version.

What about the C++ version? I don't know that lib, but on a quick look to it, I see that const is used extensively! : http://icu.sourceforge.net/apiref/icu4c/classRegexPattern.html http://icu.sourceforge.net/apiref/icu4c/classNormalizer.html .. etc. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 29 2006