Re: Dispatching values to handlers, as in std.concurrency

2013-05-07 Thread Idan Arye

On Tuesday, 7 May 2013 at 00:15:06 UTC, Luís Marques wrote:

On Monday, 6 May 2013 at 23:53:51 UTC, Idan Arye wrote:
If the type handlers are your own classes, then you can let 
them check it. Have a method in the handlers that check if an 
object can be handled by that handler, and use it on each 
handler until you find one that fits.


I don't understand. Imagine I have:

class X
{
void handleFoo(Foo msg) { ... }

void handleBar(Bar msg) { ... }
}

I want to register an instance of X to receive messages of type 
Foo (or subclass) and messages of type Bar (or subclass) in the 
respective handler methods. Where are you proposing for your 
check to be implemented?


I assume that `typeHandler` in your original code is *not* of 
type `X` - since it has a single `handler` method while `X` has 
two, with different names. That means that at some point, you had 
to create it - let's assume it's type is called `TypeHandler`. 
There is either a global function, static method, or constructor 
where you create a `TypeHandler` and pass to it the delegate you 
want to register.


Now, if that function/method/constructor is templated - than you 
already have at compile time the type you want to handle, so you 
can prepare the check there(anon function?)


If it's not templated - make it templated! You don't have to make 
the entire `TypeHanler` templated, just the method that creates 
it. There, you can create an anonymous function that receives 
`Object` and returns `bool` and all it does is check for type, 
and you can have a field in `TypeHandler` that keeps that 
function and uses it to check if it can handle a certain type.


Argument S to typeof is not an expression

2013-05-07 Thread Meta

template Test(alias N)
if (isIntegral!(typeof(N)))
{
struct S
{
typeof(N) n = N;

auto opAdd(T)(T rhs)
{
//Error: argument S to typeof is not an expression
pragma(msg, typeof(T));
//Error: variable rhs cannot be read at compile time
return Test!(n + rhs.n);
}
}
auto st = S(N);
alias Test = st;
}

void main()
{
auto a = Test!2;
auto b = Test!3;
writeln(typeof(a).stringof ~  a = , a, , ,
typeof(b).stringof ~  b = , b, , ,
typeof(a + b).stringof ~  a + b = );
}

I don't really understand why either of these error messages are 
occurring. The first is just incomprehensible, and the second 
seems like it should work. In this case, rhs is fully accessible 
at compile time in the expression (a + b), so why does the 
compiler complain?


Re: Argument S to typeof is not an expression

2013-05-07 Thread Anonimous

On Tuesday, 7 May 2013 at 06:41:25 UTC, Meta wrote:

template Test(alias N)
if (isIntegral!(typeof(N)))
{
struct S
{
typeof(N) n = N;

auto opAdd(T)(T rhs)
{
//Error: argument S to typeof is not an expression
pragma(msg, typeof(T));
//Error: variable rhs cannot be read at compile time
return Test!(n + rhs.n);
}
}
auto st = S(N);
alias Test = st;
}

void main()
{
auto a = Test!2;
auto b = Test!3;
writeln(typeof(a).stringof ~  a = , a, , ,
typeof(b).stringof ~  b = , b, , ,
typeof(a + b).stringof ~  a + b = );
}

I don't really understand why either of these error messages 
are occurring. The first is just incomprehensible, and the 
second seems like it should work. In this case, rhs is fully 
accessible at compile time in the expression (a + b), so why 
does the compiler complain?


First error occures,because typeof(T) is undefined - T is a
type,not value.
About second error,although in this case rhs is
accessible,compiler can't know
that you won't call this function in runtime,so it's expected -
it's just ordinary function.


Re: Argument S to typeof is not an expression

2013-05-07 Thread Anonimous

Sorry for my english.


How to reserve memory for a slice in a struct

2013-05-07 Thread Namal

Hello,

I am new to D. According to that power of 2 rule I want to
reserve 2 sized chunks to my array, But how do I do that in a
struct? Say:

struct Stack(int){

int a[];


}


Where do I put that a.reserve(2);

Because right after the declaration of a I get an error

Error: unexpected ( in declarator
Error: basic type expected, not 2
Error: found '2' when expecting ')'
Error: no identifier for declarator a.reserve(int)
Error: semicolon expected following function declaration
Error: Declaration expected, not ')'


Re: Argument S to typeof is not an expression

2013-05-07 Thread Dicebot

On Tuesday, 7 May 2013 at 06:41:25 UTC, Meta wrote:
I don't really understand why either of these error messages 
are occurring. The first is just incomprehensible, and the 
second seems like it should work. In this case, rhs is fully 
accessible at compile time in the expression (a + b), so why 
does the compiler complain?


1) typeof don't work on types. Period. It is often inconvenient 
in generic code (I'd love it typeof(T) to be T for simplicity) 
but it is how it is done now. In your case pragma(msg, T) will be 
correct one.


2) template parameter must be known at compile time. rhs is a 
plain function parameter, so compiler can't be sure it is known 
at compile time, so it is an error. Same goes for n. In general, 
only enum's and template parameters can be assumed to be known at 
compile-time. Your code seems to wrongly mix plain variables with 
template code all over.


If you can explain for behavior/API you are trying to achieve, 
most likely I'll be able to provide a more idiomatic D solution.




Re: How to reserve memory for a slice in a struct

2013-05-07 Thread John Colvin

On Tuesday, 7 May 2013 at 10:29:44 UTC, Namal wrote:

Hello,

I am new to D. According to that power of 2 rule I want to
reserve 2 sized chunks to my array, But how do I do that in a
struct? Say:

struct Stack(int){

int a[];


}



2 sized chunks?

Perhaps you want something like this:

struct Stack{
int a[];
this(size_t r) {
a.reserve(r);
}
}

void main() {
auto s = Stack(2);
}


Re: Argument S to typeof is not an expression

2013-05-07 Thread Jacob Carlborg

On 2013-05-07 08:41, Meta wrote:

template Test(alias N)
if (isIntegral!(typeof(N)))
{
 struct S
 {
 typeof(N) n = N;

 auto opAdd(T)(T rhs)
 {
 //Error: argument S to typeof is not an expression
 pragma(msg, typeof(T));
 //Error: variable rhs cannot be read at compile time
 return Test!(n + rhs.n);
 }
 }
 auto st = S(N);
 alias Test = st;
}

void main()
{
 auto a = Test!2;
 auto b = Test!3;
 writeln(typeof(a).stringof ~  a = , a, , ,
 typeof(b).stringof ~  b = , b, , ,
 typeof(a + b).stringof ~  a + b = );
}

I don't really understand why either of these error messages are
occurring. The first is just incomprehensible, and the second seems like
it should work. In this case, rhs is fully accessible at compile time in
the expression (a + b), so why does the compiler complain?


As a workaround for typeof you can use this:

https://github.com/jacob-carlborg/orange/blob/master/orange/util/Traits.d#L213

--
/Jacob Carlborg


Re: Argument S to typeof is not an expression

2013-05-07 Thread Dicebot

On Tuesday, 7 May 2013 at 11:03:31 UTC, Jacob Carlborg wrote:

As a workaround for typeof you can use this:

https://github.com/jacob-carlborg/orange/blob/master/orange/util/Traits.d#L213


You may want to update your implementation: 
http://dpaste.1azy.net/640a2580


Re: How to reserve memory for a slice in a struct

2013-05-07 Thread evilrat

On Tuesday, 7 May 2013 at 10:58:42 UTC, John Colvin wrote:

...
int a[];


please don't use C style declarations, D style is type followed 
by id:


int[] a;


Re: How to reserve memory for a slice in a struct

2013-05-07 Thread Steven Schveighoffer

On Tue, 07 May 2013 06:29:43 -0400, Namal soti...@mail.ru wrote:


Hello,

I am new to D. According to that power of 2 rule I want to
reserve 2 sized chunks to my array, But how do I do that in a
struct? Say:

struct Stack(int){

int a[];


}


Where do I put that a.reserve(2);

Because right after the declaration of a I get an error

Error: unexpected ( in declarator
Error: basic type expected, not 2
Error: found '2' when expecting ')'
Error: no identifier for declarator a.reserve(int)
Error: semicolon expected following function declaration
Error: Declaration expected, not ')'


You cannot statically reserve heap space for any type.

You have two choices:

1. make 'a' a fixed sized array (this reserves space inside the struct):

int[2] a;

2. reserve space at runtime (e.g. during constructor):

this(size_t n) { a.reserve(n); }

Unfortunately, structs have no default constructor, so you can't specify  
that a *always* is reserved.


A note of caution -- reserving space via a.reserve does *not* give you  
access to the space, it just reserves a block for your use to append the  
slice into the array.  So for example:


a.reserve(2);
assert(a.length == 0); // length is still 0.
assert(a.ptr !is null); // but block has been allocated with at least 2  
elements.

a ~= 1; // pointer has not changed, a is now filling into allocated block.

If you want to reserve accessible space, set the length:

a.length = 2;

One other thing, the space you reserve is not exactly a power of 2.  It  
will be 2^^n - 1.  This is due to requirements of the array runtime.


The minimal heap space for an int array is 3.  Then it goes 7, 15, 31,  
etc.  Once you get to page size, the amount of space you can reserve grows  
linearly.  These are implementation details of the GC, so you shouldn't  
depend on this never changing.  In any case, whatever space you request,  
the GC will give you at LEAST that much.


-Steve


Re: How to reserve memory for a slice in a struct

2013-05-07 Thread Maxim Fomin

On Tuesday, 7 May 2013 at 10:29:44 UTC, Namal wrote:

Hello,

I am new to D. According to that power of 2 rule I want to
reserve 2 sized chunks to my array, But how do I do that in a
struct?


You can set some kind of statically allocated array size:

struct S
{
int[] a;
this(size_t size)
{
a.length = size;
}
}

enum SE : S
{
A = S(2)
}

static assert(SE.init.a.length is 2);

void main()
{
SE se;
assert(se.a.length is 2);
}

Unfortunately this does not work with array reserve.


Re: WinAPI callbacks and GC

2013-05-07 Thread Regan Heath
On Tue, 07 May 2013 00:03:58 +0100, Sean Kelly s...@invisibleduck.org  
wrote:



On May 2, 2013, at 6:17 AM, Regan Heath re...@netmail.co.nz wrote:

On Wed, 01 May 2013 01:12:39 +0100, Sean Kelly s...@invisibleduck.org  
wrote:


On Apr 23, 2013, at 2:21 PM, Jack Applegame jappleg...@gmail.com  
wrote:


According WinAPI documentation, CtrlHandler will be called in new  
additional thread. Is it safe to allocate GC memory in NOT Phobos  
threads?
If not, how to make it safe? I'm trying call thread_attachThis() at  
the beginning of CtrlHandler fucntion, but it doesn't compile because  
thread_attachThis() is not no throw.



thread_attachThis should probably just be labeled nothrow.  I don't  
think there's anything in that function that can throw an Exception.


That makes it callable.. but did you see my post about the various  
timing issues with using this in a non-GC thread (potentially while the  
GC is already collecting - or similar).


The GC holds a lock on the global thread list while collecting, so it  
shouldn't be possible for thread_attachThis to register a thread when  
this is happening.  In fact, thread_attachThis even temporarily disables  
the GC, and since this operation is protected by the GC lock, it's  
blocked there as well.


Excellent.  Might be nice to see some of these details in the docs :p  ..  
or even just a will block if collection is in progress.


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


unittest + struct ctorю + nested mixin template + alias

2013-05-07 Thread ref2401

Version D 2.062

class MyClass
{}

struct MyStruct(T)
if (is(T == class))
{
string _message = nothing;

this(T obj)
{
if (obj is null){
_message = Null reference message;
}
else{
_message = All right message;
}
}

mixin Foo!();

private mixin template Foo()
{
void foo() {}
}
}


unittest
{
alias MyStruct!MyClass StructType;
auto inst = StructType(null);

string msg = inst._message; // Wrong value!
}


The behavior varies between executions: sometimes msg contains 
empty string, in other times it holds nothing.
If StructType is replaced with MyStruct!MyClass then everything 
works as expected.

auto inst = MyStruct!MyClass(null); // OK

If declaration of the Foo template is moved out of struct 
MyStruct(T) definition, everything works fine too.
This strange behavior is observed only in unittest block, not 
when executed in main().

Am I doing something incorrectly or is this a bug?


Re: Argument S to typeof is not an expression

2013-05-07 Thread Meta

On Tuesday, 7 May 2013 at 10:33:58 UTC, Dicebot wrote:

On Tuesday, 7 May 2013 at 06:41:25 UTC, Meta wrote:
I don't really understand why either of these error messages 
are occurring. The first is just incomprehensible, and the 
second seems like it should work. In this case, rhs is fully 
accessible at compile time in the expression (a + b), so why 
does the compiler complain?


1) typeof don't work on types. Period. It is often inconvenient 
in generic code (I'd love it typeof(T) to be T for simplicity) 
but it is how it is done now. In your case pragma(msg, T) will 
be correct one.


2) template parameter must be known at compile time. rhs is a 
plain function parameter, so compiler can't be sure it is known 
at compile time, so it is an error. Same goes for n. In 
general, only enum's and template parameters can be assumed to 
be known at compile-time. Your code seems to wrongly mix plain 
variables with template code all over.


If you can explain for behavior/API you are trying to achieve, 
most likely I'll be able to provide a more idiomatic D solution.


This is a little test to see if I can wrap types in structs and
do some checking at compile time. For example, statically
verifying in opAdd that neither number being added is negative. I
added in the pragma to see what T's type is because I had the
example compiling before, but two S structs added together was
giving a result of void, and I was trying to figure out why that
was happening.


Re: unittest + struct ctorю + nested mixin template + alias

2013-05-07 Thread Steven Schveighoffer

On Tue, 07 May 2013 10:58:09 -0400, ref2401 refacto...@gmail.com wrote:


Version D 2.062

class MyClass
{}

struct MyStruct(T)
if (is(T == class))
{
string _message = nothing;

this(T obj)
{
if (obj is null){
_message = Null reference message;
}
else{
_message = All right message;
}
}

mixin Foo!();

private mixin template Foo()
{
void foo() {}
}
}


unittest
{
alias MyStruct!MyClass StructType;
auto inst = StructType(null);

string msg = inst._message; // Wrong value!
}


The behavior varies between executions: sometimes msg contains empty  
string, in other times it holds nothing.
If StructType is replaced with MyStruct!MyClass then everything works as  
expected.

auto inst = MyStruct!MyClass(null); // OK

If declaration of the Foo template is moved out of struct MyStruct(T)  
definition, everything works fine too.
This strange behavior is observed only in unittest block, not when  
executed in main().

Am I doing something incorrectly or is this a bug?


How are you determining that _message is wrong?  I see no observable  
printouts or anything.


It may be that if you are using a debugger, the debugger can't handle the  
mixin and is looking at the wrong data, or maybe the compiler is  
outputting wrong debug info.


If I put this line in, it never asserts:

assert(msg == Null reference message);

I think the compiler is outputting correct code.  I don't have 2.062, only  
the beta, and 2.061.  Tested with the latest beta.


-Steve


Re: unittest + struct ctorю + nested mixin template + alias

2013-05-07 Thread ref2401

i'm using VisualD.

this assertion fails assert(msg == Null reference message);
in my actual code instead of variable _message an exception is 
thrown if (obj is null) == true.

i'm using the unittest block to test exception throwing.

...
this(T obj)
{
if (obj is null){
throw new Exception(Null reference.);
}
}
...


unittest
{
alias MyStruct!MyClass StructType;
std.exception.assertThrown(StructType(null));   // Wrong assertion
}


Re: How to reserve memory for a slice in a struct

2013-05-07 Thread Diggory
You could allocate space inside a class itself with something 
like this:

class Base {
int[] slice;
}

template Derived(size_t N) {
class Derived : Base {
int[N] array;

this() {
slice = array;
}
}
}

Base b = new Derived!32();

A bit pointless though...


Re: Argument S to typeof is not an expression

2013-05-07 Thread Jacob Carlborg

On 2013-05-07 13:08, Dicebot wrote:


You may want to update your implementation: http://dpaste.1azy.net/640a2580


Thanks.

--
/Jacob Carlborg


Deallocate array?

2013-05-07 Thread Matic Kukovec

Hi

I'm running Windows Vista 64 with dmd 2.062.

I have a simple program:

import std.stdio, core.memory, std.cstream;
void main()
{
string[] temp_array;

for(int i=0;i500;i++)
{
++temp_array.length;
temp_array[temp_array.length - 1] = a;
}

temp_array = null;

GC.collect();
writeln(end);   
din.getc();
}

When the program waits at din.getc();, memory usage in the Task 
Manager is 150MB.


Why isn't the memory deallocating?

P.S.;
I tried temp_array.clear() and destroy(temp_array), but nothing 
changed.


Re: Deallocate array?

2013-05-07 Thread Ali Çehreli

On 05/07/2013 04:09 PM, Matic Kukovec wrote: Hi

 When the program waits at din.getc();, memory usage in the Task
 Manager is 150MB.

 Why isn't the memory deallocating?

 P.S.;
 I tried temp_array.clear() and destroy(temp_array), but nothing changed.

GC.minimize() may work.

Ali



Re: Deallocate array?

2013-05-07 Thread Matic Kukovec

On Tuesday, 7 May 2013 at 23:14:20 UTC, Ali Çehreli wrote:

On 05/07/2013 04:09 PM, Matic Kukovec wrote: Hi

 When the program waits at din.getc();, memory usage in the
Task
 Manager is 150MB.

 Why isn't the memory deallocating?

 P.S.;
 I tried temp_array.clear() and destroy(temp_array), but
nothing changed.

GC.minimize() may work.

Ali


Thanks for the quick reply, Ali.

Tried it, no changes.



Re: Deallocate array?

2013-05-07 Thread Ali Çehreli

On 05/07/2013 04:18 PM, Matic Kukovec wrote:

 On Tuesday, 7 May 2013 at 23:14:20 UTC, Ali Çehreli wrote:
 GC.minimize() may work.

 Tried it, no changes.

Works for your test program under Linux but as the documentation says, 
it is not guaranteed to have any effect at all.


Ali



Re: Deallocate array?

2013-05-07 Thread Matic Kukovec

On Tuesday, 7 May 2013 at 23:31:41 UTC, Ali Çehreli wrote:

On 05/07/2013 04:18 PM, Matic Kukovec wrote:

 On Tuesday, 7 May 2013 at 23:14:20 UTC, Ali Çehreli wrote:
 GC.minimize() may work.

 Tried it, no changes.

Works for your test program under Linux but as the 
documentation says, it is not guaranteed to have any effect at 
all.


Ali


I found this problem with a program that reads a large xml file 
(25+ lines), then stores the lines in a string[], does a 
comparison with another array and finally clears the original 
array.
On the second or third file I always get an OutOfMemoryError, 
when the Task Manager shows about 1.3GB memory usage.


Is this a Windows specific thing or am I doing something wrong?


Re: Deallocate array?

2013-05-07 Thread Ali Çehreli

On 05/07/2013 04:42 PM, Matic Kukovec wrote:

 On Tuesday, 7 May 2013 at 23:31:41 UTC, Ali Çehreli wrote:
 On 05/07/2013 04:18 PM, Matic Kukovec wrote:

  On Tuesday, 7 May 2013 at 23:14:20 UTC, Ali Çehreli wrote:
  GC.minimize() may work.

  Tried it, no changes.

 Works for your test program under Linux but as the documentation says,
 it is not guaranteed to have any effect at all.

 Ali

 I found this problem with a program that reads a large xml file (25+
 lines), then stores the lines in a string[], does a comparison with
 another array and finally clears the original array.

You don't need to clear the original array but it should be harmless.

 On the second or third file I always get an OutOfMemoryError, when the
 Task Manager shows about 1.3GB memory usage.

 Is this a Windows specific thing or am I doing something wrong?

Is this a 32-bit platform? If so, the reason may be the conservative GC 
that dmd uses. What happens is, unrelated 32-bit values in other parts 
of the program may look like pointers into the allocated space and the 
GC thinks that they are still in use.


Ali



Re: Deallocate array?

2013-05-07 Thread bearophile

Matic Kukovec:


The system is Windows Vista 64bit. DMD is 2.062.


DMD doesn't yet produce 64 bit binaries on Windows.

I have tried to solve your problem using GC.free, but I am not 
seeing good results...


Bye,
bearophile


Re: Deallocate array?

2013-05-07 Thread Juan Manuel Cabo


Why isn't the memory deallocating?


The memory might be free, but still not released to the OS.

Especially in windows, when you free memory it still isn't freed 
from

your process.
But you can reuse it in your program if the GC has collected it.

The correct test would be to copy and paste the same code below, 
and see if it

stays at 150Mb or it jumps to 300Mb.

If it jumps to 300Mb, then the GC hasn't collected it.

If it stays at 150Mb, the GC had collected it but windows didn't 
claim it.


--jm



Re: Deallocate array?

2013-05-07 Thread Juan Manuel Cabo
I found this problem with a program that reads a large xml file 
(25+ lines), then stores the lines in a string[], does a 
comparison with another array and finally clears the original 
array.
On the second or third file I always get an OutOfMemoryError, 
when the Task Manager shows about 1.3GB memory usage.


Is this a Windows specific thing or am I doing something wrong?


Try the following before getting rid of your arrays:

  myarray[] = null; //if it is an array of classes or strings

  myIntArray[] = 0; //if it is an array of ints

  myBigString[] = '\0';

  etc.

This clears the contents of the arrays, and helps the garbage 
collector, so that it doesn't confuse data with pointers.


Also, avoid growing arrays little by little. This is VERY bad for 
garbage accumulation. Use instead an appender!(string[])() for 
string arrays for instance.


--jm


Re: Deallocate array?

2013-05-07 Thread Steven Schveighoffer
On Tue, 07 May 2013 19:09:28 -0400, Matic Kukovec  
matic.kuko...@pametnidom.si wrote:



Hi

I'm running Windows Vista 64 with dmd 2.062.

I have a simple program:

import std.stdio, core.memory, std.cstream;
void main()
{
string[] temp_array;

for(int i=0;i500;i++)
{




++temp_array.length;
temp_array[temp_array.length - 1] = a;


This is very inefficient, use temp_array ~= a;


}

temp_array = null;

GC.collect();
 writeln(end);  
din.getc();
}

When the program waits at din.getc();, memory usage in the Task  
Manager is 150MB.


Why isn't the memory deallocating?


The GC does not return free memory to the OS, just to free memory  
pools/free-lists.  GC.minimize may or may not help.


But your code may not have freed that memory anyway.  It is not really  
possible to ensure that temp_array isn't referred to.  For example, the  
compiler could keep temp_array in a register.




P.S.;
I tried temp_array.clear() and destroy(temp_array), but nothing changed.


Neither of these will deallocate memory.  All are equivalent to setting  
temp_array = null.


If you want to ensure deallocation, you need to free it using  
GC.free(temp_array.ptr).  A very dangerous operation, use with caution,  
make sure there are no other references to that data.


-Steve