Re: x.RC.__postblit () is not callable using argument types () const

2013-02-05 Thread Maxim Fomin

On Tuesday, 5 February 2013 at 01:15:28 UTC, Dan wrote:
I've seen these type of errors often and usually the cause kind 
of jumps out. In this case I'm totally confused. Just trying to 
move from 2.06 to 2.061.


The code is: http://dpaste.dzfl.pl/f40e4d6f
and fails with the error in subject line. Observations:

- If static if(1) is changed to static if(0) it compiles
- If either _valuationHistory or goo member of BSItem is 
commented out it compiles.


I know the code is somewhat cryptic, but I've been using binary 
reduction comment in/out to try to narrow down this issue. I 
can not understand why an introduction of opEquals on a struct 
History with no relationship to RC causes an error to show for 
RC.


Thanks
Dan


There is still problem with const structs vs. non-const postblit 
and destructor. In the past, the situation was even worse, but 
was partly fixed by laxing constness with respect to postblit and 
destructor. Now all such problems seems to come from associative 
array implementation in object.d


Re: x.RC.__postblit () is not callable using argument types () const

2013-02-05 Thread Maxim Fomin
On Tuesday, 5 February 2013 at 04:03:06 UTC, Andrej Mitrovic 
wrote:
Yeah, it's still not very helpful. And I have no idea where 
Slot comes from.


This is sub struct inside object.AssociativeArray.


Re: x.RC.__postblit () is not callable using argument types () const

2013-02-05 Thread Dan

On Tuesday, 5 February 2013 at 11:51:40 UTC, Maxim Fomin wrote:
On Tuesday, 5 February 2013 at 04:03:06 UTC, Andrej Mitrovic 
wrote:
Yeah, it's still not very helpful. And I have no idea where 
Slot comes from.


This is sub struct inside object.AssociativeArray.


Is it the case that this is a D compiler (or library) problem and 
there is no issue with the code? Or is there really a problem 
with it that I am not seeing? I gather from the responses the 
code looks fine, otherwise any misunderstanding would come up 
quickly.


I feel like I have painted myself in a corner a bit. I love D's 
templates and am a fan of the compile time reflection. I have 
mixins that support things like OpEquals, OpCmp, toHash, etc. I 
try very hard to work with const correctly.


mixin template OpEquals() {
  bool opEquals(const ref typeof(this) other) const {
return typesDeepEqual(this, other);
  }
  bool opEquals(const typeof(this) other) const {
return typesDeepEqual(this, other);
  }
}

This OpEquals in the sample was just this signature (which I have 
mixed in all over successfully) but with a 'return true'. I think 
this is the correct signature to use. If I understand correctly, 
were I to remove the const, then const instances may no longer 
call it - which is not a good change.


Transitive const is more than just simple const, and obviously 
more is better ;-). Since Slot is mentioned and 
object.AssociativeArrray it sounds like there may be a 
const-correctness issue with associative array itself rather than 
this code? Before the move to 2.061 I had to cast away const on 
const(V[K]) to get length and to iterate over them. But why the 
link between History!double and RC[int] when they are totally 
unrelated? Well, the only relation is their aggregation in 
BSItem. Baffling.


Any suggestions appreciated.

Thanks
Dan


Re: x.RC.__postblit () is not callable using argument types () const

2013-02-05 Thread Dan

On Tuesday, 5 February 2013 at 15:06:47 UTC, Maxim Fomin wrote:

The root of the problem is in:

struct DAssociativeArray(Key, Value)
{
struct Slot
{
Value value;
}
}

struct RC {
  this(this) {  }
}

void main()
{
DAssociativeArray!(int, const(RC)) goo;
}

which doesn't compile (this is how Value[Key] is rewritten).



I see - thanks. I assume it should compile and without the 
postblit it does. So - the original code is fine and there is a D 
problem with associative arrays.


- Wouldn't the scenario be exactly the same without 
ValuationHistory? That is, if I comment out the member 
_valuationHistory, the goo member is not changed in structure at 
all, and yet it compiles just fine.
- Does this mean that no one or very few developers store 
structs with postblits as value types in the standard associative 
array? Maybe I just do things differently than others.


The way I see it you have to choose how you want to develop your 
structs/classes. I have chosen to use structs and templates and 
avoid classes, thinking this would greatly simplify things. Any 
struct needs to establish up front whether it will have value 
semantics or reference semantics. So far, I have preferred value 
semantics as data sharing leads to confusion. So if I have arrays 
in a struct I include postblits to provide value semantics. In 
another thread Walter made clear his distaste for postblits and 
preference for reference semantics coupled with copy on write 
semantics where needed. That approach, just does not seem worth 
it without more systematic support for COW. Assuming postblits 
are the issue, I don't understand why they are so hard to get 
right.


Thanks
Dan



Re: new T[size] vs .reserve - alloca

2013-02-05 Thread Nick Treleaven

On 03/02/2013 13:22, bearophile wrote:

Era Scarecrow:


On Sunday, 3 February 2013 at 09:11:59 UTC, Namespace wrote:

Sure, but alloca has the same ugly interface as malloc. :/


 You mean that you have to specify how many raw bytes you want, then
cast it to what you need? I never thought alloca or malloc were that
ugly.


The interface of alloca() is bug-prone. And it's not handy if you want
to create a 2D or nD array on the stack :-) In bugzilla there is a
preliminary request for better and less bug-prone VLAs for D.


^ I know you're aware of this, but maybe others might not know the 
default-argument alloca wrapping trick:


import std.stdio;
import core.stdc.stdlib:alloca;

T *stack(T)(void* m = alloca(T.sizeof))
{
return cast(T*)m;
}

void main(string[] args)
{
auto i = stack!int();
*i = 5;
writeln(*i);
writeln(i);
int j;
writeln(j);
}

More advanced behaviour e.g. switching to heap allocation for large 
sizes of T may be possible.




Re: x.RC.__postblit () is not callable using argument types () const

2013-02-05 Thread Maxim Fomin

On Tuesday, 5 February 2013 at 15:49:59 UTC, Dan wrote:


- Wouldn't the scenario be exactly the same without 
ValuationHistory? That is, if I comment out the member 
_valuationHistory, the goo member is not changed in structure 
at all, and yet it compiles just fine.


Scenario is the same if there is struct with postblit and 
const(S) is passed as AA argument. If there is more code 
involved, the situation can be more complicated.


- Does this mean that no one or very few developers store 
structs with postblits as value types in the standard 
associative array? Maybe I just do things differently than 
others.


This does not imply such situation, simply there is a problem. 
You can workaround by


struct DAssociativeArray(Key, Value)
{
struct Slot
{
Value value;
}
}

struct RC {
int i;
void postblit() { i = -5; }
this(this) const
{
void delegate() dg = postblit;
dg();
}
}

void main()
{
RC rc1 = RC(5);
RC rc2 = rc1;
assert(rc2.i is -5);
DAssociativeArray!(int, const(RC)) goo;
}



Re: new T[size] vs .reserve - alloca

2013-02-05 Thread Nick Treleaven

On 05/02/2013 16:17, Nick Treleaven wrote:

On 03/02/2013 13:22, bearophile wrote:

Era Scarecrow:


On Sunday, 3 February 2013 at 09:11:59 UTC, Namespace wrote:

Sure, but alloca has the same ugly interface as malloc. :/


 You mean that you have to specify how many raw bytes you want, then
cast it to what you need? I never thought alloca or malloc were that
ugly.


The interface of alloca() is bug-prone. And it's not handy if you want
to create a 2D or nD array on the stack :-) In bugzilla there is a
preliminary request for better and less bug-prone VLAs for D.


^ I know you're aware of this, but maybe others might not know the
default-argument alloca wrapping trick:


I've just realized this doesn't work for variable-length allocation:

T[] stack(T)(size_t N, void* m = alloca(T.sizeof * N))

Error: undefined identifier N, did you mean alias T?

N is not visible in the caller's scope.


Re: new T[size] vs .reserve - alloca

2013-02-05 Thread bearophile

Nick Treleaven:

^ I know you're aware of this, but maybe others might not know 
the default-argument alloca wrapping trick:


For some usages it's an improvement over raw usage of alloca.
I did see this in past, but sometimes I forget.

Bye,
bearophile


Re: new T[size] vs .reserve - alloca

2013-02-05 Thread monarch_dodra

On Tuesday, 5 February 2013 at 16:37:41 UTC, Nick Treleaven wrote:

On 05/02/2013 16:17, Nick Treleaven wrote:

On 03/02/2013 13:22, bearophile wrote:

Era Scarecrow:


On Sunday, 3 February 2013 at 09:11:59 UTC, Namespace wrote:

Sure, but alloca has the same ugly interface as malloc. :/


You mean that you have to specify how many raw bytes you 
want, then
cast it to what you need? I never thought alloca or malloc 
were that

ugly.


The interface of alloca() is bug-prone. And it's not handy if 
you want
to create a 2D or nD array on the stack :-) In bugzilla there 
is a

preliminary request for better and less bug-prone VLAs for D.


^ I know you're aware of this, but maybe others might not know 
the

default-argument alloca wrapping trick:


I've just realized this doesn't work for variable-length 
allocation:


T[] stack(T)(size_t N, void* m = alloca(T.sizeof * N))

Error: undefined identifier N, did you mean alias T?

N is not visible in the caller's scope.


It does, just alias it.

//
import std.stdio;
import core.stdc.stdlib:alloca;

T* stack(T)(void* m = alloca(T.sizeof))
{
return cast(T*)m;
}
T[] stack(T, alias N)(void* m = alloca(T.sizeof * N))
{
return (cast(T*)m)[0 .. N];
}

void main(string[] args)
{
int*  p   = stack!int();
int[] arr = stack!(int, 5)();
*p = 2;
arr[0] = 5;
writeln(*p);
writeln(arr);
}
//


Re: x.RC.__postblit () is not callable using argument types () const

2013-02-05 Thread Dan

On Tuesday, 5 February 2013 at 16:36:16 UTC, Maxim Fomin wrote:

This does not imply such situation, simply there is a problem. 
You can workaround by



[snip]

struct RC {
int i;
void postblit() { i = -5; }
this(this) const
{
void delegate() dg = postblit;
dg();
}
}


Great thanks. I'll try.

But why does this even code work? I would have thought const 
guarantee would prevent calls to non-const postblit function. I 
was under impression this(this) const does not work - but maybe 
that has changed with 2.061.


What source (lang spec, TDPL, or newsgroup) led you to this 
solution and for how long will it be valid? Where can I read more 
on it?


Thanks
Dan



Re: GtkD button size

2013-02-05 Thread SaltySugar

On Monday, 4 February 2013 at 21:55:24 UTC, Mike Wey wrote:

On 02/04/2013 03:03 PM, SaltySugar wrote:
On Sunday, 3 February 2013 at 16:07:06 UTC, Artur Skawina 
wrote:

On 02/03/13 16:53, SaltySugar wrote:
GTKD. Can someone explain me how to change button size in 
vbox, hbox?

setSizeRequest (70, 50); doesn't work. Thanks.


Try playing with an interactive gui tool, such as glade. The 
fill,

expand and
size request interactions will be immediately visible.

artur


I'm waiting other answers :)


A VBox or A HBox will always expand the Widget in the direction 
opposite of the on it's managing, if it expands the Widget in 
that direction depends on the options passed to packStart. So 
get the size request to work with those containers you'll have 
to wrap a HBox in a VBoc or visa versa.


A more convenient container would be the ButtonBox which 
doesn't expand the Button in the direction it's not managing. 
And thus properly handles the size request.


A Grid or Table might also apply depending on the complete 
layout.


I can't find any tutorials about buttonboxes. Can you write how 
to use it?


Re: Allocating large 2D array in D

2013-02-05 Thread H. S. Teoh
On Mon, Feb 04, 2013 at 04:58:36PM +0100, bearophile wrote:
 monarch_dodra:
 
 If all (but last of) the dimensions are known at compile time,
 then you can dynamically allocate an array of fixed sized arrays:
 
 //
 enum size_t gridSize = 4_000;
 enum size_t total   = gridSize * gridSize;
 static assert (total == 16_000_000); //16 million doubles total
 static assert (total * double.sizeof == 128_000_000); //126 Megs
 allocated
 
 void main()
 {
 double[gridSize][] gridInfo = new
 double[gridSize][](gridSize);
 }
 //
 
 This will give you a dense array: Eg: all the data is contiguous
 in memory.
 
 Nice. This idiom should be added to the D docs.
[...]

Added to wiki: http://wiki.dlang.org/Dense_multidimensional_arrays


T

-- 
If Java had true garbage collection, most programs would delete themselves upon 
execution. -- Robert Sewell


Re: x.RC.__postblit () is not callable using argument types () const

2013-02-05 Thread Maxim Fomin

On Tuesday, 5 February 2013 at 17:05:23 UTC, Dan wrote:
But why does this even code work? I would have thought const 
guarantee would prevent calls to non-const postblit function. I 
was under impression this(this) const does not work - but maybe 
that has changed with 2.061.


Forgot to mention, it works on 2.061.

What source (lang spec, TDPL, or newsgroup) led you to this 
solution and for how long will it be valid? Where can I read 
more on it?


Thanks
Dan


Const postblit worked at least at 2.060. Originally idea was to 
make const cast on function call, but at a current time it is not 
needed. May be another bug.


Re: Allocating large 2D array in D

2013-02-05 Thread bearophile

H. S. Teoh:

Added to wiki: 
http://wiki.dlang.org/Dense_multidimensional_arrays


It contains:

enum columns = 100;
int rows = 100;
double[gridSize][] gridInfo = new double[columns][](rows);


gridSize is undefined. I suggest to write something like:

enum nColumns = 100;
int nRows = 120;
double[nColumns][] matrix2 = new double[nColumns][](nRows);

Bye,
bearophile


Re: Allocating large 2D array in D

2013-02-05 Thread H. S. Teoh
On Tue, Feb 05, 2013 at 07:38:40PM +0100, bearophile wrote:
 H. S. Teoh:
 
 Added to wiki: http://wiki.dlang.org/Dense_multidimensional_arrays
 
 It contains:
 
 enum columns = 100;
 int rows = 100;
 double[gridSize][] gridInfo = new double[columns][](rows);
 
 
 gridSize is undefined.
[...]

Oops, that was a typo. Fixed.

P.S. Feel free to edit the page yourself if you see a mistake. That's
what a wiki is for, after all.


T

-- 
I suspect the best way to deal with procrastination is to put off the 
procrastination itself until later. I've been meaning to try this, but haven't 
gotten around to it yet.  -- swr


Re: GtkD button size

2013-02-05 Thread Mike Wey

On 02/05/2013 06:33 PM, SaltySugar wrote:

I can't find any tutorials about buttonboxes. Can you write how to use it?


Here is a small example:

import gtk.MainWindow;
import gtk.Button;
import gtk.Main;
import gtk.HButtonBox;

class Application : MainWindow
{
this()
{
super(GtkD App);
setDefaultSize(200, 200);

HButtonBox hBox = new HButtonBox();

Button btnLog = new Button(Login);
btnLog.setSizeRequest (70, 50);
hBox.packStart(btnLog, false, false, 3);

add(hBox);
showAll();
}
}

void main(string[] args)
{
Main.init(args);
new Application();
Main.run();
}

It looks like this:
http://i45.tinypic.com/msivb4.png

--
Mike Wey


Re: A little of coordination for Rosettacode

2013-02-05 Thread Jos van Uden

On 5-2-2013 0:55, bearophile wrote:

Is the Fwend user of Rosettacode (or some other interested person) around here? 
I have written partial D implementations
for three tasks, maybe a little of coordination will speedup the work:

http://rosettacode.org/wiki/Permutations/Rank_of_a_permutation
http://rosettacode.org/wiki/Universal_Turing_machine




http://rosettacode.org/wiki/RCRPG


I'll give it a shot if you like. The RCRPG I'd like to try first.

By the way, I think 'Qznc' may want to have a look at 'The dining
philosophers':

http://rosettacode.org/wiki/Dining_philosophers







Re: GtkD button size

2013-02-05 Thread SaltySugar

On Tuesday, 5 February 2013 at 19:31:01 UTC, Mike Wey wrote:

On 02/05/2013 06:33 PM, SaltySugar wrote:
I can't find any tutorials about buttonboxes. Can you write 
how to use it?


Here is a small example:

import gtk.MainWindow;
import gtk.Button;
import gtk.Main;
import gtk.HButtonBox;

class Application : MainWindow
{
this()
{
super(GtkD App);
setDefaultSize(200, 200);

HButtonBox hBox = new HButtonBox();

Button btnLog = new Button(Login);
btnLog.setSizeRequest (70, 50);
hBox.packStart(btnLog, false, false, 3);

add(hBox);
showAll();
}
}

void main(string[] args)
{
Main.init(args);
new Application();
Main.run();
}

It looks like this:
http://i45.tinypic.com/msivb4.png


Thank you, Mike. One more question. Can I use hbox.add(btn); 
instead of hbox.packStart (btn,false,false,5);

What difference between them?
Sorry, for my bad English.


Re: new T[size] vs .reserve - alloca

2013-02-05 Thread Namespace

Why not:
[code]
T[] stack(T, const size_t N)(void* m = alloca(T.sizeof * N))
{
return (cast(T*)m)[0 .. N];
}
[/code]
?


Re: A little of coordination for Rosettacode

2013-02-05 Thread bearophile

Jos van Uden:

I'll give it a shot if you like. The RCRPG I'd like to try 
first.


I have already partially written those:

Partial translation of rcrpg-Python:
http://codepad.org/SflrKqbT

Partial translation of permutations_rank_of_a_permutation-Python:
http://codepad.org/El9SQwOE
Plus a better Perl implementation of the uniform() on BigInts:
http://codepad.org/LGcMpk2f

Partial translation of the universal_turing_machine-Ruby:
http://codepad.org/nUXLzAg2

Bye,
bearophile


Re: GtkD button size

2013-02-05 Thread FG

On 2013-02-05 20:48, SaltySugar wrote:

Can I use hbox.add(btn); instead of hbox.packStart (btn,false,false,5);
What difference between them?


Using add(btn) you would probably end up with a stretched button again. :)
hbox.packStart(child, expand, fill, padding)
It was explicitly said that expand = false, to prevent button resizing.

Read more here:
http://www.mono-project.com/GtkSharp:_Packing_with_Boxes
It's Gtk# but may be of some help to you.


Re: A little of coordination for Rosettacode

2013-02-05 Thread Jos van Uden

On 5-2-2013 21:10, bearophile wrote:

How do we avoid working on the same thing?


Partial translation of rcrpg-Python:
http://codepad.org/SflrKqbT

Partial translation of permutations_rank_of_a_permutation-Python:
http://codepad.org/El9SQwOE


The 2 above, I could try.


Plus a better Perl implementation of the uniform() on BigInts:
http://codepad.org/LGcMpk2f


My perl is too rusty.
 

Partial translation of the universal_turing_machine-Ruby:
http://codepad.org/nUXLzAg2


I'd have to first read up on the subject.


Bye,
bearophile




Re: new T[size] vs .reserve - alloca

2013-02-05 Thread Nick Treleaven

On 05/02/2013 16:47, monarch_dodra wrote:

On Tuesday, 5 February 2013 at 16:37:41 UTC, Nick Treleaven wrote:

I've just realized this doesn't work for variable-length allocation:

T[] stack(T)(size_t N, void* m = alloca(T.sizeof * N))

Error: undefined identifier N, did you mean alias T?

N is not visible in the caller's scope.


It does, just alias it.

//
import std.stdio;
import core.stdc.stdlib:alloca;

T* stack(T)(void* m = alloca(T.sizeof))
{
 return cast(T*)m;
}
T[] stack(T, alias N)(void* m = alloca(T.sizeof * N))
{
 return (cast(T*)m)[0 .. N];
}


This works if you know N at compile-time. But there doesn't seem to be a 
way to wrap alloca to accept a runtime-only value, e.g.:


// allocate as many ints as command-line parameters
int[] arr = stack!int(args.length);


Re: new T[size] vs .reserve - alloca

2013-02-05 Thread monarch_dodra

On Tuesday, 5 February 2013 at 20:47:46 UTC, Nick Treleaven wrote:

On 05/02/2013 16:47, monarch_dodra wrote:
On Tuesday, 5 February 2013 at 16:37:41 UTC, Nick Treleaven 
wrote:
I've just realized this doesn't work for variable-length 
allocation:


T[] stack(T)(size_t N, void* m = alloca(T.sizeof * N))

Error: undefined identifier N, did you mean alias T?

N is not visible in the caller's scope.


It does, just alias it.

//
import std.stdio;
import core.stdc.stdlib:alloca;

T* stack(T)(void* m = alloca(T.sizeof))
{
return cast(T*)m;
}
T[] stack(T, alias N)(void* m = alloca(T.sizeof * N))
{
return (cast(T*)m)[0 .. N];
}


This works if you know N at compile-time. But there doesn't 
seem to be a way to wrap alloca to accept a runtime-only value, 
e.g.:


// allocate as many ints as command-line parameters
int[] arr = stack!int(args.length);


I don't have access to my compiler, but that *should*work. Did 
you try it? BTW, the syntax would be:


int[] arr = stack!(int, args.length)();


Re: new T[size] vs .reserve - alloca

2013-02-05 Thread Nick Treleaven

On 05/02/2013 21:02, monarch_dodra wrote:

On Tuesday, 5 February 2013 at 20:47:46 UTC, Nick Treleaven wrote:

On 05/02/2013 16:47, monarch_dodra wrote:

T[] stack(T, alias N)(void* m = alloca(T.sizeof * N))
{
return (cast(T*)m)[0 .. N];
}


This works if you know N at compile-time. But there doesn't seem to be
a way to wrap alloca to accept a runtime-only value, e.g.:

// allocate as many ints as command-line parameters
int[] arr = stack!int(args.length);


I don't have access to my compiler, but that *should*work. Did you try
it? BTW, the syntax would be:

int[] arr = stack!(int, args.length)();


I've just tried it with dmd 2.059 (haven't upgraded yet). I got:

Error: variable args cannot be read at compile time

void main(string[] args)
{
int[] arr = stack!(int, args.length)();
}


Re: new T[size] vs .reserve - alloca

2013-02-05 Thread Nick Treleaven

On 05/02/2013 21:13, Nick Treleaven wrote:

I've just tried it with dmd 2.059 (haven't upgraded yet)


sorry, 2.060


Re: GtkD button size

2013-02-05 Thread Mike Wey

On 02/05/2013 08:48 PM, SaltySugar wrote:


Thank you, Mike. One more question. Can I use hbox.add(btn); instead of
hbox.packStart (btn,false,false,5);
What difference between them?
Sorry, for my bad English.


hbox.add would call packStart with the defaults, witch would be 
packStart(btn, true, true, 0); Changing packStart to add in the small 
example i posted it appears to stay the same.


--
Mike Wey


Re: new T[size] vs .reserve - alloca

2013-02-05 Thread monarch_dodra

On Tuesday, 5 February 2013 at 21:14:32 UTC, Nick Treleaven wrote:

On 05/02/2013 21:13, Nick Treleaven wrote:

I've just tried it with dmd 2.059 (haven't upgraded yet)


sorry, 2.060


Right, it's alias being finicky, because args.length isn't an 
actual variable (it's a property). The problem is not so much 
that it can't be read at compile time, that the compiler 
doesn't know what to alias to.


I'll file a bug report to try and see if we can't get a better 
message.


Use a named variable, or use a manifest constant:

//
import std.stdio;
import core.stdc.stdlib:alloca;

T* stack(T)(void* m = alloca(T.sizeof))
{
return cast(T*)m;
}
T[] stack(T, alias N)(void* m = alloca(T.sizeof * N))
{
return (cast(T*)m)[0 .. N];
}

void main(string[] args)
{
auto n = args.length;
int[] arr = stack!(int, n)();
}
//


Re: A little of coordination for Rosettacode

2013-02-05 Thread bearophile

Jos van Uden:


How do we avoid working on the same thing?


With a little coordination :-)



Partial translation of rcrpg-Python:
http://codepad.org/SflrKqbT

Partial translation of 
permutations_rank_of_a_permutation-Python:

http://codepad.org/El9SQwOE


The 2 above, I could try.


Plus a better Perl implementation of the uniform() on BigInts:
http://codepad.org/LGcMpk2f


My perl is too rusty.


That perl is meant as a part of 
permutations_rank_of_a_permutation. Feel free to search for other 
good algorithms to implement uniform(BigInt,BigInt) much better 
than me. If this code comes out good enough, it must be added to 
Phobos (and it's meant to be designed better than the Java 
uniform generator for its bigintegers, because it doesn't give a 
correct range).




Partial translation of the universal_turing_machine-Ruby:
http://codepad.org/nUXLzAg2


I'd have to first read up on the subject.


It's a simple task, just to implement an universal Turing 
machine. It's a matter of finding a balance between the too much 
high level Ruby version and a too much C-like version.
In D a simple way to implement a tape is with two dynamic arrays, 
one represents all the cells on the right to the starting 
position, and the other array is used inverted, to represent 
all the cells on the left of the right position. There are faster 
solutions, but this is enough for the purposes of Rosettacode.


Bye,
bearophile


Regarding isSorted

2013-02-05 Thread bearophile
This used to print true-false, now prints true-true. Is this a 
bug?



import std.stdio, std.algorithm;
void main() {
auto x = abcd;
writeln(isSorted(x));
auto y = acbd;
writeln(isSorted(y));
}


Maybe this line:

https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L9237

for (; !ahead.empty; ahead.popFront(), ++i)

Should be:

for (; !ahead.empty; ahead.popFront(), r.popFront(), ++i)

Bye,
bearophile


Re: Regarding isSorted

2013-02-05 Thread Jonathan M Davis
On Wednesday, February 06, 2013 01:33:29 bearophile wrote:
 This used to print true-false, now prints true-true. Is this a
 bug?
 
 
 import std.stdio, std.algorithm;
 void main() {
  auto x = abcd;
  writeln(isSorted(x));
  auto y = acbd;
  writeln(isSorted(y));
 }
 
 
 Maybe this line:
 
 https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d
 #L9237
 
  for (; !ahead.empty; ahead.popFront(), ++i)
 
 Should be:
 
  for (; !ahead.empty; ahead.popFront(), r.popFront(), ++i)

That definitely looks like a bug. acbd _isn't_ sorted.

- Jonathan M Davis


Re: Regarding isSorted

2013-02-05 Thread bearophile

Jonathan M Davis:


That definitely looks like a bug. acbd _isn't_ sorted.


OK. Thank you.

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



Brad Anderson:


Have a GitHub account, bearophile?


Not yet, but probably I will have one.



Just hit Edit at the top of
that link you gave, make the change, and click Proposal File
Change and it'll roll up a pull request. Should take less than 
a
minute. I use this for almost every minor pull requests I do. 
The

autotester takes care of the rest.


Sounds quick  easy. I will remember this. Thank you.


Looks like line 9221 is essentially the same code so you may 
want

to change that line too.


Added in the bug report.

Bye,
bearophile


Re: best D way to port C style array of void*

2013-02-05 Thread Steven Schveighoffer

On Tue, 05 Feb 2013 22:16:17 -0500, estew est...@gmail.com wrote:


Hi All,

I've some old C code which I'm porting to D. It's a learning exercise so  
I don't want to just wrap the C lib.


I have an array of void* and an array of callbacks that take void*  
pointers for user data.


I'm wondering what is a good way to port this into D and avoid the  
void*. My C++ version uses std::function for the callbacks and  
functors. I'm using std::vectorboost::any For the array of void*.


Maybe it's not the best approach but it's my best efforts. For the D  
port I'd like to improve on the C++ approach and I'd love to know a  
better way to do it.


* Could I replace the boost::any with an array of Variant from  
std.variant?


That is probably what I would recommend.  Although I would consider  
altering the design to avoid this.  D has a much better type system than C  
or C++.


* Can I assign a struct with opCall() to a function pointer, similar to  
how std::function can take a struct with an operator().


* Should I forget functors and use a callback that takes a std.variant  
(or whatever the boost::any like thing in D is) instead of void*?


Use a delegate.  A delegate is a function call with a context pointer.  No  
need to specify the type of the pointer, it's whatever type it needs to be.


You can create a delegate just about anywhere.  It can be a member  
function of a class or struct, or an internal function, or a lambda  
function (D supports closures).


e.g.:

import std.stdio;

void callit(void delegate() dg)
{
// call delegate with context pointer
dg();
}

void main()
{
int x;
auto dg = ()=writeln(++x); // create a delegate using a lambda  
function

callit(dg);
callit(dg);
callit(dg);
callit(dg);
}

-Steve


Re: best D way to port C style array of void*

2013-02-05 Thread Steven Schveighoffer
On Tue, 05 Feb 2013 23:17:59 -0500, Steven Schveighoffer  
schvei...@yahoo.com wrote:




e.g.:

import std.stdio;

void callit(void delegate() dg)
{
 // call delegate with context pointer
 dg();
}

void main()
{
 int x;
 auto dg = ()=writeln(++x); // create a delegate using a lambda  
function

 callit(dg);
 callit(dg);
 callit(dg);
 callit(dg);
}


Forgot to say, the output here would be:

1
2
3
4

-Steve


Re: best D way to port C style array of void*

2013-02-05 Thread estew

Thanks for your help, much appreciated.

I'm using the delegates now for the callbacks. At your suggestion 
I'm looking for a good way to change the design. I agree, the D 
type system is way superior to that of C.


Starting to get into mixins too, although I'm a bit wary of them. 
I know they're not macros, but I once had to debug (and 
eventually rewrote) ~5000 lines of macros that calculate 
interpolated XYZ values...still recovering :)


Cheers,
Stewart



Re: Regarding isSorted

2013-02-05 Thread Jos van Uden

On 6-2-2013 1:33, bearophile wrote:



Maybe this line:

https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L9237

 for (; !ahead.empty; ahead.popFront(), ++i)

Should be:

 for (; !ahead.empty; ahead.popFront(), r.popFront(), ++i)



Thought that line looked fishy. But I don't understand half the code in Phobos 
so I
figured it must be me...



type of if statement used for operator overloading?

2013-02-05 Thread Jeremy DeHaan
I've seen operator overloading done 3 different ways. In the 
examples I provide they all compile and work as far as I can 
tell. Is there any major difference between using a static if vs 
a regular if, or any situation that one would be better than the 
other?



struct Something1
{
   Something1 opUnary(string s)()
   {
   if (s == -)
   {
  return stuff;
   }
   }

}

struct Something2
{
   Something2 opUnary(string s)()
   {
   static if (s == -)
   {
  return stuff;
   }
   }

}

Also, I realize that if I wanted to overload just a single 
operator and that was all, I could do:


struct Something3
{
   Something3 opUnary(string s)()
  if (s == -)
   {

   return stuff;

   }

}

But I am more curious about the first two.

Thanks as usual guys!
Jeremy


Re: type of if statement used for operator overloading?

2013-02-05 Thread Jonathan M Davis
On Wednesday, February 06, 2013 07:24:10 Jeremy DeHaan wrote:
 I've seen operator overloading done 3 different ways. In the
 examples I provide they all compile and work as far as I can
 tell. Is there any major difference between using a static if vs
 a regular if, or any situation that one would be better than the
 other?
 
 
 struct Something1
 {
 Something1 opUnary(string s)()
 {
 if (s == -)
 {
return stuff;
 }
 }
 
 }

Don't do this. You want to be generating different functions for different 
overloaded operators. This just introduces extra runtime overhead. It also 
fails to deal with all of the possible values of s.

 struct Something2
 {
 Something2 opUnary(string s)()
 {
 static if (s == -)
 {
return stuff;
 }
 }
 
 }

This is better but again fails to deal with all of the possible values of s. 
You'll get a nasty error message if a different value gets passed in.

 Also, I realize that if I wanted to overload just a single
 operator and that was all, I could do:
 
 struct Something3
 {
 Something3 opUnary(string s)()
if (s == -)
 {
 
 return stuff;
 
 }
 
 }
 
 But I am more curious about the first two.

The last one is by far the best, because it protects against values for s that 
you don't intend to overload for. You can with the second example if you 
really want to and have multiple operators that you want to overload with the 
same function, but you still need a template constraint to protect against 
values that you don't intend to handle. Pretty much _every_ template that you 
write should have a template constraint on it.

And in many cases, overloaded operators should just use string mixins. For 
instance, core.time.Duration does this:

Duration opBinary(string op, D)(D rhs) @safe const pure nothrow
if((op == + || op == -) 
   (is(_Unqual!D == Duration) ||
is(_Unqual!D == TickDuration)))
{
static if(is(_Unqual!D == Duration))
return Duration(mixin(_hnsecs  ~ op ~  rhs._hnsecs));
else if(is(_Unqual!D == TickDuration))
return Duration(mixin(_hnsecs  ~ op ~  rhs.hnsecs));
}

It uses static ifs to differentiate between Duration and TickDuration (since 
they require different code), but the code doesn't differentiate between the 
operators. Rather, it just mixes in the string, and it'll do the right thing 
in both cases. The template constraint already protects against operators that 
it doesn't actually overload.

- Jonathan M Davis


Re: best D way to port C style array of void*

2013-02-05 Thread Jacob Carlborg

On 2013-02-06 06:49, estew wrote:

Thanks for your help, much appreciated.

I'm using the delegates now for the callbacks. At your suggestion I'm
looking for a good way to change the design. I agree, the D type system
is way superior to that of C.


I would suggest you try to replace the array with something more typed, 
if possible.


--
/Jacob Carlborg


Re: type of if statement used for operator overloading?

2013-02-05 Thread Jeremy DeHaan
On Wednesday, 6 February 2013 at 06:38:11 UTC, Jonathan M Davis 
wrote:

On Wednesday, February 06, 2013 07:24:10 Jeremy DeHaan wrote:

I've seen operator overloading done 3 different ways. In the
examples I provide they all compile and work as far as I can
tell. Is there any major difference between using a static if 
vs
a regular if, or any situation that one would be better than 
the

other?


struct Something1
{
Something1 opUnary(string s)()
{
if (s == -)
{
   return stuff;
}
}

}


Don't do this. You want to be generating different functions 
for different
overloaded operators. This just introduces extra runtime 
overhead. It also

fails to deal with all of the possible values of s.


struct Something2
{
Something2 opUnary(string s)()
{
static if (s == -)
{
   return stuff;
}
}

}


This is better but again fails to deal with all of the possible 
values of s.
You'll get a nasty error message if a different value gets 
passed in.



Also, I realize that if I wanted to overload just a single
operator and that was all, I could do:

struct Something3
{
Something3 opUnary(string s)()
   if (s == -)
{

return stuff;

}

}

But I am more curious about the first two.


The last one is by far the best, because it protects against 
values for s that
you don't intend to overload for. You can with the second 
example if you
really want to and have multiple operators that you want to 
overload with the
same function, but you still need a template constraint to 
protect against
values that you don't intend to handle. Pretty much _every_ 
template that you

write should have a template constraint on it.

And in many cases, overloaded operators should just use string 
mixins. For

instance, core.time.Duration does this:

Duration opBinary(string op, D)(D rhs) @safe const pure nothrow
if((op == + || op == -) 
   (is(_Unqual!D == Duration) ||
is(_Unqual!D == TickDuration)))
{
static if(is(_Unqual!D == Duration))
return Duration(mixin(_hnsecs  ~ op ~  
rhs._hnsecs));

else if(is(_Unqual!D == TickDuration))
return Duration(mixin(_hnsecs  ~ op ~  rhs.hnsecs));
}

It uses static ifs to differentiate between Duration and 
TickDuration (since
they require different code), but the code doesn't 
differentiate between the
operators. Rather, it just mixes in the string, and it'll do 
the right thing
in both cases. The template constraint already protects against 
operators that

it doesn't actually overload.

- Jonathan M Davis


Thanks for the info, Jonathan! I had no idea that I should 
constrain the kinds of operators I was overloading if I have more 
than two, but that makes sense and I will do this from now on.


Out of curiosity, what exactly happens when we don't constrain 
what operators are being overloaded? Is it undefined behavior or 
will the program just not compile?


And that is a cool use of mixins. They are still a pretty new 
concept to me so I haven't looked into them much.



Thanks a lot for the info though!
Jeremy