digitalmars.D.learn - does cast make an lvalue appear to be an rvalue
- Daniel Davidson (22/22) Oct 16 2013 The code below fails to compile due to the last line. I was
- Dicebot (5/18) Oct 16 2013 It works as it should. Make a mutable copy of t2 and pass it. Or
- Daniel Davidson (36/39) Oct 16 2013 How do you propose to make a mutable copy *generically*?
- Dicebot (7/7) Oct 16 2013 struct S {
- Daniel Davidson (13/20) Oct 16 2013 Thanks. It is cute - but not so helpful. The example stands. I
- Dicebot (6/13) Oct 16 2013 Recursively going through the levels of indirection via static
- Daniel Davidson (6/20) Oct 16 2013 I agree with the sentiment. But as it stands I think a copy
- Dicebot (11/16) Oct 16 2013 Then don't use immutable. Root of all problems with immutable
- monarch_dodra (24/42) Oct 16 2013 You can't. Let alone generically.
- Daniel Davidson (6/35) Oct 16 2013 That was my point.
- Daniel Davidson (16/42) Oct 16 2013 Just to clarify: in the code below: createRFromT(t, r) is *not*
- Maxim Fomin (4/26) Oct 16 2013 foo([cast()t2][0]);
- Daniel Davidson (2/34) Oct 16 2013 Haaah - brilliant. Scary, but brilliant.
The code below fails to compile due to the last line. I was hoping casting away immutable would allow the call to foo. I think it is not accepted because of the rval to ref issue. If that is the case, how can foo be called by casting? I'm not a fan of casting but I'm finding cases where it is the only recourse to create immutable data using impure functions that should be pure. Thanks Dan import std.conv; struct T { int[] i; string[string] ss; } void foo(ref T t) { } void main() { T t1; auto t2 = immutable T(); foo(t1); foo(cast()t2); }
Oct 16 2013
On Wednesday, 16 October 2013 at 17:05:25 UTC, Daniel Davidson wrote:import std.conv; struct T { int[] i; string[string] ss; } void foo(ref T t) { } void main() { T t1; auto t2 = immutable T(); foo(t1); foo(cast()t2); }It works as it should. Make a mutable copy of t2 and pass it. Or make foo() accept const. I can't imagine a single legitimate use case for destroying type system in a way you want.
Oct 16 2013
On Wednesday, 16 October 2013 at 17:16:39 UTC, Dicebot wrote:It works as it should. Make a mutable copy of t2 and pass it. Or make foo() accept const. I can't imagine a single legitimate use case for destroying type system in a way you want.How do you propose to make a mutable copy *generically*? I think a legitimate use would be the following. In the construction of S I want to use a T to construct an R. `this(...) immutable {}` prevents initialization of R in this case. Maybe immutable adorning `this()` should mean it is immutable upon the end of the construction, giving the initialization a chance to actually initialize. In the example below a better approach would be to have: R createRFromT(ref const(T) t) pure {...} but with what I'm using from phobos that is not possible. ------------------------------------------------ import std.conv; import std.stdio; struct R { int[] i; string[string] ss; } struct T { int[] i; string[string] ss; } struct S { R r; this(ref const(T) t) immutable { createRFromT(t, r); } } void createRFromT(ref const(T) t, ref R r) { //... } void main() { T t1; auto t2 = immutable T(); auto s = immutable S(t2); }
Oct 16 2013
struct S { R r; this(ref immutable(T) t) immutable { r.tupleof = t.tupleof; } } ?
Oct 16 2013
On Wednesday, 16 October 2013 at 17:55:56 UTC, Dicebot wrote:struct S { R r; this(ref immutable(T) t) immutable { r.tupleof = t.tupleof; } } ?Thanks. It is cute - but not so helpful. The example stands. I *need* to call a createRFromT. Their shapes are the same in this simple example because I simplified. Make R look like: struct R { string[string] ss; int[] j; } and the cute trick falls apart. In words, I have an R and I want to make a T. The R is const the T will be immutable because the ctor requires it. But it is technically not immutable until it is initialized.
Oct 16 2013
On Wednesday, 16 October 2013 at 17:50:48 UTC, Daniel Davidson wrote:On Wednesday, 16 October 2013 at 17:16:39 UTC, Dicebot wrote:Recursively going through the levels of indirection via static introspection and allocating memory for new mutable counter-parts as it goes. Maybe it should belong to Phobos, no idea right now, will know once I ever find the need for it.It works as it should. Make a mutable copy of t2 and pass it. Or make foo() accept const. I can't imagine a single legitimate use case for destroying type system in a way you want.How do you propose to make a mutable copy *generically*?
Oct 16 2013
On Wednesday, 16 October 2013 at 17:58:41 UTC, Dicebot wrote:On Wednesday, 16 October 2013 at 17:50:48 UTC, Daniel Davidson wrote:I agree with the sentiment. But as it stands I think a copy should not be necessary. I could make a local mutable R, pass it to createRFromT to get it initialized and then copy it back somehow to the member variable r. That to me is silly. The copy should not be required.On Wednesday, 16 October 2013 at 17:16:39 UTC, Dicebot wrote:Recursively going through the levels of indirection via static introspection and allocating memory for new mutable counter-parts as it goes. Maybe it should belong to Phobos, no idea right now, will know once I ever find the need for it.It works as it should. Make a mutable copy of t2 and pass it. Or make foo() accept const. I can't imagine a single legitimate use case for destroying type system in a way you want.How do you propose to make a mutable copy *generically*?
Oct 16 2013
On Wednesday, 16 October 2013 at 18:14:22 UTC, Daniel Davidson wrote:I agree with the sentiment. But as it stands I think a copy should not be necessary. I could make a local mutable R, pass it to createRFromT to get it initialized and then copy it back somehow to the member variable r. That to me is silly. The copy should not be required.Then don't use immutable. Root of all problems with immutable comes from trying to use it for something it should never be. `immutable` means "never ever can be accessed with a mutable" with any compiler optimization that may come from that. Any cast is undefined behavior in a form of time bomb. Basically, only thing immutable is good at is to create some potentially shared data and slicing / reading it when needed. If you need the same data but for passing as mutable function argument, you MUST make a copy, there is no safe way around it.
Oct 16 2013
On Wednesday, 16 October 2013 at 17:50:48 UTC, Daniel Davidson wrote:How do you propose to make a mutable copy *generically*?You can't. Let alone generically. If I give you an "immutable int* p", how do you copy it to "int* p" ? On Wednesday, 16 October 2013 at 18:11:48 UTC, Daniel Davidson wrote:Thanks. It is cute - but not so helpful. The example stands. I *need* to call a createRFromT. Their shapes are the same in this simple example because I simplified. Make R look like: struct R { string[string] ss; int[] j; } and the cute trick falls apart. In words, I have an R and I want to make a T. The R is const the T will be immutable because the ctor requires it. But it is technically not immutable until it is initialized.The problem is that you are taking a const(R). And you can't assign a const to an immutable. It has nothing to do with initialization. Remember: "const" means *you* promise not to modify the value, whereas immutable means *no one* will modify it ever. Because of this, you can't assign a const to an immutable. For example: int[] a = [1]; const(int)[] c = a; //Legal immutable(int)[] i = c; //Forbidden If that assignment passed, think of what would happen if I wrote: a[0] = 5; On Wednesday, 16 October 2013 at 18:14:22 UTC, Daniel Davidson wrote:I agree with the sentiment. But as it stands I think a copy should not be necessary. I could make a local mutable R, pass it to createRFromT to get it initialized and then copy it back somehow to the member variable r. That to me is silly. The copy should not be required.A copy *might* not be necessary provided building an immutable copy from mutable is actually legal. This is not your case. What you are doing is warping the type system.
Oct 16 2013
On Wednesday, 16 October 2013 at 19:49:25 UTC, monarch_dodra wrote:On Wednesday, 16 October 2013 at 17:50:48 UTC, Daniel Davidson wrote:That was my point.How do you propose to make a mutable copy *generically*?You can't. Let alone generically. If I give you an "immutable int* p", how do you copy it to "int* p" ?On Wednesday, 16 October 2013 at 18:11:48 UTC, Daniel Davidson wrote:No I don't think I am. What code are you looking at?Thanks. It is cute - but not so helpful. The example stands. I *need* to call a createRFromT. Their shapes are the same in this simple example because I simplified. Make R look like: struct R { string[string] ss; int[] j; } and the cute trick falls apart. In words, I have an R and I want to make a T. The R is const the T will be immutable because the ctor requires it. But it is technically not immutable until it is initialized.The problem is that you are taking a const(R). And you can't assign a const to an immutable. It has nothing to do with initialization.A copy *might* not be necessary provided building an immutable copy from mutable is actually legal. This is not your case. What you are doing is warping the type system.Based on your previous comment, I don't think you understood the setup.
Oct 16 2013
On Wednesday, 16 October 2013 at 19:49:25 UTC, monarch_dodra wrote:On Wednesday, 16 October 2013 at 17:50:48 UTC, Daniel Davidson wrote:Just to clarify: in the code below: createRFromT(t, r) is *not* meant to imply it will just try an assignment. Rather, it reads from t and builds its own data for R. The problem is with initialization - see Simen Kjaeraas response here: http://forum.dlang.org/post/mailman.2241.1381953340.1719.digitalmars-d-learn puremagic.com struct S { R r; this(ref const(T) t) immutable { createRFromT(t, r); } } void createRFromT(ref const(T) t, ref R r) { //... }How do you propose to make a mutable copy *generically*?You can't. Let alone generically. If I give you an "immutable int* p", how do you copy it to "int* p" ? On Wednesday, 16 October 2013 at 18:11:48 UTC, Daniel Davidson wrote:Thanks. It is cute - but not so helpful. The example stands. I *need* to call a createRFromT. Their shapes are the same in this simple example because I simplified. Make R look like: struct R { string[string] ss; int[] j; } and the cute trick falls apart. In words, I have an R and I want to make a T. The R is const the T will be immutable because the ctor requires it. But it is technically not immutable until it is initialized.The problem is that you are taking a const(R). And you can't assign a const to an immutable. It has nothing to do with initialization.
Oct 16 2013
On Wednesday, 16 October 2013 at 17:05:25 UTC, Daniel Davidson wrote:The code below fails to compile due to the last line. I was hoping casting away immutable would allow the call to foo. I think it is not accepted because of the rval to ref issue. If that is the case, how can foo be called by casting? I'm not a fan of casting but I'm finding cases where it is the only recourse to create immutable data using impure functions that should be pure. Thanks Dan import std.conv; struct T { int[] i; string[string] ss; } void foo(ref T t) { } void main() { T t1; auto t2 = immutable T(); foo(t1); foo(cast()t2); }foo([cast()t2][0]); (It would be good to have compound literals like in C)
Oct 16 2013
On Wednesday, 16 October 2013 at 18:09:55 UTC, Maxim Fomin wrote:On Wednesday, 16 October 2013 at 17:05:25 UTC, Daniel Davidson wrote:Haaah - brilliant. Scary, but brilliant.The code below fails to compile due to the last line. I was hoping casting away immutable would allow the call to foo. I think it is not accepted because of the rval to ref issue. If that is the case, how can foo be called by casting? I'm not a fan of casting but I'm finding cases where it is the only recourse to create immutable data using impure functions that should be pure. Thanks Dan import std.conv; struct T { int[] i; string[string] ss; } void foo(ref T t) { } void main() { T t1; auto t2 = immutable T(); foo(t1); foo(cast()t2); }foo([cast()t2][0]); (It would be good to have compound literals like in C)
Oct 16 2013