Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Suliman via Digitalmars-d-learn

What I am doing wrong?

http://www.everfall.com/paste/id.php?iwh4qdcqv6zi


Well, there's no `parseconfig` there. Do you expect the 
`parseconfig` from line 30 or line 193 to be available in line 
170?


From line 30.

In line 193 I am get in instance of class instance of parseconfig 
to be able to use config inside MySQL class.


What I should to do in situation where for creation of class I 
should pass to constructor data instances from 2 different 
classes?


Re: Scoped external function declaration

2015-01-02 Thread novice2 via Digitalmars-d-learn

Thanx Daniel, thanx Ketmar.

I just thinked that this is some sort of bug.
May be DMD should not change mangled name of external function...
Bit i dont know.


Re: Scoped external function declaration

2015-01-02 Thread ketmar via Digitalmars-d-learn
On Fri, 02 Jan 2015 10:40:22 +
novice2 via Digitalmars-d-learn 
wrote:

> Thanx Daniel, thanx Ketmar.
> 
> I just thinked that this is some sort of bug.
> May be DMD should not change mangled name of external function...
> Bit i dont know.
with `extern(C)` it didn't. what you probably not realised is that D
has nested functions, so extern which declared inside other function
becomes right this: an extern nested function. that's why D compiler
mangles it's name. there are no nested functions in C, but D is not
C. ;-)


signature.asc
Description: PGP signature


Re: getting current DateTime

2015-01-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, December 31, 2014 19:07:13 bitwise via Digitalmars-d-learn wrote:
> > Why do you need DateTime and not SysTime?
> >
> > I'm actually surprised it doesn't have that too...
> >
> > -Steve
>
> Initially I was looking for something that would be the
> equivalent to DateTime in C#. This now appears to be SysTime, not
> DateTime in D.
>
> It seems the only real reason to use DateTime is as an
> optimization.
>
>  From DateTime docs:
> "It is optimized for calendar-based operations and has no concept
> of time zone."

That and it gets used internally by SysTime for any calendar-based
operations that it has to do, so it encapsulates that functionality, but if
what you're looking for is something that represents the time from the
system rather than a date and time on a calendar, you want SysTime.

The main places that code is likely to use DateTime is if it needs to
operate on dates and times separately from any connection to the system's
time or time zones and when you want to get the separate pieces of the
date and time (year, month, etc.) efficiently, because converting to
DateTime calculates that information once, whereas calling each individual
property on SysTime results in having to do some of the calculations
multiple times if you want to access multiple of the properties (which
sometimes makes me think that I never should have put those properties on
SysTime in the first place, but it's convenient if you don't care about the
small loss of efficiency when duplicating some of the calculations to get
multiple of the properties or you only need one or two of the properties).

- Jonathan M Davis



Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Suliman via Digitalmars-d-learn
I looked at my code and it's seems that I can create instance of 
MySQL in main.


void main()
{
auto parseconfig = new parseConfig();
auto mysql = new MySQL(parseconfig, seismodownload);
}

In parseConfig I am creation instance of seismoDownload:

class parseConfig
{

if (checkLinkCode(emsc_csem) == 200)
{
auto seismodownload = new seismoDownload(emsc_csem);
seismodownload.parse();
}

}

So I should be able to call it in main ( I talk about "auto mysql 
= new MySQL(parseconfig, seismodownload);")



But I am getting error:
Error: undefined identifier seismodownload, did you mean class  
seismoDownload?




Re: Can the order in associative array change when keys are not midified?

2015-01-02 Thread Tobias Pankrath via Digitalmars-d-learn
On Thursday, 1 January 2015 at 18:58:04 UTC, Andrej Mitrovic via 
Digitalmars-d-learn wrote:

On 1/1/15, Tobias Pankrath via Digitalmars-d-learn
 wrote:

You could implement an OrderedMap!(Key, Value) via
RedBlackTree!(Tuple!(Key, Value), (a,b) => a[0] < b[0]).


We could add this as an alias into Phobos or perhaps as just a
documentation line on the website.


Will do. Going to submit some documentation PRs anyway.


What exactly shared means?

2015-01-02 Thread Daniel Kozak via Digitalmars-d-learn
I always think that shared should be use to make variable global 
across threads (similar to __gshared) with some synchronize 
protection. But this code doesn't work (app is stuck on _aaGetX 
or _aaRehash ):


shared double[size_t] logsA;

void main() {

auto logs = new double[1_000_000];

foreach(i, ref elem; parallel(logs, 4)) {
elem = log(i + 1.0);
logsA[i]= elem;
}
}


But when I add synchronized block it is OK:

shared double[size_t] logsA;

void main() {

auto logs = new double[1_000_000];

foreach(i, ref elem; parallel(logs, 4)) {
elem = log(i + 1.0);
synchronized {
logsA[i]= elem;
}
}
}


Re: What exactly shared means?

2015-01-02 Thread Moritz Maxeiner via Digitalmars-d-learn

On Friday, 2 January 2015 at 11:47:47 UTC, Daniel Kozak wrote:
I always think that shared should be use to make variable 
global across threads (similar to __gshared) with some 
synchronize protection. But this code doesn't work (app is 
stuck on _aaGetX or _aaRehash ):



But when I add synchronized block it is OK:



I am not aware of any changes since the following thread (see the 
second post): 
http://forum.dlang.org/thread/brpbjefcgauuzguyi...@forum.dlang.org#post-mailman.679.1336909909.24740.digitalmars-d-learn:40puremagic.com


So AFAIK "shared" is currently nothing more than a compiler hint 
(despite the documentation suggesting otherwise (Second to last 
paragraph of "__gshared" doc compares it to "shared", see 
http://dlang.org/attribute.html).


My current understanding is that you either use "__gshared" and 
do your own synchronisation, or you use thread local storage, 
i.e. do not use "shared", but I would be happy to be proven wrong 
on that point.


BTW, you can use the following search to find more information 
(It is was I used to find the above linked thread): 
https://www.google.com/?#q=site:forum.dlang.org+shared


Re: What exactly shared means?

2015-01-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, January 02, 2015 11:47:46 Daniel Kozak via Digitalmars-d-learn wrote:
> I always think that shared should be use to make variable global
> across threads (similar to __gshared) with some synchronize
> protection. But this code doesn't work (app is stuck on _aaGetX
> or _aaRehash ):
>
> shared double[size_t] logsA;
>
> void main() {
>
>  auto logs = new double[1_000_000];
>
>  foreach(i, ref elem; parallel(logs, 4)) {
>  elem = log(i + 1.0);
>  logsA[i]= elem;
>  }
> }
>
>
> But when I add synchronized block it is OK:
>
> shared double[size_t] logsA;
>
> void main() {
>
>  auto logs = new double[1_000_000];
>
>  foreach(i, ref elem; parallel(logs, 4)) {
>  elem = log(i + 1.0);
>  synchronized {
>  logsA[i]= elem;
>  }
>  }
> }

Objects in D default to being thread-local. __gshared and shared both make
it so that they're not thread-local. __gshared does it without actually
changing the type, making it easier to use but also dangerous to use,
because it makes it easy to violate the compiler's guarantees, because it'll
treat it like a thread-local variable with regards to optimizations and
whatnot. It's really only meant for use with C global variable declarations,
but plenty of folks end up using it for more, because it avoids having the
compiler complain at them like it does with shared. Regardless, if you use
__gshared, you need to make sure that you protect it against being accessed
by multiple threads at once using mutexes or synchronized blocks or whatnot.

shared does not add any more synchronization or automatic mutex-locking or
anything like that than __gshared does (IIRC, there is some talk in TDPL
about shared adding memory barriers - which __gshared wouldn't do - but that
hasn't been implemented and probably never would be, because it would be too
expensive with regards to efficiency). However, unlike __gshared, shared
_does_ alter the type of the variable, so the compiler will treat it
differently. That way, it won't do stuff like optimize code under the
assumption that the object is thread-local like it can do with non-shared
objects. It makes it clear which objects are thread-local and which aren't
and enforces that with the type system. In principle, this is great, since
it clearly separates thread-local and non-thread local objects and protects
you against treating a non-thread local object as if it were thread-local.
And as long as you're writing code which operates specifically on shared
variables rather than trying to use "normal" code with them, it works great.
The problem is that you inevitably want to do things like use a function
that takes thread-local variables on a shared object - e.g. if a type is
written to be used as thread-local, then none of its member functions are
shared, and none of them can be used by a shared object, which obviously
makes using such a type as shared to be a bit of a pain.

In principle, D is supposed to provide ways to safely convert shared objects
to thread-local ones - i.e. when the compiler can guarantee that the object
is protected by a mutex or synchronized block or whatnot. The main way that
this was proposed is what TDPL describes with regards to synchronized
classes. The member variables of a synchronized class would be shared, and
protected by the class, since all of its member functions would be
synchronized, and no direct access to the member variables would be allowed,
guaranteeing that any time the member variables were accessed, it would be
within a synchronized function, meaning that the compiler could guarantee
that all access to the member variables was protected by a mutex. So, the
compiler would then be able to safely strip away the outermost layer of
shared, allowing you to theoretically use the member variables with normal
functions.

However, that only strips away the outermost layer (since that's all the
compiler could guarantee was protected), which frequently wouldn't be
enough, and it requires creating entire synchronized types just to use
shared objects. So, the efficacy of the idea is questionable IMHO, much as
the motivation is a good one (only removing shared when the compiler can
guarantee that only one thread can access it). However, synchronized
classes have yet to be implemented (only synchronized functions), so we
don't currently have the ability to have the outermost layer of shared be
stripped away like that. There is currently no place in the language where
the compiler is able to guarantee that a shared object is sufficiently
protected against access from multiple threads at once for it to be able to
automatically remove shared under any circumstances.

The _only_ way to strip it away at this point is to cast it away explicitly.
So, right now, what you're forced to do is something like

shared T foo = funcThatReturnsSharedT();

synchronized(someObj)
{
// be sure at this point that all other code that access foo
// also synchr

Re: Can the order in associative array change when keys are not midified?

2015-01-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/1/15 7:32 AM, Idan Arye wrote:

If I have an associative array and I only modify it's values, without
changing the keys, can I assume that the order won't change?


I would never make that assumption. An AA is free to rehash at any time, 
for whatever reason.


What I would say is that you can probably safely assume an AA will 
iterate in the same order as long as it hasn't been changed.


If you need guaranteed ordering, use an array or a RedBlackTree.

-Steve


Re: getting current DateTime

2015-01-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/2/15 6:21 AM, Jonathan M Davis via Digitalmars-d-learn wrote:


The main places that code is likely to use DateTime is if it needs to
operate on dates and times separately from any connection to the system's
time or time zones and when you want to get the separate pieces of the
date and time (year, month, etc.) efficiently, because converting to
DateTime calculates that information once, whereas calling each individual
property on SysTime results in having to do some of the calculations
multiple times if you want to access multiple of the properties (which
sometimes makes me think that I never should have put those properties on
SysTime in the first place, but it's convenient if you don't care about the
small loss of efficiency when duplicating some of the calculations to get
multiple of the properties or you only need one or two of the properties).


Not sure if you saw it, but I think a question for you Jonathan, is why 
DateTime ignores subsecond data? Wouldn't it be trivial to include that too?


It seems to be a conflict to say, either I want to efficiently work with 
components, or I want subsecond resolution. Even if subseconds was a 
single value to deal with (like a Duration).


I personally have not used DateTime, as SysTime fits my needs quite well.

-Steve


Re: getting current DateTime

2015-01-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, January 02, 2015 08:31:11 Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 1/2/15 6:21 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
>
> > The main places that code is likely to use DateTime is if it needs to
> > operate on dates and times separately from any connection to the system's
> > time or time zones and when you want to get the separate pieces of the
> > date and time (year, month, etc.) efficiently, because converting to
> > DateTime calculates that information once, whereas calling each individual
> > property on SysTime results in having to do some of the calculations
> > multiple times if you want to access multiple of the properties (which
> > sometimes makes me think that I never should have put those properties on
> > SysTime in the first place, but it's convenient if you don't care about the
> > small loss of efficiency when duplicating some of the calculations to get
> > multiple of the properties or you only need one or two of the properties).
>
> Not sure if you saw it, but I think a question for you Jonathan, is why
> DateTime ignores subsecond data? Wouldn't it be trivial to include that too?
>
> It seems to be a conflict to say, either I want to efficiently work with
> components, or I want subsecond resolution. Even if subseconds was a
> single value to deal with (like a Duration).

It could be added, but IIRC, I decided that it didn't make sense, because
the primary reason for DateTime was for calendar-based operations, and
subsecond resolution doesn't make any sense for those. Those only make sense
for when you're dealing with the actual system time. They _do_ make some
sense when using DateTime strictly for holding the separate pieces of the
date/time rather than accessing each of the properties on SysTime directly,
but it's also cheaper to get the subseconds than any of the properties that
DateTime currently holds.

> I personally have not used DateTime, as SysTime fits my needs quite well.

For most situations, it's what you need, since most code isn't looking to
deal with dates and times without tying them to the system time and time
zone somehow. Regardless of my original intentions, I think that the primary
use case for DateTime, Date, and TimeOfDay has ended up simply being to hold
those properties for SysTime rather than calculating each of them
individually. But they'll still come in handy for anyone who actually needs
to be able to do date/time calculations for calendar stuff without getting
time zones and whatnot involved.

- Jonathan M Davis



Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Tobias Pankrath via Digitalmars-d-learn

On Friday, 2 January 2015 at 11:21:08 UTC, Suliman wrote:
I looked at my code and it's seems that I can create instance 
of MySQL in main.


void main()
{
auto parseconfig = new parseConfig();
auto mysql = new MySQL(parseconfig, seismodownload);
}

In parseConfig I am creation instance of seismoDownload:

class parseConfig
{

if (checkLinkCode(emsc_csem) == 200)
{
auto seismodownload = new seismoDownload(emsc_csem);
seismodownload.parse();
}

}

So I should be able to call it in main ( I talk about "auto 
mysql = new MySQL(parseconfig, seismodownload);")



But I am getting error:
Error: undefined identifier seismodownload, did you mean class  
seismoDownload?


Anything declared in main() is local to main and not a global.


Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Suliman via Digitalmars-d-learn

Anything declared in main() is local to main and not a global.


Ok! So I need create multiple instances of the parseconfig?

Or please suggest me any solution, I really can't understand how 
to be in such situation...


Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Tobias Pankrath via Digitalmars-d-learn

On Friday, 2 January 2015 at 14:50:54 UTC, Suliman wrote:

Anything declared in main() is local to main and not a global.


Ok! So I need create multiple instances of the parseconfig?

Or please suggest me any solution, I really can't understand 
how to be in such situation...


Have you ever used a C-like programming language or are you a 
bloody beginner? So that I can figure out how basic the 
explanation has to be.


Basically every pair of {} introduces a scope. And you can only 
refer to things declared in the current or a parent scope.


{
   int x;
   {
   // x available here
   }
}
// x not available anymore

For your example this means that

void main()
{
 auto parseconfig = new parseConfig();
}
// parseConfig unavaiable since here

class whatever
{
   // cannot use parseconfig
}

What you can do is to declare the config outside any braces and 
make it a module global. But you'll need a module constructor 
(look them up in the docs). They are declared with this() outside 
of any scope in a module.



parseConfig parseconfig;

this()
{
parseconfig = new parseConfig(...);
}

void main() { /* can use parseconfig */ }

class SomeClass { /* should be able to as well */ }
---


Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Suliman via Digitalmars-d-learn

Thanks! I will try!
D is my first compilable language, I wrote only some scripts 
without OO before.


So in my case your suggestion is best practice? Or there is any 
more simple way to pass config and data to MySQL class?


Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Tobias Pankrath via Digitalmars-d-learn

On Friday, 2 January 2015 at 15:33:06 UTC, Suliman wrote:

Thanks! I will try!
D is my first compilable language, I wrote only some scripts 
without OO before.


So in my case your suggestion is best practice? Or there is any 
more simple way to pass config and data to MySQL class?


I think it's fine to have a global config instance. Alternatively 
you can pass the config to both the seismoDownlead and 
MySqlWhatever classes.


// there ist enforce(cond, msg) for this in 
std.exception/std.conv, dunno.
if (!exists(confpath))  throw new Exception("ERROR: config.ini do 
not exists");

// it becomes
enforce(exists(confpath), "ERROR: config.ini does not exist");


Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Suliman via Digitalmars-d-learn
I think it's fine to have a global config instance. 
Alternatively you can pass the config to both the 
seismoDownlead and MySqlWhatever classes.


// there ist enforce(cond, msg) for this in 
std.exception/std.conv, dunno.
if (!exists(confpath))  throw new Exception("ERROR: config.ini 
do not exists");

// it becomes
enforce(exists(confpath), "ERROR: config.ini does not exist");


Not fully understand. How I need to declare global config 
instance?


void main()
{

}

this()
{
auto parseconfig = new parseConfig();
}

But how this() will be called in nothing in main?

And I can't understand how to pass the config to both the 
seismoDownlead and MySqlWhatever classes.


I know how to pass, but I do not understand how to do it with 
current situation with scopes.


Here is current version of my code. I am not asking to do work 
for me, but could you show what and where I should move 
http://www.everfall.com/paste/id.php?oscnkeq740ue


?



vibe.d mongodb connections

2015-01-02 Thread Benjamin Thaut via Digitalmars-d-learn
I'm currently trying around with vibe.d and I'm confused about the 
MongoDB example:


import vibe.d;

MongoClient client;

void test()
{
auto coll = client.getCollection("test.collection");
foreach (doc; coll.find(["name": "Peter"]))
logInfo("Found entry: %s", doc.toJson());
}

shared static this()
{
client = connectMongoDB("127.0.0.1");
}

"client" is TLS but is initialized within a shared module consturctor, 
meaning that only the main thread will have a initialized db-connection. 
http://vibed.org/api/vibe.db.mongo.mongo/connectMongoDB says: "Thus, the 
MongoClient instance can - and should - be shared among all fibers in a 
thread by storing in in a thread local variable."


So wouldn't it make more sense that the MongoDB example initializes the 
"client" variable in a "static this()" instead of a "shared static this()" ?


Kind Regards
Benjamin Thaut


Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Suliman via Digitalmars-d-learn

class parseConfig
{
string dbname;
string dbuser;
string dbpass;
string dbhost;
string dbport;
uint status;

this()
{

auto checkLinkCode(string link) // we need to check all links to 
be sure if they are alive

{

return status;
}
.
if (checkLinkCode(emsc_csem) == 200)
{
		auto seismodownload = new seismoDownload(emsc_csem, this); 
//here

seismodownload.parse();
}


}
}


I know that in С# I can pass to function, and this would be point 
of class from where it's call (Here is parseConfig). Is it's 
possible to do something similar in D?


Example usage of the core.sync classes

2015-01-02 Thread Matt via Digitalmars-d-learn
I'm trying to write a small 3D engine, and wanted to place the 
physics in a separate thread to the graphics, using events, 
possibly std.concurrency, to communicate between them.


How, then, do I pass large amounts of data between threads? I'm 
thinking the physics world state (matrix for each object, object 
heirarchies, etc) being passed to the graphics thread for 
rendering.


I'd assumed that I would use Mutex, or ReadWriteMutex, but I have 
no idea how to build code using these classes, if this is even 
the right way to go about this.


I would really appreciate any pointers you can give.


Many thanks


vibe.d + dub dynamic library

2015-01-02 Thread Benjamin Thaut via Digitalmars-d-learn

Is it possible to get dub to build vibe.d into a dynamic library?
Or is it at least possible to make dub link against the shared version 
of phobos?
I found this blog post about dynamic linktimes, unfortunately it does 
not describe how to actually make dub use the dynamic version of phobos.


https://code.dawg.eu/reducing-vibed-turnaround-time-part-1-faster-linking.html

(I'm on linux)

Kind Regards
Benjamin Thaut


Re: Example usage of the core.sync classes

2015-01-02 Thread Vlad Levenfeld via Digitalmars-d-learn

On Friday, 2 January 2015 at 17:39:19 UTC, Matt wrote:
I'm trying to write a small 3D engine, and wanted to place the 
physics in a separate thread to the graphics, using events, 
possibly std.concurrency, to communicate between them.


How, then, do I pass large amounts of data between threads? I'm 
thinking the physics world state (matrix for each object, 
object heirarchies, etc) being passed to the graphics thread 
for rendering.


I'd assumed that I would use Mutex, or ReadWriteMutex, but I 
have no idea how to build code using these classes, if this is 
even the right way to go about this.


I would really appreciate any pointers you can give.


Many thanks


My personal favorite method is to use the primitives in 
core.atomic with a double or triple buffer. To double buffer, 
keep two buffers in an array (data[][] or something) and an 
integer index that points to the active buffer, then use 
atomicStore to update active buffer index when you want to swap.
Triple buffering can improve runtime performance at the cost of 
more memory, and in this case you will need two indices and two 
swap methods, one for the producer and another for the consumer. 
I use cas with a timed sleep to update the indices in this case.


Take it with a grain of salt, I'm far from a pro, but this has 
worked well for me in the past. I can post some example code if 
you need it.


Re: Example usage of the core.sync classes

2015-01-02 Thread Benjamin Thaut via Digitalmars-d-learn

Am 02.01.2015 um 19:45 schrieb Vlad Levenfeld:


My personal favorite method is to use the primitives in core.atomic with
a double or triple buffer. To double buffer, keep two buffers in an
array (data[][] or something) and an integer index that points to the
active buffer, then use atomicStore to update active buffer index when
you want to swap.
Triple buffering can improve runtime performance at the cost of more
memory, and in this case you will need two indices and two swap methods,
one for the producer and another for the consumer. I use cas with a
timed sleep to update the indices in this case.

Take it with a grain of salt, I'm far from a pro, but this has worked
well for me in the past. I can post some example code if you need it.


I have to agree with Vlad here. The usual way is to do double buffering. 
So you have two buffers which hold all the data that the physics 
simulation passes to the game logic. While the physics simulation is 
computing the next frame, the game logic can use the results from the 
last frame. The only point where sinchronisation is neccessary is when 
swapping the buffers. You have to ensure that both the game logic and 
the physics thread are done with their current buffer and then sawp 
them. The only downside of this approach is, that you will get a small 
delay (usually the time taken for 1 frame) into the data you pass this 
way. Sometimes this approach is called the "exractor pattern". I use it 
to pass data from the game simulation to the renderer, so the renderer 
can render in paralell with the game simulation computing the next 
frame. You can find a example of my double buffered solution here:

https://github.com/Ingrater/Spacecraft/blob/master/game/sources/renderer/extractor.d

I had tripple buffering up and running at some point, but I went back to 
double buffering, because tripple buffering can cause micro lags and you 
don't want that.


Kind Regards
Benjamin Thaut


Re: What exactly shared means?

2015-01-02 Thread John Colvin via Digitalmars-d-learn
On Friday, 2 January 2015 at 13:14:14 UTC, Jonathan M Davis via 
Digitalmars-d-learn wrote:
Objects in D default to being thread-local. __gshared and 
shared both make
it so that they're not thread-local. __gshared does it without 
actually
changing the type, making it easier to use but also dangerous 
to use,
because it makes it easy to violate the compiler's guarantees, 
because it'll
treat it like a thread-local variable with regards to 
optimizations and

whatnot.


I'm pretty sure that's not true. __gshared corresponds to C-style 
globals, which are *not* assumed to be thread-local (see below).




shared does not add any more synchronization or automatic 
mutex-locking or
anything like that than __gshared does (IIRC, there is some 
talk in TDPL
about shared adding memory barriers - which __gshared wouldn't 
do - but that
hasn't been implemented and probably never would be, because it 
would be too
expensive with regards to efficiency). However, unlike 
__gshared, shared
_does_ alter the type of the variable, so the compiler will 
treat it
differently. That way, it won't do stuff like optimize code 
under the
assumption that the object is thread-local like it can do with 
non-shared

objects.


Are you sure about all this optimisation stuff? I had (perhaps 
wrongly) assumed that __gshared and shared variables in D 
guaranteed Sequential Consistency for Data Race Free (SCDRF) and 
nothing more, just like all normal variables in C, C++ and Java.


Thread-local variables (i.e. everything else in D ) could in 
theory be loosened up to allow some *extra* optimisations that 
C/C++/Java etc. don't normally support (because they would risk 
violating SCDRF), but I don't know how much of this is taken 
advantage of currently.


If I'm correct, then the advice to users would be "Use __gshared 
and pretend you're writing C/C++/Java, or use shared and do 
exactly the same but with type-system support for your 
convenience/frustration".


Re: What exactly shared means?

2015-01-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/2/15 2:47 PM, John Colvin wrote:



Are you sure about all this optimisation stuff? I had (perhaps wrongly)
assumed that __gshared and shared variables in D guaranteed Sequential
Consistency for Data Race Free (SCDRF) and nothing more, just like all
normal variables in C, C++ and Java.


There is nothing special about __gshared other than where it is put.

Real simple test:

__gshared int x;

void main()
{
   int xlocal;
   int *xp = (rand() % 2) ? &x; &xlocal;

   *xp = 5;
}

tell me how the compiler can possibly know anything about what type of 
data xp points at?


But with shared, the type itself carries the hint that the data is 
shared between threads. At this point, this guarantees nothing in terms 
of races and ordering, which is why shared is so useless. In fact the 
only useful aspect of shared is that data not marked as shared is 
guaranteed thread local.



If I'm correct, then the advice to users would be "Use __gshared and
pretend you're writing C/C++/Java, or use shared and do exactly the same
but with type-system support for your convenience/frustration".


Use __gshared for accessing C globals, and otherwise only if you know 
what you are doing. There are many aspects of D that make assumptions 
based on whether a type is shared or not.


-Steve


Re: How to create instance of class that get data from 2 another instance?

2015-01-02 Thread Suliman via Digitalmars-d-learn

Oh mama mia! I did it!
http://www.everfall.com/paste/id.php?a5pp73ns1e4k

auto seismodownload = new seismoDownload(emsc_csem, this);
then:
auto mysql = new MySQL(parseconfig,eqs);

So could anybody show me better way? As I said I did not fully 
understand how use global class instance...


Re: What exactly shared means?

2015-01-02 Thread John Colvin via Digitalmars-d-learn
On Friday, 2 January 2015 at 20:32:51 UTC, Steven Schveighoffer 
wrote:

On 1/2/15 2:47 PM, John Colvin wrote:



Are you sure about all this optimisation stuff? I had (perhaps 
wrongly)
assumed that __gshared and shared variables in D guaranteed 
Sequential
Consistency for Data Race Free (SCDRF) and nothing more, just 
like all

normal variables in C, C++ and Java.


There is nothing special about __gshared other than where it is 
put.


Real simple test:

__gshared int x;

void main()
{
   int xlocal;
   int *xp = (rand() % 2) ? &x; &xlocal;

   *xp = 5;
}

tell me how the compiler can possibly know anything about what 
type of data xp points at?


But with shared, the type itself carries the hint that the data 
is shared between threads. At this point, this guarantees 
nothing in terms of races and ordering, which is why shared is 
so useless. In fact the only useful aspect of shared is that 
data not marked as shared is guaranteed thread local.


If I'm correct, then the advice to users would be "Use 
__gshared and
pretend you're writing C/C++/Java, or use shared and do 
exactly the same

but with type-system support for your convenience/frustration".


Use __gshared for accessing C globals, and otherwise only if 
you know what you are doing. There are many aspects of D that 
make assumptions based on whether a type is shared or not.


-Steve


Perhaps a more precise statement of affairs would be this:
All variables/data are SC-DRF with the exception of static 
variables and globals, which are thread-local. `shared` exists 
only to express via the type-system the necessity of thread-safe 
usage, without prescribing or implementing said usage.


Hmm. I went in to writing that thinking "shared isn't so bad". 
Now I've thought about it, it is pretty damn useless. What's the 
point of knowing that data is shared without knowing how to 
safely use it? I guess it protects against completely naive usage.


Couldn't we have thread-safe access encapsulated within types 
a-la std::atomic?


Re: What exactly shared means?

2015-01-02 Thread via Digitalmars-d-learn

On Friday, 2 January 2015 at 21:06:03 UTC, John Colvin wrote:
Hmm. I went in to writing that thinking "shared isn't so bad". 
Now I've thought about it, it is pretty damn useless. What's 
the point of knowing that data is shared without knowing how to 
safely use it? I guess it protects against completely naive 
usage.


The real issue with "shared" is that objects may change status 
during runtime based on the state of the program.


What you really want to know is when a parameter is "local", that 
is, guaranteed to not be accessed by another thread during the 
execution of the function. If so you open up for optimizations.


Re: What exactly shared means?

2015-01-02 Thread John Colvin via Digitalmars-d-learn
On Friday, 2 January 2015 at 22:10:36 UTC, Ola Fosheim Grøstad 
wrote:

On Friday, 2 January 2015 at 21:06:03 UTC, John Colvin wrote:
Hmm. I went in to writing that thinking "shared isn't so bad". 
Now I've thought about it, it is pretty damn useless. What's 
the point of knowing that data is shared without knowing how 
to safely use it? I guess it protects against completely naive 
usage.


The real issue with "shared" is that objects may change status 
during runtime based on the state of the program.


What you really want to know is when a parameter is "local", 
that is, guaranteed to not be accessed by another thread during 
the execution of the function. If so you open up for 
optimizations.


What significant optimisations does SC-DRF actually prevent?


Re: What exactly shared means?

2015-01-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, January 02, 2015 19:47:50 John Colvin via Digitalmars-d-learn wrote:
> On Friday, 2 January 2015 at 13:14:14 UTC, Jonathan M Davis via
> Digitalmars-d-learn wrote:
> > Objects in D default to being thread-local. __gshared and
> > shared both make
> > it so that they're not thread-local. __gshared does it without
> > actually
> > changing the type, making it easier to use but also dangerous
> > to use,
> > because it makes it easy to violate the compiler's guarantees,
> > because it'll
> > treat it like a thread-local variable with regards to
> > optimizations and
> > whatnot.
>
> I'm pretty sure that's not true. __gshared corresponds to C-style
> globals, which are *not* assumed to be thread-local (see below).

No, the type system will treat __gshared like a thread-local variable. It
gets put in shared memory like a C global would be, but __gshared isn't
actually part of the type, so the compiler has no way of knowing that it's
anything other than a thread-local variable - which is precisely why it's so
dangerous to use it instead of shared. For instance,

__gshared int* foo;

void main()
{
foo = new int;
int* bar = foo;
}

will compile just fine, whereas if you used shared, it wouldn't.

- Jonathan M Davis



Re: What exactly shared means?

2015-01-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, January 02, 2015 15:32:51 Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> In fact the
> only useful aspect of shared is that data not marked as shared is
> guaranteed thread local.

That and the fact that you're supposed to be able to know which portions of
your program are operating on shared data quite easily that way, as opposed
to it potentially being scattered everywhere through a program like it can
be in languages like C++ or Java. But it definitely doesn't provide any of
the kinds of compiler guarantees that we all wanted it to. The result is
that it's arguably a bit like C++'s const in that it helps, but it really
doesn't ultimately provide strong guarantees. Personally, I think that we're
still far better off using shared the way it is than using __gshared or
being stuck with what C++ and the like have, but there's no question that
it's not where we want it to be.

- Jonathan M Davis



Re: What exactly shared means?

2015-01-02 Thread John Colvin via Digitalmars-d-learn
On Friday, 2 January 2015 at 23:26:57 UTC, Jonathan M Davis via 
Digitalmars-d-learn wrote:
On Friday, January 02, 2015 19:47:50 John Colvin via 
Digitalmars-d-learn wrote:

On Friday, 2 January 2015 at 13:14:14 UTC, Jonathan M Davis via
Digitalmars-d-learn wrote:
> Objects in D default to being thread-local. __gshared and
> shared both make
> it so that they're not thread-local. __gshared does it 
> without

> actually
> changing the type, making it easier to use but also dangerous
> to use,
> because it makes it easy to violate the compiler's 
> guarantees,

> because it'll
> treat it like a thread-local variable with regards to
> optimizations and
> whatnot.

I'm pretty sure that's not true. __gshared corresponds to 
C-style
globals, which are *not* assumed to be thread-local (see 
below).


No, the type system will treat __gshared like a thread-local 
variable. It
gets put in shared memory like a C global would be, but 
__gshared isn't
actually part of the type, so the compiler has no way of 
knowing that it's
anything other than a thread-local variable - which is 
precisely why it's so

dangerous to use it instead of shared. For instance,

__gshared int* foo;

void main()
{
foo = new int;
int* bar = foo;
}

will compile just fine, whereas if you used shared, it wouldn't.

- Jonathan M Davis


I understand that. As far as optimisations and codegen go, that 
is not the same as being able to assume that something is 
thread-local, far from it.


The rule (in C(++) at least) is that all data is assumed to be 
visible and mutable from multiple other threads unless proved 
otherwise. However, given that you do not write a race, the 
compiler will provide full sequential consistency. If you do 
write a race though, all bets are off.


Are you telling me that D does not obey the C(++) memory model? 
That would be a fatal hole in our C(++) interoperability.


AFAIK, the only data in D that the compiler is allowed to assume 
to be thread-local is data that it can prove is thread-local. The 
trivial case is TLS, which is thread-local by definition.


Re: What exactly shared means?

2015-01-02 Thread via Digitalmars-d-learn

On Friday, 2 January 2015 at 23:10:46 UTC, John Colvin wrote:

What significant optimisations does SC-DRF actually prevent?


By "SC-DRF" I assume you mean the Java memory model. AFAIK SCDRF 
just means that if you syncronize correctly (manually) then you 
will get sequential consistency (restriction on the compiler).


Getting rid of the restrictions on the compiler and eliding 
programmer-provided syncronization allows for more optimizations 
on loads, writes, reordering, syncronization/refcounting...?


Re: What exactly shared means?

2015-01-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, January 02, 2015 23:51:04 John Colvin via Digitalmars-d-learn wrote:
> AFAIK, the only data in D that the compiler is allowed to assume
> to be thread-local is data that it can prove is thread-local. The
> trivial case is TLS, which is thread-local by definition.

In D, if a type is not marked as shared, then it is by definition
thread-local, and the compiler is free to assume that it's thread-local. If
it's not actually thread-local (e.g. because you cast away shared), then
it's up to you to ensure that no other threads access that data while it's
being referred to via a reference or pointer that's typed as thread-local.
The only exception is immutable, in which case it's implicitly shared,
because it can never change, and there's no need to worry about multiple
threads accessing the data at the same time.

- Jonathan M Davis



Re: What exactly shared means?

2015-01-02 Thread Peter Alexander via Digitalmars-d-learn

On Friday, 2 January 2015 at 23:51:05 UTC, John Colvin wrote:
The rule (in C(++) at least) is that all data is assumed to be 
visible and mutable from multiple other threads unless proved 
otherwise. However, given that you do not write a race, the 
compiler will provide full sequential consistency. If you do 
write a race though, all bets are off.


The memory is visible and mutable, but that's pretty much the 
only guarantee you get. Without synchronization, there's no 
guarantee a write made by thread A will ever be seen by thread B, 
and vice versa.


Analogously in D, if a thread modifies a __gshared variable, 
there's no guarantees another thread will ever see that 
modification. The variable isn't thread local, but it's almost as 
if the compiler to treat it that way.


These relaxed guarantees allow the compiler to keep variables in 
registers, and re-order memory writes. These optimizations are 
crucial to performance.


cannot modify struct with immutable members

2015-01-02 Thread ted via Digitalmars-d-learn

I get the following error from the code below: (dmd2.066.1, linux)
test.d(26): Error: cannot modify struct myTest1 Test with immutable members

Is this expected?

If so, how can I achieve this result - being able to set (a new) initial value 
of myTest1 from within an nested function ?

thanks !
ted


code: 
struct A
{
int someInt;
}

struct Test
{
this( ref const(A) arg )
{
mA = arg;
}

private:
const(A) mA;
}

void main()
{
Test myTest1;
A topA;

void _someFunc( ref const(A) myA )
{
myTest1 = Test(myA);
}

Test myTest2 = Test(topA);  // is ok as expected
_someFunc( topA );// error.
}


Re: cannot modify struct with immutable members

2015-01-02 Thread ketmar via Digitalmars-d-learn
On Sat, 03 Jan 2015 13:25:31 +1030
ted via Digitalmars-d-learn  wrote:

> 
> I get the following error from the code below: (dmd2.066.1, linux)
> test.d(26): Error: cannot modify struct myTest1 Test with immutable members
> 
> Is this expected?
> 
> If so, how can I achieve this result - being able to set (a new) initial 
> value 
> of myTest1 from within an nested function ?
> 
> thanks !
> ted
> 
> 
> code: 
> struct A
> {
> int someInt;
> }
> 
> struct Test
> {
> this( ref const(A) arg )
> {
> mA = arg;
> }
> 
> private:
> const(A) mA;
> }
> 
> void main()
> {
> Test myTest1;
> A topA;
> 
> void _someFunc( ref const(A) myA )
> {
> myTest1 = Test(myA);
> }
> 
> Test myTest2 = Test(topA);  // is ok as expected
> _someFunc( topA );  // error.
> }

the question is: "why do you want `mA` to be const?" leaving aside
compiler complaints this is the one and important question. let's try
to fix your code instead of devising workarounds to beat the
compiler. ;-)

please remember that D `const` is not the same as C/C++ `const`, so my
question is not so stupid as it may look.

p.s. you can use `in A myA` instead of `ref const A myA`, in most cases
compiler is intelligent enough to use "pass-by-reference" for `in` args.


signature.asc
Description: PGP signature


Re: cannot modify struct with immutable members

2015-01-02 Thread ted via Digitalmars-d-learn
Hi,

thanks for the reply...to answer your direct question, the original code 
looked like:


struct A
{
int someInt;
}

struct Test
{
@property { const(A) getA() { return mA; } }
this( ref const(A) arg )
{
mA = arg;
}

private:
A mA;
}

void main()
{
Test myTest1;
A topA;

void _someFunc( ref const(A) myA )
{
myTest1 = Test(myA);
}

Test myTest2 = Test(topA);  // is ok as expected
_someFunc( topA );

// later on
A foo = myTest1.getA();
}

which compiles. However, I think I exercised some other compiler-related 
bug when I added a field to another structure in the module, and the 
compiler started complaining about the construct above...
'Error: cannot implicitly convert expression (arg) of type const(A) to A' 
in the constructor of Test (I'm unable to recreate this error in this 
simple code example).

(I am prototyping something, so the code I'm producing is very badly 
structured, and I have nested functions within delegates within  and I 
have also hit some odd scoping errors - definite compiler issues - 
(notwithstanding the horrible code structure)).

so (given my D knowledge is limited) I then wondered why it accepted 
(nonconst)mA=(const)arg in the first place, hence the const()...hence the 
original question.

I am assuming that the ref const(A) myA means that _someFunc (and below) is 
unable to alter any fields of myA. This may be my basic error.

thanks !






ketmar via Digitalmars-d-learn wrote:

> On Sat, 03 Jan 2015 13:25:31 +1030
> ted via Digitalmars-d-learn  wrote:
> 
>> 
>> I get the following error from the code below: (dmd2.066.1, linux)
>> test.d(26): Error: cannot modify struct myTest1 Test with immutable 
members
>> 
>> Is this expected?
>> 
>> If so, how can I achieve this result - being able to set (a new) initial
>> value of myTest1 from within an nested function ?
>> 
>> thanks !
>> ted
>> 
>> 
>> code:
>> struct A
>> {
>> int someInt;
>> }
>> 
>> struct Test
>> {
>> this( ref const(A) arg )
>> {
>> mA = arg;
>> }
>> 
>> private:
>> const(A) mA;
>> }
>> 
>> void main()
>> {
>> Test myTest1;
>> A topA;
>> 
>> void _someFunc( ref const(A) myA )
>> {
>> myTest1 = Test(myA);
>> }
>> 
>> Test myTest2 = Test(topA);  // is ok as expected
>> _someFunc( topA ); // error.
>> }
> 
> the question is: "why do you want `mA` to be const?" leaving aside
> compiler complaints this is the one and important question. let's try
> to fix your code instead of devising workarounds to beat the
> compiler. ;-)
> 
> please remember that D `const` is not the same as C/C++ `const`, so my
> question is not so stupid as it may look.
> 
> p.s. you can use `in A myA` instead of `ref const A myA`, in most cases
> compiler is intelligent enough to use "pass-by-reference" for `in` args.



Re: cannot modify struct with immutable members

2015-01-02 Thread ted via Digitalmars-d-learn

Well, I just cleared up some of my misunderstanding.

I did not realise the mA (within struct Test) would be a _copy_ of arg, not 
a reference (pointer) to arg. 

So the more correct code snippet would be:

struct A
{
int someInt;
}

struct Test
{
@property { const(A) getA() { return *mA; } }
this( in A arg )
{
mA = &arg;
}

private:
const A* mA;
}

void main()
{
Test myTest1;
A topA;

topA.someInt = 100;

void _someFunc( in A myA )
{
myTest1 = Test(myA);
}

Test myTest2 = Test(topA);  // is ok as expected
_someFunc( topA );


}

which fails to compile for the same reason (test.d(30): Error: cannot 
modify struct myTest1 Test with immutable members)

(I have been able to work around my original issue by removing @safe from 
Test, and then cast()ing ... but this is ugly)

This code snippet is me trying to understand whether I have a fundamental 
misunderstanding with const, or whether it is an issue with the compiler

(I agree with your view that 'fixing my code' is the correct approach, btw 
- I'm still curious).

(The reason for this basic structure is that _someFunc is a callback from 
another module, and myTest1 contains state information that is 
created/adjusted via the callback. And (to be safe) myTest1 contains 
references to other structures that it should not adjust - hence the 
const()). 

and I can't use @safe and pointers..

So, it appears I need to do what I want with classes, not structs:
i.e.

import std.stdio;

class A
{
int someInt;
}

@safe class Test
{
@property { const(A) getA() { return mA; } }
this( in A arg )
{
mA = arg;
}

private:
const A mA;
}

void main()
{
Test myTest1;
A topA = new A;

topA.someInt = 100;

void _someFunc( in A myA )
{
myTest1 = new Test(myA);
}

Test myTest2 = new Test(topA);  // is ok as expected
_someFunc( topA );

writeln( "topA: ", topA.someInt );
writeln( "myTest1.A: ", myTest1.getA.someInt );
}

I'm happy I've got a workaround (which seems to safely preserve the 
const'dness), but I still don't understand why the compiler barfs on the 
struct version as it should be 'replacing' the higher scoped variable

anyway...thanks for your response.apologies for the streaming 
conciousness of this reply...




Re: cannot modify struct with immutable members

2015-01-02 Thread ketmar via Digitalmars-d-learn
On Sat, 03 Jan 2015 14:45:24 +1030
ted via Digitalmars-d-learn  wrote:

> Well, I just cleared up some of my misunderstanding.
> 
> I did not realise the mA (within struct Test) would be a _copy_ of arg, not 
> a reference (pointer) to arg. 
> 
> So the more correct code snippet would be:
> 
> struct A
> {
> int someInt;
> }
> 
> struct Test
> {
> @property { const(A) getA() { return *mA; } }
> this( in A arg )
> {
> mA = &arg;
> }
> 
> private:
> const A* mA;
> }
> 
> void main()
> {
> Test myTest1;
> A topA;
> 
> topA.someInt = 100;
> 
> void _someFunc( in A myA )
> {
> myTest1 = Test(myA);
> }
> 
> Test myTest2 = Test(topA);  // is ok as expected
> _someFunc( topA );
> 
> 
> }
nonononono! ;-)
please, don't use pointers like this. try to avoid pointers altogether,
they are VERY dangerous. as for your sample: it is already invalid. see:

  this (in A arg) { mA = &arg; }

you are storing the address of *local* *var* *from* *stack* here. then
local will go out of scope and... BANG! everyone is dead.

> This code snippet is me trying to understand whether I have a fundamental 
> misunderstanding with const, or whether it is an issue with the compiler
seems that you didn't get D `const`. it's deffers from C/C++ `const`.
in most cases you don't need to use it at all. the funny thing of D
const is that const "variable" cannot be changed in any way after
assigning. that's why compiler complains: you're trying to change
variable with `const` part, which is forbidden.

structure instance with const fields can be initialized only once, upon
creation. so did `Test myTest1;` -- you initialized `myTest1` with
default values. you can't reinitialize it later.

in C++ constness on member doesn't impose such restrictions. this is
confusing for newcomers with C/C++ expirience. the best advice here is
"don't use `const` in D unless you are fully understand what you are
doing and how it work in D".

> I'm happy I've got a workaround (which seems to safely preserve the 
> const'dness), but I still don't understand why the compiler barfs on the 
> struct version as it should be 'replacing' the higher scoped variable
you don't need `const` here at all. as far as i can see you want to
tell the compiler that `mA` must not be changed after creating a
struct. to achieve that you'd better move your struct to separate
module and provide read-only getter.

you need to move your struct to separate module 'cause `private`
modifier will not affect the code in the same module. one of the D
rules is that the code in one module can access anything that was
declared in the same module, including "private" members of
structs/classes. C++ tries to achieve that with "friend" members, but
as D has full-fledged module system, it doesn't need such tricks.

tl;dr: don't use `const` here, provide an accessor and stop
worrying/helping the compiler. ;-)


signature.asc
Description: PGP signature


Re: cannot modify struct with immutable members

2015-01-02 Thread ketmar via Digitalmars-d-learn
On Sat, 03 Jan 2015 14:45:24 +1030
ted via Digitalmars-d-learn  wrote:

p.s. also please note that structs in D are always passed by value and
copied (until you not explicitly ask for something another). so:

  MyStruct a;
  MyStruct b;
  b = a;

actually does `memcpy()` (with postblit if there is any). and it's
forbidden to overwrite `const` variable contents. that's why compiler
complains: by assigning to `mA` you are trying to overwrite contents of
`const` variable.


signature.asc
Description: PGP signature


Re: cannot modify struct with immutable members

2015-01-02 Thread ted via Digitalmars-d-learn
ketmar via Digitalmars-d-learn wrote:

> On Sat, 03 Jan 2015 14:45:24 +1030
> ted via Digitalmars-d-learn  wrote:
> 
>> Well, I just cleared up some of my misunderstanding.
>> 
>> I did not realise the mA (within struct Test) would be a _copy_ of arg,
>> not a reference (pointer) to arg.
>> 
>> So the more correct code snippet would be:
>> 
>> struct A
>> {
>> int someInt;
>> }
>> 
>> struct Test
>> {
>> @property { const(A) getA() { return *mA; } }
>> this( in A arg )
>> {
>> mA = &arg;
>> }
>> 
>> private:
>> const A* mA;
>> }
>> 
>> void main()
>> {
>> Test myTest1;
>> A topA;
>> 
>> topA.someInt = 100;
>> 
>> void _someFunc( in A myA )
>> {
>> myTest1 = Test(myA);
>> }
>> 
>> Test myTest2 = Test(topA);  // is ok as expected
>> _someFunc( topA );
>> 
>> 
>> }
> nonononono! ;-)
> please, don't use pointers like this. try to avoid pointers altogether,
> they are VERY dangerous. as for your sample: it is already invalid. see:
> 
>   this (in A arg) { mA = &arg; }
> 
> you are storing the address of *local* *var* *from* *stack* here. then
> local will go out of scope and... BANG! everyone is dead.

Oops...true (*blush*) - should have noticed this.

> 
>> This code snippet is me trying to understand whether I have a
>> fundamental misunderstanding with const, or whether it is an issue with
>> the compiler
> seems that you didn't get D `const`. it's deffers from C/C++ `const`.
> in most cases you don't need to use it at all. the funny thing of D
> const is that const "variable" cannot be changed in any way after
> assigning. that's why compiler complains: you're trying to change
> variable with `const` part, which is forbidden.
> 
> structure instance with const fields can be initialized only once, upon
> creation. so did `Test myTest1;` -- you initialized `myTest1` with
> default values. you can't reinitialize it later.
> 
> in C++ constness on member doesn't impose such restrictions. this is
> confusing for newcomers with C/C++ expirience. the best advice here is
> "don't use `const` in D unless you are fully understand what you are
> doing and how it work in D".

Ironically, I'm trying to use const in an effort to understand it...but 
there seems to be an unusual amount of pain until I grok it.

> 
>> I'm happy I've got a workaround (which seems to safely preserve the
>> const'dness), but I still don't understand why the compiler barfs on the
>> struct version as it should be 'replacing' the higher scoped
>> variable
> you don't need `const` here at all. as far as i can see you want to
> tell the compiler that `mA` must not be changed after creating a
> struct. to achieve that you'd better move your struct to separate
> module and provide read-only getter.
> 
> you need to move your struct to separate module 'cause `private`
> modifier will not affect the code in the same module. one of the D
> rules is that the code in one module can access anything that was
> declared in the same module, including "private" members of
> structs/classes. C++ tries to achieve that with "friend" members, but
> as D has full-fledged module system, it doesn't need such tricks.
> 
> tl;dr: don't use `const` here, provide an accessor and stop
> worrying/helping the compiler. ;-)

Yeah.its one of those cases where the prototype code is getting too 
ugly, and a refactorisation is required.but no time !!

many thanks,
ted




Re: cannot modify struct with immutable members

2015-01-02 Thread ketmar via Digitalmars-d-learn
On Sat, 03 Jan 2015 15:56:58 +1030
ted via Digitalmars-d-learn  wrote:

> Ironically, I'm trying to use const in an effort to understand it...but 
> there seems to be an unusual amount of pain until I grok it.
just remember that `const` "infects" everything down to the bytes when
it's applied. and it's forbidden to overwrite `const` vars with
different values.

in your canse it "infects" your `A` struct, effectively converting it
to `const A` (with `const int someInt`). and as you can't change
"consted" value, and structs are `memcpy()`ed... compiler tracked that
down and refused to do it.

so you don't really need `const` fields in D. you can make getters
`const` though, so that they can be used on `const MyStruct` instances.

so two rules should help you here:
1. it's forbidden to overwrite `const` vars with new values.
2. `const` will infect everything down to bytes.

maybe this will help you like it helps me. ;-)


signature.asc
Description: PGP signature


Re: cannot modify struct with immutable members

2015-01-02 Thread ted via Digitalmars-d-learn
ketmar via Digitalmars-d-learn wrote:

> On Sat, 03 Jan 2015 15:56:58 +1030
> ted via Digitalmars-d-learn  wrote:
> 
>> Ironically, I'm trying to use const in an effort to understand it...but
>> there seems to be an unusual amount of pain until I grok it.
> just remember that `const` "infects" everything down to the bytes when
> it's applied. and it's forbidden to overwrite `const` vars with
> different values.
> 
> in your canse it "infects" your `A` struct, effectively converting it
> to `const A` (with `const int someInt`). and as you can't change
> "consted" value, and structs are `memcpy()`ed... compiler tracked that
> down and refused to do it.
> 
> so you don't really need `const` fields in D. you can make getters
> `const` though, so that they can be used on `const MyStruct` instances.
> 
> so two rules should help you here:
> 1. it's forbidden to overwrite `const` vars with new values.
> 2. `const` will infect everything down to bytes.
> 
> maybe this will help you like it helps me. ;-)


Thanks for your helpbesides the issues that you pointed out, I had 
forgotten that structs are always copied (I'm so used to thinking in 
pointers (if you ignore the fubar from my earlier example) - and a world 
where copying data structures is an expensive exercise to be 
avoided)...

I'm now taking the view that const is there for the compiler to optimise 
code on the basis that nothing can alter it once set (and can only be set 
on initialisation). So I see your point that it would not be used very 
often in general defensive code - better to provide access restrictions 
(getters) for most cases.

I am refactoring the code to use getters/setters

One of the really good things about D is that it is relatively painless to 
refactor when you have to - much less boilerplate to have to move around !

thanks again,
regards,
ted



Re: cannot modify struct with immutable members

2015-01-02 Thread ketmar via Digitalmars-d-learn
On Sat, 03 Jan 2015 16:40:14 +1030
ted via Digitalmars-d-learn  wrote:

> I'm now taking the view that const is there for the compiler to optimise 
> code on the basis that nothing can alter it once set (and can only be set 
> on initialisation). So I see your point that it would not be used very 
> often in general defensive code - better to provide access restrictions 
> (getters) for most cases.
exactly! ;-)

> thanks again,
you're welcome. hope you will keep enjoying D, it's great. ;-)


signature.asc
Description: PGP signature