www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Why D needs tail const

reply Stewart Gordon <smjg_1998 yahoo.com> writes:
With arrays and pointers, you can declare

     const(int[]) constData;
     immutable(int[]) immutableData;

to enforce constancy constraints.  The type modifiers apply both to the
reference to the 
data and to the data being referenced.  If you want to be able to change what
data the 
variables reference, just not change the data itself, no problem:

     const(int)[] constData;
     immutable(int)[] immutableData;

However, this can't be done with classes.  You can't do it with language
builtins, anyway. 
  Rather, a class object reference is either mutable, const or immutable, and
this 
simultaneously affects both the reference itself and the referenced object.

This is unideal.  Whether a reference to an object can change what it refers to
and 
whether the object itself can change are two distinct concepts.

OK, so we have std.typecons.Rebindable.  But I've found it a PITA when it comes
to generic 
programming.  Among other things, if you try to pass it around, you can end up
with a mess 
like const(Rebindable!(const(....))).  This wouldn't happen with built-in tail
const support.

I guess that, at the code level, tailConst and tailImmutable would be just type
modifiers. 
  But at the semantic level, they're just the const and immutable modifiers we
already 
have being applied at a different level.  So:

- tailConst(int[]) would be equivalent to const(int)[]

- tailConst(Class) would be a whole new type modification, under which the
reference can 
be reassigned, but the object's state cannot be changed through this reference,
and when 
calling methods of it the this pointer is const.

- const(tailConst(anything)) would just be the same as const(anything)

- tailConst(Struct) would just collapse to Struct if the struct contains no
references or 
only const and/or immutable references.  Otherwise, it would be a distinct type
modifier 
that forces all references within the struct to be const.  (Should we allow
struct methods 
to be qualified as tailConst/tailImmutable?)

- tailImmutable would work in the same way.

- You could have more involved constructs like const(tailImmutable(Class))[]. 
This would 
be an array of constant references to immutable objects.  So through this array
reference, 
neither what objects are in the array nor the objects themselves can be
changed.  But 
there may also exist a tailImmutable(Class)[] referencing the same block of
memory, 
through which what objects are in the array can be changed, but the objects
themselves 
remain immutable.

So essentially, where the columns denote top-level constancy and the rows the
next level down:
           | mutable         const                  immutable
----------+-------------------------------------------------
mutable   | <no mod>
const     | tailConst       const
immutable | tailImmutable   const(tailImmutable)   immutable


Moreover, who thinks it would be nice if immutable classes could behave just
like 
primitives?  Java gets partway there with String and others - you can just
declare a 
String variable and assign to it as you would an integer, and be confident that
some 
outside process won't change the contents of the variable behind your back.  D
could be 
there with such improvements as built-in tail immutable (and making it the
default 
modifier when a variable of an immutable class is declared).


What do people think to the whole idea?

Stewart.
Mar 28 2012
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
I'm pretty sure there's a dmd pull request or
patch or something for this already.

IIRC Michel Fortin implemented it as Object ref obj;
(which is the same as Object obj;) and const(Object) ref obj;
as tail const.

Don't know where it is now though...
Mar 28 2012
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Stewart Gordon:

 OK, so we have std.typecons.Rebindable.  But I've found it a 
 PITA when it comes to generic programming.  Among other things, 
 if you try to pass it around, you can end up with a mess like 
 const(Rebindable!(const(....))).  This wouldn't happen with 
 built-in tail const support.

This is only partially related to your post. It's for a general solution. Is it possible to invent a language construct that allows: const(Rebindable!(const(....))) To be defined as the same as: Rebindable!(const(....)) Something like an onConst()/onImmutable templated methods for structs/classes? Bye, bearophile
Mar 28 2012
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
I'm not sure how my post ended up in .announce, but anyway....

On 28/03/2012 15:24, bearophile wrote:
<snip>
 Is it possible to invent a language construct that allows:
 const(Rebindable!(const(....)))
 To be defined as the same as:
 Rebindable!(const(....))

You mean be defined the same as const(...) ? It's the only thing that makes sense.
 Something like an onConst()/onImmutable templated methods for structs/classes?

Maybe something like struct Rebindable(T) { alias const(T) onConst; } which would make const(Rebindable!(T)) just const(T)? I'm not sure whether this would be a good idea. And it would solve only one of Rebindable's many shortcomings.... Stewart.
Mar 28 2012
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 28/03/2012 16:09, Stewart Gordon wrote:
<snip>
 Something like an onConst()/onImmutable templated methods for structs/classes?


 I'm not sure whether this would be a good idea. And it would solve only one of
 Rebindable's many shortcomings....

Moreover, any feature that makes a type a completely different type if constancy is applied to it could be abused in all kinds of ways, as well as breaking generic programming. And I can't see any other genuine use case it might have. On this basis, we might as well just implement built-in tail const instead. Stewart.
Mar 28 2012
prev sibling next sibling parent "Jesse Phillips" <jessekphillips+D gmail.com> writes:
On Wednesday, 28 March 2012 at 14:11:10 UTC, Adam D. Ruppe wrote:
 I'm pretty sure there's a dmd pull request or
 patch or something for this already.

 IIRC Michel Fortin implemented it as Object ref obj;
 (which is the same as Object obj;) and const(Object) ref obj;
 as tail const.

 Don't know where it is now though...

One of the first pull requests https://github.com/D-Programming-Language/dmd/pull/3
Mar 28 2012
prev sibling parent Leandro Lucarella <luca llucax.com.ar> writes:
Stewart Gordon, el 28 de marzo a las 14:54 me escribiste:
 What do people think to the whole idea?

I think this is not an announcement at all and shouldn't be discussed in this list :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Soy como una mosca, parada en el agua. Y vos sos un transatlántico, querés nadar a mi lado. Y me estás ahogando.
Mar 28 2012