[Issue 1654] Array concatenation should result in mutable or invariant depending on usage

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu May 1 11:48:34 PDT 2008


http://d.puremagic.com/issues/show_bug.cgi?id=1654





------- Comment #14 from schveiguy at yahoo.com  2008-05-01 13:48 -------
(In reply to comment #13)
> "copying an invariant(int[]) to a int[]" fails indeed, but copying
> invariant(int[]) to an invariant(int)[] would work as well.
> So basicly what we are looking into here is tailconst. The concatenation of a
> const(T)[] with another const(T)[] conceptually returns a type that is:
> 
>   tailconst(T)[]

Not exactly.  The enhancement request has kind of mutated, due to the rule that
I stipulated (which I think was subsequently added to D 2).

What I think it should be is

const(T)[] ~ const(T)[] should return a type that is T[] if const(T) implicitly
casts to T under the rule.  If T does not implicitly cast, it should return
const(T)[].

The whole idea behind this is that ~ is always generating new data.  Why should
the result always be based on the input types?  At the very least, The pieces
of the new array that are unique should be unique, and implicitly cast to
mutable.

This problem is not an easy one to solve, I realize, but it is solvable.

> 
> and similarly for invariant/tailinvariant. This is because the "head-value" of
> T is copied, so it can be mutable. So these semantics are safe:
> 
> int[] ~ int[]                           --> returns int[]
> const(int)[] ~ const(int)[]             --> returns int[]
> int[][] ~ int[][]                       --> returns int[][]
> const(int[])[] ~ const(int[])[]         --> returns const(int)[][]
> const(int)[][] ~ const(int)[][]         --> returns const(int)[][]
> 
> How about this though? :
> 
> const(Foo)[] ~ const(Foo)[]             --> returns ???

If Foo is a struct with no pointers, then it returns Foo[].

If Foo is a class, a pointer, or a struct with pointers, then it returns
const(Foo)[].  

> Unfortunately there is no way in D to express tailconst for classes (and
> structs), so the last example would have to use normal const(T) instead of
> tailconst(T). I'm not sure what the implications of this special, and
> inconsistent case are tough, it could break generic code or something. Which
> does not mean these semantics would not be worthwhile.

Yes these cases would have to be handled delicately.  There are other things to
consider.

For example, if Foo is an alias to int *, then if you returned a tailconst
version of Foo what is that?  It would really be const(int)*, but how is that
expressed in terms of Foo?  What if Foo is a typedef to int *?

There are really two problems that need to be solved to allow this enhancement.
 The first I believe is already solved, and that is the ability to implicitly
cast to/from const/invariant/mutable if the type contains no pointers.  The
second is to allow the return type of a function to depend on how it is used
and/or called.  I'm not talking about overloading functions based on return
type, because that isn't enough in itself.  Why should I have to write multiple
functions that act the same way, just so the return type is different?  I keep
thinking that a 'unique' concept needs to be added before this whole solution
is possible.

Anyways, this issue really doesn't look like it will be solved in the near
future, without good answers for all the sub-issues involved.


-- 



More information about the Digitalmars-d-bugs mailing list