initializing const maps with value types having aliasing

2013-03-20 Thread Dan
The following works and is the only way I have found to 
initialize m.

Unfortunately it requires the cast.

Is this safe to do?
Is there a better way?
Is this a bug or are future features coming to clean it up?

Thanks
Dan

--
import std.stdio;
struct S {
  this(this) { x = x.dup; }
  char[] x;
}

const(S[string]) m;
static this() {
  // Is there a cleaner way?
  cast(S[string])m = [ foo : S(['a']) ];
}

void main() {
  writeln(m[foo]);
}


Re: initializing const maps with value types having aliasing

2013-03-20 Thread Jonathan M Davis
On Wednesday, March 20, 2013 19:41:00 Dan wrote:
 The following works and is the only way I have found to
 initialize m.
 Unfortunately it requires the cast.
 
 Is this safe to do?
 Is there a better way?
 Is this a bug or are future features coming to clean it up?
 
 Thanks
 Dan
 
 --
 import std.stdio;
 struct S {
 this(this) { x = x.dup; }
 char[] x;
 }
 
 const(S[string]) m;
 static this() {
 // Is there a cleaner way?
 cast(S[string])m = [ foo : S(['a']) ];
 }
 
 void main() {
 writeln(m[foo]);
 }

Why are you casting? The cast shouldn't be necessary, because you're doing the 
initialization inside a static constructor. If you had problems, I'd expect it 
to be that AAs don't work properly when const (I know that there are issues 
when they're immutable) or that you can't insert elements into a const or 
immutable AA (which you'll never be able to do). But what you're doing here 
should work just fine without the cast. Assuming that AAs worked with const or 
immutable correctly, then it would be normal to do something like

immutable int[string] aa;

static this()
{
 int[string] temp;
 temp[foo] = 7;
 temp[blah] = 12;
 aa = assumeUnique(temp);
}

- Jonathan M Davis


Re: initializing const maps with value types having aliasing

2013-03-20 Thread bearophile

Dan:


  this(this) { x = x.dup; }


I think this(this) doesn't work well with const.



  cast(S[string])m = [ foo : S(['a']) ];


I think I have never seen code like that. What's the meaning? :-)


(Also if you remove that cast then dmd gives bad error messages 
with no line numbers:


Error: mutable method temp.S.__postblit is not callable using a 
const object

Error: cannot modify struct this Slot with immutable members

).

Bye,
bearophile


Re: initializing const maps with value types having aliasing

2013-03-20 Thread Dan
On Wednesday, 20 March 2013 at 19:01:27 UTC, Jonathan M Davis 
wrote:
Why are you casting? The cast shouldn't be necessary, because 
you're doing the

initialization inside a static constructor.


Without it I get:
Error: mutable method cmap.S.__postblit is not callable using a 
const object

Error: cannot modify struct this Slot with immutable members



If you had problems, I'd expect it
to be that AAs don't work properly when const (I know that 
there are issues
when they're immutable) or that you can't insert elements into 
a const or
immutable AA (which you'll never be able to do). But what 
you're doing here
should work just fine without the cast. Assuming that AAs 
worked with const or
immutable correctly, then it would be normal to do something 
like


immutable int[string] aa;

static this()
{
 int[string] temp;
 temp[foo] = 7;
 temp[blah] = 12;
 aa = assumeUnique(temp);
}


For now it seems the cast is necessary - so as long as it is safe.

I am not using 'immutable S[string]aa', but it would be 
interesting to see how that could be initialized. So, how to 
initialize aa. Does assumeUnique work for associative arrays?

--
import std.exception;

struct S {
  this(this) { x = x.dup; }
  char[] x;
}

immutable S[string] aa;

static this() {
   // now what
}

Thakns
Dan


Re: initializing const maps with value types having aliasing

2013-03-20 Thread Jonathan M Davis
On Wednesday, March 20, 2013 20:15:46 Dan wrote:
 On Wednesday, 20 March 2013 at 19:01:27 UTC, Jonathan M Davis
 
 wrote:
  Why are you casting? The cast shouldn't be necessary, because
  you're doing the
  initialization inside a static constructor.
 
 Without it I get:
 Error: mutable method cmap.S.__postblit is not callable using a
 const object
 Error: cannot modify struct this Slot with immutable members

postblits do not work with const or immutable. Once you have a postblit, you 
can't copy your object. It's a major problem with postblits. They simply 
fundamentally can't work with them (because the way that they work would 
require modifying a const or immutable variable), and it almost certainly 
means that we're going to need to add copy constructors to the language, but 
that hasn't been sorted out yet.

  If you had problems, I'd expect it
  to be that AAs don't work properly when const (I know that
  there are issues
  when they're immutable) or that you can't insert elements into
  a const or
  immutable AA (which you'll never be able to do). But what
  you're doing here
  should work just fine without the cast. Assuming that AAs
  worked with const or
  immutable correctly, then it would be normal to do something
  like
  
  immutable int[string] aa;
  
  static this()
  {
  
  int[string] temp;
  temp[foo] = 7;
  temp[blah] = 12;
  aa = assumeUnique(temp);
  
  }
 
 For now it seems the cast is necessary - so as long as it is safe.

Well, it may work, but I believe that it's undefined behavior. Casting away 
const and modifying an object is undefined behavior, and while the AA itself 
may not have that problem due to the fact that it's being initialized rather 
than assigned to, the fact that it's working by making a postblit work _is_ 
undefined behavior, because that means that you're modifying a const object 
inside of the postblit constructor.

 I am not using 'immutable S[string]aa', but it would be
 interesting to see how that could be initialized. So, how to
 initialize aa. Does assumeUnique work for associative arrays?
 --
 import std.exception;
 
 struct S {
 this(this) { x = x.dup; }
 char[] x;
 }
 
 immutable S[string] aa;
 
 static this() {
 // now what
 }


All assumeUnique does is cast to immutable. It's just the idiomatic way to 
initialize an immutable variable from a unique mutable object, because it 
makes it clearer what you're doing.

- Jonathan M Davis