On Thursday, 10 October 2013 at 17:36:11 UTC, Joseph Rushton Wakeling wrote:
On 10/10/13 19:31, Jonathan M Davis wrote:
I'm honestly surprised that Andrei is rejecting the idea of casting to/from shared or immutable being normal given how it's required by our current
concurrency model. And changing that would be a _big_ change.

I'm starting to incline towards the view that type qualifications of _any_ kind become problematic once you start working with any types other than built-in, and not just in the context of concurrency. See e.g.:
http://d.puremagic.com/issues/show_bug.cgi?id=11148
http://d.puremagic.com/issues/show_bug.cgi?id=11188

I'd really appreciate advice on how to handle issues like these, because it's becoming a serious obstacle to my work on std.rational.

As qnzc pointed out - check out this thread: http://forum.dlang.org/post/sdefkajobwcfikkel...@forum.dlang.org

Your problems with BigInt occur because the language has a special optimization for assignment of structs with no mutable aliasing. Fundamental math types have no aliasing so that assignment from any to all is fine and efficient via a data copy. For types like BigInt with mutable aliasing crossing from mutable to immutable and back is a no-go because of the reasons pointed out in the response to bug 11148. You can not and should not be able to do what you are asking - pass mutable with aliasing into immutable because then immutable would not be guaranteed.

Two options are copy BigInt beforehand if you want to keep by value semantics on your function signatures or maybe pass by reference (they are big after all so why copy)?

Passing by ref won't really be the full solution to your problem on comment 6 of bug 11148. What you really want to do is take a const(BigInt) or ref to it and make a mutable copy. So do that! But wait, how can you do that? You need to have a dup type function. Ideally there would be a generic way to do this. I have one that works for most cases and including yours: https://github.com/patefacio/d-help/blob/master/d-help/opmix/dup.d
This support could easily be put in the standard.

import std.bigint, std.stdio;
import opmix.mix;

void foo(const(BigInt) n) {
  // make mutable copy
  auto bi = n.gdup;
  bi *= 2;
  writeln(bi);

}

void main() {
  const cbi = BigInt("1234567890987654321");
  foo(cbi);
  writeln(cbi);
}
----------------------
2469135781975308642
1234567890987654321

Thanks,
Dan

Reply via email to