October 10, 2013
On 10/10/13 20:28, H. S. Teoh wrote:
> I don't know about shared, though. Last I heard, shared was one big mess
> so I'm not even going to touch it.

Yes, that seems to be the consensus.

October 10, 2013
On 2013-10-10 16:14, Michel Fortin wrote:

> similar. I don't think it's a good practice to make a mutex part of the
> public interface of an object (or any public interface for that matter),
> which is why they're kept private inside the class in my examples.
> Public mutexes can be locked from anywhere in your program, they lack
> encapsulation and this makes them prone to deadlocks.

Right, it's better to keep them private.

-- 
/Jacob Carlborg
October 10, 2013
On 10/10/13 20:28, H. S. Teoh wrote:
> I left some comments on these bugs. Basically, BigInt should not be
> implicitly castable from const/immutable to unqual, because unlike the
> built-in types, it's *not* a value type:
>
> 	BigInt x = 123;
> 	BigInt y = x;  // creates an alias to x's data.

   BigInt a = 2;
   BigInt b = a;
   b = 3;
   writeln(a);
   writeln(b);

... gives you:

   2
   3

So, even though there's an array hidden away inside std.BigInt, it still seems to copy via value.

> Of course, the way BigInt is implemented, any operation on it causes new
> data to be created (essentially it behaves like a copy-on-write type),
> so it's not as though you can directly modify immutable this way, but
> it breaks the type system and opens up possible loopholes.

I guess that explains my result above .... ?

> What you need to do is to use inout for functions that need to handle
> both built-in ints and BigInts, e.g.:
>
> 	inout(Num) abs(Num)(inout(Num) x) {
> 		return (x >= 0) ? x : -x;
> 	}
>
> This *should* work (I think -- I didn't check :-P).

I did, and it results in issues with BigInt's opCmp.  But that may say more about BigInt's opCmp than about your solution.

> Arguably, a *lot* of generic code involving numerical operations is
> broken, because they assume built-in types' behaviour of being
> implicitly convertible to/from immutable (due to being value types).

How would you suggest correcting that?
October 10, 2013
On Thu, Oct 10, 2013 at 08:39:52PM +0200, Joseph Rushton Wakeling wrote:
> On 10/10/13 20:28, Sean Kelly wrote:
> >Isn't BigInt a struct?  I'd expect it to work via copying just like concrete types.
> 
> Yes, it's a struct, but somewhere inside its internals I think it contains arrays.  I'm not sure how that affects copying etc., but suffice to say that if you try the following:
> 
>     BigInt a = 2;
>     BigInt b = a;
>     b = 3;
>     assert(a != b);
>     assert(a !is b);
> 
> ... then it passes.  So it behaves at least in this extent like a value type.

I took a glance over the BigInt code, and it appears to have some kind of copy-on-write semantics. For example, in your code above, when you wrote b=a, b actually *aliases* a, but when you assign 3 to b, a new data array is created and b is updated to point to the new data instead.

So it's not really a true value type, but more like a COW reference type.


> But suffice to say that it was an unpleasant surprise that I couldn't just take it and pass to a function accepting an unqualified BigInt argument.

That only works with true value types, but BigInt isn't really one of them. :)


T

-- 
Everybody talks about it, but nobody does anything about it!  -- Mark Twain
October 10, 2013
On 10/10/2013 10:27 AM, Sean Kelly wrote:
> [...]

Sean - whatever means you're using to reply breaks the thread.
October 10, 2013
On Oct 10, 2013, at 12:11 PM, Walter Bright <newshound2@digitalmars.com> wrote:

> On 10/10/2013 10:27 AM, Sean Kelly wrote:
> > [...]
> 
> Sean - whatever means you're using to reply breaks the thread.

The mailing list Brad set up--I can't do NNTP from most locations.  I guess I'll use the website.
October 10, 2013
On 10/10/2013 12:38 PM, Sean Kelly wrote:
> On Oct 10, 2013, at 12:11 PM, Walter Bright <newshound2@digitalmars.com> wrote:
>
>> On 10/10/2013 10:27 AM, Sean Kelly wrote:
>>> [...]
>>
>> Sean - whatever means you're using to reply breaks the thread.
>
> The mailing list Brad set up--I can't do NNTP from most locations.  I guess I'll use the website.
>

I'm curious why NNTP would be blocked. I've been able to access it from any wifi hotspots I've tried it from.
October 10, 2013
On Thursday, 10 October 2013 at 20:50:10 UTC, Walter Bright wrote:
>
> I'm curious why NNTP would be blocked. I've been able to access it from any wifi hotspots I've tried it from.

My only guess is that usenet may be perceived as a illegal file sharing resource.  But it's been a while since I've tried, so I'll give it another shot.
October 10, 2013
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/sdefkajobwcfikkelxbr@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
October 10, 2013
On Thursday, 10 October 2013 at 17:39:55 UTC, Sean Kelly wrote:
> On Oct 10, 2013, at 10:23 AM, Joseph Rushton Wakeling <joseph.wakeling@webdrake.net> wrote:
>
>> On 09/10/13 06:25, Andrei Alexandrescu wrote:
>>> The way I see it we must devise a robust solution to that, NOT consider the
>>> state of the art immutable (heh, a pun).
>> 
>> Must say I have had a miserable experience with immutability and any kind of complex data structure, particularly when concurrency is involved.
>
> As long as the reference itself can be reassigned (tail-immutable, I suppose) I think immutable is occasionally quite useful for complex data structures.  It basically formalizes the RCU (read-copy-update) approach to wait-free concurrency.  I'd tend to use this most often for global data structures built up on app start, and updated rarely to never as the program runs.

Nice. Please show an example that includes complex data with associative arrays.

Thanks
Dan