Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread Benjamin Thaut

Am 16.10.2013 03:17, schrieb DoctorCaptain:

I've gotten extremely close. The DPaste link that follows demonstrates
three different templates:

...


So is there any reason why you still pass the variadic arguments to the 
generator function and not do it the way I proposed in my last dpaste 
snippet? Even if you need the variadic arguments inside the generator 
for some logic you could still reference them by using the variadic 
arguments to the actual template.


Re: cannot call impure function ~this

2013-10-16 Thread monarch_dodra

On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:

I get this error:

/d701/f223.d(11): Error: pure function 'f223.getA' cannot call 
impure function 'f223.A.~this'



with this code:

import std.stdio;

struct A {
public:
~this() {
writeln(DTor);
}
}

A getA() pure nothrow {
return A();
}

void main()
{
A a = getA();

writeln(end of main);
}


But without pure and nothrow I get this output:

end of main
DTor


Why the compiler thinks that the function should/could call 
A::~this?


It could have something to do with the fact that RVO is an 
optimization *opportunity* that the compiler is allowed to go 
for, even if it changes the program output.


Hoewever, being an *opportunity*, the compiler still has to make 
sure the code is valid without said optimization, which in this 
case, isn't: getA would destroy it's temporary after blitting it 
on the stac, leading to an impure call.


Re: cannot call impure function ~this

2013-10-16 Thread Namespace
On Wednesday, 16 October 2013 at 07:23:45 UTC, monarch_dodra 
wrote:

On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:

I get this error:

/d701/f223.d(11): Error: pure function 'f223.getA' cannot call 
impure function 'f223.A.~this'



with this code:

import std.stdio;

struct A {
public:
~this() {
writeln(DTor);
}
}

A getA() pure nothrow {
return A();
}

void main()
{
A a = getA();

writeln(end of main);
}


But without pure and nothrow I get this output:

end of main
DTor


Why the compiler thinks that the function should/could call 
A::~this?


It could have something to do with the fact that RVO is an 
optimization *opportunity* that the compiler is allowed to go 
for, even if it changes the program output.


Hoewever, being an *opportunity*, the compiler still has to 
make sure the code is valid without said optimization, which in 
this case, isn't: getA would destroy it's temporary after 
blitting it on the stac, leading to an impure call.


So it _could_ be impure, but mostly it isn't, right?


Re: should chain be pure

2013-10-16 Thread monarch_dodra

On Tuesday, 15 October 2013 at 14:15:15 UTC, bearophile wrote:

Daniel Davidson:

If you are agreeing that chain should be pure and it is just 
following all the calls and making all of them pure, until 
that happens by the professionals - is there a casting 
solution so I can fake a pure and move on?


chain is a template, and in Phobos often templates are not 
annotated with pure/nothrow, the compiler infers those 
attributes.


Regarding your code, perhaps you can put your call in an impure 
delegate and than cast it, but D has no direct means to cast 
purity, because it's highly unsafe and it's against the idea of 
having purity in the language.


So I suggest to replace the pure in your function/method tree 
with /*pure*/, and later fix the code if/when chains becomes 
pure.


Bye,
bearophile


@bearophile: The problem is actually with voldemort. Chain is 
implemented as:


auto chain(Arg...)(Args args)
{
static struct Result //Non template struct
{
auto front(); //Non template function in a non-template 
struct.

}
}

The problem is that the whole inference things stops at this 
level: the attributes of front are not infered, so chain is not 
pure simply because it isn't a template.


This could be simply solved by making Result a non voldermort 
ChainResult outside of the body of chain.


I'd do this, but Kenji had mentioned before that he thought the 
attributes should be inferred.


So for now, I didn't personally make the effort of doing anything 
to fix it myself. But if someone else where make the effort, I'd 
review and probably pull.


Re: cannot call impure function ~this

2013-10-16 Thread monarch_dodra

On Wednesday, 16 October 2013 at 07:27:25 UTC, Namespace wrote:
On Wednesday, 16 October 2013 at 07:23:45 UTC, monarch_dodra 
wrote:

On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:

I get this error:

/d701/f223.d(11): Error: pure function 'f223.getA' cannot 
call impure function 'f223.A.~this'



with this code:

import std.stdio;

struct A {
public:
~this() {
writeln(DTor);
}
}

A getA() pure nothrow {
return A();
}

void main()
{
A a = getA();

writeln(end of main);
}


But without pure and nothrow I get this output:

end of main
DTor


Why the compiler thinks that the function should/could call 
A::~this?


It could have something to do with the fact that RVO is an 
optimization *opportunity* that the compiler is allowed to go 
for, even if it changes the program output.


Hoewever, being an *opportunity*, the compiler still has to 
make sure the code is valid without said optimization, which 
in this case, isn't: getA would destroy it's temporary after 
blitting it on the stac, leading to an impure call.


So it _could_ be impure, but mostly it isn't, right?


I guess that's one way to put it. I'd say it *is* impure, but all 
its impure bits have been optimized out. That's my explanation 
anyways.


I'm curious: Is this a problem for you? The function calling getA 
*can't* be pure either, so marking getA as pure is ...


I was going to say useless, but I guess pure is always an 
optimization opportunity for the compiler.


I'd file an ER, you never know.


Re: Starting D with a project in mind.

2013-10-16 Thread Andrew



andrew@islay:~/dub$ ./build.sh
Generating version file...
Running gdmd...
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di:224: 
error: this cannot be interpreted at compile time, because it 
has no available source code
/usr/local/gdc/include/d/4.8.2/std/net/curl.d:195: note: called 
from here: dur(2L)


line 224 is trying to instantiate a Duration object. Any ideas ?


Giving up on dub, I tried niaively to build one of the vibe.d 
samples directly :-


andrew@islay:~/vibe.d/examples/http_server/source$ gdmd 
-I~/vibe.d/source app.d
/data/home/andrew/vibe.d/source/vibe/stream/ssl.d:43: error: 
module bio is in file 'deimos/openssl/bio.d' which cannot be read


Looks like I'm missing some openssl dependencies, where do these 
come from as they don't appear to be part of phobos ?



Thanks



Re: cannot call impure function ~this

2013-10-16 Thread Namespace
On Wednesday, 16 October 2013 at 07:32:27 UTC, monarch_dodra 
wrote:

On Wednesday, 16 October 2013 at 07:27:25 UTC, Namespace wrote:
On Wednesday, 16 October 2013 at 07:23:45 UTC, monarch_dodra 
wrote:

On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:

I get this error:

/d701/f223.d(11): Error: pure function 'f223.getA' cannot 
call impure function 'f223.A.~this'



with this code:

import std.stdio;

struct A {
public:
~this() {
writeln(DTor);
}
}

A getA() pure nothrow {
return A();
}

void main()
{
A a = getA();

writeln(end of main);
}


But without pure and nothrow I get this output:

end of main
DTor


Why the compiler thinks that the function should/could call 
A::~this?


It could have something to do with the fact that RVO is an 
optimization *opportunity* that the compiler is allowed to go 
for, even if it changes the program output.


Hoewever, being an *opportunity*, the compiler still has to 
make sure the code is valid without said optimization, which 
in this case, isn't: getA would destroy it's temporary after 
blitting it on the stac, leading to an impure call.


So it _could_ be impure, but mostly it isn't, right?


I guess that's one way to put it. I'd say it *is* impure, but 
all its impure bits have been optimized out. That's my 
explanation anyways.


I'm curious: Is this a problem for you? The function calling 
getA *can't* be pure either, so marking getA as pure is ...


I was going to say useless, but I guess pure is always an 
optimization opportunity for the compiler.


I'd file an ER, you never know.
No, I was just curious what's behind it. So specifically why the 
compiler could call the destructor.


Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread DoctorCaptain
On Wednesday, 16 October 2013 at 06:09:48 UTC, Benjamin Thaut 
wrote:

Am 16.10.2013 03:17, schrieb DoctorCaptain:
I've gotten extremely close. The DPaste link that follows 
demonstrates

three different templates:

...


So is there any reason why you still pass the variadic 
arguments to the generator function and not do it the way I 
proposed in my last dpaste snippet? Even if you need the 
variadic arguments inside the generator for some logic you 
could still reference them by using the variadic arguments to 
the actual template.


I suppose I was trying to give the class individual data members, 
such that passing a tuple of (WorstChild, MiddleChild, BestChild) 
would result in a class definition of:


class MagicClass {
WorstClass t1;
MiddleClass t2;
BestClass t3;
}

However, if that is impossible (and frankly it'd be more 
difficult to work with than your way even if it was achieved), 
then I'll use your approach (actually, I'm just going to use your 
approach anyway. It's significantly cleaner than my horrid mess 
of a goal). That said, what is actually happening in your example?


I reworked it a bit to demonstrate that the class has accessible 
members within T, that can be instantiated and accessed and 
whatnot.


http://dpaste.dzfl.pl/07b20d75

Note the use of typeof() to get the type of the elements at each 
index of members, to generate a type on which a constructor can 
be called to instantiate the elements at each index of members. 
Magic.


What is T within the generated class definition? Is this just how 
tuples work? T is an array of three arbitrary pointers, 
initially null, that can be instantiated with new to create valid 
pointers to objects of each type at T's indexes? Like, T in the 
DPaste example is an array of pointers, such that:
[WorstChild*, MiddleChild*, BestChild*]? Is it literally just 
magic like that?


Actually, let me formally present a couple of ending 
thoughts/questions:


First, allow me to apologize for trying to force a different, 
messy horrid mess of a goal on you, when your initial solution 
was majestic to begin with.


Second, as I was trying to figure out just a moment ago, what 
-exactly- is T in the generated class definition, and why does it 
allow me to use it as an arbitrary container for objects of the 
arbitrary types I want it to contain (Read: why is it able to do 
exactly what I want it to be able to do? What's going on behind 
the scenes?)?


Third, given that I am going to go with your solution (it works, 
it works well, and I can't seem to force my original goal to 
work, whether that was even a good idea to begin with at all (it 
wasn't)), can you think of a way to actually produce my original 
goal? That is, instead of a container T which I can use to access 
my arbitrary data members once the generated class is 
instantiated, is it actually even possible to generate individual 
data members, a la:


class MagicClass {
  T[0] t0;
  T[1] t1;
  // ... etc
} // ?

You've been wildly helpful, and admirably concise. I am 
-extremely- interested in the answer to the second thought, and 
while I'm sure the answer is simple, it also seems -too- magic to 
actually work, and yet it does.


Again, thank you to everyone who responded, and thank you 
Benjamin for your continued help.


Re: Starting D with a project in mind.

2013-10-16 Thread Stefan Frijters

On Wednesday, 16 October 2013 at 07:52:44 UTC, Andrew wrote:



andrew@islay:~/dub$ ./build.sh
Generating version file...
Running gdmd...
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di:224: 
error: this cannot be interpreted at compile time, because it 
has no available source code
/usr/local/gdc/include/d/4.8.2/std/net/curl.d:195: note: 
called from here: dur(2L)


line 224 is trying to instantiate a Duration object. Any ideas 
?


Giving up on dub, I tried niaively to build one of the vibe.d 
samples directly :-


andrew@islay:~/vibe.d/examples/http_server/source$ gdmd 
-I~/vibe.d/source app.d
/data/home/andrew/vibe.d/source/vibe/stream/ssl.d:43: error: 
module bio is in file 'deimos/openssl/bio.d' which cannot be 
read


Looks like I'm missing some openssl dependencies, where do 
these come from as they don't appear to be part of phobos ?



Thanks


As far as I know deimos is a set of official (?) bindings for 
common C libraries. I don't know dub's build process but I assume 
that if the build script would have worked for you it would have 
attempted to clone this repo 
https://github.com/D-Programming-Deimos/openssl (you can find 
more bindings if you go up one level). My gdc build hadn't 
finished yet when I had to leave for work this morning, but I'll 
try to build dub tonight, to see if I run into the same 
problems...


Re: Starting D with a project in mind.

2013-10-16 Thread Andrew


As far as I know deimos is a set of official (?) bindings for 
common C libraries. I don't know dub's build process but I 
assume that if the build script would have worked for you it 
would have attempted to clone this repo 
https://github.com/D-Programming-Deimos/openssl (you can find 
more bindings if you go up one level). My gdc build hadn't 
finished yet when I had to leave for work this morning, but 
I'll try to build dub tonight, to see if I run into the same 
problems...


I've been using a Cubieboard A20, it's much better than a RPi as 
it has 1GB RAM, dual core armv7 and much better IO including 
on-board SATA for $50. The gcc /gdc build takes around 2 - 3 
hours on that. You'll probably run into the same libphobos issues 
that I had, since there are many places where there are no ARM 
headers.


Re: Starting D with a project in mind.

2013-10-16 Thread Dicebot

On Wednesday, 16 October 2013 at 07:52:44 UTC, Andrew wrote:
Giving up on dub, I tried niaively to build one of the vibe.d 
samples directly


This is something I have used with vibe.d in absence of dub 
(untested, from my memory):


git clone https://github.com/D-Programming-Deimos/openssl
git clone https://github.com/D-Programming-Deimos/libevent
git clone https://github.com/rejectedsoftware/vibe.d
cd myvibeapp
rdmd --compiler=gdmd2 -I../openssl/ -I../libevent 
-I../vibe.d/source -J./views/ -version=VibeLibeventDriver 
--build-only source/app.d


Usage of `rdmd` is crucial here as you need something to take 
care of compiling all imported modules. dmd/gdc/ldc don't do it 
on their own and you really don't want to track that module list 
manually ;)


rdmd sources are here (it is a small trivial D app):
https://github.com/D-Programming-Language/tools


Re: Starting D with a project in mind.

2013-10-16 Thread Dicebot

On Tuesday, 15 October 2013 at 22:52:42 UTC, Andrew wrote:

andrew@islay:~/dub$ ./build.sh
Generating version file...
Running gdmd...
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di:224: 
error: this cannot be interpreted at compile time, because it 
has no available source code
/usr/local/gdc/include/d/4.8.2/std/net/curl.d:195: note: called 
from here: dur(2L)


line 224 is trying to instantiate a Duration object. Any ideas ?


Here the problem is that your install script has provided only 
*.di files as bindings to druntime and `dub` tries to use some of 
those function for compile-time constfolding (CTFE) which 
requires having full function source. *.di are supposed to be 
bindings to library blobs for cases when you want to hide 
implementation from end user, no idea why those are used here. 
Normal DMD install puts those as plain *.d modules.


Re: Starting D with a project in mind.

2013-10-16 Thread Dicebot

On Tuesday, 15 October 2013 at 23:16:07 UTC, Brad Roberts wrote:
I think you mean catch-22 rather than dead-end.  There's not 
more people helping support ARM due to ARM not yet working 
well, so there's no developers.


ARM's not exotic, it's just not on as many people's desktops.  
Thats been changing rapidly over the last several years.


In my opinion catch-22 is partial case of a dead-end - 
something that blocks your effective forward movement :)


ARM support is rather exotic among projects of current D users.


Re: Syntax for heap allocated void initialized arrays

2013-10-16 Thread bearophile

Timothee Cour:


is the following true?

int*[N] a=void;
foreach(i;N)
  a[i]=fillValue(i);// some leaks may occur during foreach loop
//at the next GC run, no more leaks due to that piece of code


I think so, but I am not an expert on GC matters, I have not yet 
written a similar GC.


Bye,
bearophile


Re: Starting D with a project in mind.

2013-10-16 Thread Dicebot

On Tuesday, 15 October 2013 at 23:03:15 UTC, Andrew wrote:

Thanks for your patience supporting me BTW.


You are welcome. D development is pure open-source movement with 
all its pros and cons - almost anyone here will gladly help you 
not only because we care about a good public image but because it 
gives a chance that you may investigate and improve situation in 
currently under-explored domain, to the greater community 
benefit. It is very important to have someone with personal 
interest in such development areas, helping with few cheap 
advises is the very least we can do :)


Interfacing via Java Native Interface

2013-10-16 Thread Andrew

Hello there!
I've decided to learn a bit of D, as I am currently Android 
Developer (mostly C++ - JNI - Java), I'm trying to create a D 
shared library which exports function (with extern (C)) for 
invocation from Java.
My .d file contains only a single function returning an int, 
.java calls this function several times.
This approach only works if d-function is trivial, e.g. it's not 
using any D functionality (I believe that it is related to GC and 
memory allocation).
For example, if my d-function just returns some constant integer, 
java side receives it. core.stdc.stdio also works and allows 
console output, but it's not the case with std.stdio.writeln and 
similar functions.
If I use any d-specific functions my program crashes while 
calling native code with some weird message like following:

Invalid memory access of location 0x0 rip=addr.

It seems like D is not initialized at all, maybe there is some 
internal function like dinit() which I can call in order to 
activate everything?


Thanks.


Re: Interfacing via Java Native Interface

2013-10-16 Thread Iain Buclaw

On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:

Hello there!
I've decided to learn a bit of D, as I am currently Android 
Developer (mostly C++ - JNI - Java), I'm trying to create a D 
shared library which exports function (with extern (C)) for 
invocation from Java.
My .d file contains only a single function returning an int, 
.java calls this function several times.
This approach only works if d-function is trivial, e.g. it's 
not using any D functionality (I believe that it is related to 
GC and memory allocation).
For example, if my d-function just returns some constant 
integer, java side receives it. core.stdc.stdio also works and 
allows console output, but it's not the case with 
std.stdio.writeln and similar functions.
If I use any d-specific functions my program crashes while 
calling native code with some weird message like following:

Invalid memory access of location 0x0 rip=addr.

It seems like D is not initialized at all, maybe there is some 
internal function like dinit() which I can call in order to 
activate everything?


Thanks.



JNI requires (to some degree) compiler support.  This could be 
done in gdc as backend support is there because of g++ JNI 
interface to gcj. But it would be some magic module or change to 
the language to add the Java types to the language.


Regards
Iain.



Re: Interfacing via Java Native Interface

2013-10-16 Thread Andrew

On Wednesday, 16 October 2013 at 10:15:17 UTC, Iain Buclaw wrote:

On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:

Hello there!
I've decided to learn a bit of D, as I am currently Android 
Developer (mostly C++ - JNI - Java), I'm trying to create a 
D shared library which exports function (with extern (C)) for 
invocation from Java.
My .d file contains only a single function returning an int, 
.java calls this function several times.
This approach only works if d-function is trivial, e.g. it's 
not using any D functionality (I believe that it is related to 
GC and memory allocation).
For example, if my d-function just returns some constant 
integer, java side receives it. core.stdc.stdio also works and 
allows console output, but it's not the case with 
std.stdio.writeln and similar functions.
If I use any d-specific functions my program crashes while 
calling native code with some weird message like following:

Invalid memory access of location 0x0 rip=addr.

It seems like D is not initialized at all, maybe there is some 
internal function like dinit() which I can call in order to 
activate everything?


Thanks.



JNI requires (to some degree) compiler support.  This could be 
done in gdc as backend support is there because of g++ JNI 
interface to gcj. But it would be some magic module or change 
to the language to add the Java types to the language.


Regards
Iain.


As far as I know, calling C from Java only requires is jni.h 
header. It can mimicked with mere D aliases. I'm currently not 
talking about calling Java from D, although it could be possible 
by writing C-wrapper library.


I just can't understand why D code compiled as a shared library 
does not work when called from Java. Why does it (does it?) work 
when called from C?


Re: Interfacing via Java Native Interface

2013-10-16 Thread John Colvin

On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:

Hello there!
I've decided to learn a bit of D, as I am currently Android 
Developer (mostly C++ - JNI - Java), I'm trying to create a D 
shared library which exports function (with extern (C)) for 
invocation from Java.
My .d file contains only a single function returning an int, 
.java calls this function several times.
This approach only works if d-function is trivial, e.g. it's 
not using any D functionality (I believe that it is related to 
GC and memory allocation).
For example, if my d-function just returns some constant 
integer, java side receives it. core.stdc.stdio also works and 
allows console output, but it's not the case with 
std.stdio.writeln and similar functions.
If I use any d-specific functions my program crashes while 
calling native code with some weird message like following:

Invalid memory access of location 0x0 rip=addr.

It seems like D is not initialized at all, maybe there is some 
internal function like dinit() which I can call in order to 
activate everything?


Thanks.


Try using Runtime.init() from core.runtime


Re: Interfacing via Java Native Interface

2013-10-16 Thread Andrew

On Wednesday, 16 October 2013 at 10:15:17 UTC, Iain Buclaw wrote:

On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:

Hello there!
I've decided to learn a bit of D, as I am currently Android 
Developer (mostly C++ - JNI - Java), I'm trying to create a 
D shared library which exports function (with extern (C)) for 
invocation from Java.
My .d file contains only a single function returning an int, 
.java calls this function several times.
This approach only works if d-function is trivial, e.g. it's 
not using any D functionality (I believe that it is related to 
GC and memory allocation).
For example, if my d-function just returns some constant 
integer, java side receives it. core.stdc.stdio also works and 
allows console output, but it's not the case with 
std.stdio.writeln and similar functions.
If I use any d-specific functions my program crashes while 
calling native code with some weird message like following:

Invalid memory access of location 0x0 rip=addr.

It seems like D is not initialized at all, maybe there is some 
internal function like dinit() which I can call in order to 
activate everything?


Thanks.



JNI requires (to some degree) compiler support.  This could be 
done in gdc as backend support is there because of g++ JNI 
interface to gcj. But it would be some magic module or change 
to the language to add the Java types to the language.


Regards
Iain.


I was talking about calling D from Java in following fashion:
https://gist.github.com/DieHertz/7005898

Java calls dinit in static initializer after loading shader 
library and then proceeds with calling dget.


Re: Interfacing via Java Native Interface

2013-10-16 Thread John Colvin

On Wednesday, 16 October 2013 at 10:53:28 UTC, Andrew wrote:
On Wednesday, 16 October 2013 at 10:41:35 UTC, John Colvin 
wrote:

On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:

Hello there!
I've decided to learn a bit of D, as I am currently Android 
Developer (mostly C++ - JNI - Java), I'm trying to create a 
D shared library which exports function (with extern (C)) for 
invocation from Java.
My .d file contains only a single function returning an int, 
.java calls this function several times.
This approach only works if d-function is trivial, e.g. it's 
not using any D functionality (I believe that it is related 
to GC and memory allocation).
For example, if my d-function just returns some constant 
integer, java side receives it. core.stdc.stdio also works 
and allows console output, but it's not the case with 
std.stdio.writeln and similar functions.
If I use any d-specific functions my program crashes while 
calling native code with some weird message like following:

Invalid memory access of location 0x0 rip=addr.

It seems like D is not initialized at all, maybe there is 
some internal function like dinit() which I can call in order 
to activate everything?


Thanks.


Try using Runtime.init() from core.runtime


Wow, thanks! Now everything works, proving that my guess on 
uninitialized runtime was correct.


No problem.

It's actually Runtime.initialize() according to documentation, 
by the way.


Ah yeah, sorry I misremembered.


Re: Interfacing via Java Native Interface

2013-10-16 Thread Jacob Carlborg

On 2013-10-16 12:53, Andrew wrote:


Wow, thanks! Now everything works, proving that my guess on
uninitialized runtime was correct.
It's actually Runtime.initialize() according to documentation, by the way.


If you're calling it from C it might be more correct to call this function:

https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L161

It's what Runtime.initialize calls.

--
/Jacob Carlborg


Re: Interfacing via Java Native Interface

2013-10-16 Thread John Colvin
On Wednesday, 16 October 2013 at 11:01:33 UTC, Jacob Carlborg 
wrote:

On 2013-10-16 12:53, Andrew wrote:


Wow, thanks! Now everything works, proving that my guess on
uninitialized runtime was correct.
It's actually Runtime.initialize() according to documentation, 
by the way.


If you're calling it from C it might be more correct to call 
this function:


https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L161

It's what Runtime.initialize calls.


Agreed. You can't call Runtime.initialize from outside D due to 
name mangling (and maybe ABI, depending on your system).


However, other than that it really makes no difference which you 
call, Runtime.initialize is just a no-op wrapper around rt_init.


Re: Interfacing via Java Native Interface

2013-10-16 Thread Andrew
On Wednesday, 16 October 2013 at 11:01:33 UTC, Jacob Carlborg 
wrote:

On 2013-10-16 12:53, Andrew wrote:


Wow, thanks! Now everything works, proving that my guess on
uninitialized runtime was correct.
It's actually Runtime.initialize() according to documentation, 
by the way.


If you're calling it from C it might be more correct to call 
this function:


https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L161

It's what Runtime.initialize calls.


Thanks for advice, I'll use it when I'm interfacing C with D :-)
For now I can't use it directly because a native function called 
from java requires a name with Java_ prefix, so I'd have to 
write a wrapper with such prefix anyway.


Re: Starting D with a project in mind.

2013-10-16 Thread Stefan Frijters

On Wednesday, 16 October 2013 at 09:11:16 UTC, Andrew wrote:


As far as I know deimos is a set of official (?) bindings for 
common C libraries. I don't know dub's build process but I 
assume that if the build script would have worked for you it 
would have attempted to clone this repo 
https://github.com/D-Programming-Deimos/openssl (you can find 
more bindings if you go up one level). My gdc build hadn't 
finished yet when I had to leave for work this morning, but 
I'll try to build dub tonight, to see if I run into the same 
problems...


I've been using a Cubieboard A20, it's much better than a RPi 
as it has 1GB RAM, dual core armv7 and much better IO including 
on-board SATA for $50. The gcc /gdc build takes around 2 - 3 
hours on that. You'll probably run into the same libphobos 
issues that I had, since there are many places where there are 
no ARM headers.


Ok, I logged onto my Pi during lunch break, and actually the 
compilation process went fine, and pragma(msg, __VERSION__); now 
correctly has 2063L as output. So in my recent experience:


- GDC master branch doesn't compile properly, because it's 
missing the ARM-specific code.
- GDC-jp91 master branch compiles, but is based on 2.060 and is 
too old to be useful.
- GDC-jp91 arm branch seems to work, although Johannes has warned 
that there is some codegen bug when compiling with -O2.


This is all now a bit confusing, but I expect GDC master branch 
to compile again for ARM when either frontend version 2.064 is 
released and merged into GDC (in a few weeks hopefully?), or 
Johannes' arm fork is merged into GDC (whenever he has time to 
find and fix his codegen bug). Then everything would be 
(relatively) easy again...


Looking into dub / vibe.d is out of my lunch scope :-P


UDAs on templates

2013-10-16 Thread John Colvin
It seems that __traits(getAttributes, T) returns an empty tuple 
for any template (or template function) T, no matter what UDAs T 
has been given.


Am I doing something wrong?

@(1) void foo(T)(){}

pragma(msg, __traits(getAttributes, foo)); // tuple()
pragma(msg, __traits(getAttributes, foo!int)); // tuple(1)


Re: UDAs on templates

2013-10-16 Thread Dicebot

On Wednesday, 16 October 2013 at 12:26:34 UTC, John Colvin wrote:
It seems that __traits(getAttributes, T) returns an empty tuple 
for any template (or template function) T, no matter what UDAs 
T has been given.


Am I doing something wrong?

@(1) void foo(T)(){}

pragma(msg, __traits(getAttributes, foo)); // tuple()
pragma(msg, __traits(getAttributes, foo!int)); // tuple(1)


I think this gets re-written like this:

template foo(T)
{
@(1) void foo() {}
}

..which does explain the observed behavior. As a workaround you 
can define some default guard value of T and assert inside foo() 
call if it is actually ever used.


Re: UDAs on templates

2013-10-16 Thread Dicebot
(quick experiments show that one can't attached UDA to template 
symbol itself by any means - weird limitation, don't know the 
rationale behind this)


Re: UDAs on templates

2013-10-16 Thread Max Samukha

On Wednesday, 16 October 2013 at 13:12:39 UTC, Max Samukha wrote:
I'd rather have the same set of attributes on both the template 
and its instantiations


Impossible, ignore


Re: UDAs on templates

2013-10-16 Thread Max Samukha

On Wednesday, 16 October 2013 at 12:37:23 UTC, Dicebot wrote:
(quick experiments show that one can't attached UDA to template 
symbol itself by any means - weird limitation, don't know the 
rationale behind this)


It is understandable why the attribute is transferred to the 
instantiation of the function template, though I'd rather have 
the same set of attributes on both the template and its 
instantiations in this case. There is no reason why attributes 
cannot be applied to templates themselves. I think that's a bug.


Re: UDAs on templates

2013-10-16 Thread Max Samukha

On Wednesday, 16 October 2013 at 13:14:31 UTC, Max Samukha wrote:
On Wednesday, 16 October 2013 at 13:12:39 UTC, Max Samukha 
wrote:
I'd rather have the same set of attributes on both the 
template and its instantiations


Impossible, ignore


@(1)
template Foo(T : int) {}

@(2)
template Foo(T : short) {}

__traits(getAttributes, Foo) == ?

The current semantics seems quite reasonable.


Re: Interfacing via Java Native Interface

2013-10-16 Thread Adam D. Ruppe
Would you mind posting your example code? I'm supposed to be 
exploring using D on android myself next week and a little kick 
to help get started would be cool; I've never actually done any 
android stuff.


As I understand it though, you aren't supposed to use native code 
for the bulk of the app which sucks. But still some D is better 
than no D.


Re: UDAs on templates

2013-10-16 Thread Dicebot

On Wednesday, 16 October 2013 at 13:24:59 UTC, Max Samukha wrote:

@(1)
template Foo(T : int) {}

@(2)
template Foo(T : short) {}

__traits(getAttributes, Foo) == ?

The current semantics seems quite reasonable.


@(1)
void foo(int) {}

@(2)
void foo(double) {}

pragma(msg, __traits(getAttributes, foo));

void main() {}

// Compilation output:
//
// tuple(1)


Re: should chain be pure

2013-10-16 Thread Jonathan M Davis
On Wednesday, October 16, 2013 09:29:31 monarch_dodra wrote:
 The problem is that the whole inference things stops at this
 level: the attributes of front are not infered, so chain is not
 pure simply because it isn't a template.

http://d.puremagic.com/issues/show_bug.cgi?id=10329

And I think that there are older bug reports which are similar. Regardless, 
attribute inference is pretty poor right now. A _lot_ of Phobos doesn't have 
its attributes being properly inferred precisely because the compiler stops at 
the first level of templated stuff rather than fully inferring a template, 
which 
quickly makes attribute inference nearly useless. It should definitely be fixed 
at the compiler level though. Anything else would just be patching holes in a 
sinking ship.

- Jonathan M Davis


Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread Benjamin Thaut

Oh something I forgot. You should really start littering your code with
pragma(msg, ...) statements to better understand what it does.
You can for example make your generator output pramga(msg, 
T.stringof); to find out what T actually is.


Kind Regards
Benjamin Thaut


Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread Benjamin Thaut

Am 16.10.2013 10:40, schrieb DoctorCaptain:

On Wednesday, 16 October 2013 at 06:09:48 UTC, Benjamin Thaut wrote:

Am 16.10.2013 03:17, schrieb DoctorCaptain:

I've gotten extremely close. The DPaste link that follows demonstrates
three different templates:

...


So is there any reason why you still pass the variadic arguments to
the generator function and not do it the way I proposed in my last
dpaste snippet? Even if you need the variadic arguments inside the
generator for some logic you could still reference them by using the
variadic arguments to the actual template.


I suppose I was trying to give the class individual data members, such
that passing a tuple of (WorstChild, MiddleChild, BestChild) would
result in a class definition of:

class MagicClass {
 WorstClass t1;
 MiddleClass t2;
 BestClass t3;
}

However, if that is impossible (and frankly it'd be more difficult to
work with than your way even if it was achieved), then I'll use your
approach (actually, I'm just going to use your approach anyway. It's
significantly cleaner than my horrid mess of a goal). That said, what is
actually happening in your example?

I reworked it a bit to demonstrate that the class has accessible members
within T, that can be instantiated and accessed and whatnot.

http://dpaste.dzfl.pl/07b20d75

Note the use of typeof() to get the type of the elements at each index
of members, to generate a type on which a constructor can be called to
instantiate the elements at each index of members. Magic.

What is T within the generated class definition? Is this just how tuples
work? T is an array of three arbitrary pointers, initially null, that
can be instantiated with new to create valid pointers to objects of each
type at T's indexes? Like, T in the DPaste example is an array of
pointers, such that:
[WorstChild*, MiddleChild*, BestChild*]? Is it literally just magic like
that?

Actually, let me formally present a couple of ending thoughts/questions:

First, allow me to apologize for trying to force a different, messy
horrid mess of a goal on you, when your initial solution was majestic to
begin with.


No problem, I can understand that you want to stick with your solution. 
But as Artur explained the template is actually not able to see the 
actual types directly and thats why full qualified identifier will not work.




Second, as I was trying to figure out just a moment ago, what -exactly-
is T in the generated class definition, and why does it allow me to use
it as an arbitrary container for objects of the arbitrary types I want
it to contain (Read: why is it able to do exactly what I want it to be
able to do? What's going on behind the scenes?)?


T is the variadic argument T that is passed to the actual template 
GrabBagT. It might become more clear when actually copy  pasting the 
generated code into the template. The problem is that you try to 
reference the classes by name. Thats not necessary. You get the classes 
passed in as template arguments. So you just reference them as template 
arguments instead of referencing them by name. It is possible to do so 
by not generating access via the name but instead use the template 
arguments passed to GrabBagT. I hope this made it a bit more clear. I 
might have some more time later today to look into your new examples and 
modify them.




Third, given that I am going to go with your solution (it works, it
works well, and I can't seem to force my original goal to work, whether
that was even a good idea to begin with at all (it wasn't)), can you
think of a way to actually produce my original goal? That is, instead of
a container T which I can use to access my arbitrary data members once
the generated class is instantiated, is it actually even possible to
generate individual data members, a la:

class MagicClass {
   T[0] t0;
   T[1] t1;
   // ... etc
} // ?


What do you need individual data members for? In my example the T 
members is actually a instance of a tuple which actually comes down to 
the exakt same data layout like individual data members. The only 
difference is that you access them by index and not by name. Which is 
actually a plus if you ask me for generic programming. You can even get 
back the tuple by doing typeof(members);




You've been wildly helpful, and admirably concise. I am -extremely-
interested in the answer to the second thought, and while I'm sure the
answer is simple, it also seems -too- magic to actually work, and yet it
does.

Again, thank you to everyone who responded, and thank you Benjamin for
your continued help.


No problem. I love the metaprogramming abilities of D and a occansional 
challenge is always welcome ;-)


--
Kind Regards
Benjamin Thaut


Re: UDAs on templates

2013-10-16 Thread Max Samukha

On Wednesday, 16 October 2013 at 13:38:44 UTC, Dicebot wrote:
On Wednesday, 16 October 2013 at 13:24:59 UTC, Max Samukha 
wrote:

@(1)
template Foo(T : int) {}

@(2)
template Foo(T : short) {}

__traits(getAttributes, Foo) == ?

The current semantics seems quite reasonable.


@(1)
void foo(int) {}

@(2)
void foo(double) {}

pragma(msg, __traits(getAttributes, foo));

void main() {}

// Compilation output:
//
// tuple(1)


That sucks. Then, getAttributes (and other traits dealing with 
overload sets) should return an empty set, a union or accept a 
pattern to match against the members of the overload set.


Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread Benjamin Thaut

Am 16.10.2013 10:40, schrieb DoctorCaptain:


http://dpaste.dzfl.pl/07b20d75

Note the use of typeof() to get the type of the elements at each index
of members, to generate a type on which a constructor can be called to
instantiate the elements at each index of members. Magic.


There is actually a easier way to instanciate the elements. Just do new 
T[i](); no need for typeof.



--
Kind Regards
Benjamin Thaut


surprised by link error

2013-10-16 Thread Daniel Davidson
The following code runs fine. There is a whole bunch of types 
imported, so whittling it down to the problem is not too easy.


import plus.models.assumption;
import pprint.pp;
import std.stdio;
import std.datetime;

void main() {
  immutable am = AssumptionModel();
  writeln(pp(am));
}

That code writes a formatted view of the assumption model. One 
small code change:


writeln(pp(am)); = writeln(pp(am));

Does not cause a compile error, but rather a link error (using 
rdmd even with --force):


How is this possible?

Link Error:

  --- errorlevel 1
  | Undefined symbols for architecture x86_64:
  |   
_D44TypeInfo_HAyayS4plus6models6common9RateCurve6__initZ, 
referenced from:
  |   
_D6object58__T16AssociativeArrayTAyaTyS4plus6models6common9RateCurveZ16AssociativeArray6rehashMFNdZHAyayS4plus6models6common9RateCurve 
in linkerror.o
  |   
_D56TypeInfo_HAyayS4plus6models10assumption15DateAssumptions6__initZ, 
referenced from:
  |   
_D6object70__T16AssociativeArrayTAyaTyS4plus6models10assumption15DateAssumptionsZ16AssociativeArray6rehashMFNdZHAyayS4plus6models10assumption15DateAssumptions 
in linkerror.o
  |   
_D57TypeInfo_HAyayS4plus6models10assumption16AssetAssumptions6__initZ, 
referenced from:
  |   
_D6object71__T16AssociativeArrayTAyaTyS4plus6models10assumption16AssetAssumptionsZ16AssociativeArray6rehashMFNdZHAyayS4plus6models10assumption16AssetAssumptions 
in linkerror.o
  |   
_D61TypeInfo_HAyayS4plus6models10assumption20LiabilityAssumptions6__initZ, 
referenced from:
  |   
_D6object75__T16AssociativeArrayTAyaTyS4plus6models10assumption20LiabilityAssumptionsZ16AssociativeArray6rehashMFNdZHAyayS4plus6models10assumption20LiabilityAssumptions 
in linkerror.o

  | ld: symbol(s) not found for architecture x86_64
  | collect2: ld returned 1 exit status


--

Original successful output:
{
 (AssumptionModel).inflation = {
  (RateCurve).curveData = [

  ]
 }
 (AssumptionModel).assetAssumptions = {
 }
 (AssumptionModel).liabilityAssumptions = {
 }
 (AssumptionModel).accountGrowthMap = {
 }
 (AssumptionModel).incomeModelOverrides = {
 }
 (AssumptionModel).expenseModelOverrides = {
 }
 (AssumptionModel).dateAssumptions = {
 }
}


Re: Interfacing via Java Native Interface

2013-10-16 Thread Andrew
On Wednesday, 16 October 2013 at 13:31:50 UTC, Adam D. Ruppe 
wrote:
Would you mind posting your example code? I'm supposed to be 
exploring using D on android myself next week and a little kick 
to help get started would be cool; I've never actually done any 
android stuff.


As I understand it though, you aren't supposed to use native 
code for the bulk of the app which sucks. But still some D is 
better than no D.


I don't mind, but the code is currently Java + D without any 
Android. I can post it in such state, the only thing that keeps 
me from moving it to Android is absence of D compiler with ARM 
back-end (though I'm sure it exists and I have even seen some 
articles about building D for ARM and Android).


Concluding, I can post the could if you like, or I can first try 
compiling it for ARM :-)


You're not supposed to use native code in Android, right, but 
many companies do. The company I work for uses C++ in order to 
make project cross-platform between iOS and Android.


Re: Interfacing via Java Native Interface

2013-10-16 Thread Daniel Kozak

On Wednesday, 16 October 2013 at 10:11:32 UTC, Andrew wrote:

Hello there!
I've decided to learn a bit of D, as I am currently Android 
Developer (mostly C++ - JNI - Java), I'm trying to create a D 
shared library which exports function (with extern (C)) for 
invocation from Java.
My .d file contains only a single function returning an int, 
.java calls this function several times.
This approach only works if d-function is trivial, e.g. it's 
not using any D functionality (I believe that it is related to 
GC and memory allocation).
For example, if my d-function just returns some constant 
integer, java side receives it. core.stdc.stdio also works and 
allows console output, but it's not the case with 
std.stdio.writeln and similar functions.
If I use any d-specific functions my program crashes while 
calling native code with some weird message like following:

Invalid memory access of location 0x0 rip=addr.

It seems like D is not initialized at all, maybe there is some 
internal function like dinit() which I can call in order to 
activate everything?


Thanks.



I just came here to ask same question :D



Re: this() immutable

2013-10-16 Thread Daniel Davidson

On Thursday, 13 June 2013 at 12:29:57 UTC, Simen Kjaeraas wrote:
On Thu, 13 Jun 2013 14:17:22 +0200, Stephan Schiffels 
stephan_schiff...@mac.com wrote:


For example, is there a way of instantiating an object 
normally (i.e. mutable), and then later freeze it to 
immutable via a simple cast or so?


In std.exception there is assumeUnique. It's basically just a 
cast, but

might be good enough for you.


Is there any other recourse here?

Why does making `this(...) immutable` fix things below?
Shouldn't that immutable designation mean no members of this will 
be modified? But that is the whole point of an initializer? Why 
does immutable make sense in this context at all?


My problem is a bit more elaborate and unfortunately to 
initialize members I need to call standard functions that have 
not been made pure (but should be).




struct T {
  int[] i;
}

struct S {
  int[] i;
  immutable T t;
  this(immutable T _t) {
t = _t;
  }
}

void main() {
  auto t = immutable T();
  auto s = immutable S(t);
}


does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Daniel Davidson
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);
}


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Dicebot
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.


Re: mutable, const, immutable guidelines

2013-10-16 Thread Daniel Davidson
On Wednesday, 2 October 2013 at 13:09:34 UTC, Daniel Davidson 
wrote:
I'm reviewing Ali's insightful presentation from 2013 DConf. I 
wonder has he or anyone else followed up on the concepts or 
formalized some guidelines that could achieve consensus. I 
definitely agree it would be helpful to have a 50 Ways To 
Improve Your D. The first thing I'd like to see is a set of 
guidelines on mutability along the lines he discussed in his 
talk. But as it stands, I don't know if there was any 
finalization/consensus. For instance, from the first two 
guidelines at the end (after several iterative reconstructions 
of those guidelines):


1. If a variable is never mutated, make it const, not immutable.
2. Make the parameter reference to immutable if that is how you 
will use it anyway. It is fine to ask a favor from the caller.

...

If you follow (1) exclusively, why the need for immutable in 
the language at all?


Maybe it is a philosophical question, but where does 
immutability really come from? Is it an aspect of some piece of 
data or is it a promise that function will not change it? Or is 
it a requirement by a function that data passed not be changed 
by anyone else?


The two keywords cover all in some sense.

I found the end of the video amusing, when one gentleman 
looking at a rather sophisticated canonical struct with three 
overloads for 'this(...)' and two overloads for opAssign, asked 
if all those methods were required. I think there was back and 
forth and head-scratching. Another asked if the language 
designers were happy with the resultant complexity. Naturally 
the answer was yes - it is a good mix. If that is the case I 
wonder if the reason is they don't write software in D like Ali 
was looking to develop. I imagine standard library code is much 
more functional than OO by its very nature. My money says you 
will not find a struct S constructed like Ali's in the wild - 
it is just too much boilerplate. But surely they have their own 
guidelines/approaches.


By posting this I am not looking for a single answer to the 
simple question above as it is just one of many questions in 
the set of how do you choose among the options in general. If 
you have such guidelines - please post them.


Thanks
Dan


After trying for several days to use immutable with types 
containing some mutable aliasing I have come to the conclusion 
that maybe rule number one should be:


If you have a type that has now or may ever have in the future 
any mutable aliasing (e.g. inclusion of T[] or T1[T1] where Ts 
are mutable) do not ever use the immutable keyword in any context 
as things just break down.


If you have had more success with a immutable with types 
containing mutable aliasing and can share your success story that 
would be great.


As D is growing are there any out there yet offering support 
services?


Thanks,
Dan


Re: mutable, const, immutable guidelines

2013-10-16 Thread Ali Çehreli

On 10/16/2013 10:23 AM, Daniel Davidson wrote:

 On Wednesday, 2 October 2013 at 13:09:34 UTC, Daniel Davidson wrote:

 guidelines):

 1. If a variable is never mutated, make it const, not immutable.
 2. Make the parameter reference to immutable if that is how you will
 use it anyway. It is fine to ask a favor from the caller.

 After trying for several days to use immutable with types containing
 some mutable aliasing I have come to the conclusion that maybe rule
 number one should be:

 If you have a type that has now or may ever have in the future any
 mutable aliasing (e.g. inclusion of T[] or T1[T1] where Ts are mutable)
 do not ever use the immutable keyword in any context as things just
 break down.

I think this topic should be carried to the main newsgroup already. I am 
convinced that this is a language issue. :-/


 Thanks,
 Dan

Ali



Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Daniel Davidson

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);
}


Re: mutable, const, immutable guidelines

2013-10-16 Thread H. S. Teoh
On Wed, Oct 16, 2013 at 07:23:24PM +0200, Daniel Davidson wrote:
 On Wednesday, 2 October 2013 at 13:09:34 UTC, Daniel Davidson wrote:
[...]
 Maybe it is a philosophical question, but where does immutability
 really come from? Is it an aspect of some piece of data or is it a
 promise that function will not change it? Or is it a requirement
 by a function that data passed not be changed by anyone else?

I think it helps to realize that D's const system is different from
C++'s.

Immutable means the data will never change, ever. It means you can put
that data in read-only memory, maybe burned into a ROM chip or something
like that.

Const means *you* can't change the data, but somebody else may be able
to.

Therefore:


[...]
 After trying for several days to use immutable with types containing
 some mutable aliasing I have come to the conclusion that maybe rule
 number one should be:

If you have mutable aliasing, that means the data cannot be immutable.
Use const.


 If you have a type that has now or may ever have in the future any
 mutable aliasing (e.g. inclusion of T[] or T1[T1] where Ts are
 mutable) do not ever use the immutable keyword in any context as
 things just break down.

Yes, because immutable means nothing, no one, can change the data after
it's constructed, ever. If you want mutable aliasing, what you want is
const, not immutable.


 If you have had more success with a immutable with types containing
 mutable aliasing and can share your success story that would be
 great.
[...]

Maybe it's helpful to understand how D's const system works. The
following diagram may help (please excuse the ASCII graphics):

   const
  / \
mutable immutable

What this means is that const subsumes mutable and immutable. A mutable
type can be implicitly converted to a const type (the receiver of the
const can't modify the data, which is fine since the code holding the
mutable reference can still mutate it), and so can immutable (immutable
cannot be modified, ever, and const doesn't let you modify it either, so
it's OK to make a const reference to immutable data). However, you
cannot implicitly convert between mutable and immutable, unless you're
copying the data by value.

So if you have immutable data and want to make changes, you have to
first make a copy of the data, then mutate it at will.

What's the use of immutable, you ask? Immutable makes hard guarantees
about the non-changeability of some piece of data. This makes it useful
for implementing strings -- in fact, the 'string' type in D is just an
alias for immutable(char)[]. You can take substrings (slices) of any
given string freely, and be assured that your copy of the (sub)string
will never unexpectedly change its value from somewhere else in the
code. This saves the need for a lot of copying, which can be costly.

One interesting subtlety here is that 'string' is immutable(char)[], but
not immutable(char[]). The latter would mean that the string itself can
never be changed -- you couldn't assign to it, you couldn't append to
it, etc., which would make strings a lot less useful than they are. But
by making strings a *mutable* array of *immutable* chars, you allow the
string to be appended to, substring'd, etc., all while guaranteeing that
the underlying bytes themselves will never change. So you can have the
best of both worlds: you can append to strings, take substrings, assign
strings to each other, etc., yet at the same time be assured that the
list of intermediate substrings you stored somewhere during the process
will continue to retain the values you assigned to them, because the
underlying bytes they point to are immutable, and therefore guaranteed
never to change.


T

-- 
Just because you survived after you did it, doesn't mean it wasn't stupid!


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Dicebot
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:


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*?


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.


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Dicebot

struct S {
  R r;
  this(ref immutable(T) t) immutable {
r.tupleof = t.tupleof;
  }
}

?


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Maxim Fomin
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)


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Daniel Davidson

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:

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*?


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.


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.


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Daniel Davidson

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.


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Daniel Davidson

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:
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)


Haaah - brilliant. Scary, but brilliant.



Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread Benjamin Thaut

Am 16.10.2013 16:08, schrieb Benjamin Thaut:

Am 16.10.2013 10:40, schrieb DoctorCaptain:


http://dpaste.dzfl.pl/07b20d75

Note the use of typeof() to get the type of the elements at each index
of members, to generate a type on which a constructor can be called to
instantiate the elements at each index of members. Magic.


There is actually a easier way to instanciate the elements. Just do new
T[i](); no need for typeof.




I'm actually wrong. new T[i]() will not work because the compiler will 
think it is a array allocation. You actually have to use new 
typeof(member[i])();


I created a example which generates individual class members for each of 
the arguments bassed to GrabBagT:


http://dpaste.dzfl.pl/eef2edec

--
Kind Regards
Benjamin Thaut


Re: mutable, const, immutable guidelines

2013-10-16 Thread Daniel Davidson

On Wednesday, 16 October 2013 at 17:55:14 UTC, H. S. Teoh wrote:

On Wed, Oct 16, 2013 at 07:23:24PM +0200, Daniel Davidson wrote:
On Wednesday, 2 October 2013 at 13:09:34 UTC, Daniel Davidson 
wrote:

[...]
Maybe it is a philosophical question, but where does 
immutability
really come from? Is it an aspect of some piece of data or is 
it a
promise that function will not change it? Or is it a 
requirement

by a function that data passed not be changed by anyone else?


I think it helps to realize that D's const system is different 
from

C++'s.

Immutable means the data will never change, ever. It means you 
can put
that data in read-only memory, maybe burned into a ROM chip or 
something

like that.

Const means *you* can't change the data, but somebody else may 
be able

to.

Therefore:


[...]
After trying for several days to use immutable with types 
containing
some mutable aliasing I have come to the conclusion that maybe 
rule

number one should be:


If you have mutable aliasing, that means the data cannot be 
immutable.

Use const.


If you have a type that has now or may ever have in the future 
any

mutable aliasing (e.g. inclusion of T[] or T1[T1] where Ts are
mutable) do not ever use the immutable keyword in any context 
as

things just break down.


Yes, because immutable means nothing, no one, can change the 
data after
it's constructed, ever. If you want mutable aliasing, what you 
want is

const, not immutable.



I think the term mutable aliasing and what you want don't 
work together. mutable aliasing is not about context of usage 
or what you want, it is a compile time attribute of a struct. I 
want to use associative arrays in composition because I think 
they are the way I view and use my data. `struct T { 
string[string] i; }` has mutable aliasing, like it or not. So, it 
is not so much that I want mutable aliasing - in fact I fear it. 
But once you use AAs it is a fact of life.




If you have had more success with a immutable with types 
containing

mutable aliasing and can share your success story that would be
great.

[...]

Maybe it's helpful to understand how D's const system works. The
following diagram may help (please excuse the ASCII graphics):

   const
  / \
mutable immutable

What this means is that const subsumes mutable and immutable. A 
mutable
type can be implicitly converted to a const type (the receiver 
of the
const can't modify the data, which is fine since the code 
holding the
mutable reference can still mutate it), and so can immutable 
(immutable
cannot be modified, ever, and const doesn't let you modify it 
either, so
it's OK to make a const reference to immutable data). However, 
you
cannot implicitly convert between mutable and immutable, unless 
you're

copying the data by value.



yes - it requires transitive deep copy.

So if you have immutable data and want to make changes, you 
have to

first make a copy of the data, then mutate it at will.

What's the use of immutable, you ask? Immutable makes hard 
guarantees
about the non-changeability of some piece of data. This makes 
it useful
for implementing strings -- in fact, the 'string' type in D is 
just an
alias for immutable(char)[]. You can take substrings (slices) 
of any
given string freely, and be assured that your copy of the 
(sub)string
will never unexpectedly change its value from somewhere else in 
the
code. This saves the need for a lot of copying, which can be 
costly.




I agree that string behaves as you say. I don't quite agree that 
immutable alone is the reason it does. I think it is an byproduct 
of the way immutable(T)[] is implemented. It is an implementation 
detail and relying on that could lead to bad deduction. We 
covered that here in this thread:

http://forum.dlang.org/post/jfjudswamyxlttgsd...@forum.dlang.org


One interesting subtlety here is that 'string' is 
immutable(char)[], but
not immutable(char[]). The latter would mean that the string 
itself can
never be changed -- you couldn't assign to it, you couldn't 
append to
it, etc., which would make strings a lot less useful than they 
are. But
by making strings a *mutable* array of *immutable* chars, you 
allow the
string to be appended to, substring'd, etc., all while 
guaranteeing that
the underlying bytes themselves will never change. So you can 
have the
best of both worlds: you can append to strings, take 
substrings, assign
strings to each other, etc., yet at the same time be assured 
that the
list of intermediate substrings you stored somewhere during the 
process
will continue to retain the values you assigned to them, 
because the
underlying bytes they point to are immutable, and therefore 
guaranteed

never to change.


T


Agreed with the description of the behavior. But disagree on why. 
It works that way because T[] is modeled as contiguous memory and 
the api associated with slice of type immutable(T)[] means there 
is no unsafe sharing. So, `struct T { string[string] 

Re: mutable, const, immutable guidelines

2013-10-16 Thread qznc

On Wednesday, 16 October 2013 at 17:55:14 UTC, H. S. Teoh wrote:

Maybe it's helpful to understand how D's const system works. The
following diagram may help (please excuse the ASCII graphics):

   const
  / \
mutable immutable


I think people in this thread know how const works, but some 
think it is broken. Scenario is this:


Library code:

struct Foo { int x; }

User code:

Foo f;
immutable f2 = f;

This works, even though the library writer might not have 
anticipated that someone makes Foo immutable. However, now the 
library writer obliviously releases a new version of the library, 
which extends it like this:


struct Foo {
  int x;
  private int[] history;
}

Unfortunately, now the user code is broken due to the freshly 
introduced mutable aliasing. Personally, I think is fine. Upon 
compilation the user code gives a  error message and user 
developer can adapt to the code to the new library version. Some 
think the library writer should have a possibility to make this 
work.




Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Dicebot
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.


Re: mutable, const, immutable guidelines

2013-10-16 Thread H. S. Teoh
On Wed, Oct 16, 2013 at 08:49:51PM +0200, Daniel Davidson wrote:
 On Wednesday, 16 October 2013 at 17:55:14 UTC, H. S. Teoh wrote:
 On Wed, Oct 16, 2013 at 07:23:24PM +0200, Daniel Davidson wrote:
[...]
 If you have a type that has now or may ever have in the future any
 mutable aliasing (e.g. inclusion of T[] or T1[T1] where Ts are
 mutable) do not ever use the immutable keyword in any context as
 things just break down.
 
 Yes, because immutable means nothing, no one, can change the data
 after it's constructed, ever. If you want mutable aliasing, what you
 want is const, not immutable.
 
 
 I think the term mutable aliasing and what you want don't work
 together. mutable aliasing is not about context of usage or what
 you want, it is a compile time attribute of a struct. I want to use
 associative arrays in composition because I think they are the way I
 view and use my data. `struct T { string[string] i; }` has mutable
 aliasing, like it or not. So, it is not so much that I want mutable
 aliasing - in fact I fear it. But once you use AAs it is a fact of
 life.
[...]
 Is the suggestion here: use immutable in any composition context
 where you have slices and you want to not worry about mutable
 aliasing. So, do like string does: any case where you have T[] as a
 member, prefer immutable(T)[] since then you don't have to worry
 about sharing. Well, not sure that works in general because the T in
 string is char and has no mutable aliasing itself. Suppose T itself
 has mutable aliasing, then what? Or, suppose it is a struct with no
 mutable aliasing *now*. Who's to say it won't change.
 
 So, where does all this leave us w.r.t. a good set of guidelines?

Sorry, I kinda barged into this conversation, so I'm not sure what
exactly you're trying to achieve here. What kind of composition contexts
do you have in mind? Maybe you could help me understand what you're
trying to do?

Keeping in mind that AA's, as they are currently implemented, leaves a
lot of room for improvement, to say the least. So you might be running
into some AA-related issues, not the type system proper.


T

-- 
Creativity is not an excuse for sloppiness.


Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread DoctorCaptain
AWW you posted that while I was writing my latest novel. So 
T[i] doesn't work? I guess I shouldn't have opened my eyes this 
morning. In any case, typeof() DOES work, so as long as there 
is a way to extract the type, we're good.


I am extremely pleased it's actually possible to get individual 
data members like I was originally attempting to do. I'm likely 
not going to actually do this, as your T members; solution is 
cleaner, but I'm glad it's not just arbitrarily impossible.


Thank you so much!


And I could have SWORN I tried to write something like what you 
have in your latest DPaste, but I must have been doing something 
wrong, of course. In any case, I'm glad this whole thing has been 
so very cleanly resolved. Infinity thank you.


Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread DoctorCaptain
On Wednesday, 16 October 2013 at 18:47:25 UTC, Benjamin Thaut 
wrote:

Am 16.10.2013 16:08, schrieb Benjamin Thaut:

Am 16.10.2013 10:40, schrieb DoctorCaptain:


http://dpaste.dzfl.pl/07b20d75

Note the use of typeof() to get the type of the elements at 
each index
of members, to generate a type on which a constructor can be 
called to

instantiate the elements at each index of members. Magic.


There is actually a easier way to instanciate the elements. 
Just do new

T[i](); no need for typeof.




I'm actually wrong. new T[i]() will not work because the 
compiler will think it is a array allocation. You actually have 
to use new typeof(member[i])();


I created a example which generates individual class members 
for each of the arguments bassed to GrabBagT:


http://dpaste.dzfl.pl/eef2edec


AWW you posted that while I was writing my latest novel. So T[i] 
doesn't work? I guess I shouldn't have opened my eyes this 
morning. In any case, typeof() DOES work, so as long as there is 
a way to extract the type, we're good.


I am extremely pleased it's actually possible to get individual 
data members like I was originally attempting to do. I'm likely 
not going to actually do this, as your T members; solution is 
cleaner, but I'm glad it's not just arbitrarily impossible.


Thank you so much!


Re: mutable, const, immutable guidelines

2013-10-16 Thread Daniel Davidson

On Wednesday, 16 October 2013 at 18:52:23 UTC, qznc wrote:

On Wednesday, 16 October 2013 at 17:55:14 UTC, H. S. Teoh wrote:
Maybe it's helpful to understand how D's const system works. 
The

following diagram may help (please excuse the ASCII graphics):

   const
  / \
mutable immutable


I think people in this thread know how const works, but some 
think it is broken. Scenario is this:




Thanks.


Library code:

struct Foo { int x; }

User code:

Foo f;
immutable f2 = f;

This works, even though the library writer might not have 
anticipated that someone makes Foo immutable. However, now the 
library writer obliviously releases a new version of the 
library, which extends it like this:


struct Foo {
  int x;
  private int[] history;
}

Unfortunately, now the user code is broken due to the freshly 
introduced mutable aliasing. Personally, I think is fine. Upon 
compilation the user code gives a  error message and user 
developer can adapt to the code to the new library version. 
Some think the library writer should have a possibility to make 
this work.


I don't understand how it could be fine. As code grows it would 
lead to people not adding useful members like history just 
because of the huge repercussions.


struct User {
   immutable(Foo) foos;
}

How can I as a user adapt to that change? Before the change 
assignment worked equally well among all of Mutable, Immutable, 
Const. After that change any `foos ~= createFoo(...)` would 
require change. And it is not clear what the change would be.


Re: mutable, const, immutable guidelines

2013-10-16 Thread H. S. Teoh
On Wed, Oct 16, 2013 at 08:52:22PM +0200, qznc wrote:
 On Wednesday, 16 October 2013 at 17:55:14 UTC, H. S. Teoh wrote:
 Maybe it's helpful to understand how D's const system works. The
 following diagram may help (please excuse the ASCII graphics):
 
 const
/ \
  mutable immutable
 
 I think people in this thread know how const works, but some think
 it is broken. Scenario is this:
 
 Library code:
 
 struct Foo { int x; }
 
 User code:
 
 Foo f;
 immutable f2 = f;
 
 This works, even though the library writer might not have
 anticipated that someone makes Foo immutable. However, now the
 library writer obliviously releases a new version of the library,
 which extends it like this:
 
 struct Foo {
   int x;
   private int[] history;
 }
 
 Unfortunately, now the user code is broken due to the freshly
 introduced mutable aliasing. Personally, I think is fine. Upon
 compilation the user code gives a  error message and user developer
 can adapt to the code to the new library version. Some think the
 library writer should have a possibility to make this work.

Well, I think here the type system is working as advertised. Since the
original version of Foo has no mutable aliasing, implicit conversion to
immutable is OK (you're making a new binary copy of the data). But in
the second case, it will obviously violate immutability guarantees,
because in D, immutable is transitive, so immutable(Foo) in the second
case is equivalent to:

struct Foo {
int x;
private immutable(int[]) history;
}

You can't implicitly convert int[] to immutable(int[]) because whoever
holds the original int[] reference can use it to change the data, which
breaks the immutable guarantee of immutable(int[]).

The only way this could work is if you made a copy of the int[]. So the
library writer would have to provide a method for creating an immutable
copy of the struct (like an .idup method or something).

You may argue that this is bad because now user code is broken and you
need to rewrite it to use .idup, but I'd argue that relying on implicit
conversion to immutable already introduces a dependency on
implementation details of Foo, which should be avoided in the first
place if you want to have a clean encapsulation.

I mean, given a Foo type exported by a library, if that type is meant to
be an opaque type, then my code should make no assumptions about whether
it can implicitly convert to immutable. I should rather require the
library writer to provide an .idup method for creating an immutable
instance of the struct than to blindly write the code to implicitly
convert to immutable (thus introducing a hidden reliance on how Foo is
implemented) and then have it broken later when the library writer
changes its implementation.

OTOH, if it's not an opaque type, then it's no surprise that changing
its implementation should also require changing the code (that depends
on its implementation details).

So I don't see anything wrong with this particular scenario. What other
scenarios were being considered?


T

-- 
He who does not appreciate the beauty of language is not worthy to bemoan its 
flaws.


Re: mutable, const, immutable guidelines

2013-10-16 Thread Dicebot
On Wednesday, 16 October 2013 at 19:06:06 UTC, Daniel Davidson 
wrote:
I don't understand how it could be fine. As code grows it would 
lead to people not adding useful members like history just 
because of the huge repercussions.


struct User {
   immutable(Foo) foos;
}

How can I as a user adapt to that change? Before the change 
assignment worked equally well among all of Mutable, Immutable, 
Const. After that change any `foos ~= createFoo(...)` would 
require change. And it is not clear what the change would be.


I think any usage of immutable with types/entities not initially 
designed for immutability is an potential mistake and in that 
sense it is good that change has broken the user code. Same goes 
for operating on immutable entity in generic code as if it is a 
value type without actually checking it via introspection.


Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-16 Thread Benjamin Thaut

Am 16.10.2013 21:02, schrieb DoctorCaptain:

On Wednesday, 16 October 2013 at 14:08:52 UTC, Benjamin Thaut wrote:

Am 16.10.2013 10:40, schrieb DoctorCaptain:


http://dpaste.dzfl.pl/07b20d75

Note the use of typeof() to get the type of the elements at each index
of members, to generate a type on which a constructor can be called to
instantiate the elements at each index of members. Magic.


There is actually a easier way to instanciate the elements. Just do
new T[i](); no need for typeof.


Thank you again for your excellent answers. I knew I shouldn't have
posted my most recent response at two in the morning or whatever it was;
when I woke up this morning I was thinking, I understand everything I
was confused about last night, and I'm going to look silly to the fellas
that answer my questions. Especially, pretty much the first thing I
thought of when I opened my eyes this morning was I don't need to do
typeof, I can index the type tuple, and now I look silly.

I definitely knew that the T in the mixed-in class definition is the
same as the variadic template parameter T in our GrabBagT template. My
question, at the time, was geared towards, How in the world does it act
like a tuple of types that we can just use? The answer to that is,
painfully obviously, T is literally a tuple of types that we can just
use, working exactly as intended.

Hopefully the following is correct, as an exercise in making sure that
my understanding is correct:

Purely theoretically speaking (as in we're no longer talking about D
specifically, but rather type theory in general), let's take the type
int[]. Variables of type int[] can be created. Let's do this:

int[] iarray;

For some within-bounds index i, iarray[i] will yield a -value- whose
-type- is int.

Along these same lines (again in a go-with-me-here, theoretical sense),
if we were to index the actual type int[], like int[i], then what is
yielded at that index is the -type- int. int[] is a homogenous type
tuple of some length, containing only the -type- int as an element at
each of its indexes. Go with me here.

This works perfectly well. At compile time, the compiler knows
everything it needs to know about int[] in order to reason about how a
variable of that type, like iarray, can behave. It knows that at every
within-bounds index of iarray, it can be sure to find a value of type
int, because int[] is a homogenous type tuple of the type int.

In exactly this same way, T is also a type tuple. The only difference
is, T can be (but by no means has to be) a heterogenous type tuple. That
is, since we're instantiating these templates (that take T...) at
compile time, all types contained within T are known at compile time,
and can be reasoned about.

So let's say we declare something like:

T members;

instantiated such that myTemplate(T...) is called like myTemplate!(int,
float, bool)

This means that, while at int[0] we can expect the -type- int, and at
int[1] we can still expect the -type- int, at T[0] we expect the -type-
int, at T[1] we expect the -type- float, and at T[2] we expect the
-type- bool.

So, at members[0], we can store a -value- of type int, at members[1] we
can store a -value- of type float, and at members[2], we can store a
-value- of type bool.

The reason this is possible is because the compiler is aware of all of
the types, and their order, in the type tuple T at compile time. The
compiler can reason about the behavior of any index within members,
because it can map that index within members back to the same index
within T. As long as members[n] is treated as the type T[n], the
compiler can reason about the behavior of a heterogenous array
members, of type T.

Correct?

And again again again, thank you for your help.


I never had type theory in university, but your explanation sounds 
reasonable and correct ;-)


Kind Regards
Benjamin Thaut


Re: Starting D with a project in mind.

2013-10-16 Thread Andrew
I'm a very happy man ! Everything is built and working including 
dub and the http_server example from vibe.d.


It's slow to build, but it executes quickly and strips down to 
about 3MB which is heavy but tolerable.


Thanks to everybody for the help, now I can start learning D, 
exploring vibe.d and Pegged and hopefully make some good progress 
on my MUD.


So to recap, to help anybody else building on ARM these are the 
steps I took :-


mkdir gdc
cd gdc
wget 
http://gcc.igor.onlinedirect.bg/snapshots/LATEST-4.8/gcc-4.8-20131010.tar.bz2

tar xvf gcc-4.8-20131010.tar.bz2
git clone https://github.com/jpf91/GDC.git arm_gdc
cd arm_gdc
git checkout arm
./setup-gcc.sh ../gcc-4.8-20131010
cd ../
mkdir build
cd build
export C_INCLUDE_PATH=/usr/include/$(gcc -print-multiarch)
export EXTRA_CONF=-mfloat-abi=hard --with-float=hard
../gcc-4.8-20131010/configure --enable-languages=d 
--disable-bootstrap --prefix=/usr/local/gdc --disable-multilib 
--disable-softfloat --with-float=hard

make -j2
sudo make install
sudo cp ../arm_gdc/libphobos/libdruntime/core/time.d 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core
sudo mv 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di.old


I don't know why that last step was necessary but dub and a few 
other things didn't build without it.


After that dub built fine once I'd hacked the build file to use 
gdc.





Re: mutable, const, immutable guidelines

2013-10-16 Thread Daniel Davidson

On Wednesday, 16 October 2013 at 19:01:59 UTC, H. S. Teoh wrote:

On Wed, Oct 16, 2013 at 08:49:51PM +0200, Daniel Davidson wrote:
On Wednesday, 16 October 2013 at 17:55:14 UTC, H. S. Teoh 
wrote:
On Wed, Oct 16, 2013 at 07:23:24PM +0200, Daniel Davidson 
wrote:

[...]
If you have a type that has now or may ever have in the 
future any
mutable aliasing (e.g. inclusion of T[] or T1[T1] where Ts 
are
mutable) do not ever use the immutable keyword in any 
context as

things just break down.

Yes, because immutable means nothing, no one, can change the 
data
after it's constructed, ever. If you want mutable aliasing, 
what you

want is const, not immutable.


I think the term mutable aliasing and what you want don't 
work
together. mutable aliasing is not about context of usage or 
what
you want, it is a compile time attribute of a struct. I want 
to use
associative arrays in composition because I think they are the 
way I
view and use my data. `struct T { string[string] i; }` has 
mutable
aliasing, like it or not. So, it is not so much that I want 
mutable
aliasing - in fact I fear it. But once you use AAs it is a 
fact of

life.

[...]
Is the suggestion here: use immutable in any composition 
context

where you have slices and you want to not worry about mutable
aliasing. So, do like string does: any case where you have 
T[] as a
member, prefer immutable(T)[] since then you don't have to 
worry
about sharing. Well, not sure that works in general because 
the T in
string is char and has no mutable aliasing itself. Suppose T 
itself
has mutable aliasing, then what? Or, suppose it is a struct 
with no

mutable aliasing *now*. Who's to say it won't change.

So, where does all this leave us w.r.t. a good set of 
guidelines?


Sorry, I kinda barged into this conversation, so I'm not sure 
what
exactly you're trying to achieve here. What kind of composition 
contexts
do you have in mind? Maybe you could help me understand what 
you're

trying to do?



Thanks. I appreciate any help I can get. Here is a small sample: 
http://pastebin.com/TeiQ9DYa


Other samples have at least 5 levels of composition. I'm 
generating the structure from json schema so I'm looking for 
something that scales and is immune to changes in deeply nested 
members.


Keeping in mind that AA's, as they are currently implemented, 
leaves a
lot of room for improvement, to say the least. So you might be 
running

into some AA-related issues, not the type system proper.



I understand. It is a shame. If the data source is rich json data 
- I think AAs are a necessity.


Re: Starting D with a project in mind.

2013-10-16 Thread Stefan Frijters

On Wednesday, 16 October 2013 at 19:18:53 UTC, Andrew wrote:
I'm a very happy man ! Everything is built and working 
including dub and the http_server example from vibe.d.


It's slow to build, but it executes quickly and strips down to 
about 3MB which is heavy but tolerable.


Thanks to everybody for the help, now I can start learning D, 
exploring vibe.d and Pegged and hopefully make some good 
progress on my MUD.


So to recap, to help anybody else building on ARM these are the 
steps I took :-


mkdir gdc
cd gdc
wget 
http://gcc.igor.onlinedirect.bg/snapshots/LATEST-4.8/gcc-4.8-20131010.tar.bz2

tar xvf gcc-4.8-20131010.tar.bz2
git clone https://github.com/jpf91/GDC.git arm_gdc
cd arm_gdc
git checkout arm
./setup-gcc.sh ../gcc-4.8-20131010
cd ../
mkdir build
cd build
export C_INCLUDE_PATH=/usr/include/$(gcc -print-multiarch)
export EXTRA_CONF=-mfloat-abi=hard --with-float=hard
../gcc-4.8-20131010/configure --enable-languages=d 
--disable-bootstrap --prefix=/usr/local/gdc --disable-multilib 
--disable-softfloat --with-float=hard

make -j2
sudo make install
sudo cp ../arm_gdc/libphobos/libdruntime/core/time.d 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core
sudo mv 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di.old


I don't know why that last step was necessary but dub and a few 
other things didn't build without it.


After that dub built fine once I'd hacked the build file to use 
gdc.


Cool. I was posting in the D.GNU newsgroup about this when I 
noticed your update, so I included a link to this work around in 
my post [1]. Maybe Iain or any of the other gurus know of a 
better way, because the last part looks awfully dirty :-D


[1] 
http://forum.dlang.org/post/wshaxsawkvkwfaefp...@forum.dlang.org


Re: UDAs on templates

2013-10-16 Thread Jacob Carlborg

On 2013-10-16 16:05, Max Samukha wrote:


That sucks. Then, getAttributes (and other traits dealing with overload
sets) should return an empty set, a union or accept a pattern to match
against the members of the overload set.


Currenrly one need to call __traits(getOverloads) and then iterate of 
the result and call __traits(getAttributes) on each item.


--
/Jacob Carlborg


Re: Starting D with a project in mind.

2013-10-16 Thread simendsjo

On Wednesday, 16 October 2013 at 19:18:53 UTC, Andrew wrote:
I'm a very happy man ! Everything is built and working 
including dub and the http_server example from vibe.d.


It's slow to build, but it executes quickly and strips down to 
about 3MB which is heavy but tolerable.


Thanks to everybody for the help, now I can start learning D, 
exploring vibe.d and Pegged and hopefully make some good 
progress on my MUD.


So to recap, to help anybody else building on ARM these are the 
steps I took :-


mkdir gdc
cd gdc
wget 
http://gcc.igor.onlinedirect.bg/snapshots/LATEST-4.8/gcc-4.8-20131010.tar.bz2

tar xvf gcc-4.8-20131010.tar.bz2
git clone https://github.com/jpf91/GDC.git arm_gdc
cd arm_gdc
git checkout arm
./setup-gcc.sh ../gcc-4.8-20131010
cd ../
mkdir build
cd build
export C_INCLUDE_PATH=/usr/include/$(gcc -print-multiarch)
export EXTRA_CONF=-mfloat-abi=hard --with-float=hard
../gcc-4.8-20131010/configure --enable-languages=d 
--disable-bootstrap --prefix=/usr/local/gdc --disable-multilib 
--disable-softfloat --with-float=hard

make -j2
sudo make install
sudo cp ../arm_gdc/libphobos/libdruntime/core/time.d 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core
sudo mv 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di 
/usr/local/gdc/include/d/4.8.2/armv7l-unknown-linux-gnueabihf/core/time.di.old


I don't know why that last step was necessary but dub and a few 
other things didn't build without it.


After that dub built fine once I'd hacked the build file to use 
gdc.


This is very cool. You should add it to the wiki so it doesn't 
get lost: http://wiki.dlang.org


Re: mutable, const, immutable guidelines

2013-10-16 Thread H. S. Teoh
On Wed, Oct 16, 2013 at 09:06:05PM +0200, Daniel Davidson wrote:
 On Wednesday, 16 October 2013 at 18:52:23 UTC, qznc wrote:
[...]
 Library code:
 
 struct Foo { int x; }
 
 User code:
 
 Foo f;
 immutable f2 = f;
 
 This works, even though the library writer might not have
 anticipated that someone makes Foo immutable. However, now the
 library writer obliviously releases a new version of the library,
 which extends it like this:
 
 struct Foo {
   int x;
   private int[] history;
 }
 
 Unfortunately, now the user code is broken due to the freshly
 introduced mutable aliasing. Personally, I think is fine. Upon
 compilation the user code gives a  error message and user
 developer can adapt to the code to the new library version. Some
 think the library writer should have a possibility to make this
 work.
 
 I don't understand how it could be fine. As code grows it would lead
 to people not adding useful members like history just because of the
 huge repercussions.
 
 struct User {
immutable(Foo) foos;
 }
 
 How can I as a user adapt to that change? Before the change
 assignment worked equally well among all of Mutable, Immutable,
 Const. After that change any `foos ~= createFoo(...)` would require
 change. And it is not clear what the change would be.

The root of the problem is reliance on assignment between mutable /
immutable / const. This reliance breaks encapsulation because you're
making an assumption about the assignability of a presumedly opaque
library type to immutable / const. In D, immutable is *physical*
immutability, not logical immutability; by writing immutable(Foo) you're
saying that you wish to have physically-immutable instances of Foo.
However, whether this is possible depends on the implementation details
of Foo, which, if Foo is supposed to be an opaque type, breaks
encapsulation. Without knowing how Foo is implemented (and user code
shouldn't know that), you can't reliably go around and claim Foo can be
made immutable from a mutable instance. The fact that you're relying on
Foo being implicitly convertible to immutable(Foo) means you're already
depending on implementation details of Foo, and should be prepared to
change code when Foo's implementation changes.

If you want to say that User cannot modify the Foo's it contains, you
should use const rather than immutable. It is safe to use const because
anything is implicitly convertible to const, so it doesn't introduce any
reliance upon implementational details of Foo.

If you insist on being able to append to immutable(Foo)[], then you'll
need a createFoo method that returns immutable instances of Foo:

struct User {
immutable(Foo)[] foos;
}
immutable(Foo) createFoo(...) { ... }

User u;
u.foos ~= createFoo(...); // now this works

The problem with this, of course, is that it unnecessarily restricts
createFoo(): if you want *mutable* instances of Foo, then you can't use
this version of createFoo(), but have to create another function that
probably does exactly the same thing. So an alternative solution is to
use Phobos' assumeUnique template:

struct User {
immutable(Foo)[] foos;
}
Foo createFoo(...) { ... }

User u;
u.foos ~= assumeUnique(createFoo(...));

The assumeUnique template basically does a cast from mutable to
immutable, but explicitly documents the purpose of this cast in the
code. It places the onus on the user to ensure that the Foo returned by
createFoo is actually unique. If not, you break the type system and the
immutability guarantee may no longer hold.

To illustrate why adding mutable aliases to Foo *should* break code,
consider this:

/* This is what Foo looked like before:
struct OriginalFoo {
int x;
}
*/

/* This is what Foo looks like now */
struct Foo {
int x;
private int[] history;
void changeHistory() { history[0]++; }
}

Foo createFoo(int x) {
Foo f;
f.x = x;
f.history = [1];
}

Foo f = createFoo();

immutable(Foo) g = f; // doesn't compile, but suppose it does
f.changeHistory();// oops, g.history has mutated, so it's
  // *not* immutable after all

That's why assigning f to g must be made illegal, since it breaks
immutability guarantees. OTOH, if you absolutely have to do it, you can
document your intent thus:

Foo f = createFoo();
immutable(Foo) g = assumeUnique(f);

// Now if you use f to mutate g, it's your own problem: you
// claimed that g was unique but actually it isn't. So it's your
// own fault when your supposedly-immutable Foo mutates.
// If you *don't* do stupid things, OTOH, this lets your code
// continue to work when the library writer decides to change
// Foo's implementation to 

Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread monarch_dodra
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.


Re: mutable, const, immutable guidelines

2013-10-16 Thread Daniel Davidson

On Wednesday, 16 October 2013 at 19:12:48 UTC, Dicebot wrote:
On Wednesday, 16 October 2013 at 19:06:06 UTC, Daniel Davidson 
wrote:
I don't understand how it could be fine. As code grows it 
would lead to people not adding useful members like history 
just because of the huge repercussions.


struct User {
  immutable(Foo) foos;
}

How can I as a user adapt to that change? Before the change 
assignment worked equally well among all of Mutable, 
Immutable, Const. After that change any `foos ~= 
createFoo(...)` would require change. And it is not clear what 
the change would be.


I think any usage of immutable with types/entities not 
initially designed for immutability is an potential mistake and 
in that sense it is good that change has broken the user code. 
Same goes for operating on immutable entity in generic code as 
if it is a value type without actually checking it via 
introspection.


I don't disagree. Now, what does it mean to initially design for 
immutability and what are the guidelines. I thought that was 
kind of what we were talking about here. How to effectively use 
const and immutable. If the rule is - don't use immutable unless 
you have immutability in mind for your design, ok. Maybe take it 
a step further...


How about this - show a good use of immutable in any context 
where mutable aliasing (e.g. AAs) are in the mix. If the response 
is there are none, it is just too hairy of a proposition then 
something is wrong.


One general idea that was presented by Ali is that an immutable 
parameter means that not only are you guaranteeing that you will 
not change your data, but also that no one else, even in another 
thread will. That sounds appealing. After all, who doesn't want 
the data they are using in a function to not change from 
underneath them? Suppose you have highly structured, deeply 
nested reference data you read from a nosql DB. Surely there is 
opportunity and some benefit to use immutable? The result of the 
query is just a read only data source. But then that data will be 
consumed - presumably by functions with either immutable or const 
parameters. If all signatures use const then when can you benefit 
from the fact that the data is really immutable (by the time it 
gets to a function with const parm the fact that it really was/is 
immutable is lost.


Re: this() immutable

2013-10-16 Thread Simen Kjaeraas

On 2013-10-16, 18:54, Daniel Davidson wrote:


On Thursday, 13 June 2013 at 12:29:57 UTC, Simen Kjaeraas wrote:
On Thu, 13 Jun 2013 14:17:22 +0200, Stephan Schiffels  
stephan_schiff...@mac.com wrote:


For example, is there a way of instantiating an object normally (i.e.  
mutable), and then later freeze it to immutable via a simple cast or  
so?


In std.exception there is assumeUnique. It's basically just a cast, but
might be good enough for you.


Is there any other recourse here?

Why does making `this(...) immutable` fix things below?
Shouldn't that immutable designation mean no members of this will be  
modified? But that is the whole point of an initializer? Why does  
immutable make sense in this context at all?


Immutable in the case of constructors means that the instance will be
created using only data implicitly castable to immutable. That way, when
construction is finished, it is safe for the type system to mark the
result as immutable.


My problem is a bit more elaborate and unfortunately to initialize  
members I need to call standard functions that have not been made pure  
(but should be).


If you're calling functions that are not marked pure in order to create
immutable data, you will need to cast to immutable afterwards. If you
know this is safe, no problem.

It would benefit us all if you reported these functions or created a pull
request for Phobos, of course.

--
  Simen


Re: this() immutable

2013-10-16 Thread Daniel Davidson
On Wednesday, 16 October 2013 at 19:55:41 UTC, Simen Kjaeraas 
wrote:

On 2013-10-16, 18:54, Daniel Davidson wrote:

On Thursday, 13 June 2013 at 12:29:57 UTC, Simen Kjaeraas 
wrote:
On Thu, 13 Jun 2013 14:17:22 +0200, Stephan Schiffels 
stephan_schiff...@mac.com wrote:


For example, is there a way of instantiating an object 
normally (i.e. mutable), and then later freeze it to 
immutable via a simple cast or so?


In std.exception there is assumeUnique. It's basically just a 
cast, but

might be good enough for you.


Is there any other recourse here?

Why does making `this(...) immutable` fix things below?
Shouldn't that immutable designation mean no members of this 
will be modified? But that is the whole point of an 
initializer? Why does immutable make sense in this context at 
all?


Immutable in the case of constructors means that the instance 
will be
created using only data implicitly castable to immutable. That 
way, when
construction is finished, it is safe for the type system to 
mark the

result as immutable.


My problem is a bit more elaborate and unfortunately to 
initialize members I need to call standard functions that have 
not been made pure (but should be).


If you're calling functions that are not marked pure in order 
to create
immutable data, you will need to cast to immutable afterwards. 
If you

know this is safe, no problem.



I'm in the learn news group for a reason. I think what you say 
makes sense - a cast is required. But perhaps you have more 
confidence that there is no problem. You and dicebot surely 
disagree on this practice as he sees no real reason to ever 
circumvent the type system.


It would benefit us all if you reported these functions or 
created a pull

request for Phobos, of course.


I reported my issue with the `chain` function to this NG and 
tried to start annotating items used by chain with pure to see 
how far the thread led. Honestly it was quickly clear that it led 
too far for me to follow it and someone else indicated the 
problem had to do with Voldermort types. If there is more I could 
do to benefit us all, beyond learning how it works and what to 
avoid in my own code - I will be glad to try.


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Daniel Davidson
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:

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 ?




That was my point.

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.




No I don't think I am. What code are you looking at?



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.


Re: does cast make an lvalue appear to be an rvalue

2013-10-16 Thread Daniel Davidson
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:

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.


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-le...@puremagic.com


struct S {
  R r;
  this(ref const(T) t) immutable {
createRFromT(t, r);
  }
}

void createRFromT(ref const(T) t, ref R r) {
  //...
}


Re: mutable, const, immutable guidelines

2013-10-16 Thread H. S. Teoh
On Wed, Oct 16, 2013 at 09:45:09PM +0200, Daniel Davidson wrote:
 On Wednesday, 16 October 2013 at 19:12:48 UTC, Dicebot wrote:
[...]
 I think any usage of immutable with types/entities not initially
 designed for immutability is an potential mistake and in that
 sense it is good that change has broken the user code. Same goes
 for operating on immutable entity in generic code as if it is a
 value type without actually checking it via introspection.
 
 I don't disagree. Now, what does it mean to initially design for
 immutability and what are the guidelines. I thought that was kind
 of what we were talking about here. How to effectively use const and
 immutable.

I'd say that user code should use const, not immutable (unless the
library provides a way of constructing immutable instances of the type,
of course), because immutable makes assumptions about implementation
details, which should not be known unless you break encapsulation. As a
user of a properly encapsulated type, I can't make any guarantees about
its immutability; the best I can do is to promise I don't change it
myself -- i.e., const.

Immutable should be used in library code to provide strong guarantees to
the user: since you're the one responsible for implementing the type,
you're in the position to make guarantees about its uniqueness (and
hence, immutability).


[...]
 One general idea that was presented by Ali is that an immutable
 parameter means that not only are you guaranteeing that you will not
 change your data, but also that no one else, even in another thread
 will. That sounds appealing. After all, who doesn't want the data
 they are using in a function to not change from underneath them?

I'm actually wary of this view, to be honest. An immutable parameter
means you expect your *caller* to provide you with a value that cannot
be changed, not by you, nor by anybody else, ever. Sure, it's nice to
have, but that imposes a rather high bar on your callers. They have to
be responsible to guarantee that whatever they hand to you cannot be
changed by anything or anyone else, at any time. If they can do this,
then great; if not, they won't be able to call your function.


 Suppose you have highly structured, deeply nested reference data you
 read from a nosql DB. Surely there is opportunity and some benefit
 to use immutable? The result of the query is just a read only data
 source. But then that data will be consumed - presumably by
 functions with either immutable or const parameters. If all
 signatures use const then when can you benefit from the fact that
 the data is really immutable (by the time it gets to a function with
 const parm the fact that it really was/is immutable is lost.

I'm of the view that code should only require the minimum of assumptions
it needs to actually work. If your code can work with mutable types,
then let it take a mutable (unqualified) type. If your code works
without modifying input data, then let it take const. Only if your code
absolutely will not work correctly unless the data is guaranteed to
never change, ever, by anyone, should it take immutable.

I'm not sure what benefits you get from requiring immutable when the
code doesn't really need to depend on immutability. It just makes the
code harder to use (you have to make sure whatever you pass to it is
immutable, and sometimes that's not easy to guarantee, and would require
a lot of copying). Immutable only benefits you when the code *can't*
work correctly unless the data is guaranteed never to change, ever. Hash
table keys come to mind -- if you compute the hash value of the key and
use that to determine which slot to put the data into, it would be very
bad if somebody else mutated that key via a mutable reference after the
fact -- now your AA is broken because the hash value no longer matches
the key.  By requiring an immutable key, you ensure that this never
happens.

Note that in D, everything is thread-local by default unless explicitly
made shared, so using immutable to guarantee other threads won't mutate
the data isn't really necessary.


T

-- 
What do you mean the Internet isn't filled with subliminal messages? What about 
all those buttons marked submit??


Re: this() immutable

2013-10-16 Thread Dicebot
On Wednesday, 16 October 2013 at 20:09:51 UTC, Daniel Davidson 
wrote:
You and dicebot surely disagree on this practice as he sees no 
real reason to ever circumvent the type system.


There are some cases were you have no other options because of 
language design limitations but it is something that should be 
done only by experienced D developers who clearly understand the 
impact upon the generated machine code and hidden behind the 
library functions. Not a casual casts in user code by any means.


Re: this() immutable

2013-10-16 Thread H. S. Teoh
On Wed, Oct 16, 2013 at 10:09:50PM +0200, Daniel Davidson wrote:
[...]
 I reported my issue with the `chain` function to this NG and tried
 to start annotating items used by chain with pure to see how far the
 thread led. Honestly it was quickly clear that it led too far for me
 to follow it and someone else indicated the problem had to do with
 Voldermort types. If there is more I could do to benefit us all,
 beyond learning how it works and what to avoid in my own code - I
 will be glad to try.

Hmm. I just did a quick-n-dirty change to Phobos, and it seems to make
chain() usable with pure code. I'm not sure why the compiler didn't
infer pure for it -- it should. (Or perhaps I'm missing something
obvious -- I didn't run the Phobos unittest so maybe the following
change breaks something.)

- In the Phobos source, edit std/range.d and look for the function `auto
  chain(Ranges...)(Ranges rs)` (around line 2022 or thereabouts), then
  the struct Result inside this function.
- Find the ctor for this struct (circa line 2074), and annotate it with
  pure.
- Now the following code compiles:

import std.range;

auto pureFunc() pure {
return chain([1,2,3], [2,3,4]);
}

void main() {
auto r = pureFunc();
}

This is just a hack, of course. The compiler *should* be able to
correctly infer that the ctor is pure. So the real fix is to find out
why the compiler isn't doing that.


T

-- 
Leather is waterproof.  Ever see a cow with an umbrella?


Re: this() immutable

2013-10-16 Thread Jonathan M Davis
On Wednesday, October 16, 2013 14:10:02 H. S. Teoh wrote:
 This is just a hack, of course. The compiler *should* be able to
 correctly infer that the ctor is pure. So the real fix is to find out
 why the compiler isn't doing that.

Because it sucks at attribute inference. The inference that it does right now 
is very shallow:

http://d.puremagic.com/issues/show_bug.cgi?id=10329

The compiler could use a considerable improvements with regards to how much 
inference it's doing for templated stuff. Without it, the attribute inference 
for Phobos is nowhere near good enough.

- Jonathan m Davis


Re: this() immutable

2013-10-16 Thread H. S. Teoh
On Wed, Oct 16, 2013 at 02:10:02PM -0700, H. S. Teoh wrote:
 On Wed, Oct 16, 2013 at 10:09:50PM +0200, Daniel Davidson wrote:
 [...]
  I reported my issue with the `chain` function to this NG and tried
  to start annotating items used by chain with pure to see how far the
  thread led. Honestly it was quickly clear that it led too far for me
  to follow it and someone else indicated the problem had to do with
  Voldermort types. If there is more I could do to benefit us all,
  beyond learning how it works and what to avoid in my own code - I
  will be glad to try.
 
 Hmm. I just did a quick-n-dirty change to Phobos, and it seems to make
 chain() usable with pure code. I'm not sure why the compiler didn't
 infer pure for it -- it should. (Or perhaps I'm missing something
 obvious -- I didn't run the Phobos unittest so maybe the following
 change breaks something.)
[...]

Actually, I just remembered why. It's because attribute inference only
happens for the template function itself, but not for any nested structs
or struct members. Arguably, the compiler should also do inference for
all nested declarations in a template too.

Do you have a bugzilla ticket for this issue? I'd like to add my
findings to it. Thanks!


T

-- 
Without geometry, life would be pointless. -- VS


Questions about VisualD

2013-10-16 Thread Namespace
I've clicked on Build Phobos browse info and now I have 
absolute no idea how I can restore my old class view for my 
current project. Any suggestions?
And it seems that VisualD ignores all of my Tasks. My Tasklist is 
always empty, whats wrong? Or is this not implemented?


Can I compile for Linux from a Windows platform?

2013-10-16 Thread Stephen Jones
Basically I want to develop a program on Windows and send the exe 
to someone to use on a Linux platform. Is this possible?


Re: Can I compile for Linux from a Windows platform?

2013-10-16 Thread Jonathan M Davis
On Thursday, October 17, 2013 02:58:50 Stephen Jones wrote:
 Basically I want to develop a program on Windows and send the exe
 to someone to use on a Linux platform. Is this possible?

AFAIK, it's not possible. It _might_ be possible to do with mingw and gdc or 
ldc (I don't know if they use mingw or not, though I'd guess that they do), 
but even if you _could_ target Linux with that (which I doubt), the versions 
of the libraries the program was built against wouldn't match what would be 
found on a Linux box, so it wouldn't actually run on any Linux box. I've heard 
of building on Linux for mingw and then running it on Windows, but that's it, 
and I think that it's pretty surprising that that works. In general, you can't 
cross-compile across operating systems.

- Jonathan M Davis


Function pointer to member function.

2013-10-16 Thread TheFlyingFiddle

I would like to get access to a member function pointer. Taking
the this* as
the first argument.

class Foo
{
void bar(int a)
{
   //do something awesome
}
}

unittest
{
Foo a = new Foo();
Foo b = new Foo();

auto fp = getFP!(Foo.bar);
fp(a, 1); //Basically calls a.foo(1)
fp(b, 1); //Basically calls b.foo(1)
}

How should i implement getFP above? Is it even possible?


Re: Can I compile for Linux from a Windows platform?

2013-10-16 Thread Adam D. Ruppe
On Thursday, 17 October 2013 at 01:18:42 UTC, Jonathan M Davis 
wrote:

In general, you can't cross-compile across operating systems.


Linux to Windows is pretty easy. You can just run the Windows 
version of dmd under wine on linux to make exes, or you can 
compile gcc (and presumably gdc, though I've never tried) for 
linux to make exes.


I'm sure similar techniques could be used, in theory at least, to 
do Windows to Linux, but I've never seen it done and you're 
absolutely right about the versions not matching up. Hell, it is 
hard enough to get a binary from one linux box working on another 
linux box!


Re: Can I compile for Linux from a Windows platform?

2013-10-16 Thread H. S. Teoh
On Thu, Oct 17, 2013 at 04:24:07AM +0200, Adam D. Ruppe wrote:
 On Thursday, 17 October 2013 at 01:18:42 UTC, Jonathan M Davis
 wrote:
 In general, you can't cross-compile across operating systems.
 
 Linux to Windows is pretty easy. You can just run the Windows
 version of dmd under wine on linux to make exes, or you can compile
 gcc (and presumably gdc, though I've never tried) for linux to make
 exes.
 
 I'm sure similar techniques could be used, in theory at least, to do
 Windows to Linux, but I've never seen it done and you're
 absolutely right about the versions not matching up. Hell, it is
 hard enough to get a binary from one linux box working on another
 linux box!

Linux is rather heavy on the compile-from-source philosophy.
Distributing binaries in Linux is fraught with peril and generally not
done, except by distro vendors (who actually have a fighting chance of
getting it right) and companies who are paranoid about distributing
source (who generally *don't* get it right, thus are unable to reach a
significant proportion of the Linux market).


T
-- 
Computers aren't intelligent; they only think they are.


Re: Function pointer to member function.

2013-10-16 Thread Chris Cain
On Thursday, 17 October 2013 at 01:17:21 UTC, TheFlyingFiddle 
wrote:

I would like to get access to a member function pointer. Taking
the this* as
the first argument.

...snip...
How should i implement getFP above? Is it even possible?


Well, it's certainly possible. If you were to do this:
```
delegate void(int) dg = a.bar;
dg(1);
```
then you'd see the behavior you're looking for. Basically the 
class reference is stored in dg.ptr and the function is in 
dg.funcptr.


With that in mind, I whipped this up:
```
import std.stdio;

class Foo {
char c;
this() {
c = 'a';
}
this(char _c) {
c = _c;
}
void bar(int i) {
writeln(i = , i,  c = , c);
}
}

import std.traits;
//ParentOf!S is pseudocode representing __traits(parent, S)
//ReturnType!S function(ParentOf!S, ParameterTypeTuple!S)
auto getFP(alias S)() if(isSomeFunction!S) {
mixin(alias Parent =  ~ __traits(parent, S).stringof ~ ;);
return (Parent r, ParameterTypeTuple!S t) {
ReturnType!S delegate(ParameterTypeTuple!S) dg;
dg.funcptr = S;
dg.ptr = cast(void*) r;
return dg(t);
};
}

void main() {
Foo a = new Foo();
Foo b = new Foo('b');

auto fp = getFP!(Foo.bar);
fp(a, 1);
fp(b, 2);
}
```

Now one thing to note is that I'm not confident it's bug-free. It 
does work in this test case, but I couldn't use __traits(parent, 
S) as a type, so I used a mixin to kind of force it to work. So 
I'm not fully sure whether it will work in all cases, but if 
someone else has some improvements, that's fine.


Another thing: I didn't spend too much time on the template 
constraint. isSomeFunction is almost certainly too permissive. 
I just threw it together and I haven't coded in D for a while.


I hope this helped!


Re: Can I compile for Linux from a Windows platform?

2013-10-16 Thread Jerome BENOIT
If you want to play within a Linux environment on Windows, you can try CygWIN: 
http://www.cygwin.com/

On 17/10/13 04:24, Adam D. Ruppe wrote:
 On Thursday, 17 October 2013 at 01:18:42 UTC, Jonathan M Davis wrote:
 In general, you can't cross-compile across operating systems.
 
 Linux to Windows is pretty easy. You can just run the Windows version of dmd 
 under wine on linux to make exes, or you can compile gcc (and presumably gdc, 
 though I've never tried) for linux to make exes.
 
 I'm sure similar techniques could be used, in theory at least, to do Windows 
 to Linux, but I've never seen it done and you're absolutely right about 
 the versions not matching up. Hell, it is hard enough to get a binary from 
 one linux box working on another linux box!