Re: Enumerating structs?

2012-01-04 Thread Heywood Floyd
> Yeah, D feels like that to me too, sometimes. Anyways, for your question -
> would using the struct name be good enough? They're easy to get hold of
> and usable in switch statements.
>
> If not, how about this:
>
>
> import std.typetuple;
>
> struct TypeEnum( T... ) {
> static pure nothrow @property
> int value( U )( ) {
> static assert ( staticIndexOf!( U, T ) != -1 );
> return staticIndexOf!( U, T );
> }
> }
>
> struct A {}
> struct B {}
>
> void main( ) {
> alias TypeEnum!(A, B) types;
>
> assert( types.value!A == 0 );
> assert( types.value!B == 1 );
> }

Ha, yes, that looks quite nice!
Thanks!

/HF


Enumerating structs?

2012-01-03 Thread Heywood Floyd

Hello!


I have some structs

  struct A { int a; }
  struct B { int b, c; }

and I'd like to be able to enumerate them (preferrably as integers) based on 
their names. I've no idea how this would look, but
some pseudo code that would use this feature:

  // pseudo
  int type = stream.read!int();
  switch(type){
case A.enumof:
  auto data = stream.read!A();
  // ...
break;
case B.enumof:
  // ...
break;
// ...

The idea here is to enable stuff like static if's etc and to enforce the 
connection between the struct and the enumeration. Right now
I have a separate enums, like so:

  enum {A_ENUM = 1, B_ENUM = 2};
  // ...
case A_ENUM:
   auto data = stream.read!A();
   // ...
break;
  //...

But this means the idea that struct A has the enumeration "1" is only by 
convention. So when I, for instance, refactor struct A to "C",
all code still compiles. It would be cool if it didn't, somehow. With this 
small example it's of course not a problem, but for larger
more complex code perhaps.

A naive idea I had was to let each struct have an enum:

  struct A{
enum TYPE_ENUM = 1;
int a;
  }

That would be refactor-friendly and be a strong connection, but then there's no 
guarantee two structs don't have the same enum,
of course. Another idea was to maybe use mixin to somehow construct the enum 
declaration:

  mixin enumByType!(A,B);

That could generate code like:

  enum {A_ENUM = 1, ...}

and then couple it with a

   // ...
   case typeEnumFor!A():
   //...
   break;
   // ...

but now it's starting to maybe feel a bit overkill?
Is there an easier/correct/other way?

-

I usually end up feeling like this a lot with D, I just realized. It's like, 
yes, with mixins I can more or less do anything, but where
does one stop? You know what I mean? I like it though. Mixin-paralysis : )


/HF











Re: Catching signals with D

2011-12-22 Thread Heywood Floyd

On 12/22/11 23:51 , Matej Nanut wrote:

Hello everyone, I've been fascinated by D lately and have been using it
for all
my school assignments (like simple ray casting and simulated annealing).

What I can't find anywhere is how to do something like
"signal(SIGINT, myhandler)" (I'm in a Linux environment).

I need this to stop the annealing process early but still keep the
current best
result. Is there a better way to interrupt my program?

Thanks!
Matej

P.s. I hope I sent this to the appropriate address. :)


Hi!

I don't know of any official way, but since D links against the c 
runtime you can just hook up functions from there, I believe. This works 
on osx at least:



import  std.stdio;

extern(C) void signal(int sig, void function(int) );

// Our handler, callable by C
extern(C) void handle(int sig){
writeln("Signal:",sig);
}

void main()
{
enum SIGINT = 2; // OS-specific

signal(SIGINT,&handle);
writeln("Hello!");
readln();
writeln("End!");
}



$ rdmd sig.d
Hello!
^CSignal:2
^CSignal:2

End!
$ _



/HF




Re: d2 file input performance

2011-08-28 Thread Heywood Floyd
Christian Köstlin Wrote:
> after some optimizing i got better, but was still way slower than c++. 
> so i started some small microbenchmarks regarding fileio: 
> https://github.com/gizmomogwai/performance in c++, java and d2.
> 
> christian


Hello!

Thanks for you effort in putting this together!


I found this interesting and played around with some of your code examples.
My findings differ somewhat from yours, so I thought I'd post them.



>From what I can tell, G++ does generate almost twice (~1.9x) as fast code, in 
>the fread()/File-example, as DMD. Even though the D-code does handle errors 
>encountered by fread(), that certainly can't explain the dramatic difference 
>in speed alone.

It would be very interesting to see how GDC and LDC perform in these tests!! (I 
don't have them installed.)



Anyway, here are my notes:

I concentrated on the G++-fread-example and the DMD-File-example, as they seem 
comparable enough. However, I did some changes to the benchmark in order to 
"level" the playing field:

  1) Made sure both C++ and D used a 1 kb (fixed-size) buffer
  2) Made sure the underlying setvbuf() buffer is the same (64 kb)
  3) Made sure the read data has an actual side effect by printing out the 
accumulated data after each file. (Cheapo CRC)

The last point, 3, particularly seemed to make the G++-example considerably 
slower, perhaps hinting G++ is otherwise doing some clever optimization here. 
The second point, 2, seemed to have no effect on C++, but it helped somewhat 
for D. This may hint at C++ doing its own buffering or something. (?) In that 
case the benchmark is bogus.

Anyway, these are the results:

(G++ 4.2.1, fread()+crc, osx)
G++ 1135 ms (no flags)
G++ 399 ms  -O1
G++ 368 ms  -O2
G++ 368 ms  -O3
G++nofx 156 ms  -O3 (Disqualified!)

(DMD 2.054, rawRead()+crc, osx)
DMD 995 ms  (no flags)
DMD 913 ms  -O
DMD 888 ms  -release
DMD 713 ms  -release -O -inline
DMD 703 ms  -release -O
DMD 693 ms  -release -O -inline -noboundscheck

Well, I suppose a possible (and to me plausable) explanation is that G++'s 
optimizations are a lot more extensive than DMD's.

Skipping printing out the CRC-value ("nofx") makes the C++ code more than twice 
as fast. Note that the code calculating the CRC-value is still in place, the 
value is just not printed out, and surely, calling printf() 10 times can hardly 
account for a 200 ms increase. (?) I think it's safe to assume code is simply 
being ignored here, as it's not having any side effect.

My gut feel is DMD is not doing inlining, at least not to the same extent G++ 
is, as that seems to be especially important since we're making a function call 
for every single byte here. (Using the -inline flag even seems to make the D 
code slower. Weird.) But of course I don't really know. Again, GDC and LDC 
would be interesting to see here.

Finally, to this I must add the size of the generated binary:

G++   15 kb
DMD   882 kb

Yikes. I believe there's nothing (large enough) to hide behind for DMD there.



That's it!
Kind regards
/HF





Here's the modifed code: (Original https://github.com/gizmomogwai/performance)

// - - - - - - 8< - - - - - - 

import  std.stdio,
std.datetime,
core.stdc.stdio;

struct FileReader
{
private:
File file;

enum BUFFER_SIZE = 1024;
ubyte[BUFFER_SIZE] readBuf;
size_t pos, len;

this(string name){
file = File(name, "rb");
//setbuf(file.getFP(), null); // No buffer
setvbuf(file.getFP(), null, _IOFBF, BUFFER_SIZE * 64);
}

bool fillBuffer()
{
auto tmpBuf = file.rawRead(readBuf);
len = tmpBuf.length;
pos = 0;
return len > 0;
}

public: 
int read()
{
if(pos == len){
if(fillBuffer() == false)
return -1;
}
return readBuf[pos++];
}
}

size_t readBytes()
{
size_t count = 0;
ulong crc = 0;
for (int i=0; i<10; i++) {
auto file = FileReader("/tmp/shop_with_ids.pb");
auto data = file.read();
while(data != -1){
count++;
crc += data;
data = file.read();
}
writeln(crc);
}
return count;
}


int main(string[] args) {
  auto sw = StopWatch(AutoStart.no);
  sw.start();
  auto count = readBytes();
  sw.stop();
  writeln("d2-6-B", count, "", sw.peek().msecs, 
"using s

Re: Create a foreach-able struct? Multi-dimensional even?

2011-08-25 Thread Heywood Floyd
Christophe Wrote:

> > Still, is the multi-dimensional part possible?
> 
> Sure, you have to make an opApply that takes several parameters in its 
> delegate.
> An exemple:
> 
> struct TwoDArray(int nx, int ny)
> {
>   int[nx][ny] data;
> 
>   int opApply(int delegate(ref int i, ref int j, ref int cell)
> {
>   foreach (i; 0..nx)
> foreach (j; 0..ny)
>   {
> int result = dg(i, j, data[i][j]);
> if (result != 0) return result;
>   }
>return 0;
> }
> }
> 
> 
> // this program prints a multiplication table:
> int main()
> {
>   TwoDArray!(10, 10) data;
>   
>   foreach(i, j, ref cell; data)
> {
>   cell = i * j;
> }
> 
>   foreach(i, j, cell; data)
> {
>   writefln("%s * %s = %s", i, j, cell);
> }
>   return 0;
> }
> 


Ha! Beautiful, thanks!!



Re: Create a foreach-able struct? Multi-dimensional even?

2011-08-25 Thread Heywood Floyd
Heywood Floyd Wrote:

> 
> Hello!
> 
> 1) How do I create a struct that I can foreach over?
> 
> I get the impression opApply has something do to with this, but I can't find 
> any documentation on it? (And I'm abroad without my TDPL.)
> 
> 
> 2) Also, is it possible to do something like this? 
> 
>   MyData!(100,100,100) data;
>   foreach(x, y, z, ref cell; data){
>  cell = x*y*z;
>   }
> 
> (The idea here is cells are stored in a plain 1-dimensional array behind the 
> scenes, but iterated as a 3-dimensional array.)
> 
> 
> Kind regards
> /HF


Ah, I'm sorry, I found the documentation regarding opApply() now. Typical. (The 
site-search didn't seem to work there. Ok..)

Still, is the multi-dimensional part possible?

/HF


Create a foreach-able struct? Multi-dimensional even?

2011-08-25 Thread Heywood Floyd

Hello!

1) How do I create a struct that I can foreach over?

I get the impression opApply has something do to with this, but I can't find 
any documentation on it? (And I'm abroad without my TDPL.)


2) Also, is it possible to do something like this? 

  MyData!(100,100,100) data;
  foreach(x, y, z, ref cell; data){
 cell = x*y*z;
  }

(The idea here is cells are stored in a plain 1-dimensional array behind the 
scenes, but iterated as a 3-dimensional array.)


Kind regards
/HF


Re: Get address of label?

2010-12-26 Thread Heywood Floyd

Thank you bearophile and Simen for your replies! Very helpful! 
I'll keep looking into it...

BR
/HF



bearophile Wrote:

> Simen kjaeraas:
> 
> > Essentially, mark the switch as final, and cover every option.
> > Likely, the optimizer does that for you if you cover every option but
> > don't mark the switch as final.
> 
> This is true in theory, and I remember Walter liking this optimization. But 
> in practice I don't know if DMD performs this optimization already, so you 
> need to take a look at the produced asm to be sure.
> 
> 
> 
> This is a little test, D2 code:
> 
> enum E { e1, e2, e3 }
> 
> int foo1(E e) {
> switch (e) {
> case E.e1: return 1;
> case E.e2: return 2;
> case E.e3: return 3;
> default: assert(0);
> }
> }
> 
> int foo2(E e) {
> switch (e) {
> case E.e1: return 1;
> case E.e2: return 2;
> default: return 3;
> }
> }
> 
> int foo3(E e) {
> final switch (e) {
> case E.e1: return 1;
> case E.e2: return 2;
> case E.e3: return 3;
> }
> }
> void main() {}
> 
> 
> _D5test4foo1FE5test31EZi
> push EAX
> test EAX,EAX
> je  L11
> cmp EAX,1
> je  L18
> cmp EAX,2
> je  L1F
> jmp short L26
> L11:pop ECX
> mov EAX,1
> ret
> L18:pop ECX
> mov EAX,2
> ret
> L1F:pop ECX
> mov EAX,3
> ret
> L26:hlt
> 
> _D5test4foo2FE5test31EZi
> push EAX
> test EAX,EAX
> je  LC
> cmp EAX,1
> je  L13
> jmp short L1A
> LC: pop ECX
> mov EAX,1
> ret
> L13:pop ECX
> mov EAX,2
> ret
> L1A:pop ECX
> mov EAX,3
> ret
> 
> _D5test4foo3FE5test31EZi
> push EAX
> test EAX,EAX
> je  L11
> cmp EAX,1
> je  L18
> cmp EAX,2
> je  L1F
> jmp short L26
> L11:pop ECX
> mov EAX,1
> ret
> L18:pop ECX
> mov EAX,2
> ret
> L1F:pop ECX
> mov EAX,3
> ret
> L26:pop EAX
> ret
> 
> 
> 
> Some C code compiled with GCC 4.5.1:
> 
> typedef enum { e1, e2, e3 } E;
> 
> int foo2(E e) {
> switch (e) {
> case e1: return 1;
> case e2: return 2;
> default: return 3;
> }
> }
> 
> int foo3(E e) {
> switch (e) {
> case e1: return 1;
> case e2: return 2;
> case e3: return 3;
> }
> }
> 
> int foo4(E e) {
> static void *array[] = { &&E1, &&E2, &&E3 };
> 
> goto *array[e];
> 
> E1: return 1;
> E2: return 2;
> E3: return 3;
> }
> 
> int main() {
> return 0;
> }
> 
> 
> _foo2:
> movl4(%esp), %edx
> movl$3, %eax
> cmpl$1, %edx
> jbe L5
> rep
> ret
> .p2align 4,,7
> L5:
> movl_CSWTCH.1(,%edx,4), %eax
> ret
> .p2align 4,,15
> 
> _foo3:
> movl4(%esp), %edx
> cmpl$1, %edx
> je  L11
> movl$1, %eax
> jb  L6
> cmpl$2, %edx
> je  L13
> .p2align 4,,3
> rep
> ret
> .p2align 4,,7
> L11:
> movl$2, %eax
> L6:
> .p2align 4,,3
> rep
> ret
> .p2align 4,,7
> L13:
> movb$3, %al
> ret
> 
> _foo4:
>   movl4(%esp), %eax
>   jmp *_array.1639(,%eax,4)
>   .p2align 4,,7
> L15:
>   movl$1, %eax
>   ret
>   .p2align 4,,7
> L17:
>   movl$2, %eax
>   ret
>   .p2align 4,,7
> L18:
>   movl$3, %eax
>   ret
> 
> 
> 
> > My forays into the inline asm idea proved fruitless, but there may yet be 
> > ways.
> 
> In D+DMD inline asm kills inlining, so you may use inline asm only if you 
> need to do lot of computations.
> In LDC there are pragma(allow_inline) and asm expressions that some most of 
> this problem.
> 
> Going back to the OP problem: in D there are no computed gotos, that are 
> useful if you want to write very fast interpreters and other things. But keep 
> in mind that DMD supports normal gotos from and in inlined asm (LLVM-LDC 
> doesn't supports this well), plus naked asm, this gives you some 
> possibilities.
> An option on Linux is to write the interpreter core using GNU C (that has 
> computed gotos) and then link the core to the D code compiled with DMD/GDC.
> 
> It's strange how something as basic, old and necessary as a switch, to create 
> a basic but fast interpreter, is so hard to compile well for compilers :-)
> 
> Bye,
> bearophile



Re: Get address of label?

2010-12-25 Thread Heywood Floyd


Thanks for the answer!
Ok, hm, how about this then:

auto opTable = [&op_add, &op_cmp, &op_end]; //etc.

ubyte[] eval(ubyte[] prog)
{
int ip = 0, sp = 0;
ubyte[4096] stack;

next:
goto opTable[prog[ip++] & OP_TABLE_MASK];

op_add:
stack[sp] += stack[sp-1];
goto next;

op_cmp:
stack[sp] = stack[sp-1] == stack[sp-2];
goto next;

/// and so on...

op_end:
return stack;
}


What I'm looking for here is a way of interpreting code without creating 
branches in the machine code, unless the interpreted code actually does a 
branch (ie a conditional jump). Seems to me a switch would introduce branching 
(?) of some sort.

I mean, even if switch is implemented as a jump table, it would still do some 
basic bounds checking, or?

I'm also interested in trying to inline the "next"-operation here, ie like

string op_next(){ return "goto opTable[prog[ip++] & OP_TABLE_MASK];"; }
//...
op_add:
stack[sp] += stack[sp-1];
mixin(op_next());

..in order to reduce a jump. Of course I'm just playing around with different 
strategies for creating a fast interepreter. In C, at least, using a jump table 
instead of a switch is faster, especially in 32-bit mode (according to some 
very simple experiments, which may or may not hold water in reality™).

Any ideas for how to make a jump-table interpreter in D? Is it doable with 
inline asm perhaps? If at least not for any other reason than to investigate if 
it's faster. (Or is it a stupid idea to begin with? Is this overkill? : )

cheers!
BR
/HF


PS. How do you export assembler code from the DMD-compiler?










Simen kjaeraas Wrote:

> Heywood Floyd  wrote:
> 
> > Is this possible somehow:
> >  int op(int r, int i)
> > {
> > static auto tbl = [&add, &sub, &mul];
> > goto tbl[i % 3];
> >add:
> > r++;
> > goto end;
> > sub:
> > r--;
> > goto end;
> > mul:
> > r*=r;
> > goto end;
> > end:
> > return r;
> > }
> 
> Absolutely:
> 
> enum ops : int {
>  add = 0,
>  sub = 1,
>  mul = 2;
> }
> 
> int op( int r, int i ) {
>  switch( i % 3 ) {
>  case add:
>  r++;
>  break;
>  case sub:
>  r--;
>  break;
>  case mul:
>  r*=r;
>  break;
>  }
>  return r;
> }
> 
> -- 
> Simen



Get address of label?

2010-12-25 Thread Heywood Floyd

Is this possible somehow:

int op(int r, int i)
{
static auto tbl = [&add, &sub, &mul];
goto tbl[i % 3];

add:
r++;
goto end;
sub:
r--;
goto end;
mul:
r*=r;
goto end;
end:
return r;
}

Happy holidays!
BR
/HF




Re: Is libdruntime deprecated in 2.051?

2010-12-24 Thread Heywood Floyd


Quick 2.051 D for Xcode fix:

Open 
   /Library/Application Support/Developer/Shared/Xcode/Plug-ins/
And do Show contents on the 'D for Xcode.xcplugin"-bundle and then open
   ./Contents/Resources/dmd2.pblinkspec
and change the line
   CommandLineArgs = { NO = (); "<>" = 
("/usr/local/lib/libphobos2.a", "/usr/local/lib/libdruntime.a"); };
to
   CommandLineArgs = { NO = (); "<>" = 
("/usr/local/lib/libphobos2.a"); };
and restart Xcode.

(Sorry for the boring post. Just documenting for future reference.)

BR
/HF



Heywood Floyd Wrote:

> 
> Build fails after upgrade to 2.051 with gcc saying
>   /usr/local/lib/libdruntime.a: No such file or directory
> 
> And indeed, the file is gone!
> 
> This is XCode with D for XCode plugin, so it assumes stuff about the build 
> tools. Using dmd from the command line works, and running it with '-v' it 
> seems it only links in phobos2? (and some other minor libs..) I can't find 
> libdruntime in the Linux-folder either, although the README-file there lists 
> it?
> 
> Is libdruntime no more?
> 
> (And if that's the case, does anyone know how to fix this is in the D for 
> XCode plugin?)
> 
> BR
> Happy holidays!
> /HF



Is libdruntime deprecated in 2.051?

2010-12-24 Thread Heywood Floyd

Build fails after upgrade to 2.051 with gcc saying
  /usr/local/lib/libdruntime.a: No such file or directory

And indeed, the file is gone!

This is XCode with D for XCode plugin, so it assumes stuff about the build 
tools. Using dmd from the command line works, and running it with '-v' it seems 
it only links in phobos2? (and some other minor libs..) I can't find 
libdruntime in the Linux-folder either, although the README-file there lists it?

Is libdruntime no more?

(And if that's the case, does anyone know how to fix this is in the D for XCode 
plugin?)

BR
Happy holidays!
/HF


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 

Re: Strange socket error

2010-12-22 Thread Heywood Floyd
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 fall straight through the
> accept call even when I am not making any connection attempt. When I do
> connect the stream stops and I get one of these outputs each time I send
> data from the browser. I should not even be near the accept at that
> point as the connection is made.
> 
> The app appears to be unaffected and works as expected. The odd think is
> if I shut down part of the app these errors stop. I can't tie it down to
> any specific thing but I suspect threading as the number of threads is
> reduced by stopping parts of the app. The error also seems to indicate
> threads are involved. I did not get this problem on Windows.
> 
> Any ideas would be much appreciated.
> 
> Thanks
> bob



Concurrency and transfering "ownership" of data between threads?

2010-12-13 Thread Heywood Floyd
Good Evening from Berlin!


Have been reading the chapter about concurrency by Andrei. Nice.

I have some questions, of varying quality, I'm sure.


Let's say that we have some sort of structure of rather complex data. To give 
us something concrete to talk about, let's say this data is a tree of nodes 
representing 3-dimensional objects. It could look something like this: (Not 
complete example, just to give an idea.)

// ...
class Cube : Node{
   float x, y, z, size, mass, elasticity;
   // ...
}
// ...
tree.add(new Cube("cube1"));
tree["cube1"].add(new Cube("cube2"));

Let's further say that this structure of data will be subjected to two 
different activities: 1) We will change properties of some nodes according to 
some complex lengthy calculations, which may even entail changing the position 
of nodes in the tree, and 2) we will traverse the tree in a recursive manner 
and read the properties in order to render a representation of these nodes to 
screen. 

These two activities will then be repeated many times, so, let's say we wish to 
do these two activities in parallel as much as possible!

How do we do that?

>From what I can tell, one way of doing this would be to actually have two data 
>structures, one which is the "original" and is used for the calculations, and 
>one which is just a copy of the data after each calculation. We could then 
>insert a third activity, which me can call "copy", inbetween the two threads. 
>Something like this:

|== Calculate ===| Copy |
   |v   |= Render |

Seems to me this would then allow us to interlock these two activites:

..|== Calculate ===| Copy |== Calculate |..
..|=== Render  ===|v   |=== Render |..

(Sorry if the ASCII graphics looks skewed.)
So let me just try and set up some kind of rudamentary code for this in 
layman's D:

// import ...
void main()
{
auto tree = new Node();
tree.add(new Cube("cube1"));

auto child = spawn(&renderLoop, thisTid);

while(true)
{
calc(tree);
auto treeCopy = tree.deepDup();
receiveOnly!bool();
send(child, treeCopy);
}
}

void renderLoop(Tid parent){
{
send(parent, true);
while(true)
{
Node tree = receiveOnly!Node();
render(tree);
send(parent, true);
}
}


So a couple of thoughts here. 

- Is this looking ok? What is the "proper" way of going about this?

- How do we send over a large chunk of complex data to another thread and sort 
of let them assume "ownership" of this data? So that the thread receiving the 
data does not need any locks etc. when working with the data? I suppose we 
could send over the entire treeCopy as immutable (?) but let's for the sake of 
argument assume that renderLoop() needs to be able to _write_ in the copy of 
the tree structure too!

(- Sidenote: How do we efficiently copy a tree-structure of data several times 
per second? Sounds insane to me?)

Let's further, for the sake of argument, NOT consider that the GPU will do most 
of the rendering and that in effect parallelising in this particular case may 
be marginally beneficial. Let's simply assume we have only one processor here: 
your normal household dual-core CPU, and a VGA-graphics card from the 80s.

For me, in my head, parallelising is very much about designing a flow of data 
through different processes, and this flow chart will have certain "hot spots" 
where data must be guarded. You have one process doing something and then 
"transfering over" some data to the next process that continues the 
calculations. (With process I simply mean data processing activity, not a "unix 
process".)

|---calc A--->Ocalc C> etc.
|---calc B-^

O = transfer point

I find it difficult to see how this is done in D. (Of course, I'm not sure this 
"transfer"-idea makes any practical sense.) I understand immutable makes data 
read-only, contagiously, and shared makes data heavily guarded. 

But yes, is there any way we can transfer "ownership" (not sure if that is the 
right term) of data from one thread to another? So that we can have two threads 
working on two pieces data, then let them copy it (or not!), and then transfer 
ownership and have a third thread work on the copied data, without barriers or 
guards or stuff like that during the time of actual work?


Kind regards and sorry for a lengthy sporadic post
/Heywood Floyd






Re: atomicOp problem

2010-10-21 Thread Heywood Floyd

Interesting!
I get the same result, ie an infinite loop, with the CPU at 100%

Some things I noticed:
- Changing the for-loops to 100 or 10 doesn't help.
- Changing the atomicOp from "+=" to just "+" makes it work (although the 
account doesn't get changed)
- Adding a Thread.sleep(1000) in one of the for-loops, before the call to 
atomic-op, makes it all work with "+=" as well


By looking at the code in atomic.d it looks the "+="-operator ends up here:

// L#131..:
T get, set;
do
{
get = set = atomicLoad!(msync.raw)( val );
mixin( "set " ~ op ~ " mod;" );
} while( !cas( &val, get, set ) );
return set;


And I suppose the cas()-function never returns true?

I don't know how atomic is supposed to work, so I'm not sure if it's a bug or 
not. I'm no expert with D, or threading for that matter, so I don't know.  (I'm 
just an expert guesser : ) 

I guess bug!


BR
/HF








Benjamin Thaut Wrote:

> I recently read the book "the D programming language" and wanted to try 
> out a few of the multithreaded examples pointed out in this book. I 
> tried to write a version of the bank account example using the atomicOp 
> from core.atomic. But when I compile it, it never finishes, it just gets 
> stuck in a endless loop inside atomic.d I think.
> Here is the code:
> 
> import std.stdio;
> import std.concurrency;
> 
> enum Messages {
>   GO
> }
> 
> shared class Account {
>   private float amount = 0;
>   
>   float getAmount() const {
>   return amount;
>   }
>   
>   void change(float change){
>   atomicOp!"+="(amount,change);
>   }
> }
> 
> shared Account bank = null;
>   
> void otherThread(Tid father){
>   send(father,Messages.GO);
>   for(int i=0;i<1000;i++)
>   bank.change(-100);
> }
> 
> void main(string[] args)
> {
>   bank = new Account();
>   spawn(&otherThread,thisTid);
>   receiveOnly!(Messages)();
>   for(int i=0;i<1000;i++)
>   bank.change(+100);
>   writefln("Program finished. Amount is %s",bank.getAmount());
> }
> 
> If you could please point out what I did wrong I would be very glad. If 
> I did not do anything wrong, I don't quite understand whats the exact 
> problem because the code inside atomic.d looks good (at least at my 
> level of understanding)
> 
> -- 
> Kind Regards
> Benjamin Thaut



Re: Stripping D symbols?

2010-10-16 Thread Heywood Floyd


..got it solved at last.. \o/
Just writing it down here for future reference (since I found nothing when 
googling etc..)




Strip can not manage this by itself. The linker, ld (el-dee) needs to be run 
with the "-exported_symbols_list"-option and given an empty file. Then the 
symbols created by dmd are treated as local, or whatever it is, and then strip 
can successfully strip them out. If CLI is used then a stripped binary can be 
created like this: (#-lines are treated as comments in the exported symbols 
file.)

   # echo "#empty symbols list for d-code stripping" > symlist
   # dmd -L-exported_symbols_list -Lsymlist myprog
   # strip myprog

If XCode is used (with the D for Xcode plugin) an empty file can be put in the 
project root and then the "Exported Symbols File"-build property (for Release) 
can be set to the name of this file. Then, lastly a new Build Phase: Run Script 
can be added with the code

   strip build/Release/MyApp.app/Contents/MacOS/MyApp

If the target is an OSX-app named MyApp. 
Hope it helps someone at some point... :)


Toodiloo!
BR
/HF





Heywood Floyd Wrote:

> 
> 
> ..ok, I got bored and installed Ubuntu I tried it, and there it worked fine!
> 
> # strip sym
> # nm sym | grep Bunny
> nm: sym: no symbols
> # _
> 
> 
> Great! The program runs fine too.
> (And the binary went from a size of 399Kb to 191Kb! Woah! That's more than 
> half gone!)
> 
> Hm, but how to I go about his now? Seems the OSX-strip is acting funny? Or 
> could it have something to do with DMD still? Maybe I should ask in some 
> darwin-forum about strip... 
> 
> BR
> /HF
> 
> 
> 
> 
> 
> 
> Heywood Floyd Wrote:
> 
> > Hello!
> > 
> > I've been trying to strip an executable created with DMD from symbols. Has 
> > anyone any experience with this?
> > 
> > I can't seem to rid my execs of more or less containing the entire 
> > class-tree. Example:
> > 
> > // sym.d - - - -
> > import std.stdio;
> > class Bunny{
> > int x;
> > int getX()
> > {
> > return x;
> > }
> > }
> > void main()
> > {
> > auto b = new Bunny();
> > writefln("Hello %d", b.getX() );
> > }
> > 
> > // - - - - - (OSX 10.6)
> > 
> > # dmd -release sym
> > # strip sym
> > # nm sym | grep Bunny
> > 28c8 T _D3sym5Bunny4getXMFZi
> > # _
> > 
> > // - - - - -
> > 
> > This was of course a simplified example. I tried putting "private" in front 
> > of the class, but that didn't change anything.
> > 
> > Any ideas? I'm just lost. Is it the same on Linux?
> > 
> > Or maybe this is one of those "features" that allows D to call functions by 
> > name or something? I see "T" is a text entry, by reading the man-pages..
> > 
> > (I suppose it really doesn't matter, but if possible I'd like to not expose 
> > function and class names in my binaries, for (I think) obvious reasons.)
> > 
> > 
> > Kind regards
> > /HF
> > 
> > 
> > 
> > 
> 



Re: Stripping D symbols?

2010-10-16 Thread Heywood Floyd


..ok, I got bored and installed Ubuntu I tried it, and there it worked fine!

# strip sym
# nm sym | grep Bunny
nm: sym: no symbols
# _


Great! The program runs fine too.
(And the binary went from a size of 399Kb to 191Kb! Woah! That's more than half 
gone!)

Hm, but how to I go about his now? Seems the OSX-strip is acting funny? Or 
could it have something to do with DMD still? Maybe I should ask in some 
darwin-forum about strip... 

BR
/HF






Heywood Floyd Wrote:

> Hello!
> 
> I've been trying to strip an executable created with DMD from symbols. Has 
> anyone any experience with this?
> 
> I can't seem to rid my execs of more or less containing the entire 
> class-tree. Example:
> 
> // sym.d - - - -
> import std.stdio;
> class Bunny{
>   int x;
>   int getX()
>   {
>   return x;
>   }
> }
> void main()
> {
>   auto b = new Bunny();
>   writefln("Hello %d", b.getX() );
> }
> 
> // - - - - - (OSX 10.6)
> 
> # dmd -release sym
> # strip sym
> # nm sym | grep Bunny
> 28c8 T _D3sym5Bunny4getXMFZi
> # _
> 
> // - - - - -
> 
> This was of course a simplified example. I tried putting "private" in front 
> of the class, but that didn't change anything.
> 
> Any ideas? I'm just lost. Is it the same on Linux?
> 
> Or maybe this is one of those "features" that allows D to call functions by 
> name or something? I see "T" is a text entry, by reading the man-pages..
> 
> (I suppose it really doesn't matter, but if possible I'd like to not expose 
> function and class names in my binaries, for (I think) obvious reasons.)
> 
> 
> Kind regards
> /HF
> 
> 
> 
> 



Stripping D symbols?

2010-10-16 Thread Heywood Floyd
Hello!

I've been trying to strip an executable created with DMD from symbols. Has 
anyone any experience with this?

I can't seem to rid my execs of more or less containing the entire class-tree. 
Example:

// sym.d - - - -
import std.stdio;
class Bunny{
int x;
int getX()
{
return x;
}
}
void main()
{
auto b = new Bunny();
writefln("Hello %d", b.getX() );
}

// - - - - - (OSX 10.6)

# dmd -release sym
# strip sym
# nm sym | grep Bunny
28c8 T _D3sym5Bunny4getXMFZi
# _

// - - - - -

This was of course a simplified example. I tried putting "private" in front of 
the class, but that didn't change anything.

Any ideas? I'm just lost. Is it the same on Linux?

Or maybe this is one of those "features" that allows D to call functions by 
name or something? I see "T" is a text entry, by reading the man-pages..

(I suppose it really doesn't matter, but if possible I'd like to not expose 
function and class names in my binaries, for (I think) obvious reasons.)


Kind regards
/HF






Re: Linking D and Obj-C code into a Cocoa app proper? (Mac)

2010-10-05 Thread Heywood Floyd

Ok! Thanks for the advice! Great work on the plugin—it got me into D :)

/FH

Michel Fortin Wrote:

> On 2010-10-05 10:02:45 -0400, Heywood Floyd  said:
> 
> > But, sometimes I get reeeaally weird bugs. I had one bug where if I 
> > added an empty function to a class in D I got EXC_BAD_ACCES (segfault). 
> > An empty function! Ie "void f(){}". Remove the function--it works. In 
> > the debugger, I got the impression maybe the stack has got messed up, 
> > but I don't know, the debugger just shows assembler code, and I don't 
> > have the proper skills.
> 
> It's hard to say without further details, but it could be that you're 
> not recompiling everything that uses the class where you add a 
> function. Unlike in Objective-C, adding a function to a D class breaks 
> most compiled code that uses that class (because you're adding an 
> offset to the virtual function table), so you need to recompile every D 
> module that uses that class (or a derived class).
> 
> Note that this is totally unrelated to having Objective-C code in the 
> same program.
> 
> 
> > This got really frustrating, needless to say, so I started playing 
> > around with the build settings. I switched from using LLVM 1.5 (for the 
> > obj-c code) to gcc 4.2. And now it magically seems to work!
> 
> Are you using D for Xcode? By doing that you basically force everything 
> to be recompiled, which solves problem described above.
> 
> 
> > [...]
> > 
> > == Question ==
> > How do you make D code and Obj-C code coexist? That is, I want to write 
> > a Cocoa-app that is mostly written in D, and with a little "glue"-code 
> > in Objective-C. How do you set that up? Is it even supposed to be 
> > possible?
> 
> It is totally possible, and not that hard. Communicating via `extern 
> (C)` functions should work well.
> 
> 
> > (And what could the bug above be? I know LLVM does link-time 
> > optimizations, and even run-time optimizations. Could it be that it 
> > messes things up?)
> 
> I doubt LLVM optimizations have anything to do with your problem. 
> Things to keep in mind when mixing Objective-C:
> 
> 1. Apple's Objective-C GC isn't supported by D, so you it's probably 
> safer to use manual memory management (retain/release) on the 
> Objective-C site.
> 
> 2. Exceptions are not compatible between the two runtimes. Throwing can 
> cause unexpected results when it unwinds stack frames in the other 
> language.
> 
> 
> -- 
> Michel Fortin
> michel.for...@michelf.com
> http://michelf.com/
> 



Linking D and Obj-C code into a Cocoa app proper? (Mac)

2010-10-05 Thread Heywood Floyd


Good Evenening Ladies and Gentlemen!



== Background ==
So I currently have a bare-bones Cocoa-app. It's just a window with an 
OpenGL-view. In the view's draw-function I make the gl-view the current OpenGL 
context and then call "extern (C) render()". Meanwhile, in a D-file I have the 
implementation for this function. Here I've copied all the function names from 
opengl.h and declared them in the D-file ("extern (C) glBlabla()" etc) so I can 
call glBegin etc from my render()-function in D. This is all in XCode and I use 
Michel Fortin's "D for XCode"-plugin btw.

This works great! The window paint triangles and what have you. Pretty! 
Happiness!

But, sometimes I get reeeaally weird bugs. I had one bug where if I added an 
empty function to a class in D I got EXC_BAD_ACCES (segfault). An empty 
function! Ie "void f(){}". Remove the function--it works. In the debugger, I 
got the impression maybe the stack has got messed up, but I don't know, the 
debugger just shows assembler code, and I don't have the proper skills.

This got really frustrating, needless to say, so I started playing around with 
the build settings. I switched from using LLVM 1.5 (for the obj-c code) to gcc 
4.2. And now it magically seems to work!

Ok. But as you might understand, the frustration is not quite gone. Adding a 
function now feels like a spinning a wheel of fortune. It's utterly 
demoralizing. So I thought about this and realized, I probably should try to 
find out what it is I'm actually doing here, and hear with some real 
programmers if there's a "proper" way of doing it. So my question, dear D 
community:



== Question ==
How do you make D code and Obj-C code coexist? That is, I want to write a 
Cocoa-app that is mostly written in D, and with a little "glue"-code in 
Objective-C. How do you set that up? Is it even supposed to be possible?

(And what could the bug above be? I know LLVM does link-time optimizations, and 
even run-time optimizations. Could it be that it messes things up?)



BR
/HF




Re: std.socket.TcpSocket.flush

2010-07-26 Thread Heywood Floyd
Rory Mcguire Wrote:

> Hi,
> 
> What is one supposed to use to flush a TcpSocket.
> 
> flush doesn't seem to exist, should I really just use the c function?
> 
> -Rory


Was in a similar situation, found this: 
   
http://stackoverflow.com/questions/855544/is-there-a-way-to-flush-a-posix-socket

I thought a socket needed to be flushed because curl and ab "hanged" when 
GETting from my server. Turns out I was just not sending the correct 
HTTP-headers...

/HF


Re: string[int[][]] ??

2010-07-23 Thread Heywood Floyd

> 
>  string[int[2]] board;
> 
>   board[[0,0]] = "Rook";
>   board[[0,1]] = "Knight";
> 
>   foreach( pos, val; board) {
> writefln( "%s: %s", pos, val);
>   }
> 
> 
> Output:
> 
> 2 9903680: Knight
> 2 9903696: Rook
> 

Changing the declaration to

   string[int[]] board;

makes it work (for me).
BR
/HF


Re: Multi dimensional array question.

2010-07-16 Thread Heywood Floyd
Mafi Wrote:

> 
> I don't really like it. Of course the order of indices feels better but 
> it breaks the rule of reading types from right to left. It also 
> introduces more parenthesis and a new keyword into types (amongst const, 
> immutable and delegate etc). Consider:
>shared array[3](const( array[5] immuttable((SList!(int)*)[]) ))
> WTF, that doesn't look good. I would be a real type if your answer was 
> accepted.
> 
> It was
>shared const( immutable(Slist!(int)*[])[5] )[3]
> which reads perfectly from right to left.
> 
> What about this:
>// int[width,height] as sugar for int[height][width]
>int[width,height] arr = ...;
>// arr[x,y] as sugar for arr[x][y]
>int element = arr[x,y];
>// then this works as expected
>int[height] column = arr[x];




Interesting!

First of all, I definitely think that how arrays are declared now would have to 
stay just the way it is, no matter what. I don't think stuff like that is 
changeable this late in a language. But, seems to me these two methods of 
declaring arrays could coexist. One is the shorter syntactical "sugar" method, 
the other is the elaborate, but perhaps clearer method. These kinds of long 
way/shortcuts are already in the language, I believe. Like how void()() is 
automatically a template, comes to mind. (Or did that make sense?)

Then, I simply can't resist commenting this exceptional beauty. I'm gonna call 
it theThing:

   shared const( immutable(Slist!(int)*[])[5] )[3] theThing;

Well. I have to confess, to me, it doesn't read perfectly from right to left. I 
might be reading it wrong, but to me it reads from right to left, and from left 
to right, at the same time. Is it a shared const array of something, or a 
shared array of const something? You can't really tell unless you go back and 
forth, and almost count the parenthesis. For instance, by looking at the 
declaration above, what type is a

   theThing[0][1] ::= ??

It's really not easy to say, for me anyway. I'm sure you get better at reading 
these things. So it might not be fair to say that it's "unclear". It's just my 
subjective opinion, and that may be biased by my lack of experience in the 
matter. Now back to the other thing:

   shared array[3] const array[5] immutable array[] (SList!(int)*)

Sure, this is too verbose. I agree. Still, I think it's clearer. Much clearer. 
Verbose, but clear.

Here I couldn't help but making an interesting obvservation: Those storage 
classes could also be seen as types. What if we allowed the storage classes to 
have some syntactical sugar too, for arrays? We could have:

   shared[3] const[5] immutable[] SList!(int)* theThing;

That does read from left to right in one go, and to me, it's still clear what's 
going on, and, it's not verbose. In fact, it's less verbose than the 
parenthesis-sprinkled version we saw first. Further, it's almost magically easy 
to read: We have a shared array of 3 const arrays of 5 immutable dynamic arrays 
of Slist!(int)*. It just reads, like you read text, quite naturally. (I'm not 
sure this would actually be the same type as the first declaration, erh, but 
yes. You get my intention.)

So again, what type is a 

   theThing[0][1] ::= ??

Well, if we look at the declaration above it's quite easy: We just cut the line 
after the second array, const[5], and the rest of the line, that's our type.

   theThing[0][1] ::= immutable[] SList!(int)*

Now, to me, that's just plain beautiful.

***

And last, the

   int[x,y] arr;

I like it. Simple. Nice. 
Maybe it becomes weird when we have mixed array types, like int[uint,,5] arr? 
Well at least the illusion of an intact order is maintained.

BR
/HF




Re: Multi dimensional array question.

2010-07-16 Thread Heywood Floyd
Lars T. Kyllingstad Wrote:
 
> I do agree that, if possible, the language should match how most people 
> think.  But in this case, it is impossible, because of templates.  How 
> would the following example work with T = int[3], if arrays worked the 
> way you want?
> 
>   struct MyArray(T)
>   {
>   T[] a;
>   }
> 
> C doesn't have this issue, because it doesn't have templates.  And I'll 
> have my templates over C-style array declarations any time, thank you. :)
> 
> -Lars


Well, I suppose the obvious way is to introduce array as a proper type, and not
just as syntactical sugar. For instance, consider:

array[11] int myArr; 

The array "wraps around" a more basic type. It's simply read from left to right.
This should feel "right" for most people. Now it's easy extend this to 
multidimensional arrays. We just allow arrays to wrap arrays:

array[3] array[11] int myArr2d;

This way it's clear what's happening. It's "true" to what's going on at the
compiler level. We have an "outer" array that holds 3 "inner" arrays of 11 
ints. 
And, it's "true" to our high level semantics—when we later access the elements, 
the order is kept intact, as we traverse down the array stack:

myArr2d[outer][inner] = 9;

It's then not too far of a stretch to allow this array-keyword to accept
multidimensional declarations, without reversing the order. Here, it's
still quite clear what's happening: (At least if we have seen the above.)

array[3][11] int myArr2d;
myArr2d[0][10] = 9; //ok

When we introduce templates, this should still work:

struct MyArray(T){
   array[3] T a;
}

// Let's try
T == array[11] int

array[3] T a;
array[3] (array[11] int) a;
array[3] array[11] a;
array[3][11] a;

a[0][10] = 9; //ok

This makes a lot more sense, for me anyway. It's closer to what's actually 
happening,
and it doesn't reverse things at a higher level.

BR
/HF




Re: Is synchronized(mutex) == mutex.lock()?

2010-07-15 Thread Heywood Floyd
Steven Schveighoffer Wrote:

> On Wed, 14 Jul 2010 23:22:20 -0400, Heywood Floyd   
> wrote:
> 
> > Hi!
> >
> > Breakfast toast: Is there any chance a) and b) below are identical in  
> > what they do?
> >
> >
> > auto mutex = new Mutex();
> > auto cond = new Condition(mutex);
> >
> > // a)
> > synchronized(mutex){
> >cond.wait();
> > }
> >
> > // b)
> > mutex.lock();
> >cond.wait();
> > mutex.unlock();
> 
> Almost, this is more equivalent:
> 
> {
>mutex.lock();
>scope(exit) mutex.unlock();
>cond.wait();
> }
> 
> But yes, the mutex object implements the monitor interface, and replaces  
> its own monitor object with a pointer to itself.
> 
> For something really nifty, you can tell mutex to be the monitor object of  
> *any* other object :)  Unfortunately, I can't point you at the docs, cause  
> they dont exist yet, but this will do it:
> 
> class C{}
> 
> auto c = new C;
> auto m = new Mutex(c); // now synchronizing on c is the same as locking m
> 
> -Steve

Cool, love it! Thanks!

/HF




Is synchronized(mutex) == mutex.lock()?

2010-07-14 Thread Heywood Floyd
Hi!

Breakfast toast: Is there any chance a) and b) below are identical in what they 
do?


auto mutex = new Mutex();
auto cond = new Condition(mutex);

// a)
synchronized(mutex){
   cond.wait();
}

// b)
mutex.lock();
   cond.wait();
mutex.unlock();


I was sprinkling my code with mutex.lock/unlock (for fun) when suddenly I 
realized that, hey, maybe synchronized would work just as well, and be even 
more fun? (If that's even possible.)

BR
/HF


Re: Multi dimensional array question.

2010-07-14 Thread Heywood Floyd
Lars T. Kyllingstad Wrote:

> 
> But then arrays would be different from all other types!  If you have an 
> array of 3 Ts, that is written T[3], regardless of what T is.  Now 
> consider these two cases:
> 
>A. T is an int.  Then T[3] becomes int[3].
> 
>B. T is an int[string].  Then T[3] becomes int[string][3].
> 
> In case A, the first element of the array is accessed like this:
> 
>int[3] a;
>int firstA = a[0];
> 
> Since a is an array of int, firstA is of course an int.
> 
> But then, since b is an array of int[string], we have
> 
>int[string][3] b;
>int[string] firstB = b[0];
> 
> If we again want to access element "foo" of the associative array which 
> is firstB, we write firstB["foo"].  And so we have the following three 
> ways to get to that element, which *must* be equivalent because that's 
> how the language is defined:
> 
>// Using firstB as an intermediate step
>int[string] firstB = b[0];
>int x = firstB["foo"];
> 
>// Drop the intermediate variable firstB
>int x = (b[0])["foo"];
> 
>// Drop the redundant parentheses
>int x = b[0]["foo"];
> 
> So you see, it can't be any other way than the way it is. :)
> 
> -Lars

Thank you for the elaborate answer!

When you put it like that, it does make sense. But I'm sorry. I refuse. The 
reason I refuse is those examples are void of any higher semantic meaning. Once 
we add a semantic meaning, it simply becomes backwards:

int[MAX_WIDTH][MAX_HEIGHT] map2d;
map2d[x][y] = 9; // Wrong!

At least in my head, this is cognitive dissonance. To me, the language acts as 
if it's low-level semantics outweighs my high-level semantics and I should 
correct my thinking for that. I refuse! Seems to me it could just as well work 
as:

int[string][3] b;
int[3] firstB = b["foo"];
int i = firstB[0];
int j = (b["foo"])[0];
int k = b["foo"][0];

But I feel like I'm the only one feeling this, so I'll just let it go and hope 
my dear C-style arrays stay in :)

BR
/HF

PS. Never thought I'd find a reason to love C.. DS.



Re: Multi dimensional array question.

2010-07-12 Thread Heywood Floyd
bearophile Wrote:

> Heywood Floyd:
> > This had me crazy. I ended up putting the brackets on the variable, like
> >   int marr[3][5];
> > then it worked like
> >   marr[2][4] = 9;
> 
> That's present only for compatibility with C syntax, this means that you can 
> use it to perform a quicker port of C code to D, but you are supposed to 
> later convert it to D-style array definitions.
> See also:
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=113185
> 
> Bye,
> bearophile

Aha, good to know! Thanks!
(So this might go away in the future? Or require a -cstyle compile flag?)

***

I have a feeling this "backwards"-array stuff is gonna be one of the things my 
brain will repel for as long as it can.

To me, it seems equal to saying "you declare a function like:


  void foo(string name, int age){
 //... }
 

And then call it by doing

   foo(90,"Benny")

and this makes sense because the arguments are actually pushed on the stack in 
reverse at runtime, so they arrive in the correct order in the function. And 
this is especially important with tuples." or something.

Ok, I understand this has some deep purpose that I still don't understand, I'm 
just, yeah. *tear*
(Although this is way out of my league: For instance, if a T is an int[3][4], 
then why can't T[string] be a int[string][3][4], and be accessed with 
arr["a"][2][3]? Seems just like a matter of taste?)

/HF

PS. I was not the thread creator. I just used the creator's terminology to 
"stay on topic". Maybe too on topic : ) Not important really. Sorry for the 
confusion. DS.




Re: Multi dimensional array question.

2010-07-12 Thread Heywood Floyd
This had me crazy. I ended up putting the brackets on the variable, like

  int marr[3][5];

then it worked like

  marr[2][4] = 9;


Re: Is the memory address of classinfo the same for all instances of a class?

2010-07-02 Thread Heywood Floyd

On Jul 2, 2010, at 15:34 , Steven Schveighoffer wrote:

> On Fri, 02 Jul 2010 09:32:39 -0400, Steven Schveighoffer 
>  wrote:
> 
>> On Fri, 02 Jul 2010 09:24:20 -0400, Heywood Floyd  wrote:
>> 
>>> 
>>> Good day!
>>> 
>>> 
>>> Consider
>>> 
>>> // - - - -
>>> class Foo{}
>>> auto one = new Foo();
>>> auto two = new Foo();
>>> writefln("one: %x  two: %x", &one.classinfo, &two.classinfo);
>>> // - - - -
>>> 
>>> For me this results in two identical memory addresses "every time".
>>> 
>>> Can I rely on this?
>>> Can I design software based on the assumption that these addresses are 
>>> always the same?
>>> 
>>> (I'd like to be able to use the memory address as the key in an associative 
>>> array, for quick by-class
>>> lookups.)
>> 
>> Use classinfo.name.  The classinfo is the same memory address in the same 
>> executable/dynamic library.  If you open another D dynamic library, the 
>> classinfo address for the same class may be different, but the name will be 
>> the same.
>> 
>> Note that comparing classinfo.names will be just as fast as comparing 
>> classinfo addresses if the names are at the same address (which will be true 
>> if the classinfo is at the same address) because the string comparison 
>> function short-circuits if the addresses are the same.
> 
> Duh, just realized, classinfos should use this same method to compare.  Just 
> use the whole class info as the key, don't take the address.
> 
> -Steve


Alright thanks!

Ok, loading in code dynamically changes the addresses. Good point. Thanks!

I looked up the TypeInfo_Class-implementation and it seems to compare class 
names. So that looks good. Will use the classinfos directly like you suggested. 
Seems proper.


***

Hm, but still, I can't quite let go of this.
Even if the string comparer can short-circuit, it still has to go through 
strings that are _not_ of the same address untill it spots a difference, as 
they could potentially be equal anyway?

I noted that the classinfo.name-strings typically looks like this:

classtype.Foo
classtype.Bar
classtype.Cat
classtype.Dog

Doesn't this first "classtype."-part introduce overhead when these strings are 
used as keys in an AA? The string comparer more or less always have to check 
the first 10 chars, which are equal for all. (I know I'm being picky here. But 
the whole using memory addresses-thing came from the fear of string comparisons 
being suboptimal.)

/heywood

(PS. Feature-request: move the "classtype."-part of classinfo names to the end 
; )


















Is the memory address of classinfo the same for all instances of a class?

2010-07-02 Thread Heywood Floyd

Good day!


Consider

// - - - -
class Foo{}
auto one = new Foo();
auto two = new Foo();
writefln("one: %x  two: %x", &one.classinfo, &two.classinfo);
// - - - -

For me this results in two identical memory addresses "every time".

Can I rely on this?
Can I design software based on the assumption that these addresses are always 
the same?

(I'd like to be able to use the memory address as the key in an associative 
array, for quick by-class
lookups.)


BR
/heywood


Re: How to call receiveTimout? (std.concurrency)

2010-06-29 Thread Heywood Floyd


Thanks!
I will!
/heywood







PS. I like D.

On Jun 29, 2010, at 19:37 , Steven Schveighoffer wrote:

> On Tue, 29 Jun 2010 13:05:50 -0400, Heywood Floyd  wrote:
> 
>> 
>> 
>> Ok, thanks!
>> 
>> How does the chain of command/responsibility work here?
>> Should I file this to bugzilla?
>> 
>> (I'm not able to fix it myself as I haven't built dmd locally. I'm just not 
>> quite there yet... : )
>> /heywood
> 
> Simen actually already filed it.  See here: 
> http://d.puremagic.com/issues/show_bug.cgi?id=4406.  In the future, just go 
> to http://d.puremagic.com/issues and you can file the bug directly.  It's 
> good to ask on d.learn if you aren't sure.
> 
> And this bug isn't in dmd, it's in phobos :)  They are compiled separately 
> (in case you are interested in trying your hand at phobos patches).  All the 
> releases come with the complete source code, just cd to the src directory and 
> type make -f blah.mak where blah is your platform (posix, windows, etc.).
> 
> -Steve



Re: How to call receiveTimout? (std.concurrency)

2010-06-29 Thread Heywood Floyd


Ok, thanks!

How does the chain of command/responsibility work here?
Should I file this to bugzilla?

(I'm not able to fix it myself as I haven't built dmd locally. I'm just not 
quite there yet... : )
/heywood



On Jun 29, 2010, at 16:31 , Steven Schveighoffer wrote:

> On Tue, 29 Jun 2010 09:53:25 -0400, Simen kjaeraas  
> wrote:
> 
>> Heywood Floyd  wrote:
>> 
>>> ops = ops[1 .. $];  // <=== line 335
>> 
>> Well, this looks like a bug to me. Should be
>> 
>> Ops = ops[1 .. $];
>> 
> 
> Ops is a type, isn't it?  Don't you need a variable there?
> 
> I agree it's a bug in the original, but I don't think that's the fix.
> 
> -Steve



How to call receiveTimout? (std.concurrency)

2010-06-29 Thread Heywood Floyd

Hello and Good morning!



I'm trying to use receiveTimeout:

// 
import  std.stdio,
std.concurrency;
int main(string[] args){
receiveTimeout(  1000L, (int i){writefln("Received: %d",i);}
) ;
return 0;
}
// 

(I removed all the surrounding code above that spawned threads etc.)

Compiler gives me:

/Library/Compilers/dmd2/osx/bin/../../src/phobos/std/concurrency.d(335): Error: 
mismatched
tuple lengths, 2 and 1


I can't see what's wrong? Help!


A look in concurrency.d shows:
// - - 8< - -

bool receiveTimeout(T...)( long ms, T ops )
{
static enum long TICKS_PER_MILLI = 10_000;
return mbox.get( ms * TICKS_PER_MILLI, ops );
}

// - - 8< - -

   final void get(T...)( T ops )
   {
   static assert( T.length );

   static if( isImplicitlyConvertible!(T[0], long) )
   {
   alias TypeTuple!(T[1 .. $]) Ops;
   assert( ops[0] >= 0 );
   long period = ops[0];
   ops = ops[1 .. $];  // <=== line 335
   }

// - - 8< - -




(DMD v2.047, OSX 10.6.4)

BR
/soul

PS. Sorry if this is a dupe. Mailman doesn't seem to like my emails? Sending 
this via the web-
interface..