Associative array and ranges

2011-02-02 Thread Nrgyzer
Hey guys,

I have an associative array like this: T[hash_t] myArray; (T means
the template type).

Is there any chance to cast/convert this array to an indexed array or
is it possible to iterate over specific indices? I know that there is
something like next() for the foreach-statement but when the array
contains some thousand instances and I only want iterate over (for
example) 5 elements I think that's the wrong way. It's for a game and
I think every next()-call influences the fps.

I hope there is any solution for my problem :) - Thanks!


Re: ASM access to array

2011-02-02 Thread Matthias Pleh

As bearophile notet, unittest are always good!!
But for the start, I always liked to make some pretty-printing functions ...
... so this is my version


import std.stdio;

uint rotl_d(uint value,ubyte rotation){
return (valuerotation) | (value(value.sizeof*8 - rotation));
}

uint rotl_asm(uint value,ubyte rotation){
asm{
mov EAX, value;   // get first argument
mov CL , rotation; // how many bits to move
rol EAX, CL;
}// return with result in EAX
}

void bin_writeln(string info,uint value, bool nl){
writefln(%1s: %02$32b%3$s,info,value,nl?\n:);
}

int main(string[] argv){
uint a=0xc0def00d;
bin_writeln(value a,a   ,false);
bin_writeln(value b,rotl_d(a,1),true);
//
bin_writeln(value a,a ,false);
bin_writeln(value b,rotl_asm(a,1),true);
return 0;
}

greets
Matthias


higher-order funcs for ranges (with usual interface)

2011-02-02 Thread spir

Hello,

This bit of code for arrays:

Out[] map (In,Out) (In[] input, Out delegate (In) f) {
Out[] output = new Out[](input.length);
foreach (i,item ; input)
output [i] = f(item);
return output;
}
unittest {
char character (uint code) {return cast(char)code;}
uint[] codes = [0x61,0x62,0x63];
// functional style
writeln(map(codes, character));// abc
// OO style
writeln(codes.map(character)); // abc
}

How to write this for ranges? I mean, with the same kind of interface to client 
code (not the interface of std.algo.map).
And is there a way to write it so that it works both for ranges and other kinds 
of sequences (arrays, strings); or even for anything iterable (AA, set, list, 
tree...).


For ranges, I'm looking for something similar to:
Range!Out map (In,Out) (Range!In input, Out delegate (In) f) {...}
Indeed, the compiler should understand that Range!T is a type id just like T[].

Denis
--
_
vita es estrany
spir.wikidot.com



Re: higher-order funcs for ranges (with usual interface)

2011-02-02 Thread Lars T. Kyllingstad
On Wed, 02 Feb 2011 13:26:39 +0100, spir wrote:

 Hello,
 
 This bit of code for arrays:
 
 Out[] map (In,Out) (In[] input, Out delegate (In) f) {
  Out[] output = new Out[](input.length); foreach (i,item ; input)
  output [i] = f(item);
  return output;
 }
 unittest {
  char character (uint code) {return cast(char)code;} uint[] codes =
  [0x61,0x62,0x63];
  // functional style
  writeln(map(codes, character));// abc // OO style
  writeln(codes.map(character)); // abc
 }
 
 How to write this for ranges? [...]

 For ranges, I'm looking for something similar to:
  Range!Out map (In,Out) (Range!In input, Out delegate (In) f) {...}
 Indeed, the compiler should understand that Range!T is a type id just
 like T[].

I don't think it's possible to do it exactly as you describe.  I mean, 
Range in that case can be anything, and you can't always return a range 
of the same kind.  Two possibilities are, you can do it eagerly,

  Out[] map(Range, In, Out)(Range input, Out delegate(In) f)
  if (isInputRange!Range  is(ElementType!Range : In))
  {
  ...
  }

or you can do it lazily by defining your own map range (untested):

  struct Map(Range, In, Out)
  if (isInputRange!Range  is(ElementType!Range : In)
  {
  Range input;
  Out delegate(In) f;

  @property bool empty() { return input.empty; }

  // Inefficient, should cache front...
  @property Out front() { return f(input.front); }
  
  void popFront() { input.popFront(); }
  }

  Map!(Range, Out) map(Range, In, Out)(Range input, Out delegate(In) f)
  if (isInputRange!R  is(ElementType!Range : In)
  {
  return typeof(return)(input, f);
  }

-Lars


Re: higher-order funcs for ranges (with usual interface)

2011-02-02 Thread Lars T. Kyllingstad
On Wed, 02 Feb 2011 13:18:07 +, Lars T. Kyllingstad wrote:

 [...]
 
   struct Map(Range, In, Out)
   if (isInputRange!Range  is(ElementType!Range : In)
   {
   Range input;
   Out delegate(In) f;
 
   @property bool empty() { return input.empty; }
 
   // Inefficient, should cache front... @property Out front() {
   return f(input.front); }
   
   void popFront() { input.popFront(); }
   }
 
   Map!(Range, Out) map(Range, In, Out)(Range input, Out delegate(In) f)
   if (isInputRange!R  is(ElementType!Range : In)
   {
   return typeof(return)(input, f);
   }

Oops, seems i missed a few closing parentheses on the template 
constraints.

-Lars


Re: Associative array and ranges

2011-02-02 Thread Simen kjaeraas

Nrgyzer nrgy...@gmail.com wrote:


Hey guys,

I have an associative array like this: T[hash_t] myArray; (T means
the template type).

Is there any chance to cast/convert this array to an indexed array or
is it possible to iterate over specific indices? I know that there is
something like next() for the foreach-statement but when the array
contains some thousand instances and I only want iterate over (for
example) 5 elements I think that's the wrong way. It's for a game and
I think every next()-call influences the fps.

I hope there is any solution for my problem :) - Thanks!


You should probably try aa.byValue:

auto o = [a: 1, b: 2];

foreach ( e; o.byValue ) {
writeln( e );
}

It seems from the (somewhat unreadable) source, that the values are
stored in an array of pointers to structs holding these values.

If this is not fast enough for your needs, I'm afraid you will have
to write an AA implementation yourself. (You can replace the code in
druntime/src/rt/aaA.d with your own if you still want the nice
syntax sugar)

--
Simen


default '==' on structs

2011-02-02 Thread spir

Hello,

What are the default semantics for '==' on structs?

I ask this because I was forced to write opEquals on a struct to get expected 
behaviour. This struct is basically:


struct Lexeme {
string tag;
string slice;
Ordinal index;
}

Equal Lexeme's compare unequal using default '=='. When I add:

const bool opEquals (ref const(Lexeme) l) {
return (
   this.tag   == l.tag
 this.slice == l.slice
 this.index == l.index
);
}

then all works fine. What do I miss?

Denis
--
_
vita es estrany
spir.wikidot.com



Re: default '==' on structs

2011-02-02 Thread Lars T. Kyllingstad
On Wed, 02 Feb 2011 15:55:53 +0100, spir wrote:

 Hello,
 
 What are the default semantics for '==' on structs?
 
 I ask this because I was forced to write opEquals on a struct to get
 expected behaviour. This struct is basically:
 
 struct Lexeme {
  string tag;
  string slice;
  Ordinal index;
 }
 
 Equal Lexeme's compare unequal using default '=='. When I add:
 
  const bool opEquals (ref const(Lexeme) l) {
  return (
 this.tag   == l.tag
   this.slice == l.slice
   this.index == l.index
  );
  }
 
 then all works fine. What do I miss?

I think the compiler does a bitwise comparison in this case, meaning that 
it compares the arrays' pointers instead of their data.  Related bug 
report:

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

-Lars


Re: Associative array and ranges

2011-02-02 Thread Jonathan M Davis
On Wednesday 02 February 2011 02:11:34 Nrgyzer wrote:
 Hey guys,
 
 I have an associative array like this: T[hash_t] myArray; (T means
 the template type).
 
 Is there any chance to cast/convert this array to an indexed array or
 is it possible to iterate over specific indices? I know that there is
 something like next() for the foreach-statement but when the array
 contains some thousand instances and I only want iterate over (for
 example) 5 elements I think that's the wrong way. It's for a game and
 I think every next()-call influences the fps.
 
 I hope there is any solution for my problem :) - Thanks!

If you know which keys you want, then just have a list of those and iterate 
over 
them, and then use them to grab their corresponding values from the AA on each 
iteration. As far as iterating over the AA itself goes, either you're iterating 
over the keys, the values, or both. You can't iterate over just part of it. I 
haven't a clue how such a thing would be implemented anyway. But there's 
nothing 
to stop you from iterating over a list of the keys that you want and then using 
those keys to grab the values from the AA.

- Jonathan M Davis


Re: default '==' on structs

2011-02-02 Thread spir

On 02/02/2011 04:20 PM, Lars T. Kyllingstad wrote:

On Wed, 02 Feb 2011 15:55:53 +0100, spir wrote:


Hello,

What are the default semantics for '==' on structs?

I ask this because I was forced to write opEquals on a struct to get
expected behaviour. This struct is basically:

struct Lexeme {
  string tag;
  string slice;
  Ordinal index;
}

Equal Lexeme's compare unequal using default '=='. When I add:

  const bool opEquals (ref const(Lexeme) l) {
  return (
 this.tag   == l.tag
   this.slice == l.slice
   this.index == l.index
  );
  }

then all works fine. What do I miss?


I think the compiler does a bitwise comparison in this case, meaning that
it compares the arrays' pointers instead of their data.  Related bug
report:

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

-Lars


Thank you, Lars.
In fact, I do not really understand what you mean. But it helped me think 
further :-)

Two points:

* The issue reported is about '==' on structs not using member opEquals when 
defined, instead performing bitwise comparison. This is not my case: Lexeme 
members are plain strings and an uint. They should just be compared as is. 
Bitwise comparison should just work fine.

Also, this issue is marked solved for dmd 2.037 (I use 2.051).

* The following works as expected:

struct Floats {float f1, f2;}
struct Strings {string s1, s2;}
struct Lexeme {
string tag;
string slice;
uint index;
}

unittest {
assert ( Floats(1.1,2.2)  == Floats(1.1,2.2) );
assert ( Strings(a,b) == Strings(a,b) );
assert ( Lexeme(a,b,1) == Lexeme(a,b,1) );
}

This shows, if I'm right:
1. Array (string) members are compared by value, not by ref/pointer.
2. Comparing Lexeme's works in this test case.

* Why does my app then need opEquals, just to compare member per member (see 
code above)?
The issue happens in a unittest. Lexemes are generated by a typical use of the 
module's features, then assert() compares them to expected result:

assert ( lexeme == Lexeme(expected_data) );
I'll try to reduce the issue to isolate the key point.

Thank you for your help,
denis
--
_
vita es estrany
spir.wikidot.com



Re: default '==' on structs

2011-02-02 Thread Andrej Mitrovic
What is Ordinal defined as? If it's a uint, I get the expected results:

alias uint Ordinal;

struct Lexeme {
   string tag;
   string slice;
   Ordinal index;
}

void main()
{
auto lex1 = Lexeme(a,b,1);
auto lex2 = Lexeme(a,b,1);

assert(lex1 == lex2);
assert(lex1 == Lexeme(a,b,1));
}

Can't say much more without knowing what your app does though.


Re: higher-order funcs for ranges (with usual interface)

2011-02-02 Thread spir

On 02/02/2011 02:18 PM, Lars T. Kyllingstad wrote:

On Wed, 02 Feb 2011 13:26:39 +0100, spir wrote:


Hello,

This bit of code for arrays:

Out[] map (In,Out) (In[] input, Out delegate (In) f) {
  Out[] output = new Out[](input.length); foreach (i,item ; input)
  output [i] = f(item);
  return output;
}
unittest {
  char character (uint code) {return cast(char)code;} uint[] codes =
  [0x61,0x62,0x63];
  // functional style
  writeln(map(codes,character));// abc // OO style
  writeln(codes.map(character)); // abc
}

How to write this for ranges? [...]

For ranges, I'm looking for something similar to:
  Range!Out map (In,Out) (Range!In input, Out delegate (In) f) {...}
Indeed, the compiler should understand that Range!T is a type id just
like T[].


I don't think it's possible to do it exactly as you describe.  I mean,
Range in that case can be anything, and you can't always return a range
of the same kind.


Right. The output range's ElementType is given by f's return type. As you say, 
the kind of range may change. Even if it's the same, how could one express 
that: range_which-elements-are-of-type-T, syntactically and in the param set, 
just like array_which-elements-are-of-type- is written T[]?
Currently, we must (1) declare the range type as template param, which is a bit 
redondant because the ElementType must also be given, (2) add some 'is' horror 
code:

 if (isInputRange!Range  is(ElementType!Range : In))
I guess the only solution would be for the compiler to support a kind of reange 
type syntax?



  Two possibilities are, you can do it eagerly,

   Out[] map(Range, In, Out)(Range input, Out delegate(In) f)
   if (isInputRange!Range  is(ElementType!Range : In))
   {
   ...
   }


OK.


or you can do it lazily by defining your own map range (untested):

   struct Map(Range, In, Out)
   if (isInputRange!Range  is(ElementType!Range : In)
   {
   Range input;
   Out delegate(In) f;

   @property bool empty() { return input.empty; }

   // Inefficient, should cache front...
   @property Out front() { return f(input.front); }

   void popFront() { input.popFront(); }
   }


That's similar to what I did.


   Map!(Range, Out) map(Range, In, Out)(Range input, Out delegate(In) f)
   if (isInputRange!R  is(ElementType!Range : In)
   {
   return typeof(return)(input, f);
   }


What's the point of map, then? My version initially had a 'MapRange' defined as 
static struct template inside map, but then map just instanciated it, so I 
suppressed map alltogether, letting the user write:

auto r2 = MapRange!(R1, In, Out)(input, f);
which is not more complicated than calling the func, I guess.


-Lars


Denis
--
_
vita es estrany
spir.wikidot.com



Re: Associative array and ranges

2011-02-02 Thread bearophile
Nrgyzer:

 Is there any chance to cast/convert this array to an indexed array or
 is it possible to iterate over specific indices? I know that there is
 something like next() for the foreach-statement but when the array
 contains some thousand instances and I only want iterate over (for
 example) 5 elements I think that's the wrong way.

Show a hypothetical code example of what you desire to do, please.

Bye,
bearophile


Re: default '==' on structs

2011-02-02 Thread bearophile
spir:

 * The issue reported is about '==' on structs not using member opEquals when 
 defined, instead performing bitwise comparison. This is not my case: Lexeme 
 members are plain strings and an uint. They should just be compared as is. 
 Bitwise comparison should just work fine.
 Also, this issue is marked solved for dmd 2.037 (I use 2.051).

Lars is right, the == among structs is broken still:

struct Foo { string s; }
void main() {
string s1 = he;
string s2 = llo;
string s3 = hel;
string s4 = lo;
auto f1 = Foo(s1 ~ s2);
auto f2 = Foo(s3 ~ s4);
assert((s1 ~ s2) == (s3 ~ s4));
assert(f1 == f2);
}

Bye,
bearophile


Re: default '==' on structs

2011-02-02 Thread spir

On 02/02/2011 05:49 PM, Andrej Mitrovic wrote:

What is Ordinal defined as? If it's a uint, I get the expected results:

alias uint Ordinal;

struct Lexeme {
string tag;
string slice;
Ordinal index;
}

void main()
{
 auto lex1 = Lexeme(a,b,1);
 auto lex2 = Lexeme(a,b,1);

 assert(lex1 == lex2);
 assert(lex1 == Lexeme(a,b,1));
}

Can't say much more without knowing what your app does though.


Actually, its size_t. But I also have everything working fine in a test case 
exactly similar to yours (see other post). Dunno yet why I need to add an 
opEquals just comparing members individually for my unittests to pass.


I take the opportunity to say a few words about the module; case (1) it helps 
debugging (2) some people are interested in it.
The module is a lexing toolkit. It allows creating a lexer from a language's 
morphology, then use it to scan source. Example for simple arithmetics:


Morphology morphology = [
[ SPACING ,`[\ \t]*` ],
[ OPEN_GROUP , `(` ],
[ CLOSE_GROUP ,`)` ],
[ operator ,   `[+*-/]` ],
[ symbol , `[a-zA-A][a-zA-A0-9]*` ],
[ number , `[+-]?[0-9]+(\.[0-9]+)?` ],
];
auto lexer = new Lexer(morphology);
auto lexemes = lexer.lexemes(source);

As you see, each lexeme kind is defined by a string tag and a regex format.
The output is an array of lexemes holding the matched slice, wrapped in a class 
LexemeStream. This class mainly provides a match method:

Lexeme* match (tag)
Match returns a pointer to the current lexeme if it is of the right kind, else 
null (same principle as D's builtin 'in' operator). So, one can either ignore 
the lexeme if all what is needed is testing the match (case of punctuation), or 
use the lexeme's slice (case of values).


The issue I get happens when checking that a result stream of lexemes is as 
expected: '==' failed. I then checked its first/last lexemes only: ditto. Thus, 
I started to wonder about the default semantics of '==' for structs, so that I 
wrote my own opEquals == pass for individual lexemes, pass for whole lexeme 
streams. Why? dunno.


Denis
--
_
vita es estrany
spir.wikidot.com



Re: default '==' on structs

2011-02-02 Thread spir

On 02/02/2011 07:05 PM, bearophile wrote:

spir:


* The issue reported is about '==' on structs not using member opEquals when
defined, instead performing bitwise comparison. This is not my case: Lexeme
members are plain strings and an uint. They should just be compared as is.
Bitwise comparison should just work fine.
Also, this issue is marked solved for dmd 2.037 (I use 2.051).


Lars is right, the == among structs is broken still:

struct Foo { string s; }
void main() {
 string s1 = he;
 string s2 = llo;
 string s3 = hel;
 string s4 = lo;
 auto f1 = Foo(s1 ~ s2);
 auto f2 = Foo(s3 ~ s4);
 assert((s1 ~ s2) == (s3 ~ s4));
 assert(f1 == f2);
}


Thank you, this helps much. I don't get the details yet, but think some similar 
issue is playing a role in my case. String members of the compared Lexeme 
structs are not concatenated, but one of them is sliced from the scanned source.
If I dup'ed instead of slicing, this would create brand new strings; thus '==' 
performing bitwise comp should run fine, don't you think? I'll try in a short 
while.


Do you know more about why/how the above fails?

Denis
--
_
vita es estrany
spir.wikidot.com



Re: default '==' on structs

2011-02-02 Thread spir

On 02/02/2011 07:09 PM, bearophile wrote:

Lars is right, the == among structs is broken still:


If necessary please open a new bug report, this is an important bug.


Right, i'll do it when (hopefully) I understand more about the details of 
why/how '==' fails in my case.


Denis
--
_
vita es estrany
spir.wikidot.com



Re: default '==' on structs

2011-02-02 Thread spir

On 02/02/2011 07:09 PM, bearophile wrote:

Lars is right, the == among structs is broken still:


If necessary please open a new bug report, this is an important bug.

Bye,
bearophile


Right, reduced the bug cases I found to:

struct S {string s;}
unittest {
// concat
string s1 = he; string s2 = llo;
string s3 = hel; string s4 = lo;
assert ( S(s1 ~ s2) != S(s3 ~ s4) );
// slice
string s = hello;
assert ( S(s[1..$-1]) != S(ell) );
}

Same for array members (indeed):

struct A {int[] a;}
unittest {
// concat
int[] a1 = [1,2]; int[] a2 = [3];
int[] a3 = [1]; int[] a4 = [2,3];
assert ( A(a1 ~ a2) != A(a3 ~ a4) );
// slice
int[] a = [1,2,3];
assert ( A(a[1..$-1]) != A([2]) );
}

But this is not very relevant, because plain arrays /members/ (unlike strings) 
seem to be compared by ref (exactly by array struct):


unittest {
// string
string s1 = hello; string s2 = hello;
assert ( S(s1) == S(s2) );
// array (note '!=' assert)
int[] a1 = [1,2,3]; int[] a2 = [1,2,3];
assert ( A(a1) != A(a2) );
}

I think at opening a new bug report in a short while, with reference to issue 
#3433 (http://d.puremagic.com/issues/show_bug.cgi?id=3433) which was (unduly?) 
marked as fixed for dmd 2.037. In the meanwhile, if anyone knows about related 
cases of bug, or has more info, please tell.


On the other hand, the example of arrays let me doubt about correct / desirable 
semantics.

1. Indeed, I think string members should be compared by value.
2. But arrays are not, so should strings be compared by ref as well, if only to 
avoid inconsistency?

3. But then, why the already existing difference between strings  arrays?
4. Or should arrays be compared by value like string?
5. But strings are not /really/ compared by value as of now...
The current behaviour is weird. I don't how it can only happen.

Denis
--
_
vita es estrany
spir.wikidot.com



Foreach type infering only works up to 2 levels?

2011-02-02 Thread Andrej Mitrovic
int[][][][] multiArray;

void main()
{
foreach (one, two; multiArray)  // ok
{
}

foreach (one, two, three; multiArray)  // fail
{
}
}

test.d(13): Error: cannot infer type for two
test.d(13): Error: cannot infer type for three

Same thing happens with hashes as well. Is this a limitation in the language or 
a bug?


Re: default '==' on structs

2011-02-02 Thread bearophile
spir:

 Do you know more about why/how the above fails?

It's simple. A string (or array) is a 2-words long struct that contains a 
pointer to the data and a size_t length. Default struct equality just compares 
the bits of those two fields. In the above example I have created f1 and f2 
using two strings that have the same contents and lengths, but the pointers are 
different, because they are generated at run-time (normally the compiler uses a 
pool of shared string literals), so the equality fails.

I have asked Walter to fix this problem with strings and arrays probably three 
years ago or more, it's not a new problem :-)

Bye,
bearophile


Re: Foreach type infering only works up to 2 levels?

2011-02-02 Thread Jesse Phillips
Andrej Mitrovic Wrote:

 Wow disregard this whole post. I've just realized how stupid that looks.
 
 Sorry. :)

See, you have material for a tutorial. I know you wouldn't run out.


Re: Foreach type infering only works up to 2 levels?

2011-02-02 Thread Andrej Mitrovic
On 2/2/11, Jesse Phillips jessekphillip...@gmail.com wrote:
 Andrej Mitrovic Wrote:

 Wow disregard this whole post. I've just realized how stupid that looks.

 Sorry. :)

 See, you have material for a tutorial. I know you wouldn't run out.


Actually, yes. TDPL doesn't discuss much about multidimensional data,
other than the simple 2-dimensional arrays (IIRC).


Re: default '==' on structs

2011-02-02 Thread spir

On 02/02/2011 07:41 PM, spir wrote:

On 02/02/2011 07:05 PM, bearophile wrote:

spir:


* The issue reported is about '==' on structs not using member opEquals when
defined, instead performing bitwise comparison. This is not my case: Lexeme
members are plain strings and an uint. They should just be compared as is.
Bitwise comparison should just work fine.
Also, this issue is marked solved for dmd 2.037 (I use 2.051).


Lars is right, the == among structs is broken still:

struct Foo { string s; }
void main() {
string s1 = he;
string s2 = llo;
string s3 = hel;
string s4 = lo;
auto f1 = Foo(s1 ~ s2);
auto f2 = Foo(s3 ~ s4);
assert((s1 ~ s2) == (s3 ~ s4));
assert(f1 == f2);
}


Thank you, this helps much. I don't get the details yet, but think some similar
issue is playing a role in my case. String members of the compared Lexeme
structs are not concatenated, but one of them is sliced from the scanned source.
If I dup'ed instead of slicing, this would create brand new strings; thus '=='
performing bitwise comp should run fine, don't you think? I'll try in a short
while.


No! idup does not help, still need opEquals. See also this example case:

struct S {string s;}
unittest {
// concat
string s1 = he; string s2 = llo;
string s3 = hel; string s4 = lo;
assert ( S(s1 ~ s2) != S(s3 ~ s4) );
// slice
string s = hello;
assert ( S(s[1..$-1]) != S(ell) );
// idup'ed
assert ( S(s[1..$-1].idup) != S(ell) );
s2 = s[1..$-1].idup;
assert ( S(s2) != S(ell) );
}

Denis
--
_
vita es estrany
spir.wikidot.com



Re: default '==' on structs

2011-02-02 Thread spir

On 02/02/2011 08:20 PM, bearophile wrote:

spir:


Do you know more about why/how the above fails?


It's simple. A string (or array) is a 2-words long struct that contains a 
pointer to the data and a size_t length. Default struct equality just compares 
the bits of those two fields. In the above example I have created f1 and f2 
using two strings that have the same contents and lengths, but the pointers are 
different, because they are generated at run-time (normally the compiler uses a 
pool of shared string literals), so the equality fails.

I have asked Walter to fix this problem with strings and arrays probably three 
years ago or more, it's not a new problem :-)


All right, you mean string literals are interned? Explaining why the case below 
works...


struct S {string s;}
unittest {
// plainly equal members
string s01 = hello; string s02 = hello;
assert ( S(s01) == S(s02) );
}

... because s01  s02 are actually the same, unique, piece of data in memory 
(thus pointers are equal indeed)?


I'm ok to write another bug report as you asked. But since you've asked for 
this already, and there is bug#3433 on a very similar topic supposedly closed 
as well, I fear it's useless, don't you?

And if we fix string, then the case of regular arrays becomes inconsistent.
The code issue about clear semantics, I guess, is that the case above works 
*due to* an implementation detail. The rest is just annoying (need to write 
opequals to get expected semantics in 99% cases, probably), but /not/ inconsistent.


Denis
--
_
vita es estrany
spir.wikidot.com



Re: Foreach type infering only works up to 2 levels?

2011-02-02 Thread Mafi

Am 02.02.2011 20:16, schrieb Andrej Mitrovic:

int[][][][] multiArray;

void main()
{
 foreach (one, two; multiArray)  // ok
 {
 }

 foreach (one, two, three; multiArray)  // fail
 {
 }
}

test.d(13): Error: cannot infer type for two
test.d(13): Error: cannot infer type for three

Same thing happens with hashes as well. Is this a limitation in the language or 
a bug?

I use the following idiom.

foreach(x, ref column; array)
foreach(y, ref element; column)
//maybe more...
{
//do something
}

It works because of constructs take one staement  one block is one 
statement. It is really great because it leads to such flexible soultions.
You might say it's bad practise bad then you have to say the same about 
'else if'.


Mafi


Re: Foreach type infering only works up to 2 levels?

2011-02-02 Thread Andrej Mitrovic
On 2/2/11, Mafi m...@example.org wrote:
 foreach(x, ref column; array)
 foreach(y, ref element; column)
 //maybe more...
 {
  //do something
 }

Cool, that fixes the indentation issue. Nice.


Re: default '==' on structs

2011-02-02 Thread bearophile
spir:

 And if we fix string, then the case of regular arrays becomes inconsistent.

The bug report is about arrays too, of course. I will write this bug report.

Bye,
bearophile


Is runtime introspection in a working state?

2011-02-02 Thread Andrej Mitrovic
After exploring object.d/di I've found upon some functions I can use on a type 
returned by .classinfo. But getMembers which I'm interested in doesn't seem 
to work:

import std.stdio;

class Foo
{
int x;
void bar()
{
}
}

void main()
{
Foo foo = new Foo();
auto info = foo.classinfo;

auto barField = info.getMembers(bar);
writeln(typeid(barField));  // const(const(object.MemberInfo)[])
writeln(barField.length);   // 0

auto fields = info.getMembers(null);
writeln(typeid(fields));// const(const(object.MemberInfo)[])
writeln(fields.length); // 0
}

I can get other methods to work, such as toString and tsize. But no luck with 
getMembers.


Re: default '==' on structs

2011-02-02 Thread bearophile
 The bug report is about arrays too, of course. I will write this bug report.

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

Bye,
bearophile


Re: ASM access to array

2011-02-02 Thread Joel Christensen

What about my edited version:

import std.stdio;

uint rotl_d(uint value,ubyte rotation){
return (valuerotation) | (value(value.sizeof*8 - rotation));
}

uint rotl_asm(uint value,ubyte rotation){
asm{
mov EAX, value;   // get first argument
mov CL , rotation; // how many bits to move
rol EAX, CL;
}// return with result in EAX
}

void bin_writeln(string info,uint value, bool nl){
writefln(%1s: %02$32b%3$s,info,value,nl?\n:);
}

int main(string[] argv){
uint a=0xc0def00d;
bin_writeln(value a,a   ,false);
bin_writeln(value b,rotl_d(a,1),true);
//
bin_writeln(value a,a ,false);
bin_writeln(value b,rotl_asm(a,1),true);

uint b;
ubyte c = 0;
while ( 1 == 1 ) { // Press Ctrl + C to quit
b = rotl_asm(0xc0def00d, c);
foreach (rst; 0 .. 5_000 )
writef(%032b %2d\r,b, c );
c = cast(ubyte)( c + 1 == 32 ? 0 : c + 1 );

}
return 0;
}



Accessing this of containing class

2011-02-02 Thread Mandeep Singh Brar
Hi,

Is there a method to access this reference of the container class
from an inner class. i.e.
class A {
class B {
   methodM() {
  callAnotherM(A::this or A.this);
   }
}
}

Thanks
Mandeep


Re: Accessing this of containing class

2011-02-02 Thread Jonathan M Davis
On Wednesday 02 February 2011 21:26:00 Mandeep Singh Brar wrote:
 Hi,
 
 Is there a method to access this reference of the container class
 from an inner class. i.e.
 class A {
 class B {
methodM() {
   callAnotherM(A::this or A.this);
}
 }
 }

The outer class is referenced via the property outer. However, if the inner 
class is static, then it has no such property and is not tied to a specific 
instance of the outer class. In such a case, it can access the private members 
of an instance of the outer class, but it's not tied to an particular instance. 
Non-static inner classes (like yours above), however, _are_ tied to a 
particular 
instance of the outer class, and they have the outer property which is the this 
of the outer class.

- Jonathan M Davis


Re: higher-order funcs for ranges (with usual interface)

2011-02-02 Thread Lars T. Kyllingstad
On Wed, 02 Feb 2011 18:38:02 +0100, spir wrote:

 On 02/02/2011 02:18 PM, Lars T. Kyllingstad wrote:
 On Wed, 02 Feb 2011 13:26:39 +0100, spir wrote:

 Hello,

 This bit of code for arrays:

 Out[] map (In,Out) (In[] input, Out delegate (In) f) {
   Out[] output = new Out[](input.length); foreach (i,item ; input)
   output [i] = f(item);
   return output;
 }
 unittest {
   char character (uint code) {return cast(char)code;} uint[] codes
   = [0x61,0x62,0x63];
   // functional style
   writeln(map(codes,character));// abc // OO style
   writeln(codes.map(character)); // abc
 }

 How to write this for ranges? [...]

 For ranges, I'm looking for something similar to:
   Range!Out map (In,Out) (Range!In input, Out delegate (In) f)
   {...}
 Indeed, the compiler should understand that Range!T is a type id just
 like T[].

 I don't think it's possible to do it exactly as you describe.  I mean,
 Range in that case can be anything, and you can't always return a range
 of the same kind.
 
 Right. The output range's ElementType is given by f's return type. As
 you say, the kind of range may change. Even if it's the same, how
 could one express that: range_which-elements-are-of-type-T,
 syntactically and in the param set, just like
 array_which-elements-are-of-type- is written T[]? Currently, we must
 (1) declare the range type as template param, which is a bit redondant
 because the ElementType must also be given, (2) add some 'is' horror
 code:
   if (isInputRange!Range  is(ElementType!Range : In))
 I guess the only solution would be for the compiler to support a kind of
 reange type syntax?

I'm not sure I understand what you mean here.  Perhaps you're looking for 
something like concepts, which have been discussed for both D and C++0x 
but rejected in both languages:

http://en.wikipedia.org/wiki/Concept_%28generic_programming%29


Anyway, if the source and target range are of the same (known) kind, 
something like this should work:

struct MyRange(T) { ... }

MyRange!Out map(In, Out)(MyRange!In input, Out delegate(In) f)
{
...
}

If they are of different kinds, but still known, this should work:

struct MySourceRange(T) { ... }
struct MyTargetRange(T) { ... }

MyTargetRange!Out map(In, Out)
(MySourceRange!In input, Out delegate(In) f)
{
...
}

Note that I am only talking about what the compiler should be able to 
figure out through IFTI (implicit function template instantiation), and 
not about actual implementation.


   Two possibilities are, you can do it eagerly,

Out[] map(Range, In, Out)(Range input, Out delegate(In) f)
if (isInputRange!Range  is(ElementType!Range : In))
{
...
}
 
 OK.
 
 or you can do it lazily by defining your own map range (untested):

struct Map(Range, In, Out)
if (isInputRange!Range  is(ElementType!Range : In)
{
Range input;
Out delegate(In) f;

@property bool empty() { return input.empty; }

// Inefficient, should cache front... @property Out front() {
return f(input.front); }

void popFront() { input.popFront(); }
}
 
 That's similar to what I did.
 
Map!(Range, Out) map(Range, In, Out)(Range input, Out delegate(In)
f)
if (isInputRange!R  is(ElementType!Range : In)
{
return typeof(return)(input, f);
}
 
 What's the point of map, then? My version initially had a 'MapRange'
 defined as static struct template inside map, but then map just
 instanciated it, so I suppressed map alltogether, letting the user
 write:
   auto r2 = MapRange!(R1, In, Out)(input, f);
 which is not more complicated than calling the func, I guess.

map() is just a helper function.   Unlike struct literals/constructors, 
functions can make use of IFTI, which makes for much prettier code:

// The range from my example, without map()
auto result =
Map!(SomeRange!int, int, bool)(someRange, someDelegate);

// The range from my example, with map()
auto result = map(someInputRange, someDelegate);

This has become a quite common idiom in Phobos.  std.range, for instance, 
is littered with helper functions like this:

  Retro, retro()
  Stride, stride()
  Chain, chain()
  ...

The list goes on.

-Lars