Re: Flag proposal

2011-06-11 Thread Ben Grabham

On 11/06/11 15:28, Andrei Alexandrescu wrote:

On 6/11/11 9:08 AM, David Nadlinger wrote:

On 6/11/11 1:54 PM, Andrei Alexandrescu wrote:

Consider two statements:

1. I dislike Flag. It looks ugly to me.

2. I dislike Flag. Instead I want named arguments.

There is little retort to (1) - it simply counts as a vote against. For
(2) the course of action is to point out the liabilities of changing the
language.


*And*, at least for me, still count it as an (informal) vote against
Flag.


Of course it does, but the point is there are arguments that might
convince the person.


You wrote about »The point is it [named arguments] would also have
disadvantages«, but at the same time, you seem to ignore that using a
non-obvious construct all over the standard library adds to perceived
the »language complexity« (from the user's perspective) just as well,
even more so if opDispatch or other »hacks« are used to beautify the
implementation.


I agree that implementation complexity has a cost. That would be
justified if the idiom becomes commonly used outside the library.


Yes, I do think named parameters would be a step forward and we should
definitely look into adding them to D. But independently, I don't think
that reinventing bool in Phobos is a good idea.


You may want to refer to my answer to Michel.


Andrei


Hey,

Don't know whether I can vote but I looked through it and I prefer using 
booleans over this. This just doesn't look very nice to me and if you 
*really* wanted to use this in a program, you could just use an enum but 
I don't see why flags is good (even after reading through all your 
counter-arguments).


Nebster


Re: D Recurrences

2011-06-11 Thread Ben Grabham

On 10/06/11 05:43, Jonathan M Davis wrote:

On 2011-06-09 20:35, Ben Grabham wrote:

On 09/06/11 20:15, Jonathan M Davis wrote:

The save property of a forward range returns a copy of that range. In
most cases, since ranges are generally restructs, it just returns the
range. You use it when you want to save the original range and still be
able pop elements off.

auto orig = range.save;

//pop off as many elements from range as I want.
//orig still has all of its elements

The elements aren't copied however, just the range. Regardless, it has
nothing to do with returning an element from a range, so I don't
understand your question about returning an index rather than a whole
object. Ranges don't really use indicies. indexOf will tell you the
index of a particular element, and you can increment a counter every
time you pop off an element if you want to know how many elements you've
consumed, but once an element has been popped off, it's not part of that
range anymore (though it could be part of a saved range), so that could
seriously affect by what you mean by index, depending on what you're
doing.

- Jonathan M Davis


I want to make it so that foreach works but I'm storing an array which
when changed, want to keep it like that, even after the foreach, I just
want to reset the index to 0

At the moment, I have to do:
foreach(i; 0..100)
...

lazy._n = 0;

foreach(i; 0..100)
...

I want to do:
foreach(n; lazy)
...
foreach(n; lazy)
...


0 .. 100 has nothing to do with ranges. That's a built-in feature of foreach.
This would use a range

foreach(i; iota(0, 100))

because iota generates one, but 0 .. 100 doesn't. But there's no array
involved in

foreach(i; 0 .. 100)

anyway, and you state that you're storing an array as part of this, so I
really don't know what you're trying to do. I'd need to see actual code to be
of any help.

- Jonathan M Davis


Sorry, didn't really make that clear.

Inside the foreach, I'm using popFront and front to get the values and 
then outside, I set the index (_n) back to 0. What I want to do is 
save the _n value and then restore it at the beginning and end of the 
foreach respectively.


I don't have the code on me atm, but when I get hold of it, I'll post it 
if you still need it.


Thanks,
Nebster


D Recurrences

2011-06-09 Thread Ben Grabham

Hey,

Shouldn't both these programs output the fibonnacci numbers? Only the 
first one does.


import std.range;
import std.stdio;
int main() {
auto a = recurrence!(a[n-1] + a[n-2])(0,1);
int i = 0;
foreach(int n; a) {
if(i++  20) break;
writefln(%d, n);
}
return 0;
}



import std.range;
import std.stdio;
int main() {
auto a = recurrence!(a[n-1] + (n  2 ? 0 : a[n-2]))(1);
int i = 0;
foreach(int n; a) {
if(i++  20) break;
writefln(%d, n);
}
return 0;
}


Re: D Recurrences

2011-06-09 Thread Ben Grabham

On 09/06/11 16:19, Ben Grabham wrote:

Hey,

Shouldn't both these programs output the fibonnacci numbers? Only the
first one does.

import std.range;
import std.stdio;
int main() {
auto a = recurrence!(a[n-1] + a[n-2])(0,1);
int i = 0;
foreach(int n; a) {
if(i++  20) break;
writefln(%d, n);
}
return 0;
}



import std.range;
import std.stdio;
int main() {
auto a = recurrence!(a[n-1] + (n  2 ? 0 : a[n-2]))(1);
int i = 0;
foreach(int n; a) {
if(i++  20) break;
writefln(%d, n);
}
return 0;
}


Also, is there a takeWhile function?
I can't find one in the documents...


Re: D Recurrences

2011-06-09 Thread Ben Grabham

On 09/06/11 17:57, bearophile wrote:

Ben Grabham:


import std.range;
import std.stdio;
int main() {
auto a = recurrence!(a[n-1] + a[n-2])(0,1);
int i = 0;
foreach(int n; a) {
if(i++  20) break;
writefln(%d, n);
}
return 0;
}


This program does something similar to yours (but it doesn't print newlines):


import std.stdio, std.range;

void main() {
 auto fib = recurrence!q{ a[n-1] + a[n-2] }(0, 1);
 writeln(take(fib, 21));
}

Bye,
bearophile


Yeah, thanks

I just wanted to post a bit of code which went wrong :P
Didn't look for optimisations.

Also, how come recurrence isn't properly lazy?
If I define a recurrence and iterate over it twice with foreach, it 
takes the same amount of time due to the stack size being set. Is there 
a way of defining a lazy list that stores the results when calculated?


Thanks,
Nebster


Re: D Recurrences

2011-06-09 Thread Ben Grabham

On 09/06/11 18:11, Steven Schveighoffer wrote:

On Thu, 09 Jun 2011 13:06:54 -0400, Ben Grabham evil.nebs...@gmail.com
wrote:


On 09/06/11 17:57, bearophile wrote:

Ben Grabham:


import std.range;
import std.stdio;
int main() {
auto a = recurrence!(a[n-1] + a[n-2])(0,1);
int i = 0;
foreach(int n; a) {
if(i++ 20) break;
writefln(%d, n);
}
return 0;
}


This program does something similar to yours (but it doesn't print
newlines):


import std.stdio, std.range;

void main() {
auto fib = recurrence!q{ a[n-1] + a[n-2] }(0, 1);
writeln(take(fib, 21));
}

Bye,
bearophile


Yeah, thanks

I just wanted to post a bit of code which went wrong :P
Didn't look for optimisations.

Also, how come recurrence isn't properly lazy?
If I define a recurrence and iterate over it twice with foreach, it
takes the same amount of time due to the stack size being set. Is
there a way of defining a lazy list that stores the results when
calculated?


That's not lazy, that's caching. lazy is 'calculate this when asked'.

You can cache with array:

auto cached = array(take(fib, 21));
// cached now contains the first 21 elements of fib.

-Steve


I tried that, but how can I calculate the values only when I want them? 
Would I have to store them in a linked list? Since if I know that I will 
need 10 prime numbers, it takes my old pc about 4.7 seconds to 
calculate them. But can I only calculate them when I need them?


I am running through the recurrence twice so I don't want to calculate 
it twice.


This is theoretical so please no answers like put them both in one loop, 
etc.


Thanks for all the info so far! I'm learning quite a lot!

Thanks,
Nebster


Re: D Recurrences

2011-06-09 Thread Ben Grabham

On 09/06/11 18:49, Steven Schveighoffer wrote:

On Thu, 09 Jun 2011 13:31:18 -0400, Ben Grabham evil.nebs...@gmail.com
wrote:


On 09/06/11 18:11, Steven Schveighoffer wrote:

On Thu, 09 Jun 2011 13:06:54 -0400, Ben Grabham evil.nebs...@gmail.com
wrote:


On 09/06/11 17:57, bearophile wrote:

Ben Grabham:


import std.range;
import std.stdio;
int main() {
auto a = recurrence!(a[n-1] + a[n-2])(0,1);
int i = 0;
foreach(int n; a) {
if(i++ 20) break;
writefln(%d, n);
}
return 0;
}


This program does something similar to yours (but it doesn't print
newlines):


import std.stdio, std.range;

void main() {
auto fib = recurrence!q{ a[n-1] + a[n-2] }(0, 1);
writeln(take(fib, 21));
}

Bye,
bearophile


Yeah, thanks

I just wanted to post a bit of code which went wrong :P
Didn't look for optimisations.

Also, how come recurrence isn't properly lazy?
If I define a recurrence and iterate over it twice with foreach, it
takes the same amount of time due to the stack size being set. Is
there a way of defining a lazy list that stores the results when
calculated?


That's not lazy, that's caching. lazy is 'calculate this when asked'.

You can cache with array:

auto cached = array(take(fib, 21));
// cached now contains the first 21 elements of fib.

-Steve


I tried that, but how can I calculate the values only when I want
them? Would I have to store them in a linked list? Since if I know
that I will need 10 prime numbers, it takes my old pc about 4.7
seconds to calculate them. But can I only calculate them when I need
them?


It's a recurring sequence. As such, each element depends on the previous
n elements. I don't see how you can only calculate them when needed,
unless you want to do some sort of memoization with recursion.
recurrence expects to be traversed in a certain order, it's sort of like
dynamic programming.

The array simply stores all the values needed to an array, so you can
re-access the same values without running through the recurrence.

One thing you could do is using Appender, you can continue a recurrence.
So let's say you need the 5th element of the array:

alias recurrence!q{ a[n-1] + a[n-2] } fib;

Appender!int app;

app.put(take(fib(0, 1), 5));

auto elems = app.data;
auto the5thElement = elems[4];

And now, you need the 10th element:

app.put(take(fib(elems[$-2], elems[$-1]), 10 - elems.length)); // extend
sequence to 10 elements

elems = app.data; // need to re-retrieve the elements
auto the10thElemet = elems[9];

Kind of ugly, but maybe it's close enough to what you want.


I am running through the recurrence twice so I don't want to calculate
it twice.


Yes, you only run through it once, then use the array with the cached
data to retrieve what you want. Accessing the array does not recalculate
the data.

The Appender solution simply keeps a running cache of the data. You
could probably abstract out the 'extending' function. In fact, this
whole thing could be abstracted into a 'cached recurrence' type.

-Steve


Thanks, that should do the trick!
At the moment I was using auto elems = array(chain(elems, take(primes - 
elems.length))); or something similar to that


Also, when using a foreach, is there a special syntax that says include 
the last number?
As an example, if I want to loop from -n to +n, I have to do foreach(i; 
-n..n+1)


Thanks,
Nebster


Re: D Recurrences

2011-06-09 Thread Ben Grabham

On 09/06/11 19:45, Andrej Mitrovic wrote:

I never understood why it's called open interval. What does it 'open'?


Don't know the answer to that one, just know it's always been called a 
open interval when both endpoints aren't included. D's foreach loops are 
half-closed intervals.


Oh well, that's a shame.

I ended up writing a lazy cached list and filter implementation anyway :)

It may use more memory but it's worth it for me!

Thanks for all the help!
Nebster


Re: D Recurrences

2011-06-09 Thread Ben Grabham

On 09/06/11 19:54, Ben Grabham wrote:

On 09/06/11 19:45, Andrej Mitrovic wrote:

I never understood why it's called open interval. What does it 'open'?


Don't know the answer to that one, just know it's always been called a
open interval when both endpoints aren't included. D's foreach loops are
half-closed intervals.

Oh well, that's a shame.

I ended up writing a lazy cached list and filter implementation anyway :)

It may use more memory but it's worth it for me!

Thanks for all the help!
Nebster


Oh, I do have one question though,

How does the save property work? I can't seem to be able to return an 
integer (index) rather than the whole object. How can I do it?


Re: D Recurrences

2011-06-09 Thread Ben Grabham

On 10/06/11 00:10, Ali Çehreli wrote:

For what it's worth, here is a Fibonacci range. (Translated from
D.ershane's Aralıklar (Ranges) chapter.)

import std.stdio;
import std.range;

struct FibonacciRange
{
 int first = 0;
 int second = 1;

 enum empty = false;

 @property int front() const
 {
 return first;
 }

 void popFront()
 {
 int next = first + second;
 first = second;
 second = next;
 }

 FibonacciRange save() const
 {
 return this;
 }
}

void main()
{
 writeln(take(FibonacciRange(), 20));
}

Ali


Have a look at bearophiles answer above. It is a bit shorter.
Fibonacci was just an example, I don't actually use it anywhere :P

Thanks for another way though,
Nebster


Re: D Recurrences

2011-06-09 Thread Ben Grabham

On 09/06/11 20:15, Jonathan M Davis wrote:

The save property of a forward range returns a copy of that range. In most
cases, since ranges are generally restructs, it just returns the range. You
use it when you want to save the original range and still be able pop elements
off.

auto orig = range.save;

//pop off as many elements from range as I want.
//orig still has all of its elements

The elements aren't copied however, just the range. Regardless, it has nothing
to do with returning an element from a range, so I don't understand your
question about returning an index rather than a whole object. Ranges don't
really use indicies. indexOf will tell you the index of a particular element,
and you can increment a counter every time you pop off an element if you want
to know how many elements you've consumed, but once an element has been popped
off, it's not part of that range anymore (though it could be part of a saved
range), so that could seriously affect by what you mean by index, depending on
what you're doing.

- Jonathan M Davis


I want to make it so that foreach works but I'm storing an array which 
when changed, want to keep it like that, even after the foreach, I just 
want to reset the index to 0


At the moment, I have to do:
foreach(i; 0..100)
...

lazy._n = 0;

foreach(i; 0..100)
...

I want to do:
foreach(n; lazy)
...
foreach(n; lazy)
...

Thanks,
Nebster


Developing a D Kernel

2011-06-04 Thread Ben Grabham

Hey,

I'm trying to develop a kernel in D2. It works fine if I don't use 
classes but as soon as I try to use classes, it complains about the lack 
of object.d.


So, I set out on a quest to develop a simple object.d that doesn't need 
to import anything to work apart from basic memory functions like 
malloc, etc (for now). I'm partially basing it off the one included in 
the D runtime. The problem is that I'm trying to find a minimal object.d 
that doesn't try to pull in too much. Has this been done before? 
Whenever I try to create one that is not the original one, I just make 
the compiler generate a segmentation fault.


I've also been trying to find a kernel project that someones started 
with classes in D2 but have yet to find one. Does anyone know one?


Thanks,
Nebster


Re: Developing a D Kernel

2011-06-04 Thread Ben Grabham

On 04/06/11 16:15, Daniel Gibson wrote:

Am 04.06.2011 17:13, schrieb Ben Grabham:

Hey,

I'm trying to develop a kernel in D2. It works fine if I don't use
classes but as soon as I try to use classes, it complains about the lack
of object.d.

So, I set out on a quest to develop a simple object.d that doesn't need
to import anything to work apart from basic memory functions like
malloc, etc (for now). I'm partially basing it off the one included in
the D runtime. The problem is that I'm trying to find a minimal object.d
that doesn't try to pull in too much. Has this been done before?
Whenever I try to create one that is not the original one, I just make
the compiler generate a segmentation fault.

I've also been trying to find a kernel project that someones started
with classes in D2 but have yet to find one. Does anyone know one?

Thanks,
Nebster


There's a kernel written in D1: http://wiki.xomb.org/


Cheers,
- Daniel


Yes, I've seen xomb, titan, osian and one posted on this newsgroup. 
Unfortunately they are all D1 kernels. The problem I'm having is 
creating a small object.d for D2 without causing the compiler to seg fault


Thanks for trying to help though!
Nebster


Re: Template error and parallel foreach bug?

2011-06-04 Thread Ben Grabham

On 04/06/11 20:16, simendsjo wrote:

On 04.06.2011 20:04, Timon Gehr wrote:

ulong SumMultiple3Or5_parallel(uint below) {
ulong sum;
foreach(i; parallel(iota(below))) {
if(i % 3 == 0 || i % 5 == 0)
sum += i; // low level data race here.
}
return sum;
}

Loop iterations in a parallel foreach loop must be independent of each
other.



I thought paralellism was using locks behind the scenes. Guess I'll have
to read the documentation then :)


You can always try reduce and map :) I can't remember whether they are 
parallel or not though!


Re: Template error and parallel foreach bug?

2011-06-04 Thread Ben Grabham

On 05/06/11 03:55, Ben Grabham wrote:

On 04/06/11 20:16, simendsjo wrote:

On 04.06.2011 20:04, Timon Gehr wrote:

ulong SumMultiple3Or5_parallel(uint below) {
ulong sum;
foreach(i; parallel(iota(below))) {
if(i % 3 == 0 || i % 5 == 0)
sum += i; // low level data race here.
}
return sum;
}

Loop iterations in a parallel foreach loop must be independent of each
other.



I thought paralellism was using locks behind the scenes. Guess I'll have
to read the documentation then :)


You can always try reduce and map :) I can't remember whether they are
parallel or not though!


Oops, sorry, missed the bit where you said you've already done parallel map!