Re: shared vs __gshared

2013-06-10 Thread Steven Schveighoffer
On Mon, 10 Jun 2013 22:33:03 -0400, Sergei Nosov   
wrote:


So, is my understanding correct? If yes, why the path with memory  
barriers was "announced", but not taken?


Having recently acquired (no pun intended) new knowledge on how hard  
memory races are to solve with language syntax and primitives, I can  
appreciate that there isn't a silver bullet way to do this.


BUT, shared should be something more than just a way to modify a type to  
say "DON'T USE ME, I SUCK!"  I think we need one more mechanism to fix  
this.  Something that allows one to move data from shared to unshared in a  
reliable and provable way.  Because really, you never want to directly  
work with shared data without claiming and proving ownership of the data,  
even if temporarily.


-Steve


Re: shared vs __gshared

2013-06-10 Thread Sergei Nosov

Thank you for answers. Let me check if I got this right.

On Monday, June 10, 2013 13:23:26 Steven Schveighoffer wrote:
shared was supposed to infer memory barriers, but AFAIK, it 
doesn't do

that. Not sure it ever will.


So, my first impression about what shared should do (no low-level 
races at all) was correct, but the things didn't work out that 
way. So that kind of doesn't solve the issue with low-level 
races, which IIRC Andrei considers the biggest crime a language 
type system can commit. And the likely (brand-new) solution to 
that is


On Monday, 10 June 2013 at 14:49:27 UTC, Dmitry Olshansky wrote:
Now there was a discussion on it recently which indicates that 
shared data might lose it's built-in ops to prevent confusion 
and require folks to just use core.atomic directly for 
lock-free or alternatively cast+mutex for lock-based.


which seems reasonable too.

So, is my understanding correct? If yes, why the path with memory 
barriers was "announced", but not taken?


Re: dispatch table; symbolic references

2013-06-10 Thread Emil
did you mean Object.factory() ? It almost does it, but still have 
to cast the object to the right class (where I can't use a string 
variable it seems) to use it or make all the classes I want to 
instantiate this way inherit from the same interface.


thank you bearophile for pointing me in the right direction ... 
reading object_.d was fun but did not understand everything in 
there and will have to postpone ambitious stuff until I finish 
reading the book.




On Saturday, 8 June 2013 at 12:46:40 UTC, bearophile wrote:
...
There is a create, but I think it's still very limited and I 
think it needs to be improved:

http://dlang.org/phobos/object.html

Bye,
bearophile




Re: shared vs __gshared

2013-06-10 Thread Steven Schveighoffer
On Mon, 10 Jun 2013 15:46:27 -0400, Jonathan M Davis   
wrote:



On Monday, June 10, 2013 13:23:26 Steven Schveighoffer wrote:

shared was supposed to infer memory barriers, but AFAIK, it doesn't do
that. Not sure it ever will.


I believe that things are definitely leaning towards shared not adding  
memory
barriers. There _might_ be something that happens with shared that  
relates to
the GC in order to be able to facilitate per-thread collection, but at  
this
point, I think that it's looking like shared will be almost like const  
in that
it's a compile-time only thing enforced by the type system but has no  
effect at
runtime (the main difference being that objects created as shared will  
be in
shared memory rather than being thread-local - which _would_ be a  
difference at
runtime - but aside from that, there may be no difference between shared  
and

non-shared at runtime).


Well, I think this should be clarified as "the compiler won't generate  
special runtime code."  Given that shared is a type modifier, run time can  
already take advantage of knowing whether something is shared or not.


For example, appending to unshared arrays avoids taking the GC lock if it  
can append in place.


-Steve


Re: shared vs __gshared

2013-06-10 Thread Jonathan M Davis
On Monday, June 10, 2013 13:23:26 Steven Schveighoffer wrote:
> shared was supposed to infer memory barriers, but AFAIK, it doesn't do
> that. Not sure it ever will.

I believe that things are definitely leaning towards shared not adding memory 
barriers. There _might_ be something that happens with shared that relates to 
the GC in order to be able to facilitate per-thread collection, but at this 
point, I think that it's looking like shared will be almost like const in that 
it's a compile-time only thing enforced by the type system but has no effect at 
runtime (the main difference being that objects created as shared will be in 
shared memory rather than being thread-local - which _would_ be a difference at 
runtime - but aside from that, there may be no difference between shared and 
non-shared at runtime).

But I believe that ironing out shared is one of the things that Andrei wants 
to discuss and sort out soon based on his comments in recent discussions on 
whether we're going to make member functions non-virtual by default.

- Jonathan M Davis


Re: GtkD not working

2013-06-10 Thread Daemon

Do you get any error messages?


None that I know of. It compiles and starts to launch, then just 
throws an exception.


Re: GtkD not working

2013-06-10 Thread Mike Wey

On 06/10/2013 04:51 PM, Daemon wrote:

Hello, I'd appreciate any help.

I downloaded the GtkD sources and built the GtkD.lib using rdmd, so far
so good. I have followed the instructions in "Installing on Windows"
(editing sc.ini and copying contents of the src folder of GtkD into
DMD's src folder, etc.). I also installed the Gtk 3.8.1 version (x86 and
x86-64).

When I tried to compile the simple Hello world type of application, I
got about 7 "undefined symbols" and it refused to compile. So I poked
around and added "GtkD.lib" into the Library Files section in project
settings (I'm using Visual D). Now it did compile, but I get an
exception in KernelBase.dll.

At this point, I just don't know what to do next. Could someone help,
please?

Below is the Hello World GtkD-style application that I tried:


Do you get any error messages?

--
Mike Wey


Re: shared vs __gshared

2013-06-10 Thread Steven Schveighoffer
On Mon, 10 Jun 2013 09:38:43 -0400, Sergei Nosov   
wrote:



Hi!

I'm puzzled with what's the difference between shared and __gshared.


shared is part of the type, __gshared is not.

The danger of __gshared is that the compiler treats it as if it were not  
shared.  You better know what you are doing, lots of code expects that  
anything not marked as shared is thread-local.


shared was supposed to infer memory barriers, but AFAIK, it doesn't do  
that.  Not sure it ever will.


-Steve


Re: can we detect at compile time module ctor/dtor cycles ?

2013-06-10 Thread Steven Schveighoffer
On Sun, 09 Jun 2013 23:15:42 -0400, Timothee Cour  
 wrote:


On Fri, Jun 7, 2013 at 11:41 PM, Jonathan M Davis  
wrote:



On Friday, June 07, 2013 23:23:25 Timothee Cour wrote:
> Why can't we detect at compile time module ctor/dtor cycles (instead  
of

> runtime) ?

At minimum, separate compilation stops it. A .di file isn't likely to  
have

them
even if its corresponding .d file did.



automatically generated di files (eg -Hffilename) *do* generate static
this();


.di files do not need to be auto-generated, in fact, in the case where you  
would want to hide implementation, you will manually create them.  And it  
is perfectly legal to omit static ctors in .di files.


But you are missing something important -- it's not just the fact that it  
has static ctors/dtors, there must be an import cycle.  .di files  
certainly may not contain private imports, and you will have no way to  
construct the graph.


-Steve


Re: shared vs __gshared

2013-06-10 Thread bearophile

Dmitry Olshansky:

Now there was a discussion on it recently which indicates that 
shared data might lose it's built-in ops to prevent confusion 
and require folks to just use core.atomic directly for 
lock-free or alternatively cast+mutex for lock-based.


Looks like a good idea.

Bye,
bearophjile


GtkD not working

2013-06-10 Thread Daemon

Hello, I'd appreciate any help.

I downloaded the GtkD sources and built the GtkD.lib using rdmd, 
so far so good. I have followed the instructions in "Installing 
on Windows" (editing sc.ini and copying contents of the src 
folder of GtkD into DMD's src folder, etc.). I also installed the 
Gtk 3.8.1 version (x86 and x86-64).


When I tried to compile the simple Hello world type of 
application, I got about 7 "undefined symbols" and it refused to 
compile. So I poked around and added "GtkD.lib" into the Library 
Files section in project settings (I'm using Visual D). Now it 
did compile, but I get an exception in KernelBase.dll.


At this point, I just don't know what to do next. Could someone 
help, please?


Below is the Hello World GtkD-style application that I tried:

module main;

import std.stdio;

import gtk.Main;
import gtk.MainWindow;

void main(string[] args)
{
Main.init(args);

MainWindow window = new MainWindow("A Window");

window.showAll();
Main.run(); 
}


Re: shared vs __gshared

2013-06-10 Thread Dmitry Olshansky

10-Jun-2013 17:38, Sergei Nosov пишет:

Hi!

I'm puzzled with what's the difference between shared and __gshared.
Until now I've (mistakenly) considered that shared variables are free
from low-level data races. I.e. the operations with shared data are
atomic. And that __gshared is the "usual" (in C++ sense) shared data.




Is this how shared is supposed to work? If so, how is the __gshared
different from it? Does it not guarantee that the result of a write is
instantly visible to all threads? If so, does this difference really
matter?


Simply put __gshared is a hack to get exactly the same as plain global 
in C. Nothing about memory visibility is guaranteed unless explicitly 
enforced with some core.sync/core.atomic primitives. Worse yet it 
pretends to be the usual thread-local variable in a type system (hence a 
hack).


Shared is above all a transitive qualifier so if you have say

struct S{
char* ptr;
int len;
}

shared S s;

s.ptr is also typed as shared(char*)

Secondly shared type should strongly limit the scope of operations you 
can do with it - for instance writing normal (TLS) pointer to S.ptr 
field. This makes it easy to separate what's shared between threads and 
what is not. In a certain sense it actively prevents inadvertent mixing 
of thread-local and global state.


Continuing with limitations: for shared classes and structs you can only 
call shared methods on a shared instance. In this case think of shared 
as "thread-safe" because currently you most likely will have to cast you 
way though and maintain it by hand.


Third is as you notated it's backed by the same simple global data 
visible by all threads. This is the same for both.


Now there was a discussion on it recently which indicates that shared 
data might lose it's built-in ops to prevent confusion and require folks 
to just use core.atomic directly for lock-free or alternatively 
cast+mutex for lock-based.


--
Dmitry Olshansky


Re: How to implement this?

2013-06-10 Thread Kenji Hara

On Monday, 10 June 2013 at 09:42:56 UTC, Elvis wrote:

class A
{
enum TypeID = 1;
}
class B : A
{
enum TypeID = 2;
}

class C : A
{
enum TypeID = 3;
}

class D : B
{
enum TypeID = 4;
}

...


Could anybody shed some light on how to make these TypeIDs auto 
increment at compile time?


version(A)
{
class A
{
 enum TypeID = 1;
}

template IncrementTypeID(Class)
{
class IncrementTypeID : Class
{
enum TypeID = Class.TypeID + 1;
}
}
alias B = IncrementTypeID!A;
alias C = IncrementTypeID!B;
alias D = IncrementTypeID!C;
}
version(B)  // more generative way
{
template MakeContinuousClasses(int endID)
{
static if (endID > 0)
{
mixin MakeContinuousClasses!(endID - 1);

enum className = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[endID - 
1];

static if (endID == 1)
enum baseClass = "";
else
enum baseClass = " : " ~ 
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[endID - 2];


import std.conv : to;
mixin("class "~className~baseClass~" { enum TypeID = 
"~endID.to!string~"; }");

}
}
mixin MakeContinuousClasses!4;
}

// test case
import std.traits;
pragma(msg, A.TypeID, ", ", BaseClassesTuple!A);  // 1, (Object)
pragma(msg, B.TypeID, ", ", BaseClassesTuple!B);  // 2, (A, 
Object)
pragma(msg, C.TypeID, ", ", BaseClassesTuple!C);  // 3, (B, A, 
Object)
pragma(msg, D.TypeID, ", ", BaseClassesTuple!D);  // 4, (C, B, A, 
Object)


Kenji Hara


Re: shared vs __gshared

2013-06-10 Thread bearophile

Sergei Nosov:

Is this how shared is supposed to work? If so, how is the 
__gshared different from it? Does it not guarantee that the 
result of a write is instantly visible to all threads? If so, 
does this difference really matter?


shared and __gshared are very different things. __gshared 
guarantees nothing, it's equivalent to a raw C global 
(module-level) variables.


Bye,
bearophile


shared vs __gshared

2013-06-10 Thread Sergei Nosov

Hi!

I'm puzzled with what's the difference between shared and 
__gshared. Until now I've (mistakenly) considered that shared 
variables are free from low-level data races. I.e. the operations 
with shared data are atomic. And that __gshared is the "usual" 
(in C++ sense) shared data.


So, in my understanding, it was that if I do

shared int s = 0;
void inc()
{
s++;
}
void main()
{
foreach (i; iota(100_000).parallel)
s++;
}

I will always get s == 100_000 by the end of foreach loop. And if 
I use __gshared specifier, I will get the undefined value less or 
equal 100_000.


But now I've run the test and I get the "undefined value" result 
for both shared and __gshared.


I've looked this up in TDPL, and careful reading got me that 
shared guarantees only that the result of a write is instantly 
visible to all threads. So according to this, I can load the 
value in register, change it there, wait until someone else 
rewrites the value, and put my version on top, discarding someone 
else's result.


Is this how shared is supposed to work? If so, how is the 
__gshared different from it? Does it not guarantee that the 
result of a write is instantly visible to all threads? If so, 
does this difference really matter?


Re: How to implement this?

2013-06-10 Thread Benjamin Thaut

Am 10/06/2013 11:42, schrieb Elvis:

class A
{
 enum TypeID = 1;
}
class B : A
{
 enum TypeID = 2;
}

class C : A
{
 enum TypeID = 3;
}

class D : B
{
 enum TypeID = 4;
}

...


Could anybody shed some light on how to make these TypeIDs auto
increment at compile time?




Thats not possible due to the compilation model. You can however do:

alias TypeTuple!(A, B, C, D) list;

class A
{
   enum TypeID = staticIndexOf!(typeof(this), list);
}

class B
{
   enum TypeID = staticIndexOf!(typeof(this), list);
}

Further you could write yoruself a helper template which calls 
staticIndexOf and does a static assert in case it returns -1 (type not 
found).


Kind Regards
Benjamin Thaut


Re: decimal to binary

2013-06-10 Thread John Colvin

On Monday, 10 June 2013 at 09:46:42 UTC, snow wrote:

Hello,
I searched a lot in the docs and search, but couldn't find 
anything so far. Is there a funtion, which converts my decimal 
number into a binary?


I presume your decimal is in a string?

use

std.conv.parse

or

std.conv.to


Re: decimal to binary

2013-06-10 Thread Infiltrator

On Monday, 10 June 2013 at 09:46:42 UTC, snow wrote:

Hello,
I searched a lot in the docs and search, but couldn't find 
anything so far. Is there a funtion, which converts my decimal 
number into a binary?


http://dlang.org/phobos/std_string.html#.format with format 
string "%b".


Or if you're printing, you can go straight with 
http://dlang.org/phobos/std_stdio.html#.writef.


decimal to binary

2013-06-10 Thread snow

Hello,
I searched a lot in the docs and search, but couldn't find 
anything so far. Is there a funtion, which converts my decimal 
number into a binary?




How to implement this?

2013-06-10 Thread Elvis

class A
{
enum TypeID = 1;
}
class B : A
{
enum TypeID = 2;
}

class C : A
{
enum TypeID = 3;
}

class D : B
{
enum TypeID = 4;
}

...


Could anybody shed some light on how to make these TypeIDs auto 
increment at compile time?





Re: Constants doesn't have UDA's?

2013-06-10 Thread Temtaime

Oh, i see, thanks.

P.S. туй васю нигодяй.



Re: Constants doesn't have UDA's?

2013-06-10 Thread Jack Applegame

http://forum.dlang.org/thread/htuakrtvoyymappje...@forum.dlang.org


Re: best way to handle UFCS with ambiguous names: using std.typetuple.Alias!

2013-06-10 Thread John Colvin

On Monday, 10 June 2013 at 02:02:09 UTC, Timothee Cour wrote:
UFCS chains are problematic when a symbol is ambiguous (eg 
after import

std.stdio:write;import std.file:write);

I previously suggested to add the syntax
'arg1.(std.file.write)(arg2)'
(see 'support UFCS with fully qualified function names (was in
"digitalmars.D.learn")'  to avoid breaking UFCS chains.


We should allow this anyway, simply to deal with static imports.