Re: How to delete dynamic array ?

2013-12-30 Thread bearophile

Ilya Yaroshenko:


case 1:
 delete ar;


It's deprecated.



case 4:
 ar = null;// (assumed that ar is only one pointer to the same 
array)


It's the simpler way.



How to free memory to the system immediately?


What is your use case?

Bye,
bearophile


Re: How to delete dynamic array ?

2013-12-30 Thread Dicebot
Answer will make more sense if ar is assumed to be any 
heap-allocated object, not just dynamic array.


On Monday, 30 December 2013 at 06:52:20 UTC, Ilya Yaroshenko 
wrote:

case 1:
 delete ar;


Deprecated. Used to call destructor and GC.free after that


case 2:
 ar.destroy();


Current solution to free resources in deterministic way. Calls 
destructor and sets `ar` to init state so that it can be 
collected by GC at some unknown point later.



case 3:
 GC.free(ar.ptr);


Marks memory as freed in GC. Unsafe and discouraged because there 
can still be references pointing at it.



case 4:
 ar = null;// (assumed that ar is only one pointer to the same 
array)


Simply cleans the reference to an object. If it was the only 
reference, it will be destroyed and freed upon next GC cycle.



What is the difference?

How to free memory to the system immediately?


GC.free

However, if you want deterministic deallocation it makes more 
sense to use C malloc or custom allocators as GC tends to run 
faster if it is aware of less memory.


Re: How to delete dynamic array ?

2013-12-30 Thread Jakob Ovrum
On Monday, 30 December 2013 at 06:52:20 UTC, Ilya Yaroshenko 
wrote:

case 1:
 delete ar;
case 2:
 ar.destroy();
case 3:
 GC.free(ar.ptr);
case 4:
 ar = null;// (assumed that ar is only one pointer to the same 
array)


What is the difference?

How to free memory to the system immediately?


It depends on how it is allocated. The `delete` operator is 
deprecated, so it is never appropriate.


For GC memory (memory allocated with `new`, the concatenation 
operators or array literals) then you should just `null` any 
reference that is no longer used, leaving it to the GC to collect 
the memory when it sees fit. This guarantees memory safety, which 
is the primary purpose of a memory garbage collector.


If you really, really must free a chunk of GC memory *right now*, 
you can use GC.free, but you lose any guarantee of memory safety. 
If you can't think of a reason your code needs to do this, then 
your code probably doesn't need it.


If the array is allocated from a non-GC heap, such as the C heap, 
use the corresponding freeing function (C heap using `malloc` + 
`free`).


`destroy` is for running destructors on, and then invalidating, 
instances of user-defined types (UDTs). For generic code 
purposes, you can use it on non-UDTs, in which case it will just 
invalidate them. Values invalidated with `destroy` must not be 
used after invalidation - it is a logic error. What it means by 
invalidation is up to the implementation, but it guarantees that 
it won't free memory. Currently, it zero-blasts the value (which 
may be different from the value's default initializer).


Recursive lambda functions?

2013-12-30 Thread Ilya Yaroshenko

Hello!

Is there any ability to lambda function call itself?

Is it correct feature for D?

Best Regards,
Ilya


Re: Recursive lambda functions?

2013-12-30 Thread lomereiter

Use Y combinator?
http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com


Re: Recursive lambda functions?

2013-12-30 Thread TheFlyingFiddle
On Monday, 30 December 2013 at 11:23:39 UTC, Ilya Yaroshenko 
wrote:

Hello!

Is there any ability to lambda function call itself?

Is it correct feature for D?

Best Regards,
Ilya


Well it's possible to do this (sort of).

//You could for instance define the Factorial function like this.

int delegate(int) f;
f = (int x) = x  0 ? f(x - 1) * x : 1;

It's not very pretty and offers little compared to just make it a 
normal function.

void f(int x) { return x  0 ? f(x - 1) * x : 1; }


Debug/reduce stack overflow in DMD on Windows

2013-12-30 Thread Jacob Carlborg
I've ported one of my projects[1] from D1 to D2 and it works perfectly 
fine on Posix. Now when I try to compile the code on Windows I get a 
stack overflow. I really suck at Windows development, I don't even know 
where to start. Which debugger should I use that can handle the debug 
format DMD is compiled with?


[1] https://github.com/jacob-carlborg/dvm/tree/master

--
/Jacob Carlborg


Re: Possible bug - should the following code cause an access violation exception?

2013-12-30 Thread Ali Çehreli

On 12/29/2013 10:38 PM, Afshin wrote:

module test;

class Foo {
 public static ulong next = 0;

 public static ulong getNext() {
 return next++;
 }
}

void main() {
 Foo.getNext();
}

/*
The next++ is the culprit.
Using a ++next does not throw an exception.
*/


Must have already been fixed. No problem on git head.

Ali



Re: Debug/reduce stack overflow in DMD on Windows

2013-12-30 Thread Benjamin Thaut

Am 30.12.2013 14:04, schrieb Jacob Carlborg:

I've ported one of my projects[1] from D1 to D2 and it works perfectly
fine on Posix. Now when I try to compile the code on Windows I get a
stack overflow. I really suck at Windows development, I don't even know
where to start. Which debugger should I use that can handle the debug
format DMD is compiled with?

[1] https://github.com/jacob-carlborg/dvm/tree/master



Compile in 64-bit and use Visual Studio or Visual Studio Express to 
debug the application. If you want to compile in 32-bit you will need to 
run cv2pdb on the generated exectuable before debugging with visual 
studio. cv2pdb is part of VisualD which I recommend using for any 
windows development.


Kind Regards
Benjamin Thaut


Re: boilerplate generation

2013-12-30 Thread Carl Sturtivant


On Monday, 30 December 2013 at 04:35:34 UTC, Dicebot wrote:

It can be forced by pragma(mangle) though. Updated code: [...]


Never heard of pragma(mangle)! Very useful. What role does it 
play in D? Is it guaranteed implemented on x86 or amd64?


Thanks for the answer, very nice.


Re: boilerplate generation

2013-12-30 Thread John Colvin
On Monday, 30 December 2013 at 17:33:13 UTC, Carl Sturtivant 
wrote:


On Monday, 30 December 2013 at 04:35:34 UTC, Dicebot wrote:

It can be forced by pragma(mangle) though. Updated code: [...]


Never heard of pragma(mangle)! Very useful. What role does it 
play in D? Is it guaranteed implemented on x86 or amd64?


Thanks for the answer, very nice.


It's unrelated to the target architecture, it's just for naming. 
See dlang.org/abi.html


module std.regex

2013-12-30 Thread Benji

Hello,
when I try to run following code:

import std.stdio;
import std.net.curl;

void main()
{
writeln(dlang.org);
}

I get following error:

Fatal Error while loading 
'/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64':

The module 'std.regex' is already defined in './maina'.
Segmentation fault (core dumped)

Somewhere I read that this should fix it:
- Make ModuleInfos immutable, which is something we should do 
anyhow.


But what are ModuleInfos ? Where I can find them and what 
exactly to do with them?


Slices, appending to arbitrary position

2013-12-30 Thread Dfr

This simple example:

string[] a;
a[10] = hello;

Gives me: core.exception.RangeError: Range violation

I know about this way:

string[] a;
a = new string[11];
a[10] = hello;

But what if i need do this many times with the same array like 
this:


a[10] = a;
...
a[1] = b;
..
a[1000] = c;

If i will call a = new string[11] all those many times, isn't 
this will be inefficient ? Also it will clear all previous 
contents of a, which is not suitable.


Re: Slices, appending to arbitrary position

2013-12-30 Thread Chris Cain

On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote:

This simple example:

string[] a;
a[10] = hello;

Gives me: core.exception.RangeError: Range violation

I know about this way:

string[] a;
a = new string[11];
a[10] = hello;

But what if i need do this many times with the same array like 
this:


a[10] = a;
...
a[1] = b;
..
a[1000] = c;


Does it *need* to be an array for some reason?
If so, resize the array prior.

Something like:

// index is the position you're changing
// value is the value you're changing to
if(a.length = index) {
a.length = index+1;
}
a[index] = value;

If you're just mapping integers to strings, then you're probably 
looking for an associative array:

http://dlang.org/hash-map.html

This is probably more like what you actually want:

string[size_t] a;
a[1] = works fine;
a[10] = also works fine;




isn't this will be inefficient ?


Yes. Resizing the array many times is very inefficient. Either 
use an associative array or know ahead of time what your array's 
length needs to be (or, at least, what it will likely need to 
be).


Re: Slices, appending to arbitrary position

2013-12-30 Thread bearophile

Dfr:


string[] a;
a[10] = hello;

Gives me: core.exception.RangeError: Range violation


Because 'a' has length 0, so the position with index 11 doesn't 
exists in the array.


By the way, this is not an appending, it's a (failed) 
assignment.




I know about this way:

string[] a;
a = new string[11];
a[10] = hello;

But what if i need do this many times with the same array like 
this:


a[10] = a;
...
a[1] = b;
..
a[1000] = c;

If i will call a = new string[11] all those many times, isn't 
this will be inefficient ? Also it will clear all previous 
contents of a, which is not suitable.


If you need to assign strings randomly then a good solution is to 
use an associative array, that is a quite different data 
structure:


string[int] aa;
aa[10] = a;
aa[1] = b;
aa[1000] = c;


As alternative if you want a normal dynamic array, you can resize 
it:


string[int] a;
a.length = max(a.length, 10 + 1);
a[10] = a;
a.length = max(a.length, 1 + 1);
a[1] = b;
a.length = max(a.length, 1000 + 1);
a[1000] = c;

Bye,
bearophile


Re: Slices, appending to arbitrary position

2013-12-30 Thread Jakob Ovrum

On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote:

This simple example:

string[] a;
a[10] = hello;

Gives me: core.exception.RangeError: Range violation

I know about this way:

string[] a;
a = new string[11];
a[10] = hello;

But what if i need do this many times with the same array like 
this:


a[10] = a;
...
a[1] = b;
..
a[1000] = c;

If i will call a = new string[11] all those many times, isn't 
this will be inefficient ? Also it will clear all previous 
contents of a, which is not suitable.


Arrays are contiguous chunks of memory. If you wanted to store 
c as the 1000th element in an array of strings, that array 
needs to have room for 1000 elements.


Perhaps what you want is an associative array:


string[uint] aa;
aa[10] = a;
aa[1] = b;
aa[1000] = c;

writeln(aa[10], aa[1], aa[1000]);



Re: module std.regex

2013-12-30 Thread John Colvin

On Monday, 30 December 2013 at 18:08:42 UTC, Benji wrote:

Hello,
when I try to run following code:

import std.stdio;
import std.net.curl;

void main()
{
writeln(dlang.org);
}

I get following error:

Fatal Error while loading 
'/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64':

The module 'std.regex' is already defined in './maina'.
Segmentation fault (core dumped)

Somewhere I read that this should fix it:
- Make ModuleInfos immutable, which is something we should do 
anyhow.


But what are ModuleInfos ? Where I can find them and what 
exactly to do with them?


Which compiler/version?


Re: Slices, appending to arbitrary position

2013-12-30 Thread Dfr


Thank you for replies, i think here i can use assoc array, but 
sometimes it is not suitable because it is not preserve order.




On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote:

This simple example:

string[] a;
a[10] = hello;

Gives me: core.exception.RangeError: Range violation

I know about this way:

string[] a;
a = new string[11];
a[10] = hello;

But what if i need do this many times with the same array like 
this:


a[10] = a;
...
a[1] = b;
..
a[1000] = c;


Does it *need* to be an array for some reason?
If so, resize the array prior.

Something like:

// index is the position you're changing
// value is the value you're changing to
if(a.length = index) {
a.length = index+1;
}
a[index] = value;

If you're just mapping integers to strings, then you're 
probably looking for an associative array:

http://dlang.org/hash-map.html

This is probably more like what you actually want:

string[size_t] a;
a[1] = works fine;
a[10] = also works fine;




isn't this will be inefficient ?


Yes. Resizing the array many times is very inefficient. Either 
use an associative array or know ahead of time what your 
array's length needs to be (or, at least, what it will likely 
need to be).


Re: module std.regex

2013-12-30 Thread Benji

On Monday, 30 December 2013 at 18:36:24 UTC, John Colvin wrote:

On Monday, 30 December 2013 at 18:08:42 UTC, Benji wrote:

Hello,
when I try to run following code:

import std.stdio;
import std.net.curl;

void main()
{
writeln(dlang.org);
}

I get following error:

Fatal Error while loading 
'/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64':

The module 'std.regex' is already defined in './maina'.
Segmentation fault (core dumped)

Somewhere I read that this should fix it:
- Make ModuleInfos immutable, which is something we should do 
anyhow.


But what are ModuleInfos ? Where I can find them and what 
exactly to do with them?


Which compiler/version?


DMD 2.064-2 64bit, Ubuntu 13.10


Re: Slices, appending to arbitrary position

2013-12-30 Thread H. S. Teoh
On Mon, Dec 30, 2013 at 06:40:24PM +, Dfr wrote:
 
 Thank you for replies, i think here i can use assoc array, but
 sometimes it is not suitable because it is not preserve order.

Maybe you can use std.container.RedBlackTree instead? That will preserve
order (but at the cost of asymptotically slower lookups / insertions).


T

-- 
People who are more than casually interested in computers should have at
least some idea of what the underlying hardware is like. Otherwise the
programs they write will be pretty weird. -- D. Knuth


Re: module std.regex

2013-12-30 Thread Dmitry Olshansky

30-Dec-2013 22:08, Benji пишет:

Hello,
when I try to run following code:

import std.stdio;
import std.net.curl;

void main()
{
 writeln(dlang.org);
}

I get following error:

Fatal Error while loading '/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64':
 The module 'std.regex' is already defined in './maina'.
Segmentation fault (core dumped)



It's a bug in 2.064-2 when using shared library. You as end user can't 
do much about it - wait for the next release where it should be fixed or 
use static linking for the moment.



Somewhere I read that this should fix it:
- Make ModuleInfos immutable, which is something we should do anyhow.



This is part of core developers discussion and isn't something easily 
tweaked (else it would've been already fixed).



--
Dmitry Olshansky


Re: module std.regex

2013-12-30 Thread Benji
On Monday, 30 December 2013 at 19:27:43 UTC, Dmitry Olshansky 
wrote:

30-Dec-2013 22:08, Benji пишет:

Hello,
when I try to run following code:

import std.stdio;
import std.net.curl;

void main()
{
writeln(dlang.org);
}

I get following error:

Fatal Error while loading 
'/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64':

The module 'std.regex' is already defined in './maina'.
Segmentation fault (core dumped)



It's a bug in 2.064-2 when using shared library. You as end 
user can't do much about it - wait for the next release where 
it should be fixed or use static linking for the moment.



Somewhere I read that this should fix it:
- Make ModuleInfos immutable, which is something we should do 
anyhow.




This is part of core developers discussion and isn't something 
easily tweaked (else it would've been already fixed).


Thanks! Could be downgrading to 2.063 the solution?


Re: boilerplate generation

2013-12-30 Thread Carl Sturtivant

On Monday, 30 December 2013 at 17:46:57 UTC, John Colvin wrote:
It's unrelated to the target architecture, it's just for 
naming. See dlang.org/abi.html



Apologies, I was perhaps unclear. I'm just wondering if 
pragma(mangle) is guaranteed to be implemented, so I can safely 
put it in portable D. It's not mentioned in 
http://dlang.org/pragma.html




Re: Debug/reduce stack overflow in DMD on Windows

2013-12-30 Thread Jacob Carlborg

On 2013-12-30 17:19, Benjamin Thaut wrote:


Compile in 64-bit and use Visual Studio or Visual Studio Express to
debug the application. If you want to compile in 32-bit you will need to
run cv2pdb on the generated exectuable before debugging with visual
studio. cv2pdb is part of VisualD which I recommend using for any
windows development.


I'll give that a try, thanks.

--
/Jacob Carlborg


Re: boilerplate generation

2013-12-30 Thread Dicebot
On Monday, 30 December 2013 at 20:04:00 UTC, Carl Sturtivant 
wrote:
Apologies, I was perhaps unclear. I'm just wondering if 
pragma(mangle) is guaranteed to be implemented, so I can safely 
put it in portable D. It's not mentioned in 
http://dlang.org/pragma.html


Nature of reference compiler is that anything implemented there 
is approved as part of spec. I guess one implementing it just 
forgot to add matching documentation entry as it is relatively 
new addition.


https://d.puremagic.com/issues/show_bug.cgi?id=11846


Re: Recursive lambda functions?

2013-12-30 Thread Ilya Yaroshenko

On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote:

Use Y combinator?
http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com


This is not lambda =(

I want something like

enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5);
//Recursive pure lambda function


A better way to write this function? (style question)

2013-12-30 Thread Thomas Gann
I've written a Markov bot in D, and I have function whose job it 
is to take an input string, convert all newline characters to 
spaces and all uppercase letters to lowercase, and then return an 
array of words that are generated by splitting the string up by 
whitespace. Here is the function is question:


string[] split_sentence(string input)
{
string line;

foreach(c; input)
{
if(c == '\n' || c == '\r')
line ~= ' ';

else
line ~= c.toLower();
}

return line.splitter(' ').filter!(a = a.length).array;
}

Obviously, one issue is that because the string is immutable, I 
can't modify it directly, and so I actually build an entirely new 
string in place. I would have just made a mutable duplicate of 
the input and modify that, but then I would get errors returning, 
because it expects string[] and not char[][]. Is there a more 
elegant way to do what I'm doing?


Re: Recursive lambda functions?

2013-12-30 Thread lomereiter
On Monday, 30 December 2013 at 21:15:43 UTC, Ilya Yaroshenko 
wrote:

I want something like

enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5);
//Recursive pure lambda function


That isn't supported in D. And cases where this would be useful 
are too rare to add complexity to the language. Just use a 
regular function, it's not much more code.


Re: Recursive lambda functions?

2013-12-30 Thread Timon Gehr

On 12/30/2013 10:15 PM, Ilya Yaroshenko wrote:

On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote:

Use Y combinator?
http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com



This is not lambda =(

I want something like

enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5);
//Recursive pure lambda function



enum factorial5=(function int(a)=a==0?1:a*__traits(parent,{})(a-1))(5);

(In D, you need to specify the return type for a recursive function
declaration. If one doesn't here, DMD crashes, which is a bug.
https://d.puremagic.com/issues/show_bug.cgi?id=11848)


Re: A better way to write this function? (style question)

2013-12-30 Thread John Colvin

On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote:
I've written a Markov bot in D, and I have function whose job 
it is to take an input string, convert all newline characters 
to spaces and all uppercase letters to lowercase, and then 
return an array of words that are generated by splitting the 
string up by whitespace. Here is the function is question:


string[] split_sentence(string input)
{
string line;

foreach(c; input)
{
if(c == '\n' || c == '\r')
line ~= ' ';

else
line ~= c.toLower();
}

return line.splitter(' ').filter!(a = a.length).array;
}

Obviously, one issue is that because the string is immutable, I 
can't modify it directly, and so I actually build an entirely 
new string in place. I would have just made a mutable duplicate 
of the input and modify that, but then I would get errors 
returning, because it expects string[] and not char[][]. Is 
there a more elegant way to do what I'm doing?



A few points:

by declaring a new string and appending to it you are risking a 
lot of allocations. Either use std.array.appender or allocate the 
array with the correct size at the beginning.


using .array on the end of the ufcs chain is yet another 
allocation. It can be avoided using std.algorithm.copy to copy 
the result back in to 'line'


In my opinion the whole API would be better as range-based:

auto splitSentence(R)(R input)
if(isInputRange!R)
{
return input
   .map!(c = (c == \n[0] || c == \r[0]) ? ' ' : 
c.toLower)

   .splitter!(' ')
   .filter!(a = !(a.empty));
}


Re: Debug/reduce stack overflow in DMD on Windows

2013-12-30 Thread Vladimir Panteleev

On Monday, 30 December 2013 at 13:04:38 UTC, Jacob Carlborg wrote:
I've ported one of my projects[1] from D1 to D2 and it works 
perfectly fine on Posix. Now when I try to compile the code on 
Windows I get a stack overflow. I really suck at Windows 
development, I don't even know where to start. Which debugger 
should I use that can handle the debug format DMD is compiled 
with?


[1] https://github.com/jacob-carlborg/dvm/tree/master


You could try reducing the bug using DustMite, and this helper:

https://github.com/CyberShadow/DustMite/wiki/Suppressing-Windows-crashes


Re: Recursive lambda functions?

2013-12-30 Thread Meta
On Monday, 30 December 2013 at 21:15:43 UTC, Ilya Yaroshenko 
wrote:

On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote:

Use Y combinator?
http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com


This is not lambda =(

I want something like

enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5);
//Recursive pure lambda function


You can do this with __traits(parent, {}), but it's ugly.

auto fact = function(int n)
{
if (n == 0)
{
return 1;
}
else
{
enum self = __traits(parent, {});

return n * self(n - 1);
}
};

Unfortunately, a shorter version written with the lambda syntax 
doesn't work, it just segfaults:


auto fact = (int n) =
(n  2)
? 1
: n * __traits(parent, {})(n - 1);


Re: A better way to write this function? (style question)

2013-12-30 Thread John Colvin

On Monday, 30 December 2013 at 22:17:21 UTC, John Colvin wrote:

On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote:
I've written a Markov bot in D, and I have function whose job 
it is to take an input string, convert all newline characters 
to spaces and all uppercase letters to lowercase, and then 
return an array of words that are generated by splitting the 
string up by whitespace. Here is the function is question:


string[] split_sentence(string input)
{
   string line;

   foreach(c; input)
   {
   if(c == '\n' || c == '\r')
   line ~= ' ';

   else
   line ~= c.toLower();
   }

   return line.splitter(' ').filter!(a = a.length).array;
}

Obviously, one issue is that because the string is immutable, 
I can't modify it directly, and so I actually build an 
entirely new string in place. I would have just made a mutable 
duplicate of the input and modify that, but then I would get 
errors returning, because it expects string[] and not 
char[][]. Is there a more elegant way to do what I'm doing?



A few points:

by declaring a new string and appending to it you are risking a 
lot of allocations. Either use std.array.appender or allocate 
the array with the correct size at the beginning.


using .array on the end of the ufcs chain is yet another 
allocation. It can be avoided using std.algorithm.copy to copy 
the result back in to 'line'


In my opinion the whole API would be better as range-based:

auto splitSentence(R)(R input)
if(isInputRange!R)
{
return input
   .map!(c = (c == \n[0] || c == \r[0]) ? ' ' : 
c.toLower)

   .splitter!(' ')
   .filter!(a = !(a.empty));
}


sorry, ignore that attempt, it's woefully broken...


Re: A better way to write this function? (style question)

2013-12-30 Thread Brad Anderson

On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote:
I've written a Markov bot in D, and I have function whose job 
it is to take an input string, convert all newline characters 
to spaces and all uppercase letters to lowercase, and then 
return an array of words that are generated by splitting the 
string up by whitespace. Here is the function is question:


string[] split_sentence(string input)
{
string line;

foreach(c; input)
{
if(c == '\n' || c == '\r')
line ~= ' ';

else
line ~= c.toLower();
}

return line.splitter(' ').filter!(a = a.length).array;
}

Obviously, one issue is that because the string is immutable, I 
can't modify it directly, and so I actually build an entirely 
new string in place. I would have just made a mutable duplicate 
of the input and modify that, but then I would get errors 
returning, because it expects string[] and not char[][]. Is 
there a more elegant way to do what I'm doing?


Not a huge improvement and it could be a lot faster, no doubt:

string[] split_sentence(string input)
{
import std.regex;
auto split_re = ctRegex!(r[\n\r ]);
return input.split(split_re)
.map!toLower
.filter!(a = !a.empty)
.array();
}

You could return the result of filter instead of an array to make 
it lazy and avoid an allocation if the caller is able to use it 
in that form. toLower had some really slow and incorrect behavior 
but I think that was fixed in 2.064.  It still might be ASCII 
only though.  I believe std.uni has a toLower that is correct for 
all of unicode.


Re: A better way to write this function? (style question)

2013-12-30 Thread Brad Anderson

On Monday, 30 December 2013 at 22:30:02 UTC, John Colvin wrote:

On Monday, 30 December 2013 at 22:17:21 UTC, John Colvin wrote:

On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote:
I've written a Markov bot in D, and I have function whose job 
it is to take an input string, convert all newline characters 
to spaces and all uppercase letters to lowercase, and then 
return an array of words that are generated by splitting the 
string up by whitespace. Here is the function is question:


string[] split_sentence(string input)
{
  string line;

  foreach(c; input)
  {
  if(c == '\n' || c == '\r')
  line ~= ' ';

  else
  line ~= c.toLower();
  }

  return line.splitter(' ').filter!(a = a.length).array;
}

Obviously, one issue is that because the string is immutable, 
I can't modify it directly, and so I actually build an 
entirely new string in place. I would have just made a 
mutable duplicate of the input and modify that, but then I 
would get errors returning, because it expects string[] and 
not char[][]. Is there a more elegant way to do what I'm 
doing?



A few points:

by declaring a new string and appending to it you are risking 
a lot of allocations. Either use std.array.appender or 
allocate the array with the correct size at the beginning.


using .array on the end of the ufcs chain is yet another 
allocation. It can be avoided using std.algorithm.copy to copy 
the result back in to 'line'


In my opinion the whole API would be better as range-based:

auto splitSentence(R)(R input)
   if(isInputRange!R)
{
   return input
  .map!(c = (c == \n[0] || c == \r[0]) ? ' ' : 
c.toLower)

  .splitter!(' ')
  .filter!(a = !(a.empty));
}


sorry, ignore that attempt, it's woefully broken...


Re: weird literal syntax, you didn't happen to be using dpaste to 
test and have trouble with character literals, did you?  Because 
I did and thought I was going insane until realized DPaste was 
broken.


Re: A better way to write this function? (style question)

2013-12-30 Thread John Colvin

On Monday, 30 December 2013 at 22:38:43 UTC, Brad Anderson wrote:

On Monday, 30 December 2013 at 22:30:02 UTC, John Colvin wrote:

On Monday, 30 December 2013 at 22:17:21 UTC, John Colvin wrote:
On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann 
wrote:
I've written a Markov bot in D, and I have function whose 
job it is to take an input string, convert all newline 
characters to spaces and all uppercase letters to lowercase, 
and then return an array of words that are generated by 
splitting the string up by whitespace. Here is the function 
is question:


string[] split_sentence(string input)
{
 string line;

 foreach(c; input)
 {
 if(c == '\n' || c == '\r')
 line ~= ' ';

 else
 line ~= c.toLower();
 }

 return line.splitter(' ').filter!(a = a.length).array;
}

Obviously, one issue is that because the string is 
immutable, I can't modify it directly, and so I actually 
build an entirely new string in place. I would have just 
made a mutable duplicate of the input and modify that, but 
then I would get errors returning, because it expects 
string[] and not char[][]. Is there a more elegant way to do 
what I'm doing?



A few points:

by declaring a new string and appending to it you are risking 
a lot of allocations. Either use std.array.appender or 
allocate the array with the correct size at the beginning.


using .array on the end of the ufcs chain is yet another 
allocation. It can be avoided using std.algorithm.copy to 
copy the result back in to 'line'


In my opinion the whole API would be better as range-based:

auto splitSentence(R)(R input)
  if(isInputRange!R)
{
  return input
 .map!(c = (c == \n[0] || c == \r[0]) ? ' ' : 
c.toLower)

 .splitter!(' ')
 .filter!(a = !(a.empty));
}


sorry, ignore that attempt, it's woefully broken...


Re: weird literal syntax, you didn't happen to be using dpaste 
to test and have trouble with character literals, did you?  
Because I did and thought I was going insane until realized 
DPaste was broken.


oohhh so that was what that was. Anyway, here's what I have so 
far:


import std.range : isInputRange;

auto splitSentence(R)(R input)
if(isInputRange!R)
{
import std.algorithm : map, splitter, filter;
import std.uni : toLower;
import std.range : ElementType;

dchar preProc(ElementType!R c)
{
return (c == '\n' || c == '\r') ? ' ' : c.toLower;
}

return input
.map!preProc
.splitter!(c = c == ' ')
.filter!(a = !(a.empty));
}

I have to have the function instead of a lamda in order to get 
the return type correct. I guess I could cast or use std.conv.to 
instead.


Anyway, the big problem I've hit is that AFAICT std.algorithm 
makes a complete mess of unicode and i can't find a byCodeUnit 
range anywhere in order to make it correct.


Re: Recursive lambda functions?

2013-12-30 Thread Meta

On Monday, 30 December 2013 at 21:58:29 UTC, Timon Gehr wrote:

On 12/30/2013 10:15 PM, Ilya Yaroshenko wrote:

On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote:

Use Y combinator?
http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com



This is not lambda =(

I want something like

enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5);
//Recursive pure lambda function



enum factorial5=(function 
int(a)=a==0?1:a*__traits(parent,{})(a-1))(5);


(In D, you need to specify the return type for a recursive 
function

declaration. If one doesn't here, DMD crashes, which is a bug.
https://d.puremagic.com/issues/show_bug.cgi?id=11848)


And of course I'm wrong about that as soon as I post. No idea why 
one works when the other doesn't...


Re: A better way to write this function? (style question)

2013-12-30 Thread bearophile

Thomas Gann:

I've written a Markov bot in D, and I have function whose job 
it is to take an input string, convert all newline characters 
to spaces and all uppercase letters to lowercase, and then 
return an array of words that are generated by splitting the 
string up by whitespace.


Take a look at the ways I have used here:
http://forum.dlang.org/thread/zdhfpftodxnvbpwvk...@forum.dlang.org

Bye,
bearophile


Re: Recursive lambda functions?

2013-12-30 Thread Timon Gehr

On 12/30/2013 11:50 PM, Meta wrote:


enum factorial5=(function int(a)=a==0?1:a*__traits(parent,{})(a-1))(5);

(In D, you need to specify the return type for a recursive function
declaration. If one doesn't here, DMD crashes, which is a bug.
https://d.puremagic.com/issues/show_bug.cgi?id=11848)


And of course I'm wrong about that as soon as I post. No idea why one
works when the other doesn't...


AFAICT, none of the cases is supposed to work: 
https://d.puremagic.com/issues/show_bug.cgi?id=8307


Presumably it is the same bug that causes the segfault. The underlying 
cause might be a missing check for completion of return type inference. 
In the first case, this means that the return type of the function is 
null when it is encountered in the function body. When null is checked 
for compatibility with multiplication with an int, a null pointer 
dereference occurs. In the second case, the return type has been partly 
resolved to 'int' as the first return statement has been analyzed to 
completion before the function call is encountered.


Re: Debug/reduce stack overflow in DMD on Windows

2013-12-30 Thread Jacob Carlborg

On 2013-12-30 23:21, Vladimir Panteleev wrote:


You could try reducing the bug using DustMite, and this helper:


Thanks, DustMite was able to find a reduced test case. It was this 
little piece of code:


enum : DWORD
{
DWORD = REG_DWORD
}

--
/Jacob Carlborg


Re: Possible bug - should the following code cause an access violation exception?

2013-12-30 Thread Afshin

Thanks Ali.

I uninstalled 2.63.x.
Installed the 2.64.2.

I compiled and ran the test, and surely enough there were no 
problems.


However, when I build using Visual D environment, the problem 
persists.


Microsoft Visual Studio 2010 Ultimate.
Visual D plugin.

Thankfully, there is a simple workaround, but hopefully someone 
can get to the bottom of this issue.




Re: Possible bug - should the following code cause an access violation exception?

2013-12-30 Thread Ali Çehreli

On 12/30/2013 04:55 PM, Afshin wrote:

Thanks Ali.

I uninstalled 2.63.x.
Installed the 2.64.2.

I compiled and ran the test, and surely enough there were no problems.

However, when I build using Visual D environment, the problem persists.

Microsoft Visual Studio 2010 Ultimate.
Visual D plugin.

Thankfully, there is a simple workaround, but hopefully someone can get
to the bottom of this issue.



Not unless somebody files a bug report. ;)

  https://d.puremagic.com/issues/

Ali



Re: A better way to write this function? (style question)

2013-12-30 Thread Thomas Gann
Thanks for all your replies, guys! I have done some further 
research in the meantime and I have found out that I am, in fact, 
an idiot. There is actually a standard library function that does 
exactly what I am trying to do! As it turns out, 
std.string.split():


1) It automatically discards empty tokens, so there is no need to 
filter it manually.
2) Its definition of whitespace includes spaces, tabs, and both 
types of newlines, so there is no need to convert newlines to 
spaces.


An equivalent, but much less verbose, form of the function 
becomes the following:


input.toLower.split;

So I'm noticing a common theme here, though, which is that lots 
of operations on arrays is bad? Should I be using ranges pretty 
much everywhere, then? Or just in performance-critical areas of 
code where I want to avoid a lot of copying? Would that just 
leave plain vanilla dynamic arrays to the task of (relatively) 
permanent storage?


How to organize using modules?

2013-12-30 Thread Afshin
Is it possible to describe modules in terms of packages (as found 
in Java)?


The features that Java packages have that I can't seem to get in 
D are:
1) You can have classes that are in the same package, but kept in 
separate files.

2) You can import many classes using the '*' syntax.

Is this possible in D?

What I understand is that if I have ClassA and ClassB in Module1, 
and I want to keep the classes in separate files, then I have to 
use the following module statements:


in ClassA:
module Module1.ClassA;

in ClassB:
module Module1.ClassB;

But now it becomes cumbersome to use the classes because now I 
have to import them explicitely:


import Module1.ClassA;
import Module1.ClassB;



If I wanted to use:
import Module1;

Then it seems I have to have ClassA and ClassB in the same D file.

Am I missing something?


Re: How to organize using modules?

2013-12-30 Thread TheFlyingFiddle

On Tuesday, 31 December 2013 at 06:01:21 UTC, Afshin wrote:
Is it possible to describe modules in terms of packages (as 
found in Java)?


The features that Java packages have that I can't seem to get 
in D are:
1) You can have classes that are in the same package, but kept 
in separate files.

2) You can import many classes using the '*' syntax.

Is this possible in D?

What I understand is that if I have ClassA and ClassB in 
Module1, and I want to keep the classes in separate files, then 
I have to use the following module statements:


in ClassA:
module Module1.ClassA;

in ClassB:
module Module1.ClassB;

But now it becomes cumbersome to use the classes because now I 
have to import them explicitely:


import Module1.ClassA;
import Module1.ClassB;



If I wanted to use:
import Module1;

Then it seems I have to have ClassA and ClassB in the same D 
file.


Am I missing something?



It is possible if you have your file system set up like this.

Module1
-ClassA.d
-ClassB.d
-package.d

//In Module1/ClassA.d
module Module1.ClassA;
class ClassA { ... }

//In Module1/ClassB.d
module Module1.ClassB;
class ClassB { ... }

//In Module1/package.d
module Module1;

public import Module1.ClassA;
public import Module1.ClassB;


//In main.d

module main;

import Module1; //This will import both ClassA and ClassB.

Very important! The name of the file with the public imports must 
be package.d








Re: How to organize using modules?

2013-12-30 Thread TheFlyingFiddle

2) You can import many classes using the '*' syntax.


You don't use the * syntax. Just stop after the module name.