Re: Physics libraries in D

2013-05-09 Thread Andrea Fontana

On Wednesday, 8 May 2013 at 09:43:43 UTC, Mike Parker wrote:
Last I checked, Bullet doesn't have a C interface. That means 
it's unlikely you'll find a D binding. And I haven't heard of 
any.


If it has a c++ interface probably you can bind it using swig.



Re: Scoped import bug?

2013-05-09 Thread Kenji Hara

On Thursday, 9 May 2013 at 05:01:15 UTC, Mike Linford wrote:
I'm not sure whether or not I've encountered a bug or whether 
my understanding of scoped imports is just faulty.


blah.d:

  1 module blah;
  2
  3 version(A)
  4 {
  5import std.range;
  6 }
  7
  8 struct Blah(R)
  9 {
 10version(B)
 11{
 12   import std.range;
 13}
 14static assert(isInputRange!R);
 15
 16void blah(R r)
 17{
 18   version(C)
 19   {
 20  assert(r.front == 'h');
 21   }
 22}
 23 }
 24
 25 void main()
 26 {
 27Blah!string blah;
 28blah.blah(hello);
 29 }

Results:
rdmd -version=A -version=C blah
Compiles fine. Module-level import works for the static assert 
on line 14 and the runtime assert on line 20


rdmd -version=B blah
Compiles fine! Struct-level import works for the static assert 
on line 14


rdmd -version=B -version=C blah
Fails to compile. I get the following error messages:
blah.d(20): Error: no property 'front' for type 'string'
blah.d(27): Error: template instance blah.Blah!(string) error 
instantiating


So it appears that when my import is at the struct level like 
line 12 I'm able to use the static assert but *not* the runtime 
assert. Why cant the function Blah.blah() find the array 
implementation of front?


This is a known UFCS name look-up issue.
In 2.063dev, the bug is fixed. Please wait the release.

Kenji Hara


Template alias parameter does not accept types

2013-05-09 Thread ref2401

Version D 2.062
http://dlang.org/template.html#TemplateAliasParameter
Is is said in the documentation that is's possible but i get 
compile time error.


template GetString(alias Arg)
{
enum string GetString = Arg.stringof;
}

void main(string[] argv)
{
writeln(GetString!1234);
writeln(GetString!18);

	writeln(GetString!int); // Error: template instance 
GetString!(int)

// GetString!(int) does not match template
// declaration GetString(alias Arg)

readln();
}


Re: Template alias parameter does not accept types

2013-05-09 Thread bearophile

ref2401:


template GetString(alias Arg)
{
enum string GetString = Arg.stringof;
}

...

writeln(GetString!int); // Error: template instance


Template alias arguments don't yet accept built-in types as int. 
It will be fixed.


Bye,
bearophile


Tricky code with exceptions

2013-05-09 Thread bearophile

A little Java program I've just found in a blog post:


class Flow {
static public void main(String[] args) {
for (int i = 0; i  6; ++i) {
System.out.println(Loop:  + i);

try {
try {
if (i == 3)
break;
} finally {
if (i % 2 != 0)
throw new Exception();
}
} catch (Exception e) {
System.out.println(Caught);
}
}
}
}


Its output:

Loop: 0
Loop: 1
Caught
Loop: 2
Loop: 3
Caught
Loop: 4
Loop: 5
Caught


My D translation:

import std.stdio;

void main() {
foreach (i; 0 .. 6) {
writeln(Loop: , i);

try {
try {
if (i == 3)
break;
} finally {
if (i % 2 != 0)
throw new Exception();
}
} catch (Exception e) {
writeln(Caught);
}
}
}


It prints:

Loop: 0
Loop: 1
Caught
Loop: 2
Loop: 3

And then it crashes.

Bye,
bearophile


Re: Template alias parameter does not accept types

2013-05-09 Thread Anonimous

On Thursday, 9 May 2013 at 10:59:02 UTC, ref2401 wrote:

Version D 2.062
http://dlang.org/template.html#TemplateAliasParameter
Is is said in the documentation that is's possible but i get 
compile time error.


template GetString(alias Arg)
{
enum string GetString = Arg.stringof;
}

void main(string[] argv)
{
writeln(GetString!1234);
writeln(GetString!18);

	writeln(GetString!int); // Error: template instance 
GetString!(int)

// GetString!(int) does not match template
// declaration GetString(alias Arg)

readln();
}


You just can't pass by alias built-in types like int or char

Workaround:

import std.stdio;

template GetString(Arg...)
if(Arg.length == 1)
{
enum string GetString = Arg[0].stringof;
}

void main(string[] argv)
{
writeln(GetString!1234);
writeln(GetString!18);

	writeln(GetString!int); // Error: template instance 
GetString!(int)


// GetString!(int) does not match template
// declaration GetString(alias Arg)

readln();
}


Re: Template alias parameter does not accept types

2013-05-09 Thread Dicebot

On Thursday, 9 May 2013 at 11:19:38 UTC, bearophile wrote:

It will be fixed.


Ugh, proof-link? I have always thought it is by design and that 
actually makes sense.


Re: Argument S to typeof is not an expression

2013-05-09 Thread Dicebot

On Thursday, 9 May 2013 at 01:08:28 UTC, Meta wrote:
I can't get the structs to be evaluated at compile time, so I 
guess that's a lost cause.


Well, structs can be evaluated at compile-time but can't be value 
template parameters. You can do a small trick in this case though:


http://dpaste.1azy.net/c2188c90

struct Test(int N)
{
enum n = N;

auto add(int i)()
{
return Test!(n + i)();
}

alias n this;
}

void main()
{
import std.stdio;
enum a = Test!5();
enum b = Test!3();
writeln(a.add!b());
}

Will this do?

But actually this feels more like a task for CTFE. You can write 
a normal opAdd that does bounds check at run-time and then add 
if (!__ctfe) assert(0); to guarantee it will never be used in 
real run-time.


Re: Tricky code with exceptions

2013-05-09 Thread Mike James


bearophile bearophileh...@lycos.com wrote in message 
news:pnwldlckpgrjvvuje...@forum.dlang.org...


SNIP


My D translation:

import std.stdio;

void main() {
foreach (i; 0 .. 6) {
writeln(Loop: , i);

try {
try {
if (i == 3)
break;
} finally {
if (i % 2 != 0)
throw new Exception();
}
} catch (Exception e) {
writeln(Caught);
}
}
}


It prints:

Loop: 0
Loop: 1
Caught
Loop: 2
Loop: 3

And then it crashes.

Bye,
bearophile


Strangely, if you replace the break instruction with continue (I know 
it's pointless code), it also crashes...


Regards, Mike. 



Re: Argument S to typeof is not an expression

2013-05-09 Thread Meta
then add if (!__ctfe) assert(0); to guarantee it will never 
be used in real run-time.


I don't think I've ever seen __ctfe before. Is it specific to DMD?


Re: Tricky code with exceptions

2013-05-09 Thread Maxim Fomin
It works on dpaste http://dpaste.dzfl.pl/fcd2f2b5 which seems to 
be based on linux 2.62. Which platform do you use?


P.S. Seems we can define new kind of forum contribution - some 
code works as expected in language X, but equivalent code in D 
goes ballistic. This is very sad.


Re: Argument S to typeof is not an expression

2013-05-09 Thread Dicebot

On Thursday, 9 May 2013 at 12:35:29 UTC, Meta wrote:
then add if (!__ctfe) assert(0); to guarantee it will never 
be used in real run-time.


I don't think I've ever seen __ctfe before. Is it specific to 
DMD?


It is documented here : http://dlang.org/function.html

The __ctfe boolean pseudo-variable, which evaluates to true at 
compile time, but false at run time, can be used to provide an 
alternative execution path to avoid operations which are 
forbidden at compile time. Every usage of __ctfe is evaluated 
before code generation and therefore has no run-time cost, even 
if no optimizer is used


So no, it is quite official and not specific to dmd.


Re: Template alias parameter does not accept types

2013-05-09 Thread Steven Schveighoffer

On Thu, 09 May 2013 06:58:57 -0400, ref2401 refacto...@gmail.com wrote:


Version D 2.062
http://dlang.org/template.html#TemplateAliasParameter
Is is said in the documentation that is's possible but i get compile  
time error.


template GetString(alias Arg)
{
enum string GetString = Arg.stringof;
}

void main(string[] argv)
{
writeln(GetString!1234);
writeln(GetString!18);

writeln(GetString!int); // Error: template instance GetString!(int)
// GetString!(int) does not match template
// declaration GetString(alias Arg)

readln();
}


Others have answered, but the technical issue is that alias accepts a  
*symbol*, int is a *keyword*.


Annoying, I know, but I don't see how the compiler can make sense of it,  
the way it is built.  Keywords are special and must go in the right places.


You can alias int, and it works:

alias int intalias;

writeln(GetString!intalias); // writes intalias

You can also overload GetString to accept builtin types:

template GetString(T) if (is(T == int) || is(T == float) || ...)
{
   enum string GetString = T.stringof;
}

There may even already be a template for detecting a builtin type, not  
sure.


On Thu, 09 May 2013 07:19:37 -0400, bearophile bearophileh...@lycos.com  
wrote:


Template alias arguments don't yet accept built-in types as int. It will  
be fixed.


I don't think this is true, alias strictly accepts symbols or literals,  
not keywords.  Do you have evidence of an official statement to the  
contrary?


-Steve


Re: Template alias parameter does not accept types

2013-05-09 Thread Kenji Hara

On Thursday, 9 May 2013 at 12:09:03 UTC, Dicebot wrote:

On Thursday, 9 May 2013 at 11:19:38 UTC, bearophile wrote:

It will be fixed.


Ugh, proof-link? I have always thought it is by design and that 
actually makes sense.


AFAIK, there is no plan for fix. The behavior is currently a part 
of language design.


Kenji Hara


Re: Template alias parameter does not accept types

2013-05-09 Thread bearophile

Steven Schveighoffer:


Do you have evidence of an official statement to the contrary?


Here I don't have evidence, just faith :-)

Bye,
bearophile


Re: Template alias parameter does not accept types

2013-05-09 Thread Dicebot
On Thursday, 9 May 2013 at 13:27:35 UTC, Steven Schveighoffer 
wrote:

template GetString(T) if (is(T == int) || is(T == float) || ...)
{
   enum string GetString = T.stringof;
}


Current idiomatic D way to handle both built-in types and symbols 
looks like this:


template Hello(T...)
if (T.length == 1)
{
static if (is(T[0]))
// ...
else
// ...
}

I actually don't understand why it accepts literals as those are 
not symbols and, for example, you can't attach UDA to literal.


Re: Tricky code with exceptions

2013-05-09 Thread bearophile

Maxim Fomin:

It works on dpaste http://dpaste.dzfl.pl/fcd2f2b5 which seems 
to be based on linux 2.62.

On dpaste it also works on gdc2.060 and ldc2.060, both 64 bit.



Which platform do you use?


Vista 32. Probably I will add it to Bugzilla.


P.S. Seems we can define new kind of forum contribution - some 
code works as expected in language X, but equivalent code in D 
goes ballistic. This is very sad.


On the other hand often it's broken code in other languages that 
works as desired in D :-)


Bye,
bearophile


Re: Template alias parameter does not accept types

2013-05-09 Thread bearophile

Kenji Hara:

AFAIK, there is no plan for fix. The behavior is currently a 
part of language design.


Considering matters of D semantic uniformity, and the code shown 
by Dicebot:


template Hello(T...)
if (T.length == 1)
{
static if (is(T[0]))
// ...
else
// ...
}

Then maybe the current behavior is worth reconsidering.

Bye,
bearophile


Re: Template alias parameter does not accept types

2013-05-09 Thread Steven Schveighoffer

On Thu, 09 May 2013 09:38:29 -0400, Dicebot m.stras...@gmail.com wrote:


On Thursday, 9 May 2013 at 13:27:35 UTC, Steven Schveighoffer wrote:

template GetString(T) if (is(T == int) || is(T == float) || ...)
{
   enum string GetString = T.stringof;
}


Current idiomatic D way to handle both built-in types and symbols looks  
like this:


template Hello(T...)
 if (T.length == 1)
{
 static if (is(T[0]))
 // ...
 else
 // ...
}

I actually don't understand why it accepts literals as those are not  
symbols and, for example, you can't attach UDA to literal.


I think it was a happy accident, or else a relaxation of the rules to  
allow more flexibility.  Possibly the same reason could be used to relax  
the rules again.  But I think it would be a more difficult prospect in the  
compiler.


alias cannot accept literals in a normal alias statement.  But what  
allowing it for template alias parameters does is enable the whole  
std.algorithm acceptance of a string literal for function lambdas.   
Arguably, this is no longer needed due to the new lambda syntax (but I  
think we have found other uses for it).  It has also caused some headaches:


map!a.x(foo)

is a different instantiation with identical code to:

map! a.x(foo)

-Steve


Re: Template alias parameter does not accept types

2013-05-09 Thread Dicebot
Feels like I am the only one who wants to restrict rules, not 
relax them =/


But, erm, you don't need alias accepting literals for old syntax! 
Strings are valid as template value parameters: 
http://dpaste.1azy.net/54e5d3f2


Re: Template alias parameter does not accept types

2013-05-09 Thread Steven Schveighoffer

On Thu, 09 May 2013 10:00:45 -0400, Dicebot m.stras...@gmail.com wrote:

Feels like I am the only one who wants to restrict rules, not relax them  
=/


But, erm, you don't need alias accepting literals for old syntax!  
Strings are valid as template value parameters:  
http://dpaste.1azy.net/54e5d3f2


Hm.. maybe it was a bug that turned into a feature :)  Perhaps I'm not  
remembering correctly why this was introduced.


It is true that you could simply accept a literal with an int/long or  
string, and then you can have different template instantiations based on  
that.


-Steve


Re: Tricky code with exceptions

2013-05-09 Thread Sean Kelly

For what it's worth, this runs fine on 64-bit OSX.


Re: Tricky code with exceptions

2013-05-09 Thread Brad Anderson

On Thursday, 9 May 2013 at 11:24:03 UTC, bearophile wrote:

A little Java program I've just found in a blog post:


class Flow {
static public void main(String[] args) {
for (int i = 0; i  6; ++i) {
System.out.println(Loop:  + i);

try {
try {
if (i == 3)
break;
} finally {
if (i % 2 != 0)
throw new Exception();
}
} catch (Exception e) {
System.out.println(Caught);
}
}
}
}


Its output:

Loop: 0
Loop: 1
Caught
Loop: 2
Loop: 3
Caught
Loop: 4
Loop: 5
Caught


My D translation:

import std.stdio;

void main() {
foreach (i; 0 .. 6) {
writeln(Loop: , i);

try {
try {
if (i == 3)
break;
} finally {
if (i % 2 != 0)
throw new Exception();
}
} catch (Exception e) {
writeln(Caught);
}
}
}


It prints:

Loop: 0
Loop: 1
Caught
Loop: 2
Loop: 3

And then it crashes.

Bye,
bearophile



I just tested this for you when you hopped in IRC but you left 
before I could tell you that a 64-bit Windows dmd build did not 
crash and here is the output.


Loop: 0
Loop: 1
Caught
Loop: 2
Loop: 3
Caught
Loop: 4
Loop: 5
Caught


Re: Tricky code with exceptions

2013-05-09 Thread Brad Anderson

On Thursday, 9 May 2013 at 18:24:46 UTC, Brad Anderson wrote:
I just tested this for you when you hopped in IRC but you left 
before I could tell you that a 64-bit Windows dmd build did not 
crash and here is the output.




Oh, and this was dmd 2.062 (just -m64).


Re: Scoped import bug?

2013-05-09 Thread Mike Linford

On Thursday, 9 May 2013 at 09:52:12 UTC, Kenji Hara wrote:

On Thursday, 9 May 2013 at 05:01:15 UTC, Mike Linford wrote:
I'm not sure whether or not I've encountered a bug or whether 
my understanding of scoped imports is just faulty.


blah.d:

 1 module blah;
 2
 3 version(A)
 4 {
 5import std.range;
 6 }
 7
 8 struct Blah(R)
 9 {
10version(B)
11{
12   import std.range;
13}
14static assert(isInputRange!R);
15
16void blah(R r)
17{
18   version(C)
19   {
20  assert(r.front == 'h');
21   }
22}
23 }
24
25 void main()
26 {
27Blah!string blah;
28blah.blah(hello);
29 }

Results:
rdmd -version=A -version=C blah
Compiles fine. Module-level import works for the static assert 
on line 14 and the runtime assert on line 20


rdmd -version=B blah
Compiles fine! Struct-level import works for the static assert 
on line 14


rdmd -version=B -version=C blah
Fails to compile. I get the following error messages:
blah.d(20): Error: no property 'front' for type 'string'
blah.d(27): Error: template instance blah.Blah!(string) error 
instantiating


So it appears that when my import is at the struct level like 
line 12 I'm able to use the static assert but *not* the 
runtime assert. Why cant the function Blah.blah() find the 
array implementation of front?


This is a known UFCS name look-up issue.
In 2.063dev, the bug is fixed. Please wait the release.

Kenji Hara


Thank you for the explanation. Was this the issue? 
http://d.puremagic.com/issues/show_bug.cgi?id=6185


Re: Variant associative arrays

2013-05-09 Thread Byron Heads
On Thu, 09 May 2013 03:29:06 +0200, evilrat wrote:

 first doesn't compile with DMD 2.062 as int implicitly not converted to
 long.
 
 foo func takes associative array, within this example you can use type
 Variant[string] to make life a bit easier(but i can't recommend it for
 ur real code cause we don't know the usage).
 
 and for third func here is example code, though it doesn't takes
 associative array you can rewrite it to suit ur needs, also notice that
 it's a bit dirty and not very readable cause i'm superlazy and quite in
 a hurry, so you can improve it yourself
 
 ---
 
 void bar(...)
 {
   import core.vararg;
 
   enum string handler = `.visit! (
   // string type handler (string s) = write(s, pos %2 == 
0 ? ':' :
   '\n'),
   // long type handler (long l) = write(l, pos %2 == 0 ? 
':' : '\n')
   )();`;
 
 
   for( int pos = 0; pos  _arguments.length ; pos++ )
   {
 
   if ( _arguments[pos] == typeid(HDType) )
   mixin(`(va_arg!(HDType)(_argptr))` ~ handler );
 
   else if ( _arguments[pos] == typeid(string) )
   mixin(`HDType(va_arg!(string)(_argptr))` ~ 
handler );
 
   else if ( _arguments[pos] == typeid(long) )
   mixin(`HDType(va_arg!(long)(_argptr))` ~ handler 
);
 
   else
   throw new Exception(wrong type);
   }
 }



I think I had a large const in there when I tested so it worked then.  
This gives me a few ideas, but I may try a different API.


Re: Variant associative arrays

2013-05-09 Thread Byron Heads
On Thu, 09 May 2013 02:33:08 +0200, bearophile wrote:

 Byron Heads:
 
 I have a variant associative array.  In the example below I am
 wondering if there is a way to create the array without having to
 indicate the variant type on all of the values. Would like to be able
 to write code like #2, or something cleaner/better for #1.
 ...
  // #1 This works foo([first : HDType(John),
  last : HDType(Doe), phone : HDType(1234546)]);

  // #2 Wont compile, type mismatch string and long foo([first :
  John,
  last : Doe,
  phone : 1234546]);
 
 If your purpose is to write such associative literal without repeating
 the HDType(), then a possibility is to write the data in a single
 string, and feed it to a compile-time function that splits it and builds
 the associative array.
 
 Bye,
 bearophile

That approch may work.  Will have to experiment with the API more.


kxml help.

2013-05-09 Thread Zz

Hi,

I decided to try out kxml and I have the following error.

test.d(10): Error: found '.' when expecting ','
test.d(11): Error: found '.' when expecting ','

when the following is compiled.

module test;

import kxml.xml;
private import std.string;
private import std.stdio;

void main()
{
auto node = new XmlNode();
node.addChild(new XmlNode(mynode).setAttribute(x, 50).
addChild(new XmlNode(Waldo).addCData(Hello!)));
}


-
it's taken out of an example in the code.

Zz


Re: kxml help.

2013-05-09 Thread John Colvin

On Thursday, 9 May 2013 at 19:32:44 UTC, Zz wrote:

Hi,

I decided to try out kxml and I have the following error.

test.d(10): Error: found '.' when expecting ','
test.d(11): Error: found '.' when expecting ','

when the following is compiled.

module test;

import kxml.xml;
private import std.string;
private import std.stdio;

void main()
{
auto node = new XmlNode();
node.addChild(new XmlNode(mynode).setAttribute(x, 50).
addChild(new XmlNode(Waldo).addCData(Hello!)));
}


-
it's taken out of an example in the code.

Zz


You just need brackets around the new statements:

node.addChild((new XmlNode(mynode)).setAttribute(x, 50).

addChild((new XmlNode(Waldo)).addCData(Hello!)));


Re: Tricky code with exceptions

2013-05-09 Thread bearophile

Brad Anderson:


a 64-bit Windows dmd build did not crash and here is the output.


Thank you for the data point. So maybe the problem is only on 32 
bit Windows.


Bye,
bearophile


Re: kxml help.

2013-05-09 Thread Zz

Thanks

On Thursday, 9 May 2013 at 20:26:28 UTC, John Colvin wrote:

On Thursday, 9 May 2013 at 19:32:44 UTC, Zz wrote:

Hi,

I decided to try out kxml and I have the following error.

test.d(10): Error: found '.' when expecting ','
test.d(11): Error: found '.' when expecting ','

when the following is compiled.

module test;

import kxml.xml;
private import std.string;
private import std.stdio;

void main()
{
auto node = new XmlNode();
node.addChild(new XmlNode(mynode).setAttribute(x, 50).
addChild(new XmlNode(Waldo).addCData(Hello!)));
}


-
it's taken out of an example in the code.

Zz


You just need brackets around the new statements:

node.addChild((new XmlNode(mynode)).setAttribute(x, 50).

addChild((new XmlNode(Waldo)).addCData(Hello!)));




Re: Tricky code with exceptions

2013-05-09 Thread evilrat

On Thursday, 9 May 2013 at 20:33:17 UTC, bearophile wrote:

Brad Anderson:

a 64-bit Windows dmd build did not crash and here is the 
output.


Thank you for the data point. So maybe the problem is only on 
32 bit Windows.


Bye,
bearophile


win8 dmd 2.062 32-bit also crashes


Re: Deallocate array?

2013-05-09 Thread Matic Kukovec

Hi again Steve, or anyone else whose reading this.
I was playing around with D and C# and need help getting this 
array stuff to work.


My D program:
import std.stdio, std.cstream, std.array;

void main()
{
string[] temp_array = new string[1];
for(int i=0;i1;i++)
{
temp_array[i] = a;
}   
temp_array = null;

temp_array = new string[1];
for(int i=0;i1;i++)
{
temp_array[i] = a;
}
temp_array = null;

writeln(end);   

din.getc();
}

This program causes an OutOfMemoryError.


My C# program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testing
{
class Program
{
static void Main(string[] args)
{

string[] temp_array = new string[1];
for (int i = 0; i  1; i++)
{
temp_array[i] = a;
}
temp_array = null;

temp_array = new string[1];
for (int i = 0; i  1; i++)
{
temp_array[i] = a;
}
temp_array = null;

temp_array = new string[1];
for (int i = 0; i  1; i++)
{
temp_array[i] = a;
}
temp_array = null;


Console.WriteLine(end);
Console.ReadKey(true);
}
}
}

It's the same program, but doesn't cause and OutOfMemory 
exception, even if i double the times i run the loop part.


My question is what is how do i get the same C# functionality in 
D without running out of memory and preferably without using the 
GC directly?


I'm running Windows Vista 64bit, DMD 2.062 fresh install, 
compiling with -m32 flag.


Re: Tricky code with exceptions

2013-05-09 Thread Juan Manuel Cabo

Tested on Linux - Kubuntu 12.04 64bits
  dmd 2.058 -m32
  dmd 2.058 64 bits
  dmd 2.062 -m32
  dmd 2.062
and the output is this for all of the above:

Loop: 0
Loop: 1
Caught
Loop: 2
Loop: 3
Caught
Loop: 4
Loop: 5
Caught

Then, tested on Windows XP SP3 32 bits, dmd 2.062,
and it DIDN'T CRASH. The output is:

Loop: 0
Loop: 1
Caught
Loop: 2
Loop: 3

--jm


Re: Tricky code with exceptions

2013-05-09 Thread Juan Manuel Cabo

On Friday, 10 May 2013 at 01:05:39 UTC, Juan Manuel Cabo wrote:


Then, tested on Windows XP SP3 32 bits, dmd 2.062,
and it DIDN'T CRASH. The output is:


Mm, sorry!!, it did crash but I had dr watson disabled in that VM.
Confirmed adding a writeln(finished) after the foreach, which 
isn't reached.


So It DID CRASH in Windows XP 32 bits. Sorry for the noise.

--jm





Re: Deallocate array?

2013-05-09 Thread Ali Çehreli

On 05/09/2013 05:58 PM, Matic Kukovec wrote:

 Hi again Steve, or anyone else whose reading this.
 I was playing around with D and C# and need help getting this array
 stuff to work.

[...]

 My question is what is how do i get the same C# functionality in D
 without running out of memory and preferably without using the GC 
directly?


 I'm running Windows Vista 64bit, DMD 2.062 fresh install, compiling with
 -m32 flag.

You have a string array of 100_000_000 elements. (You can insert 
underscores in literals to make code more readable.)


On a 32-bit system string is 8 bytes (e.g. by pragma(msg, 
string.sizeof)). So you have a single array of 800 million bytes. Then, 
each of those strings point at 22 bytes of individully allocated memory 
areas.


Note that 800 million is about 20% of the entire addressable memory of 
that system. If you have a single value that happens to look like a 
pointer into that memory, that huge block will remain in memory forever. 
The funny thing about dmd's current conservative GC is that even an 
integer can be mistaken to be a pointer into that memory.


So that's the problem today.

I don't know the exact requirement here but if you really must have 100 
million strings at one time, then you may want to do your own memory 
management. The following should work:


import std.stdio;
import core.memory;

void main()
{
enum size_t times = 10;
enum size_t stringCount = 100_000_000;

foreach (i; 0 .. times) {
auto rawMemory = cast(string*)GC.calloc(string.sizeof * 
stringCount);


// D's cool feature of making a slice from raw pointer
auto tempArray = rawMemory[0 .. stringCount];

foreach (ref s; tempArray) {
s = a;
}

GC.free(rawMemory);
// You may want to set tempArray to null at this point to prevent
// using it accidentally but it is not necessary.

writefln(Done with allocation %s/%s; please press Enter,
 i + 1, times);
readln();
}
}

Ali



Re: Deallocate array?

2013-05-09 Thread Steven Schveighoffer

On Thu, 09 May 2013 22:14:41 -0400, Ali Çehreli acehr...@yahoo.com wrote:

On a 32-bit system string is 8 bytes (e.g. by pragma(msg,  
string.sizeof)). So you have a single array of 800 million bytes. Then,  
each of those strings point at 22 bytes of individully allocated memory  
areas.


No, each array points at static data.  Strings are immutables stored in  
the data segment.


Note that 800 million is about 20% of the entire addressable memory of  
that system. If you have a single value that happens to look like a  
pointer into that memory, that huge block will remain in memory forever.  
The funny thing about dmd's current conservative GC is that even an  
integer can be mistaken to be a pointer into that memory.


So that's the problem today.


Correct, the only solution at the moment is to deallocate explicitly.

It is important to keep in mind that C# has a *precise* garbage collector,  
D has a *conservative* garbage collector.  C# will always do better than D  
at GC as long as this is true.


64 bit address space also helps tremendously.

I don't know the exact requirement here but if you really must have 100  
million strings at one time, then you may want to do your own memory  
management. The following should work:


import std.stdio;
import core.memory;

void main()
{
 enum size_t times = 10;
 enum size_t stringCount = 100_000_000;

 foreach (i; 0 .. times) {
 auto rawMemory = cast(string*)GC.calloc(string.sizeof *  
stringCount);


 // D's cool feature of making a slice from raw pointer
 auto tempArray = rawMemory[0 .. stringCount];


You can allocate normally, and just use free on the pointer



 foreach (ref s; tempArray) {
 s = a;
 }

 GC.free(rawMemory);


GC.free(tempArray.ptr); // also works

 // You may want to set tempArray to null at this point to  
prevent

 // using it accidentally but it is not necessary.

 writefln(Done with allocation %s/%s; please press Enter,
  i + 1, times);
 readln();
 }
}


-Steve


Re: Deallocate array?

2013-05-09 Thread Ali Çehreli

On 05/09/2013 07:43 PM, Steven Schveighoffer wrote:

 On Thu, 09 May 2013 22:14:41 -0400, Ali Çehreli acehr...@yahoo.com 
wrote:


 Then, each of those strings point at 22 bytes of individully allocated
 memory areas.

 No, each array points at static data.  Strings are immutables stored in
 the data segment.

You are right. They start at pointing to the same string but as soon as 
each string is used in a special way, say each gets appended a char, 
then they own their special characters:


s = a;

// Some time later:
s ~= 'x';

Now each s.ptr is different.

Ali



Re: Tricky code with exceptions

2013-05-09 Thread Dan Olson
evilrat evilrat...@gmail.com writes:

 On Thursday, 9 May 2013 at 20:33:17 UTC, bearophile wrote:
 Brad Anderson:

 a 64-bit Windows dmd build did not crash and here is the output.

 Thank you for the data point. So maybe the problem is only on 32 bit
 Windows.

 Bye,
 bearophile

 win8 dmd 2.062 32-bit also crashes

Anybody looked at the assembly for the crashing executables?  The truth
is in there.

 


Re: Scoped import bug?

2013-05-09 Thread Kenji Hara

On Thursday, 9 May 2013 at 18:25:39 UTC, Mike Linford wrote:

On Thursday, 9 May 2013 at 09:52:12 UTC, Kenji Hara wrote:

On Thursday, 9 May 2013 at 05:01:15 UTC, Mike Linford wrote:
I'm not sure whether or not I've encountered a bug or whether 
my understanding of scoped imports is just faulty.


blah.d:

1 module blah;
2
3 version(A)
4 {
5import std.range;
6 }
7
8 struct Blah(R)
9 {
10version(B)
11{
12   import std.range;
13}
14static assert(isInputRange!R);
15
16void blah(R r)
17{
18   version(C)
19   {
20  assert(r.front == 'h');
21   }
22}
23 }
24
25 void main()
26 {
27Blah!string blah;
28blah.blah(hello);
29 }

Results:
rdmd -version=A -version=C blah
Compiles fine. Module-level import works for the static 
assert on line 14 and the runtime assert on line 20


rdmd -version=B blah
Compiles fine! Struct-level import works for the static 
assert on line 14


rdmd -version=B -version=C blah
Fails to compile. I get the following error messages:
blah.d(20): Error: no property 'front' for type 'string'
blah.d(27): Error: template instance blah.Blah!(string) error 
instantiating


So it appears that when my import is at the struct level like 
line 12 I'm able to use the static assert but *not* the 
runtime assert. Why cant the function Blah.blah() find the 
array implementation of front?


This is a known UFCS name look-up issue.
In 2.063dev, the bug is fixed. Please wait the release.

Kenji Hara


Thank you for the explanation. Was this the issue? 
http://d.puremagic.com/issues/show_bug.cgi?id=6185


Yes, that's right!

Kenji Hara