Array of closures assign

2010-12-23 Thread bearophile
This D2 program compiles with no errors:

void delegate()[1] foo;
void main() {
int n;
foo[0] = { n++; };
}


But this one:

void delegate()[1] foo;
void main() {
int n;
foo[] = [{ n++; }];
}



test.d(4): Error: cannot implicitly convert expression ([delegate void()

{

n++;

}

]) of type void delegate()[] to const(void delegate()[])

Is this a front-end bug?

Bye,
bearophile


Re: Strange socket error

2010-12-23 Thread Bob Cowdery
Hi Heywood

Thankyou for your time. Yes I agree making the call blocking does stop
the exceptions churning. Unfortunately the application stops accepting
data now because after the first incoming transfer from the web socket
client it sees data on the listening socket and promptly blocks on it
and never comes off until I make another connection. I think this is
expected behaviour. I could spawn a thread for each connection which I
would normally do but shouldn't need to as it's really only a few users
and I believe that would only sidestep the real problem.

There are lots of things here that don't make sense.

1. It works for Windows and it should work for Linux (and Mac) unless
Windows is broken and Linux is behaving as it should.
2. I should only see data on the listen socket when I make a new
connection. What I see is data on the listen socket when I send data on
the connected socket and with non-blocking even when I don't make a
connection or send any data at all.
2. The really confusing thing is if I stop my USB and DSP threads it
stops behaving like this and sees data on the correct sockets. In other
words it works as it does on Windows so I have to assume this is the
correct behaviour.
3. I've played around with trying to figure out exactly what it is in
the other threads that causes the behaviour. I got as far as finding
that only the DSP thead is required so that rules out misbehaving USB.
Very oddly there is a loop that is creating some Json data (not very
efficiently) as it's doing a lot of string concatenation. If I comment
out this loop or reduce its iterations the exception slow down to the
point where I just get 2 and then they stop. This points to something
horrible going on.

I can only hope I've done something stupid that I just happen to be
getting away with on Windows. If it's a bug in the compiler or libraries
I think I'm stuffed as I wouldn't know where to start.

Regards
bob

On 23/12/2010 00:20, Heywood Floyd wrote:
 Hi Bob!


 My guess: You're listener is set to be non-blocking. That means that when you 
 call listener.accept() it will return immediately with an 
 SocketAcceptException, if there's no connection. And you're basically calling 
 listener.accept() over and over again in an infinite loop.

 The following example shows it:

 import std.concurrency, std.stdio, std.conv, std.socket;
 void main()
 {
   ushort port = ;
   Socket listener = new TcpSocket;
   assert(listener.isAlive);
   listener.blocking = false;
   listener.bind(new InternetAddress(port));
   listener.listen(10);
   writeln(Listening on port: , port);
   Socket sn;
   while(true){
   try
   {
   writeln (Accepting);
   sn = listener.accept();
   writeln(Connection from , 
 sn.remoteAddress().toString(),  established );
   assert(sn.isAlive);
   assert(listener.isAlive);
   break;
   }
   catch(Exception e)
   {
   writeln(Error accepting: , e.toString() );
   if(sn)
   sn.close();
   }
   }
   writeln(end);
 }

 Running the example will print
 Error accepting: std.socket.SocketAcceptException: Unable to accept 
 socket connection: Resource temporarily unavailable
 for ever. (Tested on Mac.) When a user connects to 127.0.0.1: (by for 
 instance opening the URL in a browser) socket.accept _does_ return a 
 connection and the program prints end.

 I don't know why the program doesn't do this on Windows. As far as I can tell 
 the endless exceptions _is_ the correct behaviour, right?

 Anyway, if you comment out the the line
 listener.blocking = false;
 in 'listener.d', does it work as intended then? In the example above this 
 will cause the listener.accept()-call to actually wait until it gets a 
 connection, and thus not spew out all the exceptions.

 BR
 /heywood




 Bob Cowdery Wrote:

 Hi all,

 This is a long shot but I'm out of ideas. I ported an app from Windows
 to Linux and after many issues it is working but I'm left with a strange
 problem. The app basically reads data streams from a USB device,
 processes them and outputs real-time graphical data to a browser. There
 is also some control input from the browser. The interface to the
 browser is web sockets for which I have written a D web-socket server.
 Depending on how much of my application I allow to run I get a stream of
 these errors.

 Error accepting: std.socket.SocketAcceptException: Unable to accept
 socket connection: Resource temporarily unavailable
 
 ./DcSdr() [0x80aa2ed]
 ./DcSdr() [0x806f52b]
 ./DcSdr() [0x804f752]
 ./DcSdr() [0x809b422]
 ./DcSdr() [0x80ae77e]
 /lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0x48496e]
 /lib/tls/i686/cmov/libc.so.6(clone+0x5e) [0xc5fa4e]

 This is the web-socket accept. I seem to 

Re: double - double[]... | feature or bug?

2010-12-23 Thread spir
On Thu, 23 Dec 2010 00:34:41 -0600
Christopher Nicholson-Sauls ibisbase...@gmail.com wrote:

 On 12/22/10 15:06, Andrej Mitrovic wrote:
  Oooh. That cought me off guard, sorry.
  
  Thanks Steve.
  
 
 I'll concede that the syntax can be odd at first, but it also enables
 some interesting things.  For example, this works:
 
 class Foo {
 this (int i, double f) { /*...*/ }
 /*...*/
 }
 
 void someFunc ( Foo foo ... ) { /*...*/ }
 
 someFunc( 5, 3.14 );
 
 Basically, given a class (and I think struct's work as well) as the
 variadic type, it will accept either an instance of said class, or any
 combination of values which can be mapped to a constructor of that
 class.  It can be convenient sometimes.

While I understand some may consider this a nice feature, for me this is an 
enormous bug. A great way toward code obfuscation. I like D among other reasons 
because it's rather clear compared to other languages of the family. There 
should be no automagic constructor call (at least in this case, when the type 
is not even mentionned on the caller side).
This may even lead to very naughty bugs. And what if Foo has subtypes, and the 
one actually invoked is the one intended by the user?

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



Re: double - double[]... | feature or bug?

2010-12-23 Thread bearophile
spir:

 While I understand some may consider this a nice feature, for me this is an 
 enormous bug. A great way toward code obfuscation. I like D among other 
 reasons because it's rather clear compared to other languages of the family.

The main problem here is that I have never felt the need of that feature, so 
for me it's useless. Has Walter added it after a good number of people have 
asked for this feature? Has any one here needed it?

Bye,
bearophile


import from subdir

2010-12-23 Thread spir
Hello,

Say I have a project with the following tree structure:

[app]
app.d
util.d
[test]
test.d
[data]
data.d

Is there a way to import util  data from test?

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



Re: import from subdir

2010-12-23 Thread Jonathan M Davis
On Thursday 23 December 2010 04:38:56 spir wrote:
 Hello,
 
 Say I have a project with the following tree structure:
 
 [app]
   app.d
   util.d
   [test]
   test.d
   [data]
   data.d
 
 Is there a way to import util  data from test?

Use the -I flag when compiling. Presumably, you'd do something like -I../ so 
that 
it would also search for files starting at the parent directory.

- Jonathan M Davis


Re: is this the expected output

2010-12-23 Thread Dmitry Olshansky

On 23.12.2010 3:40, g g wrote:

Thanks for the answers
what I did is this ( i feel that it is quite clumsy):

Node* x = cast(Node*) (GC.malloc(Node.sizeof));
 *x = xa;
 x.up = curnode;
 ...

which could be improved:
Node* x = new Node(...);//paste your constructor args in place of ...  
if Node has a constructor, or just

Node* x = new Node;// if no constructors

--
Dmitry Olshansky



Re: import from subdir

2010-12-23 Thread spir
On Thu, 23 Dec 2010 05:26:57 -0800
Jonathan M Davis jmdavisp...@gmx.com wrote:

 On Thursday 23 December 2010 04:38:56 spir wrote:
  Hello,
  
  Say I have a project with the following tree structure:
  
  [app]
  app.d
  util.d
  [test]
  test.d
  [data]
  data.d
  
  Is there a way to import util  data from test?
 
 Use the -I flag when compiling. Presumably, you'd do something like -I../ so 
 that 
 it would also search for files starting at the parent directory.
 
 - Jonathan M Davis

Thank you, I'll try this solution. So, there is no syntax? (I tried import 
..util; and import ..data.data; without any success ;-)

What about proposing that each _single_ leading dot moves up one dir? In my 
case, this would give import .util; and import .data.data;. I find this 
simple, practical and very useful.


Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



DMD2 out parameters

2010-12-23 Thread Pete
Hi,

I'm not sure if this is already a widely known phenomenon but I ran across a
little gotcha yesterday regarding floating point out parameters using DMD2.

A year or so ago I wrote a ray tracer using DMD1. A few months ago I tried
compiling and running it using DMD2. It was 50% slower. This disappointed me
so much that I stopped using D2 until about a week ago. I spent a few hours
yesterday investigating why the D2 version of the code was so much worse than
the D1 version. After some head scratching and use of -profile and objconv, I
eventually managed to isolate the problem. It boiled down to this example:

float f;
func(f);

void func(out float ff) {
ff = 1;
}

This use of 'out' causes func to execute in around 250 ticks on DMD2. Change
'out' to 'ref' and it takes around 10 ticks (the same time as the 'out'
version executes on DMD1). If you initialise f to 0 before calling func then
it all works quickly again which makes me wonder whether it's some strange
DMD2 nan/fpu exceptions quirk which may be documented somewhere?? When I
looked at the generated assembly I saw that both DMD1 and DMD2 seem to
generate the same thing (using -O -inline - release):

func  LABEL NEAR
pushebp
mov ebp, esp
pusheax   // eax = ptr to ff
fld dword ptr [_nan]
fstpdword ptr [eax]
fld dword ptr [_one]
fstpdword ptr [eax]

mov esp, ebp
pop ebp
ret

Now this code looks ok if you ignore the fact that 'ff' is being written to
twice. And the strange seemingly redundant push of EAX.

Has anyone else come across this and if so is it a bug? I'm also interested in
people's thoughts on the strange code gen.

My D2 version is now running faster than the old D1 version by the way :)

Regards,
Pete.


Re: DMD2 out parameters

2010-12-23 Thread Pete
//If you initialise f to 0 before calling func then it all works quickly again

Actually I think this is a red herring. I don't think initialising f helps


Re: double - double[]... | feature or bug?

2010-12-23 Thread Andrej Mitrovic
On 12/23/10, bearophile bearophileh...@lycos.com wrote:
 spir:

 While I understand some may consider this a nice feature, for me this is
 an enormous bug. A great way toward code obfuscation. I like D among other
 reasons because it's rather clear compared to other languages of the
 family.

 The main problem here is that I have never felt the need of that feature, so
 for me it's useless. Has Walter added it after a good number of people have
 asked for this feature? Has any one here needed it?

 Bye,
 bearophile


You should probably ask in d-general. It looks like a dangerous
feature to have. If you have that function laying in another imported
module you might not even realize that you're constructing an object.
Consider this:

void test(int x, int y, string z);  // your module which you
accidentally forgot to import
void test(int x, Foo f ...);  // some other module that *is* imported
test(1, 4, def);  // calling site that constructs a Foo object

Maybe it takes more typing, but I prefer this:
test(1, new Foo(4, def));

It's explicit and you can reason about it without having to inspect
other modules.


Re: Strange socket error

2010-12-23 Thread Heywood Floyd

Hi!


I see.

I think my previous answer was a bit naive—I didn't appreciate the full scope 
of the problem. Sorry for that, but you know, internet is fast, snap snap : )

Ok, for now I'm afraid I don't have any more to add. (An isolated example would 
of course help greatly!)

All I can say is, in my experience, the D sockets library _does_ behave 
differently on different platforms. Had a server that just died seemingly 
random on osx, while working fine on Linux. Turned out to be bug in D sockets. 
So there you go. (The bug is still there btw... *cough*)

Hm, also, I realize I'm not sure I quite understand the structure of your app, 
and where in this structure the bug happends. Is this bug happening when your 
html/5-client tries to connect to the server? Or are the threads using sockets 
to communicate between eachother?


BR
/heywood



Bob Cowdery Wrote:

 Hi Heywood
 
 Thankyou for your time. Yes I agree making the call blocking does stop
 the exceptions churning. Unfortunately the application stops accepting
 data now because after the first incoming transfer from the web socket
 client it sees data on the listening socket and promptly blocks on it
 and never comes off until I make another connection. I think this is
 expected behaviour. I could spawn a thread for each connection which I
 would normally do but shouldn't need to as it's really only a few users
 and I believe that would only sidestep the real problem.
 
 There are lots of things here that don't make sense.
 
 1. It works for Windows and it should work for Linux (and Mac) unless
 Windows is broken and Linux is behaving as it should.
 2. I should only see data on the listen socket when I make a new
 connection. What I see is data on the listen socket when I send data on
 the connected socket and with non-blocking even when I don't make a
 connection or send any data at all.
 2. The really confusing thing is if I stop my USB and DSP threads it
 stops behaving like this and sees data on the correct sockets. In other
 words it works as it does on Windows so I have to assume this is the
 correct behaviour.
 3. I've played around with trying to figure out exactly what it is in
 the other threads that causes the behaviour. I got as far as finding
 that only the DSP thead is required so that rules out misbehaving USB.
 Very oddly there is a loop that is creating some Json data (not very
 efficiently) as it's doing a lot of string concatenation. If I comment
 out this loop or reduce its iterations the exception slow down to the
 point where I just get 2 and then they stop. This points to something
 horrible going on.
 
 I can only hope I've done something stupid that I just happen to be
 getting away with on Windows. If it's a bug in the compiler or libraries
 I think I'm stuffed as I wouldn't know where to start.
 
 Regards
 bob
 
 On 23/12/2010 00:20, Heywood Floyd wrote:
  Hi Bob!
 
 
  My guess: You're listener is set to be non-blocking. That means that when 
  you call listener.accept() it will return immediately with an 
  SocketAcceptException, if there's no connection. And you're basically 
  calling listener.accept() over and over again in an infinite loop.
 
  The following example shows it:
 
  import std.concurrency, std.stdio, std.conv, std.socket;
  void main()
  {
  ushort port = ;
  Socket listener = new TcpSocket;
  assert(listener.isAlive);
  listener.blocking = false;
  listener.bind(new InternetAddress(port));
  listener.listen(10);
  writeln(Listening on port: , port);
  Socket sn;
  while(true){
  try
  {
  writeln (Accepting);
  sn = listener.accept();
  writeln(Connection from , 
  sn.remoteAddress().toString(),  established );
  assert(sn.isAlive);
  assert(listener.isAlive);
  break;
  }
  catch(Exception e)
  {
  writeln(Error accepting: , e.toString() );
  if(sn)
  sn.close();
  }
  }
  writeln(end);
  }
 
  Running the example will print
  Error accepting: std.socket.SocketAcceptException: Unable to accept 
  socket connection: Resource temporarily unavailable
  for ever. (Tested on Mac.) When a user connects to 127.0.0.1: (by for 
  instance opening the URL in a browser) socket.accept _does_ return a 
  connection and the program prints end.
 
  I don't know why the program doesn't do this on Windows. As far as I can 
  tell the endless exceptions _is_ the correct behaviour, right?
 
  Anyway, if you comment out the the line
  listener.blocking = false;
  in 'listener.d', does it work as intended then? In the example above this 
  will cause the listener.accept()-call to actually wait until it gets a 
  connection, and thus not spew out all the exceptions.
 
  BR
  /heywood
 
 
 
 
  Bob Cowdery Wrote:
 
 

Re: double - double[]... | feature or bug?

2010-12-23 Thread Don

bearophile wrote:

spir:


While I understand some may consider this a nice feature, for me this is an 
enormous bug. A great way toward code obfuscation. I like D among other reasons 
because it's rather clear compared to other languages of the family.


The main problem here is that I have never felt the need of that feature, so 
for me it's useless. Has Walter added it after a good number of people have 
asked for this feature? Has any one here needed it?

Bye,
bearophile


I'm almost certain that the behaviour is not intentional.


Do we already have full compile time / runtime separation?

2010-12-23 Thread Mariusz Gliwiński
Hello,
I've been trying to manage this on my own for like 2 days but still couldn't 
do that, and because my brain just suddenly turned-off, I would ask You for 
some guidance.

The thing is:
I'd like to make some kind of messaging in my application. So, there is 
- interface Msg
- classes that are implementing it, i.e. MsgWindowClose
- interface Provider for message publishers, i.e. MsgProviderWindowClose
- interface Listener for message subscibers i.e. MsgListenerWindowClose
- interface Handler for message filters i.e. bool MsgHandlerWindowClose.log()
- interface Mediator for message passing between program classes, i.e. 
MsgMediatorDMultiThreading() - which is using D messages btw.

Nothing related to D so far. Key thing is, that most of this Msg objects will 
be really generic, so I'm building object generator, i.e 
MsgProviderGen!WindowClose:
code
template MsgProviderGen(string MSG, Args...) {

const char[] MsgProviderGen = class MsgProvider~MSG~ : MsgProvider {

~override Msg~MSG~ getMsg() {
~return new Msg~MSG~;
~}

~};

}
/code
Which will be bigger of course.

Then, for standard and generic messages i can easily define:
code
private import
msg.msg,
msg.provider.gen,
msg.handler.gen;

class MsgWindowClose : Msg {
 
}
mixin(MsgProviderGen!WindowClose);
/code


So far so good, but then if I'd like to add
codemixin(immutable uint id=~static_id~;)/code
for each *class* (not object) I got a 

PROBLEM:
Each compile-time variable has to be const, right? So I can't increment my 
`static_id` each time I build a class (how many times template has generated 
provider/listener of this type). This wont let me statically check if each 
listener has its provider.

Surely it's not the only use of this feature, For loosen coupling, I'd wish to 
add function that statically returns array of Msg defined in module. It isn't 
an option without compile-time variables too.

Is it something about undefined module initialization?
Or maybe there is any way to overcome this problems, since I'm still new @ D 
language.

Ps. How to make associative array of dynamic arrays?
codeMsgHandler[hash_t][] _handlers = new MsgHandler[hash_t][];/code
wont work.

Thanks for help,
Mariusz Gliwiński


signature.asc
Description: This is a digitally signed message part.


Re: double - double[]... | feature or bug?

2010-12-23 Thread Steven Schveighoffer

On Thu, 23 Dec 2010 12:34:45 -0500, Don nos...@nospam.com wrote:


bearophile wrote:

spir:

While I understand some may consider this a nice feature, for me this  
is an enormous bug. A great way toward code obfuscation. I like D  
among other reasons because it's rather clear compared to other  
languages of the family.
 The main problem here is that I have never felt the need of that  
feature, so for me it's useless. Has Walter added it after a good  
number of people have asked for this feature? Has any one here needed  
it?

 Bye,
bearophile


I'm almost certain that the behaviour is not intentional.


From http://www.digitalmars.com/d/2.0/function.html :

Typesafe variadic functions are used when the variable argument portion  
of the arguments are used to construct an array  or class object .


(emphasis added)

And it goes on to show a similar example as to what has been discussed  
here.


I think it's intentional, and I agree that I've never used or thought  
gee, I wish D did this.  I wouldn't be sorry to see it go.  In fact, I'd  
advocate for getting rid of it.  It creates a hidden allocation, which I'm  
very much against.


-Steve


Vim: Anyone using taglist.vim with D?

2010-12-23 Thread Andrej Mitrovic
I know there's a few people here that use Vim, so has anyone succesfully used 
the taglist.vim plugin with D?

Ctags work for me (on XP), but I can't get taglist to work with D. It does work 
with C/CPP files, but it seems to ignore D files.

I'm asking before I try to modify the plugin, because either I have ctags set 
up wrong for D, or taglist simply won't work with D files, and there's a 
function in there called function! s:Tlist_Skip_File(filename, ftype) which 
looks tempting to modify. 

I can use ctags on D files already but not with the taglist plugin itself.

P.S. I've uploaded a new Ctags Windows binary on the prowiki page, and added 
.di as another D file extension (i'll put up the patch later). I'm not sure how 
up-to-date the D2 support is in that 5.8 patch, for example some template 
functions are ignored in ctags. So I might update these soon.

http://prowiki.org/wiki4d/wiki.cgi?ReferenceForTools/ExuberantCtags


Re: DMD2 out parameters

2010-12-23 Thread Don

Pete wrote:

Ok, i've done some more investigating and it appears that in DMD2 a float NaN is
0x7FE0 (in dword format) but when it initialises a float 'out' parameter it
initialises it with 0x7FA0H. This causes an FPU trap which is where the time
is going. This looks like a bug to me. Can anyone confirm?

Thanks.


Yes, it sounds like a NaN-related peformance issue. Note, though, that 
the slowdown you experience is processor-model specific. It's a penalty 
of ~250 cycles on a Pentium 4 with x87 instructions, but zero cycles on 
many other processors. (in fact, it's also zero cycles with SSE on 
Pentium 4!).


Re: DMD2 out parameters

2010-12-23 Thread Johann MacDonagh

On 12/23/2010 12:19 PM, Pete wrote:

Ok, i've done some more investigating and it appears that in DMD2 a float NaN is
0x7FE0 (in dword format) but when it initialises a float 'out' parameter it
initialises it with 0x7FA0H. This causes an FPU trap which is where the time
is going. This looks like a bug to me. Can anyone confirm?

Thanks.


I just did a test with DMD 2.051 on Linux

void F1(ref float a)
{
a++;
}

void F2(out float a)
{
a++;
}

void main()
{
float a;
float b;

F1(a);
F2(b);
}

And ASM:

080490e4 _D3out2F1FKfZv:
 80490e4:   55  push   ebp
 80490e5:   8b ec   movebp,esp
 80490e7:   83 ec 04subesp,0x4
 80490ea:   d9 e8   fld1
 80490ec:   d8 00   fadd   DWORD PTR [eax]
 80490ee:   d9 18   fstp   DWORD PTR [eax]
 80490f0:   c9  leave
 80490f1:   c3  ret
 80490f2:   90  nop
 80490f3:   90  nop

080490f4 _D3out2F2FJfZv:
 80490f4:   55  push   ebp
 80490f5:   8b ec   movebp,esp
 80490f7:   83 ec 04subesp,0x4
 80490fa:   d9 05 00 81 05 08   fldDWORD PTR ds:0x8058100
 8049100:   d9 18   fstp   DWORD PTR [eax]
 8049102:   d9 e8   fld1
 8049104:   d8 00   fadd   DWORD PTR [eax]
 8049106:   d9 18   fstp   DWORD PTR [eax]
 8049108:   c9  leave
 8049109:   c3  ret
 804910a:   90  nop
 804910b:   90  nop

0804910c _Dmain:
 804910c:   55  push   ebp
 804910d:   8b ec   movebp,esp
 804910f:   83 ec 08subesp,0x8
 8049112:   d9 05 00 81 05 08   fldDWORD PTR ds:0x8058100
 8049118:   d9 5d f8fstp   DWORD PTR [ebp-0x8]
 804911b:   d9 05 00 81 05 08   fldDWORD PTR ds:0x8058100
 8049121:   d9 5d fcfstp   DWORD PTR [ebp-0x4]
 8049124:   8d 45 f8leaeax,[ebp-0x8]
 8049127:   e8 b8 ff ff ff  call   80490e4 _D3out2F1FKfZv
 804912c:   8d 45 fcleaeax,[ebp-0x4]
 804912f:   e8 c0 ff ff ff  call   80490f4 _D3out2F2FJfZv
 8049134:   31 c0   xoreax,eax
 8049136:   c9  leave
 8049137:   c3  ret

And 0x8058100 is 0x7FA0. As you can see out doesn't force the 
loading and storing of a different NaN value.


Of course, maybe the compiler should skip initializing a float that gets 
passed into a routine as an out parameter as its first use. E.g.


float a;
a = 1.0;

wouldn't generate two separate assignments.


Re: import from subdir

2010-12-23 Thread CrypticMetaphor

On 12/23/2010 1:38 PM, spir wrote:

Is there a way to import util  data from test?


I think this should work:

util.d first line:
module util;

data.d first line
module data.data;

test.d first lines
module test.test;
import util;
import data.data;


Disclaimer: I don't know if directory names and file names may overlap, 
maybe you should rename them.


Re: Undefined references when linking to C library

2010-12-23 Thread Peter Federighi
Jonathan M Davis wrote:
 Did you wrap the C declarations in an extern(C) block? Without that, it's 
 going
 to think that your variables are D variables not C variables. The same goes 
 for
 any functions - _especially_ for the functions. In fact, a large portion of - 
 in
 not all of - your gpm.d file should likely be in extern(C).

I tried extern (C) for the whole module and individually.  I get the following
error:
/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld:
_gpm_arg: TLS reference in gev.o mismatches non-TLS definition in
/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data
/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read
symbols: Bad value
collect2: ld returned 1 exit status
--- errorlevel 1

Is this a 32/64 bit issue?  I have both versions of libgpm installed.  Those 
file
paths are obtuse, but they do point to the 32 bit libraries.  I've successfully
compiled other programs that use C libraries such as SDL and OpenGL (both via 
the
Derelict2 modules).

I also tried htod and compared the output with what I wrote.  The differences 
are
inconsequential.

Thank you,
- Peter Federighi


Re: Memory allocation faile on string concat

2010-12-23 Thread Steven Schveighoffer
On Thu, 11 Nov 2010 07:42:36 -0500, Steven Schveighoffer  
schvei...@yahoo.com wrote:



On Wed, 10 Nov 2010 23:33:58 -0500, Xie xiema...@gmail.com wrote:


OK, this actually makes sense to me.



It's a manifestation of this issue:
http://d.puremagic.com/issues/show_bug.cgi?id=3929


I'm think - it's truth but not at all.

Sorry, but i'm give incomplete data.

My example run fine, when benchmark(1), (2), but not 10.
This means, that memory not collected _between_ calls.


Yes, this is what the bug report is about -- the memory is not collected  
even though there are no references left, because the cache used to  
speed up appending still has a reference.


OK, so I have actually implemented a fix for bug 3929.  Essentially, the  
cache will no longer hold hostage the data that was being appended.


However, I have found that this *still* doesn't fix the problem.  Even  
though the cache no longer holds the memory as allocated, the example does  
something that we can't really get around.


When you allocate a very very large block of data (in this case 1/20 of  
your address space), it is inevitable with a conservative GC that this  
data never gets collected.  Why?  Because the stack is scanned  
conservatively, and the chances that some 4-bytes of data looks like it  
points to the space is very high.


So in order to fix this, we would not only need precise heap scanning, but  
*also* precise stack scanning, and precise TLS/global data scanning.


But I'm still going to check this in to fix the bug, because it does seem  
to help with smaller blocks.


I'll post more on the main newsgroup on this issue.

-Steve


Re: Do we already have full compile time / runtime separation?

2010-12-23 Thread Jonathan M Davis
On Thursday 23 December 2010 01:11:40 Mariusz Gliwiński wrote:
 Hello,
 I've been trying to manage this on my own for like 2 days but still
 couldn't do that, and because my brain just suddenly turned-off, I would
 ask You for some guidance.
 
 The thing is:
 I'd like to make some kind of messaging in my application. So, there is
 - interface Msg
 - classes that are implementing it, i.e. MsgWindowClose
 - interface Provider for message publishers, i.e. MsgProviderWindowClose
 - interface Listener for message subscibers i.e. MsgListenerWindowClose
 - interface Handler for message filters i.e. bool
 MsgHandlerWindowClose.log() - interface Mediator for message passing
 between program classes, i.e. MsgMediatorDMultiThreading() - which is
 using D messages btw.
 
 Nothing related to D so far. Key thing is, that most of this Msg objects
 will be really generic, so I'm building object generator, i.e
 MsgProviderGen!WindowClose:
 code
 template MsgProviderGen(string MSG, Args...) {
 
   const char[] MsgProviderGen = class MsgProvider~MSG~ : MsgProvider {
 
   ~override Msg~MSG~ getMsg() {
   ~return new Msg~MSG~;
   ~}
 
   ~};
 
 }
 /code
 Which will be bigger of course.
 
 Then, for standard and generic messages i can easily define:
 code
 private import
   msg.msg,
   msg.provider.gen,
   msg.handler.gen;
 
 class MsgWindowClose : Msg {
 
 }
 mixin(MsgProviderGen!WindowClose);
 /code
 
 
 So far so good, but then if I'd like to add
 codemixin(immutable uint id=~static_id~;)/code
 for each *class* (not object) I got a
 
 PROBLEM:
 Each compile-time variable has to be const, right? So I can't increment my
 `static_id` each time I build a class (how many times template has
 generated provider/listener of this type). This wont let me statically
 check if each listener has its provider.
 
 Surely it's not the only use of this feature, For loosen coupling, I'd wish
 to add function that statically returns array of Msg defined in module. It
 isn't an option without compile-time variables too.
 
 Is it something about undefined module initialization?
 Or maybe there is any way to overcome this problems, since I'm still new @
 D language.
 
 Ps. How to make associative array of dynamic arrays?
 codeMsgHandler[hash_t][] _handlers = new MsgHandler[hash_t][];/code
 wont work.

You're mixing up several concepts, which complicates things a fair bit.

When directly initializing static variables or member variables, the values 
used 
to initialize those variables must not depend on ordering. That generally means 
that the values used to initialize such variables must either come from 
constants, templates, or CTFE. So,

auto a = 7;
auto b = a;

is not legal, because a is not constant. If it were

immutable a = 7;
auto b = a;

then it's legal. However, note that b itself is not const, immutable, or an 
enum. It's fully mutable. Other ways to initialize such variables would be 
through eponymous templates and calling functions via CTFE (compile-time 
function evaluation):

template add(int a, int b)
{
enum add = a + b;
}

double multiply(double a, double b)
{
return a * b;
}

auto a = add!(7, 5);
auto b = multiply(2, 3);

Enforcing the lack of ordering in direct initialization for static variables 
and 
member variables makes it so that you avoid bugs like you get in some languages 
when you try to do something like

auto a = b;
auto b = 7;

and a ends up being garbage because the variables are being initialized in 
order 
and b hasn't been initialized yet. It also makes it potentially much faster to 
compile static and member variables, because they can actually be compiled in 
parallel instead of enforcing an ordering to them. And, of course, if you did 
something like

auto a = b;
auto b = a;

the circular dependency would screw you. If you have such ordering issues or if 
you need such variables to be mutable and yet able be initialized from one 
another, you need to use static constructors (which also work on immutable 
variables as long as you initialize them only once, though enums must still be 
known at compile time, so it doesn't work for them).


Now, for templates, the template itself depends on the values/types of its 
parameters. It's pure code generation. A classic example would be something like

struct Pair(T, U)
{
T first;
U second;
}

When you declare Pair!(int, float), the compiler creates code similar to

struct Pair!(int, float)
{
int first;
float second;
}

If you declared Pair!(double, double), then you'd get a second Pair struct type 
generated. Because code is being generated like this, the template parameters - 
be they types or values - must be known at compile time. So, the rules for what 
can be passed as a template argument are essentially the same as what can be 
used to initialize a static or member variable directly.


Now, with string mixins, you are also generating code. 

Re: import from subdir

2010-12-23 Thread Jonathan M Davis
On Thursday 23 December 2010 11:30:40 CrypticMetaphor wrote:
 On 12/23/2010 1:38 PM, spir wrote:
  Is there a way to import util  data from test?
 
 I think this should work:
 
 util.d first line:
   module util;
 
 data.d first line
   module data.data;
 
 test.d first lines
   module test.test;
   import util;
   import data.data;
 
 
 Disclaimer: I don't know if directory names and file names may overlap,
 maybe you should rename them.

That only works if test/test.d is the module test.test rather than test, and 
he's trying to compile from the parent directory rather than the test directory.

- Jonathan M Davis


Re: Vim: Anyone using taglist.vim with D?

2010-12-23 Thread Andrej Mitrovic
Got it working! I just needed to create an extra variable for
taglists. I'm using this:

let tlist_d_settings='d;c:classes;d:macro definitions;e:enumerators
(values inside an enumeration);f:function definitions;g:enumeration
names;l:local variables [off];m:class, struct, and union
members;M:module;n:namespaces;p:function prototypes [off];s:structure
names;t:typedefs;T:templates;u:union names;v:variable
definitions;x:external and forward variable declarations
[off];X:mixin;V:conditional compilation'

You can choose your own from the list ctags gives you with:
ctags --list-kinds=d

And more docs here: http://vim-taglist.sourceforge.net/extend.html

I'll add this to prowiki.

On 12/23/10, Andrej Mitrovic n...@none.none wrote:
 I know there's a few people here that use Vim, so has anyone succesfully
 used the taglist.vim plugin with D?

 Ctags work for me (on XP), but I can't get taglist to work with D. It does
 work with C/CPP files, but it seems to ignore D files.

 I'm asking before I try to modify the plugin, because either I have ctags
 set up wrong for D, or taglist simply won't work with D files, and there's a
 function in there called function! s:Tlist_Skip_File(filename, ftype)
 which looks tempting to modify.

 I can use ctags on D files already but not with the taglist plugin itself.

 P.S. I've uploaded a new Ctags Windows binary on the prowiki page, and added
 .di as another D file extension (i'll put up the patch later). I'm not sure
 how up-to-date the D2 support is in that 5.8 patch, for example some
 template functions are ignored in ctags. So I might update these soon.

 http://prowiki.org/wiki4d/wiki.cgi?ReferenceForTools/ExuberantCtags



Re: Undefined references when linking to C library

2010-12-23 Thread Jonathan M Davis
On Thursday 23 December 2010 11:38:28 Peter Federighi wrote:
 Jonathan M Davis wrote:
  Did you wrap the C declarations in an extern(C) block? Without that, it's
  going to think that your variables are D variables not C variables. The
  same goes for any functions - _especially_ for the functions. In fact, a
  large portion of - in not all of - your gpm.d file should likely be in
  extern(C).
 
 I tried extern (C) for the whole module and individually.  I get the
 following error:
 /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld:
 _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in
 /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section
 .data /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so:
 could not read symbols: Bad value
 collect2: ld returned 1 exit status
 --- errorlevel 1
 
 Is this a 32/64 bit issue?  I have both versions of libgpm installed. 
 Those file paths are obtuse, but they do point to the 32 bit libraries. 
 I've successfully compiled other programs that use C libraries such as SDL
 and OpenGL (both via the Derelict2 modules).
 
 I also tried htod and compared the output with what I wrote.  The
 differences are inconsequential.

Yeah. It looks like the compiler is finding the 64-bit versions rather than the 
32-bit versions. How to fix that will likely depend on the libraries in 
question 
and on how your system is set up. Obviously, a 32-bit chroot environment would 
fix the problem, but that's also obviously not a pleasant, or even necessarily 
simple, solution.

I'm not really all that well-versed in dealing with linking issues like this, 
but I'd say that either the compiler is just not finding the 32-bit versions, 
because of a messed up or missing path, or you need to be linking separately 
because you're on a 64-bit system (which I don't _think_ is the case, but it 
might be). Regardless, you can try compiling all of the code with -c and then 
linking it with gcc directly (probably with -m32).

Unfortunately, while I do run a 64-bit environment, due to problems with Arch 
and multilib systems, I've generally had to run dmd in a chrooted environment, 
and you don't have to deal with the 32-bit vs 64-bit issues with that, so I 
don't have much experience with this sort of problem. Regardless, I'll be very 
glad when the 64-bit port of dmd is completed.

- Jonathan M Davis


Re: Undefined references when linking to C library

2010-12-23 Thread Jérôme M. Berger
Peter Federighi wrote:
 Jonathan M Davis wrote:
 Did you wrap the C declarations in an extern(C) block? Without that, it's 
 going
 to think that your variables are D variables not C variables. The same goes 
 for
 any functions - _especially_ for the functions. In fact, a large portion of 
 - in
 not all of - your gpm.d file should likely be in extern(C).
 
 I tried extern (C) for the whole module and individually.  I get the 
 following
 error:
 /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld:
 _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in
 /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data
 /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read
 symbols: Bad value
 collect2: ld returned 1 exit status
 --- errorlevel 1
 
 Is this a 32/64 bit issue?  I have both versions of libgpm installed.  Those 
 file
 paths are obtuse, but they do point to the 32 bit libraries.  I've 
 successfully
 compiled other programs that use C libraries such as SDL and OpenGL (both via 
 the
 Derelict2 modules).
 
I think gpm_zerobased, _bpm_buf and _gpm_arg should be declared
__gshared.

Jerome
-- 
mailto:jeber...@free.fr
http://jeberger.free.fr
Jabber: jeber...@jabber.fr



signature.asc
Description: OpenPGP digital signature


Re: [D1] type of type

2010-12-23 Thread %u
Should have been this:

void func(type t){
  new t();
}




Re: DMD2 out parameters

2010-12-23 Thread Pete
I noticed this on an Intel Core 2. I skipped the pentium 4 generation :)


Re: Undefined references when linking to C library

2010-12-23 Thread wrzosk

On 23.12.2010 20:38, Peter Federighi wrote:

Jonathan M Davis wrote:

Did you wrap the C declarations in an extern(C) block? Without that, it's going
to think that your variables are D variables not C variables. The same goes for
any functions - _especially_ for the functions. In fact, a large portion of - in
not all of - your gpm.d file should likely be in extern(C).


I tried extern (C) for the whole module and individually.  I get the following
error:
/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld:
_gpm_arg: TLS reference in gev.o mismatches non-TLS definition in
/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data
/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read
symbols: Bad value
collect2: ld returned 1 exit status
--- errorlevel 1

Is this a 32/64 bit issue?  I have both versions of libgpm installed.  Those 
file
paths are obtuse, but they do point to the 32 bit libraries.  I've successfully
compiled other programs that use C libraries such as SDL and OpenGL (both via 
the
Derelict2 modules).

I also tried htod and compared the output with what I wrote.  The differences 
are
inconsequential.

Thank you,
- Peter Federighi


I've had simmilar issue a few days ago. The problem is that global 
values from C should be marked shared in D


extern int val; - extern (C) shared int val;

or maybe __gshared. Both makes linking stage finishes with success.


Re: Undefined references when linking to C library

2010-12-23 Thread Peter Federighi
wrzosk wrote:
 I've had simmilar issue a few days ago. The problem is that global values 
 from C
should be marked shared in D
 extern int val; - extern (C) shared int val;
 or maybe __gshared. Both makes linking stage finishes with success.

Jerome M. Berger wrote:
 I think gpm_zerobased, _bpm_buf and _gpm_arg should be declared __gshared.

Indeed.  So I added a bunch of __gshareds to all the variables and it compiles
and links.  Yah!  I just have to remember to declare handler functions with 
extern
(C), otherwise the program will segfault once the handler returns.

Where should I post/upload the files that I converted?  There are a whole two of
them:  One is gpm.h which is specific to libgpm.  The other is paths.h which I 
was
surprised to find not already available.  I would assume that it should be
available as std.c.linux.paths or core.sys.posix.paths.  Also, should the files
end with .d or .di  I may be the only person who wants to use libgpm with D, 
but I
figure it should be available just in case.

Thank you all for your help.
- Peter Federighi


Re: import from subdir

2010-12-23 Thread spir
On Thu, 23 Dec 2010 12:54:42 -0800
Jonathan M Davis jmdavisp...@gmx.com wrote:

 What you're trying to do is pretty abnormal really, as far as your average 
 module goes. I assume that you're writing a test app which needs access to 
 the 
 main body of code and are trying to find a way to point it to that code 
 without 
 mixing the two.

What is then abnormal in having test modules in their own dir? And indeed they 
need to import the module(s) they're supposed to test (and possibly ordinary 
and test data from another dir). AFAIK, this is very ordinary lib structuration 
for the sake of clarity. Dunno.

 The normal way to deal with that would be -I. The same goes for 
 C++ actually. Not to mention, you probably don't want your tests to rely on 
 where they are on disk in comparison to the rest of your code. If you later 
 want 
 to change where you put your test code, it could be a big hassle to have to 
 go 
 change all of your imports. Just use -I. It makes your test code properly 
 portable and is really the intended way to do the sort of thing that you're 
 trying to do.

Hem, I do not find a hassle to change one a few import once if ever I move a 
test module in the dir tree. But I find very unconvenient to have different 
compile/link command lines for every module just because of the lack of an 
importing syntax, requiring the use of -I. Instead of a command-line option, I 
would prefere to write it down once and for in the module itself. Maybe we 
could have something like
pathlevel 2;
saying that (when an imported module is not found) the indicated path is to be 
understood as relative to 2 dir levels higher (which would probably be the root 
of the lib).

By the way, when I write import data.foo, the language actually searches and 
inside /data (relative to the current module's dir) and find foo.d there. (Even 
if the module is not explicitely named at all.) So, there is still an implicite 
or default relationship between dir tree structure and module denomination. Or 
do I misinterpret your words?

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



Re: import from subdir

2010-12-23 Thread Jonathan M Davis
On Thursday 23 December 2010 16:42:15 spir wrote:
 On Thu, 23 Dec 2010 12:54:42 -0800
 
 Jonathan M Davis jmdavisp...@gmx.com wrote:
  What you're trying to do is pretty abnormal really, as far as your
  average module goes. I assume that you're writing a test app which needs
  access to the main body of code and are trying to find a way to point it
  to that code without mixing the two.
 
 What is then abnormal in having test modules in their own dir? And indeed
 they need to import the module(s) they're supposed to test (and possibly
 ordinary and test data from another dir). AFAIK, this is very ordinary lib
 structuration for the sake of clarity. Dunno.

What is abnormal is having your test code rely where your normal code is on 
disk. Also, depending on what you're doing for testing, normally you'd just 
have 
the unit tests alongside your normal code and do a unittest build to test your 
code. So, you wouldn't even need separate test code unless you're doing 
something more exotic that you don't want in your unit tests.

  The normal way to deal with that would be -I. The same goes for
  C++ actually. Not to mention, you probably don't want your tests to rely
  on where they are on disk in comparison to the rest of your code. If you
  later want to change where you put your test code, it could be a big
  hassle to have to go change all of your imports. Just use -I. It makes
  your test code properly portable and is really the intended way to do
  the sort of thing that you're trying to do.
 
 Hem, I do not find a hassle to change one a few import once if ever I move
 a test module in the dir tree. But I find very unconvenient to have
 different compile/link command lines for every module just because of the
 lack of an importing syntax, requiring the use of -I. Instead of a
 command-line option, I would prefere to write it down once and for in the
 module itself. Maybe we could have something like pathlevel 2;
 saying that (when an imported module is not found) the indicated path is to
 be understood as relative to 2 dir levels higher (which would probably be
 the root of the lib).
 
 By the way, when I write import data.foo, the language actually searches
 and inside /data (relative to the current module's dir) and find foo.d
 there. (Even if the module is not explicitely named at all.) So, there is
 still an implicite or default relationship between dir tree structure and
 module denomination. Or do I misinterpret your words?

You misunderstand. From the module's perspective, import foo.bar; imports a 
module with the name foo.bar. It knows that bar is in the foo package, so 
unless 
the module doing the importing is in the foo package, it can't access the 
package-restricted functions and types from foo.bar or any other module in foo. 
It knows that bar is the module. But it doesn't care at all about what that 
means for files on disk. Consider the fact that you can have this directory 
structure:

dir/dir1/foo/bar.d
dir/dir2/dir3/hello/world.d
dir/dir2/dir3/foo/silly.d

where you're compiling from dir/dir2/dir3 and have -I../../dir1/. bar.d and 
silly.d are considered to be in the same package in spite of the fact that the 
fact that they're in different directories. When hello.world imports foo.bar, 
it 
doesn't care that it's not in the same directory as foo.silly. If foo.silly 
calls a package-restricted function in foo.bar, it's allowed to because they're 
in the same package, but it doesn't care that they're not in the same directory.

The directory structure relates to the package hierarchy. The compiler finds 
files 
using that structure/hierarchy. It knows that if a module is importing foo.bar, 
that there is a directory foo either in  the directory where compilation is 
taking place or in one of the directories given by the -I flag, and it knows 
that 
bar.d (or bar.di) will be in the foo directory. If there are multiple such 
directories (because of the -I flag being used), then it knows that bar.d is in 
one of them (if it were in more than one, then there would be an ambiguity 
error). The package hiercharcy tells the compiler where the source files are.

However, the imports themselves don't care at all about the directory 
structure. 
As shown in the example above, you could have each module in a package in a 
different directory as long as it was in the appropriate place in the directory 
structure given all of the -I flags being used. So, importing has no concept of 
directories or files - only packages and modules. The compiler is able to 
translate that to directories and files, but the imports don't care about it. 
From the language's perspective, it would be perfectly possible to change it so 
that all files were always in the same directory but used dots to separate 
packages and modules:

dir/dir1/foo.bar.d
dir/dir2/dir3/hello.world.d
dir/dir2/dir3/foo.silly.d

Now, no compiler is going to function that way, but conceptually, it could. So, 
trying to use .. and the like in 

TDPL dictionary example - error

2010-12-23 Thread Caligo
Greetings,

I just joined here, so sorry if this has been posted before.

I'm reading TDPL and the example on page 8 doesn't compile.  I'm using the
latest GDC with GCC 4.4.5.  I've checked the errata, but nothing for this
error.

import std.stdio;
import std.string;

void main(){

 size_t[char[]] dictionary;
foreach(line; stdin.byLine()){
  foreach(word; splitter(strip(line))){
  if(word in dictionary) continue;
auto newID = dictionary.length;
  dictionary[word] = newID;
writeln(newID, '\t', word);
}
}
//writeln(dictionary.length);
}


This is the error:
dictionary.d:12: Error: associative arrays can only be assigned values with
immutable keys, not char[]

If i use immutable keys, it works, but it defeats the purpose.  So what's
wrong with the code?


Re: TDPL dictionary example - error

2010-12-23 Thread Mariusz Gliwiński
Friday 24 December 2010 @ 06:24:34 Caligo:
 Greetings,
 
 I just joined here, so sorry if this has been posted before.
 
 I'm reading TDPL and the example on page 8 doesn't compile.  I'm using the
 latest GDC with GCC 4.4.5.  I've checked the errata, but nothing for this
 error.
 
 import std.stdio;
 import std.string;
 
 void main(){
 
  size_t[char[]] dictionary;
 foreach(line; stdin.byLine()){
   foreach(word; splitter(strip(line))){
   if(word in dictionary) continue;
 auto newID = dictionary.length;
   dictionary[word] = newID;
 writeln(newID, '\t', word);
 }
 }
 //writeln(dictionary.length);
 }
 
 
 This is the error:
 dictionary.d:12: Error: associative arrays can only be assigned values with
 immutable keys, not char[]
 
 If i use immutable keys, it works, but it defeats the purpose.  So what's
 wrong with the code?

It works for DMD, I think it's a GDC bug (i'm new in D too, so i might be 
wrong). Keep in mind that GDC implements only D 1.0 and book has D 2.0 code.

Sincerely,
Mariusz Gliwiński


signature.asc
Description: This is a digitally signed message part.


Re: TDPL dictionary example - error

2010-12-23 Thread Caligo
No, GDC supports D1 and D2.  Version 2.051 I think.  I know I've compiled
mine with D2 support.

2010/12/24 Mariusz Gliwiński alienballa...@gmail.com

 Friday 24 December 2010 @ 06:24:34 Caligo:
  Greetings,
 
  I just joined here, so sorry if this has been posted before.
 
  I'm reading TDPL and the example on page 8 doesn't compile.  I'm using
 the
  latest GDC with GCC 4.4.5.  I've checked the errata, but nothing for this
  error.
 
  import std.stdio;
  import std.string;
 
  void main(){
 
   size_t[char[]] dictionary;
  foreach(line; stdin.byLine()){
foreach(word; splitter(strip(line))){
if(word in dictionary) continue;
  auto newID = dictionary.length;
dictionary[word] = newID;
  writeln(newID, '\t', word);
  }
  }
  //writeln(dictionary.length);
  }
 
 
  This is the error:
  dictionary.d:12: Error: associative arrays can only be assigned values
 with
  immutable keys, not char[]
 
  If i use immutable keys, it works, but it defeats the purpose.  So what's
  wrong with the code?

 It works for DMD, I think it's a GDC bug (i'm new in D too, so i might be
 wrong). Keep in mind that GDC implements only D 1.0 and book has D 2.0
 code.

 Sincerely,
 Mariusz Gliwiński