Re: Source code output

2013-07-16 Thread JS

On Wednesday, 17 July 2013 at 05:29:26 UTC, H. S. Teoh wrote:

On Wed, Jul 17, 2013 at 05:27:34AM +0200, JS wrote:
With heavy ctfe code generation usage is it possible to have 
the d
compiler output the source code after all mixin templates have 
been
"used"? This way it is easier to visually check for errors in 
the

generated code.

I imagine one could use pragma in a "special way" to do this 
but I

was hoping for something more direct.


Yeah I've been looking for this too. Once you have templates 
and mixins
nested deeply enough, it can be near impossible to figure out 
just

exactly *what* is being compiled at the end of it all.

Though I suppose the common approach is to generate a string
representing the code, and then using mixin(str) to compile it; 
this
lets you use pragma(msg) to output str and thereby see what 
exactly is

being compiled. But this may not be possible in some cases.


T


That is what I use but at some point it will become worthless. I 
was thinking it may be possible to optionally pragma the code 
depending on a symbol like __codegen, which would then trigger 
all the appropriate pragma's, the problem is, the output will be 
a mess because of the nesting(code duplication). Only the most 
outside mixin's pragma needs to be triggered, the one directly 
used in the code(not inside another template).





Re: Source code output

2013-07-16 Thread H. S. Teoh
On Wed, Jul 17, 2013 at 05:27:34AM +0200, JS wrote:
> With heavy ctfe code generation usage is it possible to have the d
> compiler output the source code after all mixin templates have been
> "used"? This way it is easier to visually check for errors in the
> generated code.
> 
> I imagine one could use pragma in a "special way" to do this but I
> was hoping for something more direct.

Yeah I've been looking for this too. Once you have templates and mixins
nested deeply enough, it can be near impossible to figure out just
exactly *what* is being compiled at the end of it all.

Though I suppose the common approach is to generate a string
representing the code, and then using mixin(str) to compile it; this
lets you use pragma(msg) to output str and thereby see what exactly is
being compiled. But this may not be possible in some cases.


T

-- 
Be in denial for long enough, and one day you'll deny yourself of things you 
wish you hadn't.


Re: Template explosion

2013-07-16 Thread JS

On Wednesday, 17 July 2013 at 03:34:17 UTC, Timothee Cour wrote:
On Tue, Jul 16, 2013 at 8:29 PM, Timothee Cour 
wrote:



On Tue, Jul 16, 2013 at 7:52 PM, JS  wrote:



It seems that one must use two templates to process built in 
times and

strings

template A(string a) { ... }
template A(a) { enum A = A(typeof(a).stringof); }

This is so we can do stuff like A!(double) and A!("double").

The problem is when we have many parameters the number of 
permutations

increases exponentially.

Is there a better way to unify the two?



template a(T...)if(T.length==1){
  enum a=1;
}
void main(){
  auto a1=a!double;
  auto a2=a!"double";
}

However:
This syntax sucks.
Why not support the following syntax:
template a(auto T) {...}
with same semantics?

Because this is problematic with more arguments:
I'd like this:
template a(auto T1, double T2){...}

but instead have to do that:
template a(T...)if(is(T[1]==double)) {...}
and it gets quickly more complicated



A)
actually, I'm not sure if auto would be the best keyword here, 
but maybe

another keyword.

B)
What's the rationale why alias can't match to a primitive type 
in the first

place?

I think this is the real problem, else it would be rather easy. I 
don't mind writing static if's for each argument as that's linear.

C)
correction: above, it should be:
template a(T...)if(T.length==2 && is(T[1]==double)) {...}
which is quite verbose.




Re: Template explosion

2013-07-16 Thread Timothee Cour
On Tue, Jul 16, 2013 at 8:29 PM, Timothee Cour wrote:

> On Tue, Jul 16, 2013 at 7:52 PM, JS  wrote:
>
>>
>> It seems that one must use two templates to process built in times and
>> strings
>>
>> template A(string a) { ... }
>> template A(a) { enum A = A(typeof(a).stringof); }
>>
>> This is so we can do stuff like A!(double) and A!("double").
>>
>> The problem is when we have many parameters the number of permutations
>> increases exponentially.
>>
>> Is there a better way to unify the two?
>>
>
> template a(T...)if(T.length==1){
>   enum a=1;
> }
> void main(){
>   auto a1=a!double;
>   auto a2=a!"double";
> }
>
> However:
> This syntax sucks.
> Why not support the following syntax:
> template a(auto T) {...}
> with same semantics?
>
> Because this is problematic with more arguments:
> I'd like this:
> template a(auto T1, double T2){...}
>
> but instead have to do that:
> template a(T...)if(is(T[1]==double)) {...}
> and it gets quickly more complicated
>
>
A)
actually, I'm not sure if auto would be the best keyword here, but maybe
another keyword.

B)
What's the rationale why alias can't match to a primitive type in the first
place?

C)
correction: above, it should be:
template a(T...)if(T.length==2 && is(T[1]==double)) {...}
which is quite verbose.


Re: Template explosion

2013-07-16 Thread Timothee Cour
On Tue, Jul 16, 2013 at 7:52 PM, JS  wrote:

>
> It seems that one must use two templates to process built in times and
> strings
>
> template A(string a) { ... }
> template A(a) { enum A = A(typeof(a).stringof); }
>
> This is so we can do stuff like A!(double) and A!("double").
>
> The problem is when we have many parameters the number of permutations
> increases exponentially.
>
> Is there a better way to unify the two?
>

template a(T...)if(T.length==1){
  enum a=1;
}
void main(){
  auto a1=a!double;
  auto a2=a!"double";
}

However:
This syntax sucks.
Why not support the following syntax:
template a(auto T) {...}
with same semantics?

Because this is problematic with more arguments:
I'd like this:
template a(auto T1, double T2){...}

but instead have to do that:
template a(T...)if(is(T[1]==double)) {...}
and it gets quickly more complicated


Source code output

2013-07-16 Thread JS
With heavy ctfe code generation usage is it possible to have the 
d compiler output the source code after all mixin templates have 
been "used"? This way it is easier to visually check for errors 
in the generated code.


I imagine one could use pragma in a "special way" to do this but 
I was hoping for something more direct.




Re: Using static opCall instead of the default constructor.

2013-07-16 Thread Jaehunt

On Tuesday, 16 July 2013 at 23:00:06 UTC, Namespace wrote:


static PriorityQueue opCall(T)() {
PriorityQueue!T po;

po.A = new T[DEFAULT_QueueSIZE];
po.num = 1;

return po;
}



Thanks a lot.


Template explosion

2013-07-16 Thread JS


It seems that one must use two templates to process built in 
times and strings


template A(string a) { ... }
template A(a) { enum A = A(typeof(a).stringof); }

This is so we can do stuff like A!(double) and A!("double").

The problem is when we have many parameters the number of 
permutations increases exponentially.


Is there a better way to unify the two?


Re: A little of coordination for Rosettacode

2013-07-16 Thread bearophile

OK, the code now works :-)


And the results are a bit hilarious:


...>md5_implementation5_dmd
md5  digest("")  = D41D8CD98F00B204E9800998ECF8427E
zmd5 digest("")  = D41D8CD98F00B204E9800998ECF8427E

Test performance / message size 200MBytes
digest(data) = F083432AB71F6177A8EC2CA5157F7B83
std.md5:16.59 M/sec  (12.05 secs)
digest(data) = F083432AB71F6177A8EC2CA5157F7B83
zmd5   :81.90 M/sec  ( 2.44 secs)



...>md5_implementation5_ldc
md5  digest("")  = D41D8CD98F00B204E9800998ECF8427E
zmd5 digest("")  = D41D8CD98F00B204E9800998ECF8427E

Test performance / message size 200MBytes
digest(data) = F083432AB71F6177A8EC2CA5157F7B83
std.md5:   112.36 M/sec  ( 1.78 secs)
digest(data) = F083432AB71F6177A8EC2CA5157F7B83
zmd5   :98.18 M/sec  ( 2.04 secs)


The zmd5 version is generated asm with a small part in D. LDC2 
compiles the standard D version even better... :-)


Bye,
bearophile


Re: A little of coordination for Rosettacode

2013-07-16 Thread bearophile
But the code in that link is all wrong because it needs all the 
code from std.md5 to work.

And even then I don't know where Decode() is.


OK, the code now works :-)

Bye,
bearophile


Re: A little of coordination for Rosettacode

2013-07-16 Thread bearophile

http://codepad.org/g4RBio8E


this line:
.replace("TT", "0x" ~ text(T(n), 16));

Needs to be:
.replace("TT", "0x" ~ to!string(T(n), 16));

But the code in that link is all wrong because it needs all the 
code from std.md5 to work.

And even then I don't know where Decode() is.

Bye,
bearophile


Re: Using static opCall instead of the default constructor.

2013-07-16 Thread Namespace


static PriorityQueue opCall(T)() {
PriorityQueue!T po;

po.A = new T[DEFAULT_QueueSIZE];
po.num = 1;

return po;
}



Re: nested enum like template generator

2013-07-16 Thread JS

On Tuesday, 16 July 2013 at 21:12:36 UTC, Ali Çehreli wrote:

On 07/16/2013 02:01 PM, Ali Çehreli wrote:

> On 07/16/2013 01:40 PM, JS wrote:

>  > It would be nice if we had some way to data globally(in
module).
>  >
>  > e.g., __ctfestore["name"] = value;
>
> I would expect model-level objects start their lives after
the program
> starts running but their initial value can be calculated
during compile
> time:
>
> import std.stdio;
> import std.conv;
>
> int[string] ctfestore;
>
> static this()
> {
>  ctfestore = A!().globalFunc();
> }

Ok, I've been silly. That's not CTFE. I meant something like 
this:


static this()
{
enum initialValue = A!().globalFunc();
ctfestore = initialValue;
}

And only then I got the problem:

> template A()
> {
>  int c;
>
>  int[string] globalFunc()
>  {
>  int[string] result;
>
>  void func()
>  {
>  for ( ; c < 10; ++c) {

Error: static variable c cannot be read at compile time
   called from here: func()
   called from here: globalFunc()

>  result[c.to!string] = c;
>  }
>  }
>
>  func();
>  return result;
>  }
> }
>
> void main()
> {
>  writeln(ctfestore);
> }
>
> Prints:
>
> ["0":0, "4":4, "8":8, "1":1, "5":5, "9":9, "2":2, "6":6,
"3":3, "7":7]

Ali


yes, that error is the bitch that D loves to slap me with 
constantly when using ctfe's and I have to use wierd methods to 
get around it. Note that I am mainly talking about string mixins 
but the issue is that c is a template variable which is a compile 
time construct that has no real meaning inside a ctfe(if that 
makes sense). This is why nested functions have to be used... but 
then if you want global variables(cross-template variables) you 
need some other technique, if it's even possible.


template A() {
int c;  // doesn't create a variable c for functions in the 
template to use but tells the template define a variable when 
used, I guess, as a normal template(not a mixin).


That is, I was initially thinking `int c;` created a compile time 
variable inside the template but it doesn't... c does't even 
exist until the template is used, but by then, it's too late... 
specially if the template is used as a string mixin.


I think we would need somethign like

template A() {

template int c; // or possibly internal int c;

which defines c as a template variable(not a symbolic expression 
inserted into code where A is used.


here is code that makes it clear:
module main;

import std.stdio, std.cstream, std.conv;

template A()
{
int c;
int foo() { return ++c; }
enum A = foo();  // Comment out to change A to a standard 
template

}


void main(string[] argv)
{   
alias A!() a;
//writeln(a.c, a.foo());
writeln(a);
}

Note that A is used two different ways. A as a sort of function 
itself(with return foo() and, if that line is commented out, as a 
sort of container holding an int and a function.


I think this is the confusion that I had not realizing they are 
two different beasts.


When A is acting as a container, foo can use c no problem. When A 
is acting as a ctfe, foo can't use c. I'm not sure if this is a 
flaw, bug, or what...


I don't see any reason why it can't work both ways, and nesting 
the template as a function works to solve the compile time error.


I think both concepts can be unified by having the compiler 
implicitly wrap everything inside the template in a function, 
accept assignments to A, when used as a ctfe. (this may not work 
well though but a start in the right direction)






Re: A little of coordination for Rosettacode

2013-07-16 Thread bearophile

This entry has stopped working since lot of time:
http://rosettacode.org/wiki/MD5/Implementation#D

This is an improved version, but help is welcome:
http://codepad.org/g4RBio8E

Bye,
bearophile


Using static opCall instead of the default constructor.

2013-07-16 Thread Jaehunt
Hello, I am trying to using static opCall instead of the default 
constructor.


When I run it, I got "Error: need 'this' to access member A".

How to fix it?

Here is my code.

struct PriorityQueue(T) {
static const int DEFAULT_QueueSIZE = 1;
T[] A;
int num;

this(this){
A = A.dup;
}

static PriorityQueue opCall() {

A =  new T[DEFAULT_QueueSIZE];  // Error
num = 1;// Error

PriorityQueue priorityQueue;

return priorityQueue;
}

bool empty() { return num == 0; }

void insert( T item) {
if( A.length == num ) A.length *= 2;
A[ num++] = item;
}

T extractMax() {
A.sort;
return A[ --num];
}
}


Re: nested enum like template generator

2013-07-16 Thread Ali Çehreli

On 07/16/2013 02:01 PM, Ali Çehreli wrote:

> On 07/16/2013 01:40 PM, JS wrote:

>  > It would be nice if we had some way to data globally(in module).
>  >
>  > e.g., __ctfestore["name"] = value;
>
> I would expect model-level objects start their lives after the program
> starts running but their initial value can be calculated during compile
> time:
>
> import std.stdio;
> import std.conv;
>
> int[string] ctfestore;
>
> static this()
> {
>  ctfestore = A!().globalFunc();
> }

Ok, I've been silly. That's not CTFE. I meant something like this:

static this()
{
enum initialValue = A!().globalFunc();
ctfestore = initialValue;
}

And only then I got the problem:

> template A()
> {
>  int c;
>
>  int[string] globalFunc()
>  {
>  int[string] result;
>
>  void func()
>  {
>  for ( ; c < 10; ++c) {

Error: static variable c cannot be read at compile time
   called from here: func()
   called from here: globalFunc()

>  result[c.to!string] = c;
>  }
>  }
>
>  func();
>  return result;
>  }
> }
>
> void main()
> {
>  writeln(ctfestore);
> }
>
> Prints:
>
> ["0":0, "4":4, "8":8, "1":1, "5":5, "9":9, "2":2, "6":6, "3":3, "7":7]

Ali



Re: nested enum like template generator

2013-07-16 Thread Ali Çehreli

On 07/16/2013 01:40 PM, JS wrote:

> The problem is I can't declare my "global" int variables directly inside
> the template. This does make it hard to use the same variable across
> multiple functions...
>
> template A
> {
>  int c; // makes c near useless, can't use it like a normal it...
> }

Could you please provide complete code. The following works:

import std.stdio;
import std.conv;

template A()
{
int c;
}

string func(T)()
{
string result;

alias counter = A!().c;

for ( ; counter < 10; ++counter) {
result ~= counter.to!string;
}

return result;
}

void main()
{
writeln(func!int());
}

Prints:

0123456789

This works as well:

import std.stdio;
import std.conv;

template A()
{
int c;

string func()
{
string result;

for ( ; c < 10; ++c) {
result ~= c.to!string;
}

return result;
}
}

void main()
{
writeln(A!().func());
}

Prints the same:

0123456789

> the error message given obfuscates the reason.

What is the error message?

> Unfortunately it requires a messy technique to get around by using nested
> functions. (The parent function holds the global state of the child
> functions)

Well, this works as well:

import std.stdio;
import std.conv;

template A()
{
int c;

string globalFunc()
{
string result;

void func()
{
for ( ; c < 10; ++c) {
result ~= c.to!string;
}
}

func();
return result;
}
}

void main()
{
writeln(A!().globalFunc());
}

Again, prints the same:

0123456789

> It would be nice if we had some way to data globally(in module).
>
> e.g., __ctfestore["name"] = value;

I would expect model-level objects start their lives after the program 
starts running but their initial value can be calculated during compile 
time:


import std.stdio;
import std.conv;

int[string] ctfestore;

static this()
{
ctfestore = A!().globalFunc();
}

template A()
{
int c;

int[string] globalFunc()
{
int[string] result;

void func()
{
for ( ; c < 10; ++c) {
result[c.to!string] = c;
}
}

func();
return result;
}
}

void main()
{
writeln(ctfestore);
}

Prints:

["0":0, "4":4, "8":8, "1":1, "5":5, "9":9, "2":2, "6":6, "3":3, "7":7]

Ali



Re: nested enum like template generator

2013-07-16 Thread JS

On Tuesday, 16 July 2013 at 14:05:38 UTC, Ali Çehreli wrote:

On 07/15/2013 10:51 PM, JS wrote:

> On Tuesday, 16 July 2013 at 04:37:33 UTC, Ali Çehreli wrote:
>> On 07/15/2013 08:43 PM, JS wrote:
>>
>> > http://dpaste.dzfl.pl/7c8b0ba9
>> >
>> > Why the heck can't we use integers in ctfe's? There seems
to
>> be no
>> > simple way to create a counter and this is one of the most
>> basic
>> > programming constructs to use.. yet with ctfe's it's
>> impossible.
>> >
>> > I'd like each variable in the nested structs to be
>> incremented properly.
>>
>> I did not read the code but just from your description, the
separate
>> compilation model that D uses would preclude that. For
example,
>> compilation of a.d would not know anything about the counter
that b.d
>> has counted during its compilation.
>>
>> Ali
>
> Huh? what is a.d and b.d?

Yeah, I should have read your code before writing that. My 
comment is for the general case where a.d and b.d are two 
separte modules that are compiler separately. I thought that 
you wanted a counter to continue counting between modules.




That wold be nice but require external storage to an ctfe which 
is a limitation of ctfe's.


Ok, at least this post has helped me solve my problem. I guess 
the issue was the error message given.


The problem is I can't declare my "global" int variables directly 
inside the template. This does make it hard to use the same 
variable across multiple functions...


template A
{
int c; // makes c near useless, can't use it like a normal 
it...

}

solution, one has to use nested functions:

template A
{
 string templateScope()
 {
 int c;  // c now acts like a normal global int value to 
all nested functions.


 }
}


I think I understand why this works and is done this way but the 
error message given obfuscates the reason. Unfortunately it 
requires a messy technique to get around by using nested 
functions. (The parent function holds the global state of the 
child functions)


It would be nice if we had some way to data globally(in module).

e.g., __ctfestore["name"] = value;

I understand this wouldn't probably work well outside the module 
since compilation order may be not be consistent. (but maybe 
__ctfeVolitileStore could be used for cross module storage)


Re: Are associative arrays stable in D?

2013-07-16 Thread Jonathan M Davis
On Tuesday, July 16, 2013 21:37:13 Gary Willoughby wrote:
> Are associative arrays stable in D? I have to ask because i'm
> having a great deal of problems with them for simple operations.
> For example the following crashes.
> 
> import std.stdio;
> 
> void main(string[] args)
> {
> int[string] waiting;
> 
> waiting["gary"] = 1;
> waiting["tess"] = 2;
> 
> foreach (string key; waiting.byKey())
> {
> writeln(key);
> writeln(waiting[key]);
> waiting.remove(key);
> }
> }
> 
> If however you remove the .byKey() call and use .keys instead, it
> works!
> 
> Also if you remove the 'writeln(waiting[key]);' line from the
> above code it prints about 40 blank lines.

It's not safe to remove anything from the AA while iterating over it. Doing so 
will invalidate the range. If you did

foreach(auto key; waiting.keys())
{
 writeln(key);
 writeln(waiting[key]);
 waiting.remove(key);
}

then you'd be okay - either that or create a new array which you append the 
keys to that you want to remove and then have a second loop which loops over 
that array and removes each of the keys from the AA. In this particular case, 
since you're removing everything, it's probably more efficient to just allocate 
the array with all of them up front with keys(), but if you were only removing 
some of them, then it would probably be more efficient to create an array of 
the 
keys to remove and then iterate over those in a second loop.

- Jonathan M davis


Are associative arrays stable in D?

2013-07-16 Thread Gary Willoughby
Are associative arrays stable in D? I have to ask because i'm 
having a great deal of problems with them for simple operations. 
For example the following crashes.


import std.stdio;

void main(string[] args)
{
int[string] waiting;

waiting["gary"] = 1;
waiting["tess"] = 2;

foreach (string key; waiting.byKey())
{
writeln(key);
writeln(waiting[key]);
waiting.remove(key);
}
}

If however you remove the .byKey() call and use .keys instead, it 
works!


Also if you remove the 'writeln(waiting[key]);' line from the 
above code it prints about 40 blank lines.


Re: What is the correct way to test for an empty string?

2013-07-16 Thread Gary Willoughby

On Tuesday, 16 July 2013 at 19:33:13 UTC, bearophile wrote:

The right, safe and readable way is to use std.array.empty:

if (myString.empty)


OMG, of course. Thanks!



Re: What is the correct way to test for an empty string?

2013-07-16 Thread bearophile

Gary Willoughby:


What is the correct way to test for an empty string?

I've used

if (string == "")

and

if (string is null)

and both (O_o) in some places, it's starting to do my head in. 
What is the correct way?


The right, safe and readable way is to use std.array.empty:

if (myString.empty)

If you don't want to import functions, then test for the length:

if (string.length == 0)

Bye,
bearophile


Re: What is the correct way to test for an empty string?

2013-07-16 Thread Adam D. Ruppe

I just use

if(string.length == 0) {}

which covers both cases and is pretty intuitive too.


What is the correct way to test for an empty string?

2013-07-16 Thread Gary Willoughby

What is the correct way to test for an empty string?

I've used

if (string == "")

and

if (string is null)

and both (O_o) in some places, it's starting to do my head in. 
What is the correct way?


Re: interacting with a process with redirected stdin/stdout/stderr

2013-07-16 Thread Timothee Cour
On Tue, Jul 16, 2013 at 10:01 AM, Anthony Goins  wrote:

> On Monday, 15 July 2013 at 06:46:52 UTC, timotheecour wrote:
>
>> On Monday, 15 July 2013 at 03:49:10 UTC, Timothee Cour wrote:
>>
>>> I'm trying to interact with a process using std.process and
>>> redirected stdin/stdout/stderr.
>>> What would be the recommended way?
>>>
>>> For example:
>>> 
>>> auto pipes=pipeShell("myprocess",**Redirect.all);
>>> while(true){
>>>  pipes.stdin.rawWrite(some_**command);
>>>  foreach (line; pipes.stdout.byLine) {
>>>//do something with line
>>>  }
>>> }
>>> 
>>>
>>> This doesn't work because it might block inside pipes.stdout.byLine, as
>>> the
>>> process is requesting more inputs to be written to its stdin before
>>> outputting more bytes to its stdout.
>>>
>>> What's the right approach?
>>> * fcntl(fd, F_SETFL, O_NONBLOCK); didn't seem to work
>>> * reading pipes.stdout inside a separate thread?
>>> In that second case, how to cleanly dispose of a blocked thread when we
>>> no
>>> longer need it?
>>>
>>> Any detailed example would help.
>>> Thanks!
>>>
>>
>>
>>
>> I tried using a separate thread for reading the process' stdout. It
>> works, except that sometimes the output is shuffled out of order.
>>
>> Is there anything buggy in this:
>>
>> 
>> __gshared string output;
>>
>> void readBlocking(){
>> while ((c = fgetc(filepointer)) >= 0)
>>   output~=cast(char) c;
>> //NOTE: i can use something more efficient here but that's beside the
>> question
>> }
>>
>> thread = new Thread(& readBlocking);
>> output=null;
>> while(true){
>> Thread.sleep(...);
>> if(condition) break;
>> }
>> //now output is shuffled out of order sometimes
>> 
>>
>> Furthermore, is there a standard way to tell when a process is waiting
>> for stdin input ? (cf condition above). Currently I'm checking whether
>> 'output' was modified within a timeout period T, but that's fragile and
>> incurs of penalty of T at least.
>>
>
> Are you looking for select() or poll()
> Poll I believe is posix only but I think select is more widely available.
> Not much of an answer but I hope it helps
>
>

Thanks, I had actually used select to solve another problem I had:
[std.process: how to process stdout chunk by chunk without waiting for
process termination]
That should work for here as well.

I think std.process is a bit limited currently, I keep having to implement
basic stuff it doesn't support.


Re: interacting with a process with redirected stdin/stdout/stderr

2013-07-16 Thread Anthony Goins

On Monday, 15 July 2013 at 06:46:52 UTC, timotheecour wrote:

On Monday, 15 July 2013 at 03:49:10 UTC, Timothee Cour wrote:

I'm trying to interact with a process using std.process and
redirected stdin/stdout/stderr.
What would be the recommended way?

For example:

auto pipes=pipeShell("myprocess",Redirect.all);
while(true){
 pipes.stdin.rawWrite(some_command);
 foreach (line; pipes.stdout.byLine) {
   //do something with line
 }
}


This doesn't work because it might block inside 
pipes.stdout.byLine, as the
process is requesting more inputs to be written to its stdin 
before

outputting more bytes to its stdout.

What's the right approach?
* fcntl(fd, F_SETFL, O_NONBLOCK); didn't seem to work
* reading pipes.stdout inside a separate thread?
In that second case, how to cleanly dispose of a blocked 
thread when we no

longer need it?

Any detailed example would help.
Thanks!




I tried using a separate thread for reading the process' 
stdout. It works, except that sometimes the output is shuffled 
out of order.


Is there anything buggy in this:


__gshared string output;

void readBlocking(){
while ((c = fgetc(filepointer)) >= 0)
  output~=cast(char) c;
//NOTE: i can use something more efficient here but that's 
beside the question

}

thread = new Thread(& readBlocking);
output=null;
while(true){
Thread.sleep(...);
if(condition) break;
}
//now output is shuffled out of order sometimes


Furthermore, is there a standard way to tell when a process is 
waiting for stdin input ? (cf condition above). Currently I'm 
checking whether 'output' was modified within a timeout period 
T, but that's fragile and incurs of penalty of T at least.


Are you looking for select() or poll()
Poll I believe is posix only but I think select is more widely 
available.

Not much of an answer but I hope it helps



request for a RSS feed of the D Forum

2013-07-16 Thread JohnnyK
I could not find any posts on this and have not found a link on 
the site about this either.  It would be nice if there was a RSS 
feed for the forum at least for the announce forum.  It is very 
difficult to monitor changes and updates with so much activity 
just through the forum.  Sorry if this is the wrong place to post 
this but I did not see a forum for Forum suggestions or web site 
suggestions.


Re: Need a way to get compressed mangling of a symbol.

2013-07-16 Thread QAston

On Tuesday, 16 July 2013 at 13:58:10 UTC, Adam D. Ruppe wrote:
The reason I snipped the implementations here is the backend is 
under a more restrictive license so I don't want to get into 
copying that. But with just what I've said here combined with 
guess+check against dmd's output it might be enough to do a 
clean room implementation.


Thank you for the reply!

My current clean room implementation is limited to:

const(char)* mangledSymbol(alias symbol)()
{
static assert(((symbol.mangleof) ~ "\0").length < 128, "long 
names won't be available in a library!");

return ((symbol.mangleof) ~ "\0").ptr;
}

as it turned out i_didn't_need_that_descriptive_names. I'm 
posting it here, so maybe it'll be easier for some people to 
follow the currently bumpy road of DLLs in D :)


Re: Optlink search directory path containing spaces?

2013-07-16 Thread Jacob Carlborg

On 2013-07-16 12:41, Jeremy DeHaan wrote:

This seems kind of strange to me, but when I go to specify a search
directory for the linker I can't seem to get it to work for a path that
contains spaces.


It's a known issue.

--
/Jacob Carlborg


Re: nested enum like template generator

2013-07-16 Thread Ali Çehreli

On 07/15/2013 10:51 PM, JS wrote:

> On Tuesday, 16 July 2013 at 04:37:33 UTC, Ali Çehreli wrote:
>> On 07/15/2013 08:43 PM, JS wrote:
>>
>> > http://dpaste.dzfl.pl/7c8b0ba9
>> >
>> > Why the heck can't we use integers in ctfe's? There seems to
>> be no
>> > simple way to create a counter and this is one of the most
>> basic
>> > programming constructs to use.. yet with ctfe's it's
>> impossible.
>> >
>> > I'd like each variable in the nested structs to be
>> incremented properly.
>>
>> I did not read the code but just from your description, the separate
>> compilation model that D uses would preclude that. For example,
>> compilation of a.d would not know anything about the counter that b.d
>> has counted during its compilation.
>>
>> Ali
>
> Huh? what is a.d and b.d?

Yeah, I should have read your code before writing that. My comment is 
for the general case where a.d and b.d are two separte modules that are 
compiler separately. I thought that you wanted a counter to continue 
counting between modules.


> The template transforms a string into a D code string... which is then
> string mixed in. The counter and code generation have nothing to do with
> the result. A counter is needed in the generation of the code to
> generate enum like characteristics.
>
> It does use recursion, and I could pass a variable that counts the
> number of elements but this too would probably not work due to D
> bitching about using ints.

I must still be in the dark but I seriously doubt that you would have 
problems incrementing an int in D.


> I imagine one could hack D to make it's flawed CTFE system work, to some
> degree... like using strings:
>
>
> template inc(string s)
> {
>  string _(string a)
>  {
>  if (a == "0") return "1";
>  if (a == "1") return "2";
>  if (a == "2") return "3";
>  if (a == "3") return "4";
>  return "0";
>  }
>  enum inc = _(s); pragma(msg, ":"~_(s));
> }
>
> which is a modulo 4 incrementer. So, CTFE's have the ability to count...
> but extremely short sighted that they don't. I imagine can write a whole
> template library using strings to emulate ints in ctfe's... what a shame
> though...

That would be extreme.

Ali



Re: nested enum like template generator

2013-07-16 Thread Ali Çehreli

On 07/15/2013 08:43 PM, JS wrote:

> http://dpaste.dzfl.pl/7c8b0ba9
>
> Why the heck can't we use integers in ctfe's?

That is false:

import std.range;
import std.algorithm;
import std.conv;
import std.stdio;

string makeCode(int begin, int end)
{
auto result = appender!string(`enum made = "`);

iota(begin, end)
.map!(a => a.to!string)
.joiner(", ")
.copy(result);

result ~= `";`;

return result.data;
}

unittest
{
assert(makeCode(3, 7) == `enum made = "3, 4, 5, 6";`);
}

void main()
{
mixin (makeCode(-3, 3));
writeln(made);
}

> There seems to be no
> simple way to create a counter and this is one of the most basic
> programming constructs to use..

That would be pretty limiting, right?

> yet with ctfe's it's impossible.

I have a feeling that you had something else in mind.

> I'd like each variable in the nested structs to be incremented properly.

It should be simple to convert the code above to do that.

Ali



Re: Optlink search directory path containing spaces?

2013-07-16 Thread Jeremy DeHaan




Any chance:
-L+"C:\Users\Jeremy\Desktop\Search Directory\"

works?



Nope, same error.


Re: Need a way to get compressed mangling of a symbol.

2013-07-16 Thread Adam D. Ruppe

I'm looking at the dmd source now...

The compression is done in the backend, file cgobj.c

The conditions are:


#define LIBIDMAX 128
if (len > LIBIDMAX)
{
// Attempt to compress the name
name2 = id_compress(name, len);
 // snip
if (len2 > LIBIDMAX)// still too long
{
/* Form md5 digest of the name and store it in the
 * last 32 bytes of the name.
 */

// snip impl, open the source to see specific details




/**
 * Compress an identifier.
 * Format: if ASCII, then it's just the char
 *  if high bit set, then it's a length/offset pair
 * Returns:
 *  malloc'd compressed identifier
 */

char *id_compress(char *id, int idlen)
{



The implementation, same source file, looks like it compresses by 
looking for longest duplicate strings and then removes them, 
using the offset instead.




The reason I snipped the implementations here is the backend is 
under a more restrictive license so I don't want to get into 
copying that. But with just what I've said here combined with 
guess+check against dmd's output it might be enough to do a clean 
room implementation.




Or if Walter can give us permission to copy/paste this into a D 
file we could use id directly.


Need a way to get compressed mangling of a symbol.

2013-07-16 Thread QAston
I'd like to dynamically load procedures from a dll in my app. To 
load a symbol from a DLL i need it's mangled name. D currently 
offers .mangleof which I currently use to generate the name. It 
works very good, but only for short symbols. Is there any way to 
get the final mangled name of a symbol during compilation, or 
maybe there's some documentation describing how compression is 
done (code'd be fine too)? http://dlang.org/abi.html doesn't 
cover the compression scheme.


Re: trouble with long

2013-07-16 Thread bearophile

eles:

Don C.: "There's a root cause issue -- integer overflow is not 
an error in general.


A good design for a modern language is to offer safe numbers on 
default, and overflowing/modular integral types for the uncommon 
cases where the programmer wants such behaviors.


Bye,
bearophile


Re: trouble with long

2013-07-16 Thread bearophile

eles:

Don C.: "There's a root cause issue -- integer overflow is not 
an error in general. The paper which bearophile keeps posting, 
which he has apparently never read, shows quite convincingly

that you cannot make it an error in a C-family language. There
are just too many legitimate uses of integer wraparound.

eg. int.max + 200 - 300 should not be an error."


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

Bye,
bearophile


Re: trouble with long

2013-07-16 Thread eles

On Tuesday, 16 July 2013 at 11:14:44 UTC, bearophile wrote:

eles:

Bye,
bearophile


Don C.: "There's a root cause issue -- integer overflow is not an
error in general. The paper which bearophile keeps posting, which
he has apparently never read, shows quite convincingly that you
cannot make it an error in a C-family language. There are just
too many legitimate uses of integer wraparound.

eg. int.max + 200 - 300 should not be an error."

Frankly, I keep thinking if FreePascal didn't nail it the good
way: consider all integral values as belonging to the widest
integral type, perform calculation (as if) in that type, then
truncate (if needed) only the final result, on assignment.


Re: trouble with long

2013-07-16 Thread eles

On Tuesday, 16 July 2013 at 11:14:44 UTC, bearophile wrote:

eles:

Bye,
bearophile


Walter: "Consider all the addressing modes used - they are all 
adds, with no overflow checks. Secondly, they all rely on 
wraparound (overflow) arithmetic, after all, that is how 
subtraction is done."


I think the way to go is to introduce "sanitized" integral types,
in conjunction with some compiler flag. If one day Walter agrees
with... This way, everybody is free to use whatever it likes.


Re: Reverse Lexical Order

2013-07-16 Thread monarch_dodra

On Tuesday, 16 July 2013 at 01:13:15 UTC, H. S. Teoh wrote:
On Mon, Jul 15, 2013 at 08:59:44PM -0400, Jonathan M Davis 
wrote:

On Monday, July 15, 2013 14:48:08 Manfred Nowak wrote:
> Jonathan M Davis wrote:
> > gotos in such a context seem like a bit
> > of a nightmare to me though.
> 
> I did realize this nightmare. Therefore the assurance in the 
> docs
> is probably true only in the absence within the scope of at 
> least

> gotos to targets within the scope.

Well, I'd have to study exactly how goto works to say how 
exactly it
would interact with stuff like try-catch. I've pretty much 
only used
goto with case statements and loops and haven't spent the time 
trying
to sort out all of its idiosyncracies. I guess that I should 
add that

to be my todo list.

[...]

My understanding is that goto translates directly to a jump in 
assembly,
so jumping in/out of blocks with declarations or stuff that 
needs
cleanups should immediately raise red flags. Of course, the 
compiler may
do something intelligent by inserting implicit stack pointer 
adjustments
and/or cleanup blocks, but I wouldn't count on it unless the 
language

spec explicitly requires so.


T


That's wrong. That's "longjmp", which does a raw ASM jump.

C's goto correctly handles stack decrement if the jump would make 
you leave a scope (destroying a variable), and make a variable 
disappear. goto's aren't allowed to jump over declarations 
(unless they "skip" a scope entirelly). Some implementations 
allow it, but I have no idea how they non-POD type construction 
:S but stack pointer is always correctly handled.


With C++'s destructors, goto has also been "improved" to 
guarantee that the destructor is called when a goto would make a 
variable leave a scope. In C++, I don't think it is possible to 
"leak" a stack variable's destructor, short of doing a longjmp.


Long story short, in C, goto always perfectly safe (AFAIK). In 
C++, it depends on what the compiler will allow you to to do, 
depending on its "features". If it respects "strict ANSI", 
though, then you shouldn't be able to go wrong.




Related: I use goto fairly often, but I've yet to find a use-case 
for it outside of loop "improvement", or goto end cleanup. In 
both these cases, scope blocks should not be a problem.


Re: Optlink search directory path containing spaces?

2013-07-16 Thread monarch_dodra

On Tuesday, 16 July 2013 at 10:41:51 UTC, Jeremy DeHaan wrote:
This seems kind of strange to me, but when I go to specify a 
search directory for the linker I can't seem to get it to work 
for a path that contains spaces.


I tried to put quotes around the switch like I've done for 
other switches, but when my program goes to link I get some 
strange errors.


If I use something like "-L+C:\Users\Jeremy\Desktop\Search 
Directory\" (with the quotes) I get the errors


C:\Users\Jeremy\Desktop\Search.lib

 Warning 2: File Not Found C:\Users\Jeremy\Desktop\Search.lib

Directory.lib

 Warning 2: File Not Found Directory.lib


It seems to do the same thing even without the space in the 
path if I leave the quotes around it. The only way I have 
gotten it to work is by not using quotes and not having any 
spaces in the path to the directory I want to have searched. Am 
I doing something wrong?


Jeremy


Any chance:
-L+"C:\Users\Jeremy\Desktop\Search Directory\"

works?


Re: trouble with long

2013-07-16 Thread monarch_dodra

On Tuesday, 16 July 2013 at 10:37:59 UTC, eles wrote:


Isn't the promotion to int so awful? Better ideas? (yes, I know
about casting to long).


What do you mean, there is no promotion to int here.


Re: trouble with long

2013-07-16 Thread bearophile

eles:


Isn't the promotion to int so awful? Better ideas? (yes, I know
about casting to long).


Bug report/ER:
http://d.puremagic.com/issues/show_bug.cgi?id=4835

There is a pull request, but it's currently stalled:
http://d.puremagic.com/issues/show_bug.cgi?id=4835

Bye,
bearophile


Re: trouble with long

2013-07-16 Thread Simen Kjaeraas

On Tue, 16 Jul 2013 12:37:58 +0200, eles  wrote:


$cat test.cpp:

#include 

int main() {
long long x = 125000 * 2;
std::cout << x << std::endl;
return 0;
}

g++-generated exe displays: -1794967296

$cat test.d:

import std.stdio;

int main() {
long x = 125000 * 2;
writefln("%d",x);
return 0;
}

dmd- and gdc-generated exes display: -1794967296

compiling with g++ at least gives a warning:

warning: integer overflow in expression [-Woverflow]
long long x = 125000 * 2;

Both dmd and gdc do not complain in any way.

Isn't the promotion to int so awful? Better ideas? (yes, I know
about casting to long).


This is where integer suffixes can help:

long x = 125000L * 2;

--
Simen


Optlink search directory path containing spaces?

2013-07-16 Thread Jeremy DeHaan
This seems kind of strange to me, but when I go to specify a 
search directory for the linker I can't seem to get it to work 
for a path that contains spaces.


I tried to put quotes around the switch like I've done for other 
switches, but when my program goes to link I get some strange 
errors.


If I use something like "-L+C:\Users\Jeremy\Desktop\Search 
Directory\" (with the quotes) I get the errors


C:\Users\Jeremy\Desktop\Search.lib

 Warning 2: File Not Found C:\Users\Jeremy\Desktop\Search.lib

Directory.lib

 Warning 2: File Not Found Directory.lib


It seems to do the same thing even without the space in the path 
if I leave the quotes around it. The only way I have gotten it to 
work is by not using quotes and not having any spaces in the path 
to the directory I want to have searched. Am I doing something 
wrong?


Jeremy



trouble with long

2013-07-16 Thread eles

$cat test.cpp:

#include 

int main() {
long long x = 125000 * 2;
std::cout << x << std::endl;
return 0;
}

g++-generated exe displays: -1794967296

$cat test.d:

import std.stdio;

int main() {
long x = 125000 * 2;
writefln("%d",x);
return 0;
}

dmd- and gdc-generated exes display: -1794967296

compiling with g++ at least gives a warning:

warning: integer overflow in expression [-Woverflow]
long long x = 125000 * 2;

Both dmd and gdc do not complain in any way.

Isn't the promotion to int so awful? Better ideas? (yes, I know
about casting to long).


Re: Reverse Lexical Order

2013-07-16 Thread Manfred Nowak

On Tuesday, 16 July 2013 at 07:19:05 UTC, Jacob Carlborg wrote:

The docs say: "Any intervening finally clauses are executed,


This does not solve:
/begin{ code}


markA:
if( exp1) goto markB;
if( exp2) goto markC;
...
scope ...
...

markB:
if( exp3) goto markA;
if( exp4) goto markC;
...
scope ...
...

markC:


/end{ code}

where all expi are pairwise different.
-manfred


Re: Naming convention for template parameters

2013-07-16 Thread monarch_dodra
On Monday, 15 July 2013 at 23:09:59 UTC, Joseph Rushton Wakeling 
wrote:

On 07/16/2013 01:02 AM, H. S. Teoh wrote:

I generally use R 'cos it's less typing and I'm lazy


... ditto ... :-)

but Walter has been recently of the opinion that a more 
descriptive name
is necessary for ddoc purposes, e.g., 
MyStruct(InputRange)(InputRange r)

is much more self-documenting than MyStruct(R)(R r).


Yes, that was my main consideration for this case.  I'm worried 
about the
potential for clashes with other elements of the namespace, 
though.


I'm thinking in particular of the tendency to use Random as the 
template
parameter name for a random number generator, when Random is 
actually an alias
for the default RNG type.  I've proposed a blanket rewrite of 
such template
parameter names to Rng: 
http://d.puremagic.com/issues/show_bug.cgi?id=10434


Particular context is that I'm trying to tidy up/standardize 
some bits of

std.random and I'd like my standards to be future-proof. :-)


struct SomeRangeWrapper(Range)
{
alias R = Range;
//...
}

Fixed.

I think "Range" is better, because it shows up in the docs, and 
is a bit clearer than "R" (although anybody doing D should 
understand it). But when working, "R" is easier. The above 
approach solves both.


Re: nested enum like template generator

2013-07-16 Thread Dicebot

On Tuesday, 16 July 2013 at 05:51:53 UTC, JS wrote:

...


Once again you post a complex and messy snippet and than jump to 
wrong conclusions. This works:


template inc(int i)
{
enum inc = i + 1;
}

pragma(msg, inc!3);

Integers are treated normally in CTFE/templates, contrary to your 
last statement. You need to reduce to the real problem.


Re: Allocate N elements

2013-07-16 Thread monarch_dodra

On Monday, 15 July 2013 at 17:39:43 UTC, H. S. Teoh wrote:

On Mon, Jul 15, 2013 at 07:32:37PM +0200, monarch_dodra wrote:

On Monday, 15 July 2013 at 15:54:57 UTC, bearophile wrote:
>monarch_dodra:
>
>>>But that (of new arrays) is a bad design, it wastes too much
>>>memory, and I think it should be fixed. In Python this 
>>>doesn't

>>>overallocate:
>>
>>So what? The only thing you showed, is that 
>>minimallyInitialized
>>doesn't know how much it allocated. If you allocate 513 
>>elements

>>with malloc, you'll way over allocate too. What's your point?
>>You'll waste memory either way.
>
>I didn't know it, sorry. I forgot.
>Can we let minimallyInitializedArray know the capacity?

I'm working on it ;)

>Regarding the small arrays, so to avoid the memory wasting you
>need to allocate a larger one and slice it.
>
>Bye,
>bearophile

One of the problems is that when you want an arbitrarily sized
allocation, it is usually standard to allocate 2^N in size. 
While
this is optimal for "traditional" malloc, it's actually the 
*worst*
allocation size you could ask for a GC array with appendable 
info

(eg, traditional new) :/


This is wrong. The 2^N size should be applied *after* GC 
appendable info
(or whatever else bookkeeping info you need) has been accounted 
for, not
before. If the GC header/whatever requires, say, 16 bytes, then 
the
ideal array size should be 2^N-16, so that everything fits 
neatly within
a power of 2. Otherwise you end up with 2^N+16 bytes that are 
actually

allocated, and it just goes downhill from there.


T


Just to be clear, the GC itself has no overhead. Only the 
APPENDABLE bookkeeping does any overhead.

EG: GC.malloc(1024);
This will allocate a 1024 byte block. No problem here.

HOWEVER, if you write:
int[] arr = new int[](1000); //Allocates a  4Ki block
int[] arr = new int[](1024); //Allocates an 8Ki block
The example is a bit extreme, but you should get what I mean.

If you do a malloc with GC.BlkAttr.APPENDABLE, you will also get 
exactly what you asked for. However, it will be the user's 
responsibility to take into account that some of those allocated 
bytes will not actually be useable (the APPENDABLE block).


FYI, the way APPEDNABLE works:
Arrays 1-255 bytes: 1 extra byte will be appended for used 
capacity info at the end of the array.

Arrays 256-2046: 2 extra bytes will be appended.
2047+: The array will *start* with a 16 byte block for appendable 
info. A dummy 1 byte block will also be appended to the end of 
the block, for "arr[$ .. $]". (So yes, you need to accound for a 
*17* byte overhead)


That said, allocating an array using a straight up 
malloc(APPEDNABLE) is *very* complicated, and it is all very 
specific to the current GC anyways: It is very very error prone, 
and non portable.


Re: Types of regex

2013-07-16 Thread Larry

AAAh !!

Got it !

I will make the switch !

Thanks a lot :)

Larry


Re: Types of regex

2013-07-16 Thread H. S. Teoh
On Tue, Jul 16, 2013 at 08:15:16AM +0200, Larry wrote:
> I have gdc 4.6 on Debian testing.
> 
> Is that so old ?

That is extremely old. You want to get gdc-4.8.1 from unstable, if you
can. A great number of bugs have been fixed since gdc-4.6; in fact, the
entire std.regex has been replaced, which is probably why you're seeing
these problems with regexes that the rest of us don't see.


T

-- 
If it's green, it's biology, If it stinks, it's chemistry, If it has
numbers it's math, If it doesn't work, it's technology.


Re: Reverse Lexical Order

2013-07-16 Thread Jacob Carlborg

On 2013-07-16 03:11, H. S. Teoh wrote:


My understanding is that goto translates directly to a jump in assembly,
so jumping in/out of blocks with declarations or stuff that needs
cleanups should immediately raise red flags. Of course, the compiler may
do something intelligent by inserting implicit stack pointer adjustments
and/or cleanup blocks, but I wouldn't count on it unless the language
spec explicitly requires so.


The docs say: "Any intervening finally clauses are executed, along with 
releasing any intervening synchronization mutexes."


http://dlang.org/statement.html#GotoStatement

--
/Jacob Carlborg