Re: prune with dirEntries

2012-11-30 Thread Dan

On Friday, 30 November 2012 at 07:29:59 UTC, Joshua Niehus wrote:
On Friday, 30 November 2012 at 06:29:01 UTC, Joshua Niehus 
wrote:
I think if you go breadth first, you can filter out the 
unwanted directories before it delves into them


Good idea, thanks. I could not get original to compile as is - 
but the concept is just what was needed. I got an error on line 8:
Error: not a property dirEntries(path, cast(SpanMode)0, 
true).filter!(__lambda2)

I'm using a quite recent version of dmd and phobos.

But, I pulled the lamda out into a function and it works great. I 
assume the parallel is for performance, and it actually runs 
significantly slower than without on my test case - but no work 
is being done other than build the list of files, so that is 
probably normal. For my case the breakdown is:


No Pruning: 11 sec
Pruning Parallel: 4.78 sec
Pruning Serial: 0.377 sec

Thanks
Dan

-
import std.algorithm, std.regex, std.stdio, std.file;
import std.parallelism;

bool interested(DirEntry path) {
  static auto exclude = regex(r\.git|\.DS_Store, g);
  return match(path.name, exclude).empty;
}

DirEntry[] prune(string path, ref DirEntry[] files)
{
  static if(0) {
foreach(_path; 
taskPool.parallel(filter!interested(dirEntries(path, 
SpanMode.shallow  {

  files ~= _path;
  if (isDir(_path.name)) { prune(_path.name, files); }
}
  } else {
foreach(_path; filter!(interested)(dirEntries(path, 
SpanMode.shallow)))  {

  files ~= _path;
  if (isDir(_path.name)) { prune(_path.name, files); }
}
  }
  return files;
}

void main()
{
  DirEntry[] files;
  prune(/path, files);
  //  foreach(file;files) { writeln(file.name); }
}


Re: Type converter from build in to user type

2012-11-30 Thread js.mdnq

On Friday, 30 November 2012 at 03:40:31 UTC, Ali Çehreli wrote:

On 11/29/2012 07:24 PM, jerro wrote:

On Friday, 30 November 2012 at 02:59:06 UTC, js.mdnq wrote:
I have a struct I am trying convert from int's to the type. 
Since I
can't add a opCast overload to an int I don't know how to do 
it. My
opCast convertors in my class do not work for the assignment 
operator:



class myType
{
opCast, opAssign
}

mytype = 3;

Error that we can't convert an int to myType. While it's very 
easy to
go from a myType to whatever by writing a cast for it(in the 
class),

how do I go from an int to myType(in the class)?

For example, I can do

mytype = mytype.opCast(3);
or mytype.opAssign(3);

but these are too verbose to be useful.


Why can't you use opAssign? This works fine:

class A
{
void opAssign(int i)
{
writeln(i);
}
}

auto a = new A();
a = 1; // prints 1



A complete example:

import std.conv;

class C
{
int i;

this(int i)
{
this.i = i;
}

C opAssign(int i)
{
this.i = i;
return this;
}

int opCast(T : int)() const
{
return i;
}
}

void main()
{
auto c = new C(42);
c = 43;
auto i = to!int(c);
assert(i == 43);
}

Ali


Thanks, I was using a generic opCast which was causing the 
problem. It must have gotten that way from other mistakes I was 
probably making.


C!T opAssign(T i) rather than C!T opAssign(T)(T i)

It thought the D compiler would automatically deduce the second 
case but I guess it's redundant.





Re: Templated Function pointers

2012-11-30 Thread js.mdnq
It seems one can accomplish this using delegates assigned by 
generic functions. The delegate will end hold holding the state 
of the function. It sort of acts like a binder. It seems to work 
but more testing needs to be done. I'm not sure how efficient it 
is or if there is a better way but basically it seems rather 
elegant(rather than trying to create some new type to deal with 
it).








alias this

2012-11-30 Thread js.mdnq
I've seen this technique pop up in several things and I'm curious 
to what it is/how it's used?


alias t this;

does what? It seems like it's used as a way to trick the 
compiler into doing some cool/useful things?






Re: alias this

2012-11-30 Thread js.mdnq
On Friday, 30 November 2012 at 14:02:42 UTC, Andrej Mitrovic 
wrote:

On 11/30/12, js.mdnq js_adddot+m...@gmail.com wrote:

alias t this;


This should explain: http://dlang.org/class.html#AliasThis


Thanks, I'm sure I saw that at some point but I guess it just 
didn't sink in. This seems really cool and might solve a problem 
I had much more elegantly...


Re: Templated Function pointers

2012-11-30 Thread bearophile

js.mdnq:

It seems one can accomplish this using delegates assigned by 
generic functions.


If you care so much for performance, when you work with D 
delegates it's useful to know the difference between static/scope 
delegates (that are just a fat pointer) and closures (that often 
induce a heap allocation).


Bye,
bearophile


How can I store delegates in array?

2012-11-30 Thread Chopin

Hi!

I've never used delegates before etc. not really familiar with it.
I was trying something like this:

import std.stdio;
import std.regex;

bool lol(string name, string val)
{
if (name == lal)
if (val[0..3] == 2124)
return true;
return false;
}

bool lal(string name, string val) { return false; }

void main()
{
struct Filter
{
private bool delegate(string, string)[] delFuncs; // 
array with functions :D


public void add(bool delegate(string, string) 
filter_func) {

delFuncs ~= filter_func;
}
}

auto x = Filter();
x.add(lol);
x.add(lal);

writeln(x);
}

How can I make this work? Thank you :)


Re: How can I store delegates in array?

2012-11-30 Thread H. S. Teoh
On Fri, Nov 30, 2012 at 04:41:40PM +0100, Chopin wrote:
 Hi!
 
 I've never used delegates before etc. not really familiar with it.
[...]

You could try something like this:

alias bool delegate(string, string) DgType;
DgType[] arrayOfDelegates;


T

-- 
Why waste time learning, when ignorance is instantaneous? -- Hobbes, from 
Calvin  Hobbes


Re: How can I store delegates in array?

2012-11-30 Thread Chopin

I tried the following:

import std.stdio;
import std.regex;

bool lol(string name, string val)
{
if (name == lal)
if (val[0..3] == 2124)
return true;
return false;
}

bool lal(string name, string val) { return false; }
alias bool delegate(string, string) DgType;
void main()
{
struct Filter
{

private DgType[] delFuncs; // array with functions :D


public void add(DgType filter_func) {
delFuncs ~= filter_func;
}
}

auto x = Filter();
x.add(lol);
x.add(lal);

writeln(x);
}

Didn't work... just a bunch of errors...

t.d(28): Error: function t.main.Filter.add (bool delegate(string, 
string) filter_func) is not callable using argument types (bool 
function(string name, string v

al))
t.d(28): Error: cannot implicitly convert expression ( lol) of 
type bool function(string name, string val) to bool 
delegate(string, string)
t.d(29): Error: function t.main.Filter.add (bool delegate(string, 
string) filter_func) is not callable using argument types (bool 
function(string name, string v

al))
t.d(29): Error: cannot implicitly convert expression ( lal) of 
type bool function(string name, string val) to bool 
delegate(string, string)


Thanks for help!




Re: How can I store delegates in array?

2012-11-30 Thread H. S. Teoh
On Fri, Nov 30, 2012 at 04:57:44PM +0100, Chopin wrote:
 I tried the following:
 
 import std.stdio;
 import std.regex;
 
 bool lol(string name, string val)
 {
 if (name == lal)
 if (val[0..3] == 2124)
 return true;
 return false;
 }
 
 bool lal(string name, string val) { return false; }
 alias bool delegate(string, string) DgType;
 void main()
 {
 struct Filter
 {
 
 private DgType[] delFuncs; // array with functions :D
 
 
 public void add(DgType filter_func) {
 delFuncs ~= filter_func;
 }
 }
 
 auto x = Filter();
 x.add(lol);
 x.add(lal);
 
 writeln(x);
 }
 
 Didn't work... just a bunch of errors...
 
 t.d(28): Error: function t.main.Filter.add (bool delegate(string,
 string) filter_func) is not callable using argument types (bool
 function(string name, string v
 al))
[...]

Ah, I see the problem. What you want are *function pointers*, not
delegates. So do this instead:

alias bool function(string,string) FuncType;
struct Filter
{
private FuncType[] delFuncs;
...
}


T

-- 
Prosperity breeds contempt, and poverty breeds consent. -- Suck.com


Re: How can I store delegates in array?

2012-11-30 Thread Chopin

Amazing! It works! Thank you so much :)


Re: prune with dirEntries

2012-11-30 Thread Joshua Niehus

On Friday, 30 November 2012 at 12:02:51 UTC, Dan wrote:
Good idea, thanks. I could not get original to compile as is - 
but the concept is just what was needed. I got an error on line 
8:
Error: not a property dirEntries(path, cast(SpanMode)0, 
true).filter!(__lambda2)

I'm using a quite recent version of dmd and phobos.


hmm strange... I'm using 2.060 (on a mac),

But, I pulled the lamda out into a function and it works great. 
I assume the parallel is for performance, and it actually runs 
significantly slower than without on my test case - but no work 
is being done other than build the list of files, so that is 
probably normal. For my case the breakdown is:


No Pruning: 11 sec
Pruning Parallel: 4.78 sec
Pruning Serial: 0.377 sec


Thats cool.
Yea I thought parallel would make a big difference (in the 
positive sense) for large directories, but I guess if we are 
recursively spawning parallel tasks, the overhead involved starts 
accumulating, resulting in worse performance (my best guess 
anyway).





Linker error

2012-11-30 Thread RenatoUtsch

Hello,

I was trying to play with modules and import, but I couldn't 
understand why this code is giving linker errors:


/classy/widget.d

module classy.widget;

class ReturnItself
{
public ref ReturnItself returnItself()
{
return this;
}

public int returnNumber(in int number)
{
return number;
}
}


/testReturn.d

import std.stdio, std.conv, classy.widget;

void main()
{
auto returnItself = new ReturnItself;
int number = 13;

writeln(to!string(returnItself.returnItself()
.returnItself()
.returnItself()
.returnItself()
.returnNumber(number)));
}


The linker error is the following:

$ dmd testReturn.d
testReturn.o: In function `_Dmain':
testReturn.d:(.text._Dmain+0xa): undefined reference to 
`_D6classy6widget12ReturnItself7__ClassZ'

collect2: error: ld returned 1 exit status
--- errorlevel 1
$


I am using Fedora 17, x86_64.


I will be grateful for all help I can get.


Re: Apparent problem with GC not collecting on Windows

2012-11-30 Thread Dmitry Olshansky

11/30/2012 12:36 AM, Ali Çehreli пишет:


On 11/29/2012 12:06 PM, Michael wrote:
  Because you used uint instead of ubyte, array is bigger, memory
  exhausts faster.
  Oh, I see.
 
  3. Why it helps?
  GC.free(data.ptr);
 
  Initial leak happened because for some reason array allocated in
  previous iteration was not collected by GC when allocating new one, so
  the new one was allocated in another space growing the heap. If you
  place GC.free the array gets removed from heap on each iteration and
  each new allocation reuses the same memory, heap doesn't grow.
  If we do this manually it's works, but automatically is broken?
 

Nothing is broken. GC.free would have been applied by the GC only if
there have been no more references to the allocated block of memory.

The fact is, dmd uses a conservative GC. The issue is due to the
combination of conservative GC, 32-bit address space, and a large chunk
of memory. When that happens, it is very likely that any other value in
the system, including an innocent int, has the risk of looking like a
reference into that memory. For that reason the GC keeps that memory
block allocated.



I'd just throw in that we have a (almost) precise GC that is used by  at 
least one large project (the VisualD apparently). Though there were some 
problems with it. Anyway I'd expect to see it in upstream by 2.062 at 
least. It should help the cases like this tremendously.


P.S. Either way the manual memory management (and reuse) is the way to 
go with big allocations.


--
Dmitry Olshansky


Re: prune with dirEntries

2012-11-30 Thread Dmitry Olshansky

11/30/2012 11:29 AM, Joshua Niehus пишет:

On Friday, 30 November 2012 at 06:29:01 UTC, Joshua Niehus wrote:

I think if you go breadth first, you can filter out the unwanted
directories before it delves into them


oh wait... it probably still looks through all those dir's.
What about this?

import std.algorithm, std.regex, std.stdio, std.file;
import std.parallelism;
DirEntry[] prune(string path, ref DirEntry[] files)
{
   auto exclude = regex(r\.git|\.DS_Store, g);
   foreach(_path; taskPool.parallel(dirEntries(path, SpanMode.shallow)
 .filter!(a = match(a.name, exclude).empty)))
   {
 files ~= _path;


I do think that there is a race on 'files' variable. parallel doesn't 
auto-magically lock anything.



 if (isDir(_path.name)) { prune(_path.name, files); }


An yes, I have a bad feeling that spawning a few threads per directory 
recursively is a bad idea.




   }
return files;
}

void main()
{
   DirEntry[] files;
   prune(/path, files);
   foreach(file;files) { writeln(file.name); }
}



Otherwise I think there is a better way to filter out directories inside 
because here you a basically doing what dirEntries depth search does 
(but with recursion vs queue).


Maybe file it as an enhancement?


--
Dmitry Olshansky


Re: Linker error

2012-11-30 Thread Maxim Fomin

On Friday, 30 November 2012 at 18:44:31 UTC, RenatoUtsch wrote:

skipped
$ dmd testReturn.d
...


because you didn't compiled the second file.


Re: Linker error

2012-11-30 Thread RenatoUtsch

On Friday, 30 November 2012 at 19:09:12 UTC, Maxim Fomin wrote:

On Friday, 30 November 2012 at 18:44:31 UTC, RenatoUtsch wrote:

skipped
$ dmd testReturn.d
...


because you didn't compiled the second file.


Man, I was going to say that it didn't work, that I tested it 
before, but then I noticed that I added classy.widget.d to the 
command line, not classy/widget.d, it worked.


Sorry for the dumb mistake.


Re: prune with dirEntries

2012-11-30 Thread Jonathan M Davis
On Friday, November 30, 2012 13:02:50 Dan wrote:
 On Friday, 30 November 2012 at 07:29:59 UTC, Joshua Niehus wrote:
  On Friday, 30 November 2012 at 06:29:01 UTC, Joshua Niehus
  
  wrote:
  I think if you go breadth first, you can filter out the
  unwanted directories before it delves into them
 
 Good idea, thanks. I could not get original to compile as is -
 but the concept is just what was needed. I got an error on line 8:
 Error: not a property dirEntries(path, cast(SpanMode)0,
 true).filter!(__lambda2)
 I'm using a quite recent version of dmd and phobos.

If you're compiling with -property, filter must have the parens for the 
function call as it's a function, not a property. The !() is for the template 
arguments and is separate from the parens for the function call. That means 
that if you're compiling with -property and using UFCS, then you end up with 
range.filter!(pred)(), whereas you have range.filter!(pred).

- Jonathan M Davis


Re: alias this

2012-11-30 Thread Rob T

On Friday, 30 November 2012 at 14:14:36 UTC, js.mdnq wrote:
On Friday, 30 November 2012 at 14:02:42 UTC, Andrej Mitrovic 
wrote:

On 11/30/12, js.mdnq js_adddot+m...@gmail.com wrote:

alias t this;


This should explain: http://dlang.org/class.html#AliasThis


Thanks, I'm sure I saw that at some point but I guess it just 
didn't sink in. This seems really cool and might solve a 
problem I had much more elegantly...


Note that multiple alias this declarations are slated to be 
allowed, but have not yet been implemented:


---
Multiple AliasThis are allowed. For implicit conversions and 
forwarded lookups, all AliasThis declarations are attempted; if 
more than one AliasThis is eligible, the ambiguity is disallowed 
by raising an error. Note: Multiple AliasThis is currently 
unimplemented.

---




Re: alias this

2012-11-30 Thread js.mdnq

On Friday, 30 November 2012 at 21:46:47 UTC, Rob T wrote:

On Friday, 30 November 2012 at 14:14:36 UTC, js.mdnq wrote:
On Friday, 30 November 2012 at 14:02:42 UTC, Andrej Mitrovic 
wrote:

On 11/30/12, js.mdnq js_adddot+m...@gmail.com wrote:

alias t this;


This should explain: http://dlang.org/class.html#AliasThis


Thanks, I'm sure I saw that at some point but I guess it just 
didn't sink in. This seems really cool and might solve a 
problem I had much more elegantly...


Note that multiple alias this declarations are slated to be 
allowed, but have not yet been implemented:


---
Multiple AliasThis are allowed. For implicit conversions and 
forwarded lookups, all AliasThis declarations are attempted; if 
more than one AliasThis is eligible, the ambiguity is 
disallowed by raising an error. Note: Multiple AliasThis is 
currently unimplemented.

---


I've seen that, how does it work?

struct A{
 Sometype val1;
 int val2;
 alias val1 this;
 alias val2 this; //???
}


How can A act both as Sometype and int? (at least without major 
issues) Does the compiler try to choose the appropriate alias 
depending on the lvalue or rvalue?







Re: prune with dirEntries

2012-11-30 Thread Dan
On Friday, 30 November 2012 at 19:52:26 UTC, Jonathan M Davis 
wrote:


If you're compiling with -property, filter must have the parens 
for the
function call as it's a function, not a property. The !() is 
for the template
arguments and is separate from the parens for the function 
call. That means
that if you're compiling with -property and using UFCS, then 
you end up with

range.filter!(pred)(), whereas you have range.filter!(pred).


That is it, thanks. The first project I looked at was vibe and 
they used that flag so I put it in my script.


Regarding the timings, the relative orderings are the same, but 
the magnitude of the difference is much more reasonable now that 
I switched back to release of phobos, druntime (oops :-).


No filtering:
  parallel: 0.268 sec
  serial: 0.125 sec

With filtering:
  parallel: 0.119 sec
  serial: 0.064 sec


Compile And Run in emacs

2012-11-30 Thread Aytug

So I have installed dmd, gdc, emacs and d-mode.el on my Debian
machine.

I can compile the program fine with M-compile. The problem starts
after that.

I cannot run the output file properly from within emacs. Either
there is a way and I cannot find it, or there really is no way.

What I try instead:
1. Write the sourcecode.
2. M-compile.
3. Launch a separate terminal, and run the executable from there.
Or,
3. Launch a shell in emacs, and use that. Which sucks.

What am I doing wrong? Isn't there a compilerun option? And
one more thing, is there maybe a C-* alternative to M-compile
since it takes time to type that everytime?


Re: Compile And Run in emacs

2012-11-30 Thread Dan

On Friday, 30 November 2012 at 23:13:10 UTC, Aytug wrote:

So I have installed dmd, gdc, emacs and d-mode.el on my Debian
machine.

I can compile the program fine with M-compile. The problem 
starts

after that.

I cannot run the output file properly from within emacs. Either
there is a way and I cannot find it, or there really is no way.

What I try instead:
1. Write the sourcecode.
2. M-compile.
3. Launch a separate terminal, and run the executable from 
there.

Or,
3. Launch a shell in emacs, and use that. Which sucks.

What am I doing wrong? Isn't there a compilerun option? And
one more thing, is there maybe a C-* alternative to M-compile
since it takes time to type that everytime?


I use the lisp code below. Then from the source with main I do:
C-c @   To run the main in the current buffer
C-c #   To run the unit test in the current buffer


Thanks
Dan

-- lisp code

(defun unittest-d-file (args)
   (interactive sEnter args:)
   (setq fname (buffer-file-name))
   (setq cmdStr (concat time rdmd -unittest --main \   fname
\  args))
   (setq buffname (format *%s* cmdStr))
   (save-excursion
 (message (concat Running: cmdStr))
 (if (not (eq nil (get-buffer buffname))) (kill-buffer
buffname))
 (setq compilation-scroll-output t)
 (compile cmdStr)
 (set-buffer *compilation*)
 (rename-buffer buffname t)
 ))

(defun run-current-file-args (args)
   (let (extention-alist fname suffix progName cmdStr)
 (setq extention-alist ; a keyed list of file suffix to
comand-line program to run
   '(
 (php . php)
 (pl . perl)
 (py . python)
 (rb . ruby)
 (rspec . rspec)
 (js . js)
 (sh . bash)
 (bash . bash)
 (ml . ocaml)
 (vbs . cscript)
 (java . javac)
 (go . rungo.sh)
 (d . rdmd)
 (html . firefox)
 )
   )
 (setq fname (buffer-file-name))
 (setq suffix (file-name-extension fname))
 (setq progName (cdr (assoc suffix extention-alist)))
 (setq cmdStr (concat time  progName  \   fname \ 
args))
 (setq buffname (format *%s* cmdStr))

 (if (string-equal suffix el)
 (load-file fname)
   (if progName; is not nil
   (save-excursion
 (message (concat Running: cmdStr))
 (if (not (eq nil (get-buffer buffname))) (kill-buffer
buffname))
 (setq compilation-scroll-output t)
 (compile cmdStr)
 (set-buffer *compilation*)
 (rename-buffer buffname t)
 (message No recognized program file suffix for this
file.)
 )

(defun run-current-file ()
   Execute or compile the current file.
For example, if the current buffer is the file x.pl,
then it'll call “perl x.pl” in a shell.
The file can be php, perl, python, ruby, javascript, bash, ocaml,
java.
File suffix is used to determine what program to run.
   (interactive)
   (run-current-file-args ))

(defun run-current-file-prompt (args)
   (interactive sEnter args:)
   (run-current-file-args args))

(global-set-key \C-c@ 'run-current-file-prompt)
(global-set-key \C-c# 'unittest-d-file)

---


Re: Compile And Run in emacs

2012-11-30 Thread Timon Gehr

On 12/01/2012 12:13 AM, Aytug wrote:

So I have installed dmd, gdc, emacs and d-mode.el on my Debian
machine.

I can compile the program fine with M-compile. The problem starts
after that.

I cannot run the output file properly from within emacs. Either
there is a way and I cannot find it, or there really is no way.

What I try instead:
1. Write the sourcecode.
2. M-compile.
3. Launch a separate terminal, and run the executable from there.
Or,
3. Launch a shell in emacs, and use that. Which sucks.

What am I doing wrong? Isn't there a compilerun option? And
one more thing, is there maybe a C-* alternative to M-compile
since it takes time to type that everytime?


It is emacs. Every key binding is a possible alternative.
I use

(global-set-key (kbd \C-c c) 'compile)
(global-set-key (kbd \C-c n) 'next-error)

Usually I just run non-interactive programs from within compile,

M-x compile
dmd -run program args  program input

or
M-x compile
make  ./program args  program input

or just
M-x compile
./program args  program input

or even
M-x gdb
r  program input

otherwise I have a separate console (are you using a sane window 
manager?) or use M-x ansi-term.


Re: alias this

2012-11-30 Thread js.mdnq
I'm running into an issue of trying to get back the normal this 
pointer ;/


If I so `alias a this;` how do I get the pointer to the object 
back for other purposes?




get address of object if opCast is overridden

2012-11-30 Thread js.mdnq

Let O be an object with opCast overridden, then


writeln(O); //prints string
writeln(cast(void *)O)) // error, works fine if I comment out the 
opCast override

writeln(O) // address of pointer to O, not what I want.

I want to compare a few objects based on their location. (I know 
this is bad because of the GC, but I will probably pin them if I 
go this route)


It seems I have a difficult time getting the original behavior 
when something is syntactically overridden in D. I understand the 
point of cast(void *) not working when opCast is overridden but I 
then do not know how to still get the address.


Any Ideas?




Re: get address of object if opCast is overridden

2012-11-30 Thread Jonathan M Davis
On Saturday, December 01, 2012 03:05:00 js.mdnq wrote:
 Let O be an object with opCast overridden, then
 
 
 writeln(O); //prints string
 writeln(cast(void *)O)) // error, works fine if I comment out the
 opCast override
 writeln(O) // address of pointer to O, not what I want.
 
 I want to compare a few objects based on their location. (I know
 this is bad because of the GC, but I will probably pin them if I
 go this route)
 
 It seems I have a difficult time getting the original behavior
 when something is syntactically overridden in D. I understand the
 point of cast(void *) not working when opCast is overridden but I
 then do not know how to still get the address.
 
 Any Ideas?

For the moment, you're probably screwed. Certainly, if you overload opCast, 
then none of the normal casts work any more, which is a definite bug:

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

So, unless there's a way to do it without a cast, you're stuck. And I have no 
idea how you could possibly do it without a cast.

- Jonathan M Davis