Re: Uri class and parser

2012-10-24 Thread Jacob Carlborg

On 2012-10-23 22:47, Mike van Dongen wrote:

Hi all!

I've been working on an URI parser which takes a string and then
separates the parts and puts them in the correct properties.
If a valid URI was provided, the (static) parser will return an instance
of Uri.

I've commented all relevant lines of code and tested it using unittests.

Now what I'm wondering is if it meets the phobos requirements and
standards.
And of course if you think I should do a pull request on GitHub!

My code can be found here, at the bottom of the already existing file
uri.d:
https://github.com/MikevanDongen/phobos/blob/uri-parser/std/uri.d


Thanks,

Mike van Dongen.


I would have expected a few additional components, like:

* Domain
* Password
* Username
* Host
* Hash

A way to build an URI base on the components.
It would be nice if there were methods for getting/setting the path 
component as an array. Also methods for getting/setting the query 
component as an associative array.


A few stylistic issues. There are a lot of places where you haven't 
indented the code, at least how it looks like on github.


I wouldn't put the private methods at the top.

--
/Jacob Carlborg


Re: Mixin replacement for switch...case?

2012-10-24 Thread Jerome

Thanks Philippe! Great solution!

I have two remarks.

Remark 1: I understand that your mixin will be expanded into 
cascaded if...else statements. It would probably be more 
efficient to expand into switch...case, don't you think?


Remark 2: I infer from your code that the "delegate" keyword is 
not mandatory, so my solution could also be called like this:


mixin Select!(value,
  if0, { then0(); },
  if1, { then1(); },
  if2, { foo(); bar(); },
  { thenDefault(); }
);

instead of:

mixin Select!(value,
  if0, delegate { then0(); },
  if1, delegate { then1(); },
  if2, delegate { foo(); bar(); },
  delegate { thenDefault(); }
);

Is that correct?




Passing static arrays to C

2012-10-24 Thread Jakob Bornecrantz

Hey everybody.

How are you supposed to pass static arrays to C functions? I'm 
asking because I'm getting conflicting info from how DMD works 
and on IRC.


The below example prints:
test1 0x7fff857c1db0
test2 0x7fff857c1db0
test3 (nil)
test4 0x7fff857c1db0


D:
void main()
{
float[3] arr;
test1(arr);
test2(&arr[0]);
test3(0, arr);
test4(0, &arr[0]);
}

extern(C):
void test1(float[3] arr);
void test2(float *arr);
void test3(int, float[3] arr);
void test4(int, float *arr);


C:
#include 

void test1(float arr[3]) { printf("test1 %p\n", &arr[0]); }
void test2(float arr[3]) { printf("test2 %p\n", &arr[0]); }
void test3(int anything, float arr[3]) { printf("test3 %p\n", 
&arr[0]); }
void test4(int anything, float arr[3]) { printf("test4 %p\n", 
&arr[0]); }


Comments please.

Cheers, Jakob.




Re: Mixin replacement for switch...case?

2012-10-24 Thread Jerome
Remark 1: I understand that your mixin will be expanded into 
cascaded if...else statements. It would probably be more 
efficient to expand into switch...case, don't you think?


Oh! I've just figured out that it is not a mixin, but a function 
template.


On D development

2012-10-24 Thread Robert
When reading stuff, like: "Yes this is bad, but people use it already,
so we could only possible change this in D3 or something" and reading
endless discussions about a new feature (e.g. ref semantics) of how it
could break things and so on, I thought it might be a good idea to
implement new features in an experimental version, which can then be
thoroughly tested and only if nothing bad found they will be merged in
the stable branch. People simply have to be aware that they should not
rely on semantics implemented in experimental.

Discussions about new features before their are implemented would of
course still be a very good idea, but it would reduce the pressure a
bit, because you can simply try. This does not solve everything, because
some issues will only pop up if used for a long time or only in real
complicated production code, but I think it is better than the approach
of having no way back?

I don't believe this idea is entirely new or maybe I am missing
something. What do you think?

Best regards,

Robert



Re: On D development

2012-10-24 Thread Jens Mueller
Robert wrote:
> When reading stuff, like: "Yes this is bad, but people use it already,
> so we could only possible change this in D3 or something" and reading
> endless discussions about a new feature (e.g. ref semantics) of how it
> could break things and so on, I thought it might be a good idea to
> implement new features in an experimental version, which can then be
> thoroughly tested and only if nothing bad found they will be merged in
> the stable branch. People simply have to be aware that they should not
> rely on semantics implemented in experimental.
> 
> Discussions about new features before their are implemented would of
> course still be a very good idea, but it would reduce the pressure a
> bit, because you can simply try. This does not solve everything, because
> some issues will only pop up if used for a long time or only in real
> complicated production code, but I think it is better than the approach
> of having no way back?
> 
> I don't believe this idea is entirely new or maybe I am missing
> something. What do you think?

Sounds useful to me.
How would you implement it? I fear it complicates the compiler a lot
and hence introduces bugs.

Jens


Re: On D development

2012-10-24 Thread Daniel Kozák

On Wednesday, 24 October 2012 at 08:06:55 UTC, Robert wrote:
When reading stuff, like: "Yes this is bad, but people use it 
already,
so we could only possible change this in D3 or something" and 
reading
endless discussions about a new feature (e.g. ref semantics) of 
how it
could break things and so on, I thought it might be a good idea 
to
implement new features in an experimental version, which can 
then be
thoroughly tested and only if nothing bad found they will be 
merged in
the stable branch. People simply have to be aware that they 
should not

rely on semantics implemented in experimental.

Discussions about new features before their are implemented 
would of
course still be a very good idea, but it would reduce the 
pressure a
bit, because you can simply try. This does not solve 
everything, because
some issues will only pop up if used for a long time or only in 
real
complicated production code, but I think it is better than the 
approach

of having no way back?

I don't believe this idea is entirely new or maybe I am missing
something. What do you think?

Best regards,

Robert


It is a good idea. I already thinking about something similar 
before.


Re: Passing static arrays to C

2012-10-24 Thread Jacob Carlborg

On 2012-10-24 09:54, Jakob Bornecrantz wrote:

Hey everybody.

How are you supposed to pass static arrays to C functions? I'm asking
because I'm getting conflicting info from how DMD works and on IRC.

The below example prints:
test1 0x7fff857c1db0
test2 0x7fff857c1db0
test3 (nil)
test4 0x7fff857c1db0


D:
void main()
{
 float[3] arr;
 test1(arr);
 test2(&arr[0]);
 test3(0, arr);
 test4(0, &arr[0]);
}

extern(C):
void test1(float[3] arr);
void test2(float *arr);
void test3(int, float[3] arr);
void test4(int, float *arr);


C:
#include 

void test1(float arr[3]) { printf("test1 %p\n", &arr[0]); }
void test2(float arr[3]) { printf("test2 %p\n", &arr[0]); }
void test3(int anything, float arr[3]) { printf("test3 %p\n", &arr[0]); }
void test4(int anything, float arr[3]) { printf("test4 %p\n", &arr[0]); }


That seems weird. Since static arrays are passed by value in D you need 
to send a reference:


extern (C) void test1(ref float[3] arr);

float[3] arr;
test1(arr);

BTW, do not ever use "&arr[0]", use "arr.ptr" instead to get the pointer 
of the array.


http://dlang.org/interfaceToC.html

Search for "Passing D Array Arguments to C Functions".

--
/Jacob Carlborg


Re: Passing static arrays to C

2012-10-24 Thread Walter Bright

On 10/24/2012 12:54 AM, Jakob Bornecrantz wrote:
> How are you supposed to pass static arrays to C functions?

C accepts static arrays as pointers, so T[n] in D would be C prototyped as T*.

Pass a pointer to the first element.



Re: [proposal] version statements with multiple arguments.

2012-10-24 Thread Walter Bright

On 10/22/2012 8:17 PM, 1100110 wrote:
> The last one could be intuitively described as:
> version(Windows && DigitalMars)
> { blah; }

It was a very deliberate design choice to not allow !, || or && in version 
statements. Such tend to devolve over time into unmaintainable chaos.


Re: Very simple SIMD programming

2012-10-24 Thread Don Clugston

On 24/10/12 04:41, bearophile wrote:

I have found a nice paper, "Extending a C-like Language for Portable
SIMD Programming", (2012), by Roland L., Sebastian Hack and Ingo Wald:

http://www.cdl.uni-saarland.de/projects/vecimp/vecimp_tr.pdf




They present a simple scalar program in C:

struct data_t {
 int key;
 int other;
};

int search(data_t* data , int N) {
 for (int i = 0; i < N; i++) {
 int x = data[i].key;
 if (4 < x & x <= 8) return x;
 }
 return -1;
}


I don't know what that code does. I think the if statement is always 
true. Try compiling it in D.


test.d(8): Error: 4 < x must be parenthesized when next to operator &
test.d(8): Error: x <= 8 must be parenthesized when next to operator &

Making that an error was such a good idea.



Re: [proposal] version statements with multiple arguments.

2012-10-24 Thread Walter Bright

On 10/22/2012 9:26 PM, timotheecour wrote:
> Another point is that we are sometimes too lazy to write statements as 
follows:
> version (linux){  version = linuxOrBSD;}
> version (BSD){  version = linuxOrBSD;}
> version(linuxOrBSD){do_something;}
> (that's ugly but it's the official recommended way; much more verbose than:
> version(linux || BSD){do_something;}
> )

1. Verbosity is not the enemy. Clarity is the goal.

2. The example would be better as:

  version (linux){  version = Something;}
  version (BSD){  version = Something;}
  version(Something){do_Something;}

where Something is the name of the feature being enabled. With careful selection 
of Something, the code can be quite readable.


Re: Very simple SIMD programming

2012-10-24 Thread Timon Gehr

On 10/24/2012 11:24 AM, Don Clugston wrote:

On 24/10/12 04:41, bearophile wrote:

I have found a nice paper, "Extending a C-like Language for Portable
SIMD Programming", (2012), by Roland L., Sebastian Hack and Ingo Wald:

http://www.cdl.uni-saarland.de/projects/vecimp/vecimp_tr.pdf




They present a simple scalar program in C:

struct data_t {
 int key;
 int other;
};

int search(data_t* data , int N) {
 for (int i = 0; i < N; i++) {
 int x = data[i].key;
 if (4 < x & x <= 8) return x;
 }
 return -1;
}


I don't know what that code does. I think the if statement is always
true.


No, the code is fine.


Try compiling it in D.

test.d(8): Error: 4 < x must be parenthesized when next to operator &
test.d(8): Error: x <= 8 must be parenthesized when next to operator &

Making that an error was such a good idea.



C's precedence rules are the same as in math in this case.


Re: On D development

2012-10-24 Thread Joseph Rushton Wakeling

On 10/24/2012 09:38 AM, Robert wrote:

When reading stuff, like: "Yes this is bad, but people use it already,
so we could only possible change this in D3 or something" and reading
endless discussions about a new feature (e.g. ref semantics) of how it
could break things and so on, I thought it might be a good idea to
implement new features in an experimental version, which can then be
thoroughly tested and only if nothing bad found they will be merged in
the stable branch. People simply have to be aware that they should not
rely on semantics implemented in experimental.


The problem AFAICS is not _new_ features, or even stability per se -- the 
problem is modifying the behaviour of existing features, even if the 
modification is an improvement.


If you modify an existing feature, then it means that you will break downstream 
users' code -- not because your modification is wrong per se, but because that 
downstream code assumes that this feature will behave a certain way.  The larger 
your downstream codebase, the more problematic that becomes, hence the reason 
why certain kinds of change have to be limited to "major version" updates.


Also, it's not just a problem of causing work for downstream developers, but 
also about the sense of security/stability people have with D, that they are 
building on solid ground and not quicksand.  If people see features changing too 
often, they are likely to be unwilling to adopt D as a development platform.


D already has a deprecation path for features that really need to be changed, 
and where necessary this _does_ happen, but it's clear from past list 
discussions that this comes at a cost to D's reputation as a 
ready-for-production-use development language.


An experimental branch is a nice idea for other purposes, but it doesn't solve 
the problem you've identified.


Re: [proposal] version statements with multiple arguments.

2012-10-24 Thread Don Clugston

On 23/10/12 05:17, 1100110 wrote:

Looking at std.io (hopefully the right version maybe?) I see this:

version(OSX)
{ do something; }
version(Windows)
{ do the same thing as above; }
version(FreeBSD)
{ ditto; }
version(Linux)
{finally do something different; }
and:
version(Windows) version(DigitalMars)
{ something; }


I was rather surprised that this wasn't accepted:
//Error: found '||' when expecting ')'

version(OSX || Windows || FreeBSD)
{ do something; }
version(Linux)
{ do something different; }


The last one could be intuitively described as:
version(Windows && DigitalMars)
{ blah; }


That allows you to create the same bird's nest that you can get with 
#ifdef in C.


See bug 7417 for a different solution that fixes other problems as well.
Just make version declarations behave like bool variable declarations:

version useTheOrdinaryWay = OSX || Windows || FreeBSD;

version dmdWindows = Windows && DigitalMars;
version (dmdWindows) { blah; }






Re: Passing static arrays to C

2012-10-24 Thread Jakob Bornecrantz
On Wednesday, 24 October 2012 at 09:03:25 UTC, Jacob Carlborg 
wrote:

On 2012-10-24 09:54, Jakob Bornecrantz wrote:

Hey everybody.

How are you supposed to pass static arrays to C functions? I'm 
asking
because I'm getting conflicting info from how DMD works and on 
IRC.


The below example prints:
test1 0x7fff857c1db0
test2 0x7fff857c1db0
test3 (nil)
test4 0x7fff857c1db0


D:
void main()
{
float[3] arr;
test1(arr);
test2(&arr[0]);
test3(0, arr);
test4(0, &arr[0]);
}

extern(C):
void test1(float[3] arr);
void test2(float *arr);
void test3(int, float[3] arr);
void test4(int, float *arr);


C:
#include 

void test1(float arr[3]) { printf("test1 %p\n", &arr[0]); }
void test2(float arr[3]) { printf("test2 %p\n", &arr[0]); }
void test3(int anything, float arr[3]) { printf("test3 %p\n", 
&arr[0]); }
void test4(int anything, float arr[3]) { printf("test4 %p\n", 
&arr[0]); }


That seems weird. Since static arrays are passed by value in D 
you need to send a reference:


Yeah I'm wondering if this isn't a bug.



extern (C) void test1(ref float[3] arr);

float[3] arr;
test1(arr);

BTW, do not ever use "&arr[0]", use "arr.ptr" instead to get 
the pointer of the array.


Right you are, thats what you get when mixing C and D code.



http://dlang.org/interfaceToC.html

Search for "Passing D Array Arguments to C Functions".


Thanks for the info.

Cheers, Jakob.




Re: Passing static arrays to C

2012-10-24 Thread Era Scarecrow
On Wednesday, 24 October 2012 at 09:16:30 UTC, Walter Bright 
wrote:
C accepts static arrays as pointers, so T[n] in D would be C 
prototyped as T*.


Pass a pointer to the first element.


 In GCC (or any c compiler) isn't it possible in optimizing to 
copy the static array to the stack (say 8 bytes or less as a 
guess)? Course this assumes the static size is set as part of the 
function signature too...


 It makes sense for it to work both ways (in their own way); But 
then more bugs can lie in wait as well.


Re: Normal/Gaussian random number generation for D

2012-10-24 Thread Joseph Rushton Wakeling

On 10/23/2012 04:36 PM, jerro wrote:

I have an implementation of the Ziggurat algorithm at
https://github.com/jerro/phobos/blob/master/std/random.d#L2035.


OK, so I had a reasonable (not totally in-depth!) look through.  Looks good! 
And of course reminds of the other benefit of Ziggurat, that it can be used for 
multiple different random number distributions.


It looks like it should be readily possible to integrate the core Ziggurat 
functionality and to convert the normal() function in your code to be a 
NormalRandomNumberEngine struct -- so assuming you like my own architecture 
proposal, let's do this (I'm happy to hear suggestions for alternative designs, 
as I don't feel particularly confident in my API-designing abilities).


For the other distributions, my feeling is that in some cases there's a value in 
also having this "engine" approach, e.g. for exponentially-distributed numbers 
one could use Ziggurat or one could use the approach


T u = uniform!("[)", T, T, UniformRandomNumberGenerator)(0.0, 1.0, urng);
return -log(1 - u)/lambda;

... which is not as fast but has a much lower memory footprint.


It modified the Ziggurat algorithm a bit, so that it doesn't need as many layers
to work well, which reduces the memory consumption and makes initialization 
faster.


Can you expand on this, and maybe provide a reference?  I don't doubt your 
code's effectiveness but I think where RNGs are concerned we really need to be 
able to justify our algorithmic choices.  There's too much literature out there 
showing how commonly-used algorithms actually carry statistical flaws.


Bigger picture on my approach to non-uniform random number distributions.  The 
goal is to have the following:


* Where useful, it should be possible to define and use multiple different
  internal "engines" for generating random numbers from the given
  distribution

* For each distribution, there should be a function interface and a struct
  interface.

* The struct implementation should store the distribution parameters and an
  instance of the internal engine (if any).

* The function implementation should have 2 versions: one which allows the
  user to pass an engine of choice as input, one which contains a static
  instance of the specified engine (hence, thread-safe, distinguished
  according to both engine type and underlying uniform RNG type).

* ... unless there's no call for distinct underlying engines, in which case
  the function version just takes parameters and uniform RNG :-)

* The struct version should be useful to couple with an RNG instance to
  create an arbitrary random-number range à la Boost's variate_generator
  class.

So, a nice way to expand on our respective approaches might be to incorporate 
your Ziggurat, adapt it to my Normal engine API, and for me to write a similar 
setup for exponentially-distributed random numbers that uses the simple approach 
above and can also use your Ziggurat implementation.


What do you think?

Best wishes,

-- Joe


Re: On D development

2012-10-24 Thread Robert Klotzner
Simply don't release a new stable version with new features, semantics,
but first release an experimental version. Encourage people to compile
their code with it, try out the new features/semantics, ... but always
let them keep in mind, that things can break with further improvements.
The idea is that features in an experimental release can be changed at
any time without having to worry about breaking users code, because they
expect it. It seems to me that until now things are just discussed very
thoroughly, implemented and released. If this is really the case, then I
guess the only reason this works so surprisingly well is because the
people (Andrei, Walter, ...) are amazingly smart and have learned from
the mistakes of other languages. But introducing a (limited) way of
learning from own mistakes without breaking things, might be useful
especially for new concepts not found in other languages.

I don't see how this complicates the compiler?

People could choose between using the experimental version for the
awesome feature xy and taking the risk of fixing code with incompatible
changes or stick with the stable version.

Robert
> 
> Sounds useful to me.
> How would you implement it? I fear it complicates the compiler a lot
> and hence introduces bugs.
> 
> Jens




Re: On D development

2012-10-24 Thread Andrei Alexandrescu

On 10/24/12 6:24 AM, Robert Klotzner wrote:

People could choose between using the experimental version for the
awesome feature xy and taking the risk of fixing code with incompatible
changes or stick with the stable version.


That fosters balkanization.

At this point in D's evolution I very strongly think it's the time to 
put to good use its many features, instead of making it any easier to 
add more. Constraints are liberating. Innovation can be found in the 
minds of people, and the thought that there's always a new feature that 
can be added instead of an innovative solution within the existing 
language stifles creativity.



Andrei


Re: On D development

2012-10-24 Thread Robert Klotzner

> At this point in D's evolution I very strongly think it's the time to 
> put to good use its many features, instead of making it any easier to 
> add more. Constraints are liberating. Innovation can be found in the 
> minds of people, and the thought that there's always a new feature that 
> can be added instead of an innovative solution within the existing 
> language stifles creativity.

I completely agree, D's feature set is already very good and well
thought of. But having more thorough testing, might still be a good
idea. In fact I am very happy with D's feature set, but as long as D is
alive there will be improvements from time to time and having a way of
testing them thoroughly, can't really harm the language. But I don't
know. You and other people more involved in development are of course
better judges of usefulness of this proposal. Basically I was just
curious why it is not done this way.




Re: On D development

2012-10-24 Thread Jens Mueller
Robert Klotzner wrote:
> Simply don't release a new stable version with new features, semantics,
> but first release an experimental version. Encourage people to compile
> their code with it, try out the new features/semantics, ... but always
> let them keep in mind, that things can break with further improvements.
> The idea is that features in an experimental release can be changed at
> any time without having to worry about breaking users code, because they
> expect it. It seems to me that until now things are just discussed very
> thoroughly, implemented and released. If this is really the case, then I
> guess the only reason this works so surprisingly well is because the
> people (Andrei, Walter, ...) are amazingly smart and have learned from
> the mistakes of other languages. But introducing a (limited) way of
> learning from own mistakes without breaking things, might be useful
> especially for new concepts not found in other languages.
> 
> I don't see how this complicates the compiler?
> 
> People could choose between using the experimental version for the
> awesome feature xy and taking the risk of fixing code with incompatible
> changes or stick with the stable version.

But this complicates the development of the compiler. There may be even
incompatible features. What do you do then?
Just because you release an experimental version of the compiler does
not ease integration of experimental features. Further at some point you
have to integrate a feature into the stable line.
I believe this is possible using a particular git work flow but I think
it's far from easy. Further there needs to be some API between parts of
the compiler. Maybe one can learn from the development of the Linux
kernel.
I'd like to have this but it's not as straightforward as it seems.

Jens


Re: Very simple SIMD programming

2012-10-24 Thread bearophile

Don Clugston:


Making that an error was such a good idea.



There are two other common sources of bugs code that I'd like to 
see removed from D code:


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

Bye,
bearophile


Re: Uri class and parser

2012-10-24 Thread Adam D. Ruppe
On Tuesday, 23 October 2012 at 20:47:26 UTC, Mike van Dongen 
wrote:

https://github.com/MikevanDongen/phobos/blob/uri-parser/std/uri.d


If you want to take any of the code from mine, feel free. It is 
struct Uri in my cgi.d:


https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/cgi.d#L1615

My thing includes relative linking and some more parsing too. The 
ctRegex in there however, when it works it is cool, but if 
there's an error in an *other* part of the code, other module, 
doesn't call it, completely unrelated such as just making a typo 
on a local variable name... the compiler spews like 20 errors 
about ctRegex.


That's annoying. But the bug is in the compiler and only makes 
other errors uglier so I'm just ignoring it for now.


Re: Very simple SIMD programming

2012-10-24 Thread Paulo Pinto

On Wednesday, 24 October 2012 at 02:41:53 UTC, bearophile wrote:
I have found a nice paper, "Extending a C-like Language for 
Portable SIMD Programming", (2012), by Roland L., Sebastian 
Hack and Ingo Wald:


http://www.cdl.uni-saarland.de/projects/vecimp/vecimp_tr.pdf

SIMD programming is necessary in a system language, or in any 
language that wants to use the modern CPUs well. So languages 
like C, C++, D (and Mono-C#) support such wider registers.


The authors of this paper have understood that it's also 
important to make SIMD programming easy, almost as easy as 
scalar code, so most programmers are able to write such kind of 
correct code.


So this this paper presents ideas to better express SIMD 
semantics in a C-like language. They introduce few new 
constructs in a large subset of C language, with few ideas. The 
result coding patterns seem easy enough (they are surely look 
simpler than most multi-core coding patterns I've seen, 
including Cilk+).



They present a simple scalar program in C:

struct data_t {
int key;
int other;
};

int search(data_t* data , int N) {
for (int i = 0; i < N; i++) {
int x = data[i].key;
if (4 < x & x <= 8) return x;
}
return -1;
}


Then they explain the three most common ways to represent an 
array of structs, here a struct that contains 3 values:


x0 y0 z0 x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 x5 y5 z5 x6 y6 z6 
x7 y7 z7

(a) Array of Structures (AoS)

x0 x1 x2 x3 x4 x5 x6 x7   y0 y1 y2 y3 y4 y5 y6 y7   z0 z1 z2 z3 
z4 z5 z6 z7

(b) Structure of Arrays (SoA)

x0 x1 x2 x3 y0 y1 y2 y3 z0 z1 z2 z3 x4 x5 x6 x7 y4 y5 y6 y7 z4 
z5 z6 z7

(c) Hybrid Structure of Arrays (Hybrid SoA)

They explain how the (c) is the preferred pattern in SIMD 
programming.



Using the (c) data pattern they show how in C with (nice) SIMD 
intrinsics you write vectorized code (a simd_data_t struct 
instance contains 8 int values):


struct simd_data_t {
simd_int key;
simd_int other;
};

int search(simd_data_t* data , int N) {
for (int i = 0; i < N/L; ++i) {
simd_int x = load(data[i].key);
simd_int cmp = simd_and(simd_lt(4, x),
simd_le(x, 8));
int mask = simd_to_mask(cmp);
if (mask != 0) {
simd_int result = simd_and(mask , x);
for (int j = 0; j < log2(L); j++)
result = simd_or(result ,
whole_reg_shr(result , 1 << j));
return simd_extract(result , 0);
}
}
return -1;
}


D should do become able to do this (that is not too much bad), 
or better.



Their C language extensions allow to write nicer code like:

struct data_t {
int key;
int other;
};

int search(data_t *scalar data , int scalar N) {
int L = lengthof(*data);
for (int i = 0; i < N/L; ++i) {
int x = data[i].key;
if (4 < x & x <= 8)
int block[L] result = [x, 0];
scalar {
for (int j = 0; j < log2(L); ++j)
result |= whole_reg_shr(result , 1 << j);
return get(x, 0);
}
}
return -1;
}


This is based on just few simple ideas, explained in the paper 
(they are interesting, but quoting here those parts of the 
paper is not a good idea). Such ideas are not directly portable 
to D (unless the front-end is changed. Their compiler works by 
lowering, and emits regular C++ code with intrinsics).



Near the end of the paper they also propose some C++ library 
code:


the C++ template mechanism would allow to define a hybrid SoA 
container class: Similar to std::vector which abstracts a 
traditional C array, one could implement a wrapper around a T 
block[N]*:<



// scalar context throughout this example
struct vec3 { float x, y, z; };
// vec3 block[N]* pointing to ceil(n/N) elements
hsoa  vecs(n);
// preferred vector length of vec3 automatically derived
static const int N = hsoa ::vector_length;
int i = /*...*/
hsoa ::block_index ii = /*...*/
vec3 v = vecs[i]; // gather
vecs[i] = v; // scatter
vec3 block[N] w = vecs[ii]; // fetch whole block
hsoa ::ref r = vecs[i]; // get proxy to a scalar
r = v; // pipe through proxy
// for each element
vecs.foreach([](vec3& scalar v) { /*...*/ });


Regardless of the other ideas of their C-like language, a 
similar struct should be added to Phobos once a bit higher 
level SIMD support is in better shape in D. Supporting 
Hybrid-SoA and few operations on it will be an important but 
probably quite short and simple addition to Phobos collections 
(it's essentially an struct that acts like an array, with few 
simple extra operations).


I think no commonly used language allows both very simple and 
quite efficient SIMD programming (Scala, CUDA, C, C++, C#, 
Java, Go, and currently Rust too, are not able to support SIMD 
programming well. I think currently Haskell too is not 
supporting it well, but Haskell is very flexible, and it's 
compiled by a native compiler, so such things are maybe 
possible to add). So supporting it we

Re: [proposal] version statements with multiple arguments.

2012-10-24 Thread Nick Treleaven

On 24/10/2012 10:40, Don Clugston wrote:

On 23/10/12 05:17, 1100110 wrote:

Looking at std.io (hopefully the right version maybe?) I see this:

version(OSX)
{ do something; }
version(Windows)
{ do the same thing as above; }
version(FreeBSD)
{ ditto; }
version(Linux)
{finally do something different; }
and:
version(Windows) version(DigitalMars)
{ something; }


I was rather surprised that this wasn't accepted:
//Error: found '||' when expecting ')'

version(OSX || Windows || FreeBSD)
{ do something; }
version(Linux)
{ do something different; }


The last one could be intuitively described as:
version(Windows && DigitalMars)
{ blah; }


That allows you to create the same bird's nest that you can get with
#ifdef in C.

See bug 7417 for a different solution that fixes other problems as well.
Just make version declarations behave like bool variable declarations:

version useTheOrdinaryWay = OSX || Windows || FreeBSD;

version dmdWindows = Windows && DigitalMars;
version (dmdWindows) { blah; }


Vote up!
http://d.puremagic.com/issues/show_bug.cgi?id=7417


Re: Very simple SIMD programming

2012-10-24 Thread bearophile

Paulo Pinto:

Actually, I am yet to see any language that has SIMD as part of 
the language standard and not as an extension where each vendor 
does its own way.


D is, or is going to be, one such language :-)

Bye,
bearophile


Re: Uri class and parser

2012-10-24 Thread Adam D. Ruppe
On Wednesday, 24 October 2012 at 07:38:58 UTC, Jacob Carlborg 
wrote:
It would be nice if there were methods for getting/setting the 
path component as an array. Also methods for getting/setting 
the query component as an associative array.


BTW don't forget that this is legal:

?value&value=1&value=2

The appropriate type for the AA is

string[][string]


This is why my cgi.d has functions two decodeVariables and 
decodeVariablesSingle and two members (in the Cgi class, I didn't 
add it to the Uri struct) get and getArray.


decodeVariables returns the complete string[][string]

and the single versions only keep the last element of the 
string[], which gives a string[string] for convenience.


Re: Very simple SIMD programming

2012-10-24 Thread Manu
On 24 October 2012 15:39, Paulo Pinto  wrote:

> On Wednesday, 24 October 2012 at 02:41:53 UTC, bearophile wrote:
>
>> I have found a nice paper, "Extending a C-like Language for Portable SIMD
>> Programming", (2012), by Roland L., Sebastian Hack and Ingo Wald:
>>
>> http://www.cdl.uni-saarland.**de/projects/vecimp/vecimp_tr.**pdf
>>
>> SIMD programming is necessary in a system language, or in any language
>> that wants to use the modern CPUs well. So languages like C, C++, D (and
>> Mono-C#) support such wider registers.
>>
>> The authors of this paper have understood that it's also important to
>> make SIMD programming easy, almost as easy as scalar code, so most
>> programmers are able to write such kind of correct code.
>>
>> So this this paper presents ideas to better express SIMD semantics in a
>> C-like language. They introduce few new constructs in a large subset of C
>> language, with few ideas. The result coding patterns seem easy enough (they
>> are surely look simpler than most multi-core coding patterns I've seen,
>> including Cilk+).
>>
>>
>> They present a simple scalar program in C:
>>
>> struct data_t {
>> int key;
>> int other;
>> };
>>
>> int search(data_t* data , int N) {
>> for (int i = 0; i < N; i++) {
>> int x = data[i].key;
>> if (4 < x & x <= 8) return x;
>> }
>> return -1;
>> }
>>
>>
>> Then they explain the three most common ways to represent an array of
>> structs, here a struct that contains 3 values:
>>
>> x0 y0 z0 x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 x5 y5 z5 x6 y6 z6 x7 y7 z7
>> (a) Array of Structures (AoS)
>>
>> x0 x1 x2 x3 x4 x5 x6 x7   y0 y1 y2 y3 y4 y5 y6 y7   z0 z1 z2 z3 z4 z5 z6
>> z7
>> (b) Structure of Arrays (SoA)
>>
>> x0 x1 x2 x3 y0 y1 y2 y3 z0 z1 z2 z3 x4 x5 x6 x7 y4 y5 y6 y7 z4 z5 z6 z7
>> (c) Hybrid Structure of Arrays (Hybrid SoA)
>>
>> They explain how the (c) is the preferred pattern in SIMD programming.
>>
>>
>> Using the (c) data pattern they show how in C with (nice) SIMD intrinsics
>> you write vectorized code (a simd_data_t struct instance contains 8 int
>> values):
>>
>> struct simd_data_t {
>> simd_int key;
>> simd_int other;
>> };
>>
>> int search(simd_data_t* data , int N) {
>> for (int i = 0; i < N/L; ++i) {
>> simd_int x = load(data[i].key);
>> simd_int cmp = simd_and(simd_lt(4, x),
>> simd_le(x, 8));
>> int mask = simd_to_mask(cmp);
>> if (mask != 0) {
>> simd_int result = simd_and(mask , x);
>> for (int j = 0; j < log2(L); j++)
>> result = simd_or(result ,
>> whole_reg_shr(result , 1 << j));
>> return simd_extract(result , 0);
>> }
>> }
>> return -1;
>> }
>>
>>
>> D should do become able to do this (that is not too much bad), or better.
>>
>>
>> Their C language extensions allow to write nicer code like:
>>
>> struct data_t {
>> int key;
>> int other;
>> };
>>
>> int search(data_t *scalar data , int scalar N) {
>> int L = lengthof(*data);
>> for (int i = 0; i < N/L; ++i) {
>> int x = data[i].key;
>> if (4 < x & x <= 8)
>> int block[L] result = [x, 0];
>> scalar {
>> for (int j = 0; j < log2(L); ++j)
>> result |= whole_reg_shr(result , 1 << j);
>> return get(x, 0);
>> }
>> }
>> return -1;
>> }
>>
>>
>> This is based on just few simple ideas, explained in the paper (they are
>> interesting, but quoting here those parts of the paper is not a good idea).
>> Such ideas are not directly portable to D (unless the front-end is changed.
>> Their compiler works by lowering, and emits regular C++ code with
>> intrinsics).
>>
>>
>> Near the end of the paper they also propose some C++ library code:
>>
>>  the C++ template mechanism would allow to define a hybrid SoA container
>>> class: Similar to std::vector which abstracts a traditional C array, one
>>> could implement a wrapper around a T block[N]*:<
>>>
>>
>>
>> // scalar context throughout this example
>> struct vec3 { float x, y, z; };
>> // vec3 block[N]* pointing to ceil(n/N) elements
>> hsoa  vecs(n);
>> // preferred vector length of vec3 automatically derived
>> static const int N = hsoa ::vector_length;
>> int i = /*...*/
>> hsoa ::block_index ii = /*...*/
>> vec3 v = vecs[i]; // gather
>> vecs[i] = v; // scatter
>> vec3 block[N] w = vecs[ii]; // fetch whole block
>> hsoa ::ref r = vecs[i]; // get proxy to a scalar
>> r = v; // pipe through proxy
>> // for each element
>> vecs.foreach([](vec3& scalar v) { /*...*/ });
>>
>>
>> Regardless of the other ideas of their C-like language, a similar struct
>> should be added to Phobos once a bit higher level SIMD support is in better
>> shape in D. Supporting Hybrid-SoA and few operations on it will be an
>> important but probably quite short and simple addition to Phobos
>> collections (it's essentially an s

Re: Uri class and parser

2012-10-24 Thread ponce

On Wednesday, 24 October 2012 at 07:38:58 UTC, Jacob Carlborg
wrote:


I would have expected a few additional components, like:

* Domain
* Password
* Username
* Host
* Hash

A way to build an URI base on the components.
It would be nice if there were methods for getting/setting the 
path component as an array. Also methods for getting/setting 
the query component as an associative array.


I have a public domain URI parser here:
http://github.com/p0nce/gfm/blob/master/common/uri.d






Re: Very simple SIMD programming

2012-10-24 Thread bearophile

Manu:

D already has what's required to do some fairly nice (by 
comparison) simd stuff with good supporting libraries.


After reading that paper I am not sure you are right. See how 
their language manages masks by itself. This is from page 3:



// vector length of context = 1; current_mask = T
int block[4] v = <0,3,4,1>;
int block[4] w = 3; // <3,3,3,3> via broadcast
bool block[4] m = v < w; // 
++v; // <1,4,5,2>
if (m) {
// vector length of context = 4; current_mask = m
v += 2; // <3,4,5,4>
} else {
// vector length of context = 4; current_mask = ~m
v += 3; // <3,7,8,4>
}
// vector length of context = 1; current_mask = T


(The simple benchmarks of the paper show a 5-15% performance loss 
compared to handwritten SIMD code.)


Bye,
bearophile


Re: Passing static arrays to C

2012-10-24 Thread Alex Rønne Petersen

On 24-10-2012 12:00, Era Scarecrow wrote:

On Wednesday, 24 October 2012 at 09:16:30 UTC, Walter Bright wrote:

C accepts static arrays as pointers, so T[n] in D would be C
prototyped as T*.

Pass a pointer to the first element.


  In GCC (or any c compiler) isn't it possible in optimizing to copy the
static array to the stack (say 8 bytes or less as a guess)? Course this
assumes the static size is set as part of the function signature too...

  It makes sense for it to work both ways (in their own way); But then
more bugs can lie in wait as well.


Passing static arrays by reference to the first element is part of the 
calling convention/ABI. If the C compiler generated code that doesn't 
work this way, the C compiler has a bug.


--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


Re: Very simple SIMD programming

2012-10-24 Thread Don Clugston

On 24/10/12 11:33, Timon Gehr wrote:

On 10/24/2012 11:24 AM, Don Clugston wrote:

On 24/10/12 04:41, bearophile wrote:

I have found a nice paper, "Extending a C-like Language for Portable
SIMD Programming", (2012), by Roland L., Sebastian Hack and Ingo Wald:

http://www.cdl.uni-saarland.de/projects/vecimp/vecimp_tr.pdf




They present a simple scalar program in C:

struct data_t {
 int key;
 int other;
};

int search(data_t* data , int N) {
 for (int i = 0; i < N; i++) {
 int x = data[i].key;
 if (4 < x & x <= 8) return x;
 }
 return -1;
}


I don't know what that code does. I think the if statement is always
true.


No, the code is fine.


Oh, you're right. It's crap code though.


Re: Very simple SIMD programming

2012-10-24 Thread Paulo Pinto

On Wednesday, 24 October 2012 at 12:50:44 UTC, Manu wrote:
On 24 October 2012 15:39, Paulo Pinto  
wrote:


On Wednesday, 24 October 2012 at 02:41:53 UTC, bearophile 
wrote:


I have found a nice paper, "Extending a C-like Language for 
Portable SIMD
Programming", (2012), by Roland L., Sebastian Hack and Ingo 
Wald:


http://www.cdl.uni-saarland.**de/projects/vecimp/vecimp_tr.**pdf

SIMD programming is necessary in a system language, or in any 
language
that wants to use the modern CPUs well. So languages like C, 
C++, D (and

Mono-C#) support such wider registers.

The authors of this paper have understood that it's also 
important to
make SIMD programming easy, almost as easy as scalar code, so 
most

programmers are able to write such kind of correct code.

So this this paper presents ideas to better express SIMD 
semantics in a
C-like language. They introduce few new constructs in a large 
subset of C
language, with few ideas. The result coding patterns seem 
easy enough (they
are surely look simpler than most multi-core coding patterns 
I've seen,

including Cilk+).


They present a simple scalar program in C:

struct data_t {
int key;
int other;
};

int search(data_t* data , int N) {
for (int i = 0; i < N; i++) {
int x = data[i].key;
if (4 < x & x <= 8) return x;
}
return -1;
}


Then they explain the three most common ways to represent an 
array of

structs, here a struct that contains 3 values:

x0 y0 z0 x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 x5 y5 z5 x6 y6 
z6 x7 y7 z7

(a) Array of Structures (AoS)

x0 x1 x2 x3 x4 x5 x6 x7   y0 y1 y2 y3 y4 y5 y6 y7   z0 z1 z2 
z3 z4 z5 z6

z7
(b) Structure of Arrays (SoA)

x0 x1 x2 x3 y0 y1 y2 y3 z0 z1 z2 z3 x4 x5 x6 x7 y4 y5 y6 y7 
z4 z5 z6 z7

(c) Hybrid Structure of Arrays (Hybrid SoA)

They explain how the (c) is the preferred pattern in SIMD 
programming.



Using the (c) data pattern they show how in C with (nice) 
SIMD intrinsics
you write vectorized code (a simd_data_t struct instance 
contains 8 int

values):

struct simd_data_t {
simd_int key;
simd_int other;
};

int search(simd_data_t* data , int N) {
for (int i = 0; i < N/L; ++i) {
simd_int x = load(data[i].key);
simd_int cmp = simd_and(simd_lt(4, x),
simd_le(x, 8));
int mask = simd_to_mask(cmp);
if (mask != 0) {
simd_int result = simd_and(mask , x);
for (int j = 0; j < log2(L); j++)
result = simd_or(result ,
whole_reg_shr(result , 1 << j));
return simd_extract(result , 0);
}
}
return -1;
}


D should do become able to do this (that is not too much 
bad), or better.



Their C language extensions allow to write nicer code like:

struct data_t {
int key;
int other;
};

int search(data_t *scalar data , int scalar N) {
int L = lengthof(*data);
for (int i = 0; i < N/L; ++i) {
int x = data[i].key;
if (4 < x & x <= 8)
int block[L] result = [x, 0];
scalar {
for (int j = 0; j < log2(L); ++j)
result |= whole_reg_shr(result , 1 << j);
return get(x, 0);
}
}
return -1;
}


This is based on just few simple ideas, explained in the 
paper (they are
interesting, but quoting here those parts of the paper is not 
a good idea).
Such ideas are not directly portable to D (unless the 
front-end is changed.
Their compiler works by lowering, and emits regular C++ code 
with

intrinsics).


Near the end of the paper they also propose some C++ library 
code:


 the C++ template mechanism would allow to define a hybrid 
SoA container
class: Similar to std::vector which abstracts a traditional 
C array, one

could implement a wrapper around a T block[N]*:<




// scalar context throughout this example
struct vec3 { float x, y, z; };
// vec3 block[N]* pointing to ceil(n/N) elements
hsoa  vecs(n);
// preferred vector length of vec3 automatically derived
static const int N = hsoa ::vector_length;
int i = /*...*/
hsoa ::block_index ii = /*...*/
vec3 v = vecs[i]; // gather
vecs[i] = v; // scatter
vec3 block[N] w = vecs[ii]; // fetch whole block
hsoa ::ref r = vecs[i]; // get proxy to a scalar
r = v; // pipe through proxy
// for each element
vecs.foreach([](vec3& scalar v) { /*...*/ });


Regardless of the other ideas of their C-like language, a 
similar struct
should be added to Phobos once a bit higher level SIMD 
support is in better
shape in D. Supporting Hybrid-SoA and few operations on it 
will be an
important but probably quite short and simple addition to 
Phobos
collections (it's essentially an struct that acts like an 
array, with few

simple extra operations).

I think no commonly used language allows both very simple and 
quite
efficient SIMD programming (Scala, CUDA, C, C++, C#, Java, 
Go, and
currently Rust too, are not able to support SIMD programming 
well. I think
currentl

Re: Very simple SIMD programming

2012-10-24 Thread jerro

Simple example:
  T opCompound(string seq)(T a, T b, T c) if(seq == "* +") { 
return

_madd(a, b, c); }


It may be useful to have a way to define compound operators for 
other things (although you can already write expression 
templates), but this is an optimization that the compiler back 
end can do. If you compile this code:


float4 foo(float4 a, float4 b, float4 c){ return a * b + c; }

With gdc with flags -O2 -fma, you get:

 <_D3tmp3fooFNhG4fNhG4fNhG4fZNhG4f>:
   0:   c4 e2 69 98 c1  vfmadd132ps xmm0,xmm2,xmm1
   5:   c3  ret



Re: Very simple SIMD programming

2012-10-24 Thread Paulo Pinto

On Wednesday, 24 October 2012 at 12:47:38 UTC, bearophile wrote:

Paulo Pinto:

Actually, I am yet to see any language that has SIMD as part 
of the language standard and not as an extension where each 
vendor does its own way.


D is, or is going to be, one such language :-)

Bye,
bearophile


Is it so?

From what I can understand the SIMD calls depend on which D 
compiler is being used.


That doesn't look like part of the language standard to me. :(

--
Paulo


[just talk] what if implicitly typed literals were disallowed

2012-10-24 Thread Adam D. Ruppe
I'm saying [just talk] because this isn't a serious proposal to 
change the D language, I just want to discuss what if.



The thread about string and rep had me bring up my library string 
implementation again, and it was shot down because of "auto a = 
"foo";" meaning a would not have the library type.


It made me wonder: what if we got rid of literals? Well, can't do 
that, we need some kind of building block. But, what if we 
required their use to have a clear type?


I'm tempted to say literals should only be used when there is an 
explicit type given somewhere



int a = 10; // allowed, explicitly int
auto a = 10; // disallowed, literal 10 has no declared type

int foo(int a) { return 0; /* allowed, explicit type in function 
signature */ }


foo(10); // allowed, explicit type in function signature

auto a = 1 + 1; // illegal, the type is still not explicit

int a = 10;
auto b = 10 + a; // legal, a has an explicit type, so b does too

void foo(T)(T a)  {}

foo(10); // illegal, T is implicit and it is literals so no go
foo!int(10); // legal

auto a = cast(int) 10; // legal, the cast makes it explicit



Why does this matter? Well it gives you a lot of user defined 
capabilities here. Let's combine with the following:


* make the internal type of the literals a special word. _int 
instead of int for example. Now int is not a keyword - it is 
available to library redefinitions (surely in object.d, but you 
can import your own int if you wanted to)


* have the library give them the prettier names. this might be 
"alias int = _int;" or it might be struct int { this(_int i) { } 
/* custom functionality */}; in other words you can give complete 
user defined behavior without name conflicts. This can be 
replaced at any time by hacking up your druntime.



* the requirement of being explicit ensures the internal types 
don't leak out somewhere unintentionally in templates or other 
auto types, so your behavior is always predictable, thus solving 
the problem of the library replacement for string




Now using the existing richness for library types, we can 
customize everything and put it in without the compiler even 
caring.



Of course having to explicitly name literals *somewhere* could be 
a major hassle... the code breakage means that part is definitely 
out for D (though renaming the compiler types is something we 
could do, since the object.d aliases will just work except maybe 
for error messages)


But how annoying? Ignoring the reality of the situation, is this 
a good idea in theory?


destroy


Re: Very simple SIMD programming

2012-10-24 Thread F i L

Manu wrote:
One thing I can think of that would really improve simd (and 
not only simd)

would be a way to define compound operators.
If the library could detect/hook sequences of operations and 
implement them
more efficiently as a compound, that would make some very 
powerful

optimisations available.

Simple example:
  T opCompound(string seq)(T a, T b, T c) if(seq == "* +") { 
return

_madd(a, b, c); }
  T opCompound(string seq)(T a, T b, T c) if(seq == "+ *") { 
return

_madd(b, c, a); }


I thought about that before and it might be nice to have that 
level of control in the language, but ultimately, like jerro 
said, I think it would be better suited for the compiler's 
backend optimization. Unfortunately I don't think more complex 
patterns, such as Matrix multiplications, are found and optimized 
by GCC/LLVM... I could be wrong, but these are area where my 
hand-tuned code always outperforms basic math code.


I think having that in the back-end makes a lot of sense, because 
your code is easier to read and understand, without sacrificing 
performance. Plus, it would be difficult to map a sequence as 
complex as matrix multiplication to a single compound operator. 
That being said, I do think something similar would be useful in 
general:


  struct Vector
  {
  ...

  static float distance(Vector a, Vector b) {...}
  static float distanceSquared(Vector a, Vector b) {...}

  float opSequence(string funcs...)(Vector a, Vector b)
if (funcs[0] == "Math.sqrt" &&
funcs[1] == "Vector.distance")
  {
  return distanceSquared(a, b);
  }
  }

  void main()
  {
  auto a = Vector.random( ... );
  auto b = Vector.random( ... );

  // Below is turned into a 'distanceSquared()' call
  float dis = Math.sqrt(Vector.distance(a, b));
  }

Since distance requires a 'Math.sqrt()', this pseudo-code could 
avoid the operation entirely by calling 'distanceSquared()' even 
if the programmer is a noob and doesn't know to do it explicitly.


Re: Shared keyword and the GC?

2012-10-24 Thread Araq
I haven't seen proper benchmarks but some time ago I wrote in D 
and OCaml  basically the same simple program which read and 
parsed some text and performed some calculations, allocating a 
lot of temporary arrays or lists:

https://gist.github.com/2902247
https://gist.github.com/2922399
and OCaml version was 2 times faster than D (29 and 59 seconds 
on input file of 1 million lines). After disabling GC on 
reading/parsing stage and doing calculations without 
allocations and using std.parallelism I made D version work in 
4.4 seconds.



And that makes it the "fastest GC ever made"?

One place where immutability really helps is in a generational 
GC: runtime needs to track all the pointers from old generation 
to the young generation, if most of the data is immutable there 
are not so many such pointers, this makes collection faster. 
When all data is immutable there is no such pointers at all, 
each object can only have pointers to older ones.


That's true. But you don't need to know about immmutability at 
compile time to get this benefit.




Re: Passing static arrays to C

2012-10-24 Thread Walter Bright

On 10/24/2012 2:55 AM, Jakob Bornecrantz wrote:

On Wednesday, 24 October 2012 at 09:03:25 UTC, Jacob Carlborg wrote:

On 2012-10-24 09:54, Jakob Bornecrantz wrote:

Hey everybody.

How are you supposed to pass static arrays to C functions? I'm asking
because I'm getting conflicting info from how DMD works and on IRC.

The below example prints:
test1 0x7fff857c1db0
test2 0x7fff857c1db0
test3 (nil)
test4 0x7fff857c1db0


D:
void main()
{
float[3] arr;
test1(arr);
test2(&arr[0]);
test3(0, arr);
test4(0, &arr[0]);
}

extern(C):
void test1(float[3] arr);
void test2(float *arr);
void test3(int, float[3] arr);
void test4(int, float *arr);


C:
#include 

void test1(float arr[3]) { printf("test1 %p\n", &arr[0]); }
void test2(float arr[3]) { printf("test2 %p\n", &arr[0]); }
void test3(int anything, float arr[3]) { printf("test3 %p\n", &arr[0]); }
void test4(int anything, float arr[3]) { printf("test4 %p\n", &arr[0]); }


That seems weird. Since static arrays are passed by value in D you need to
send a reference:


Yeah I'm wondering if this isn't a bug.


In D, static arrays are passed by value, in C by pointer. Hence, you have a 
mismatch between the C and D prototypes of test1, and you'll get garbage results.




Re: Shared keyword and the GC?

2012-10-24 Thread thedeemon

On Wednesday, 24 October 2012 at 17:42:50 UTC, Araq wrote:


And that makes it the "fastest GC ever made"?


No, not that, of course. As I said, I haven't seen proper 
benchmarks. But OCaml's GC is notorious for its speed and it 
performed very well in all comparisons I saw.


One place where immutability really helps is in a generational 
GC: runtime needs to track all the pointers from old 
generation to the young generation, if most of the data is 
immutable there are not so many such pointers, this makes 
collection faster. When all data is immutable there is no such 
pointers at all, each object can only have pointers to older 
ones.


That's true. But you don't need to know about immmutability at 
compile time to get this benefit.


I agree.



Re: DConf 2013 on kickstarter.com: we're live!

2012-10-24 Thread thedeemon
On Monday, 22 October 2012 at 17:25:28 UTC, Andrei Alexandrescu 
wrote:
We're on! For one month starting today, we're raising funding 
for DConf 2013.


http://www.kickstarter.com/projects/2083649206/the-d-programming-language-conference-2013-0

Please pledge your support and encourage your friends to do the 
same. Hope to see you in 2013!


I'm a backer now, with Facebook and Amazon accounts it was real 
quick and simple.


My evil plan is the fact of organizing this conference will bring 
more people's attention to the language, more adopters and 
developers, so the implementation will get better and better 
faster.


Re: Mixin replacement for switch...case?

2012-10-24 Thread Philippe Sigaud
On Wed, Oct 24, 2012 at 9:53 AM, Jerome  wrote:
> Thanks Philippe! Great solution!
>
> I have two remarks.
>
> Remark 1: I understand that your mixin will be expanded into cascaded
> if...else statements. It would probably be more efficient to expand into
> switch...case, don't you think?

Probably, but my solution can be generalized further, to provide a
sort of pattern-matching:

template match(cases...)
{
auto match(Input...)(Input input)
{
static if (cases.length == 0)
static assert(false, "No match for args of type "~ Input.stringof);
else static if (__traits(compiles, cases[0](input))) // Can we
call cases[0] on input?
return cases[0](input); // If yes, do it
else // else, recurse farther down
return .match1!(cases[1..$])(input);
}
}

string more(T...)(T t){ return "More than two args. Isn't life wonderful?";}



void main()
{
alias match!(
()  => "No args",
(a) => "One arg, of type " ~ typeof(a).stringof ~ " with
value: " ~ to!string(a),
(a, string b)=> "Two args (" ~ to!string(a) ~ ", " ~
to!string(b) ~ "). I know the second one is a string.",
(a, b) => "Two args",
more
) matcher;

writeln(matcher());
writeln(matcher(3.1416));
writeln(matcher(1, "abc"));
writeln(matcher(1, 1));
writeln(matcher(1, "abc", 3.1416));
writeln(matcher(1,1,1,1,1));
}


As you can see, different branches are selected based on the number
and type of arguments.
This is quite powerful: auto-detection based on the number of args,
using the short syntax for function templates (args ) => result
Only for `more` did I need to define an external function. Of course,
standard (non-templated) functions can be used too.

The only limitation is that all branches must return the same type, as
for a stand switch... case statement.

But even this can be circumvented. The code is longer, I paste is there:

http://dpaste.dzfl.pl/c315a160

usage:

void main()
{
alias match!(
()  => 3.14159,
(a) => "One arg, of type " ~ typeof(a).stringof ~ " with
value: " ~ to!string(a),
(a, string b)=> "Two args (" ~ to!string(a) ~ ", " ~
to!string(b) ~ "). I know the second one is a string.",
(a, b) => 0,
more
) matcher;

writeln(matcher());
writeln(matcher(3.1416));
writeln(matcher(1, "abc"));
writeln(matcher(1, 1));
writeln(matcher(1, "abc", 3.1416));
writeln(matcher(1,1,1,1,1));
}

Different argument lists, different result types!



> Remark 2: I infer from your code that the "delegate" keyword is not
> mandatory, so my solution could also be called like this:
>
>
> mixin Select!(value,
>   if0, { then0(); },
>   if1, { then1(); },
>   if2, { foo(); bar(); },
>   { thenDefault(); }
> );
>
> instead of:
>
>
> mixin Select!(value,
>   if0, delegate { then0(); },
>   if1, delegate { then1(); },
>   if2, delegate { foo(); bar(); },
>   delegate { thenDefault(); }
> );
>
> Is that correct?

Yes, it is. code blocks are void delegate()'s in D, or T delegate()
with a return statement: { writeln("Hello World!"); return 0;} is an
int delegate().

You can also use the short delegate syntax:

mixin Select!(value,
   if0, () => then0(),
   if1, () => then1(),
   if2, () => (foo(), bar()),
() => thenDefault()
);

Notice that, in your previous example 'value' is a compile-time
value.My examples were made so as to permit runtime arguments.


Re: Passing static arrays to C

2012-10-24 Thread bearophile

Walter Bright:

In D, static arrays are passed by value, in C by pointer. 
Hence, you have a mismatch between the C and D prototypes of 
test1, and you'll get garbage results.


Isn't it possible to help the programmer avoid some similar 
mistakes with some warnings or errors?


I think the extern(C) annotation, plus the function signatures, 
give the D compiler all the info it needs.


Bye,
bearophile


Invite Distributions to the D-Conf!

2012-10-24 Thread Thomas Koch
Hi,

hopefully there'll be D-Conf in 2013. Please try to reach out to 
Distributions (Debian, Fedora, etc) for a panel to find ways of making D and 
D libraries and applications available in this Distributions.

For Debian the best way for an initial contact would be (I suppose) a mail 
to 
 pkg-d-de...@lists.alioth.debian.org
with an initial CC to
 debian-de...@lists.debian.org and
 debian-proj...@lists.debian.org

Best regards,

Thomas Koch


Re: Mixin replacement for switch...case?

2012-10-24 Thread Philippe Sigaud
Damn, I typed this a bit too fast. I forgot the imports:


> Probably, but my solution can be generalized further, to provide a
> sort of pattern-matching:

Add:

import std.conv;
import std.stdio;

> template match(cases...)
> {
> auto match(Input...)(Input input)
> {
> static if (cases.length == 0)
> static assert(false, "No match for args of type "~ 
> Input.stringof);
> else static if (__traits(compiles, cases[0](input))) // Can we
> call cases[0] on input?
> return cases[0](input); // If yes, do it
> else // else, recurse farther down
> return .match1!(cases[1..$])(input);
> }
> }
>
> string more(T...)(T t){ return "More than two args. Isn't life wonderful?";}
>
>
>
> void main()
> {
> alias match!(
> ()  => "No args",
> (a) => "One arg, of type " ~ typeof(a).stringof ~ " with
> value: " ~ to!string(a),
> (a, string b)=> "Two args (" ~ to!string(a) ~ ", " ~
> to!string(b) ~ "). I know the second one is a string.",
> (a, b) => "Two args",
> more
> ) matcher;
>
> writeln(matcher());
> writeln(matcher(3.1416));
> writeln(matcher(1, "abc"));
> writeln(matcher(1, 1));
> writeln(matcher(1, "abc", 3.1416));
> writeln(matcher(1,1,1,1,1));
> }


Re: Mixin replacement for switch...case?

2012-10-24 Thread Philippe Sigaud
On Wed, Oct 24, 2012 at 9:56 AM, Jerome  wrote:
>> Remark 1: I understand that your mixin will be expanded into cascaded
>> if...else statements. It would probably be more efficient to expand into
>> switch...case, don't you think?
>
>
> Oh! I've just figured out that it is not a mixin, but a function template.

That was to allow runtime arguments to be used. In your example, value
is a compile-time argument. In this case, all tests can be done at CT
and your code should result *only* in the right branch: no need to
develop an entire switch statement.


Re: Uri class and parser

2012-10-24 Thread Mike van Dongen
On Wednesday, 24 October 2012 at 07:38:58 UTC, Jacob Carlborg 
wrote:

I would have expected a few additional components, like:

* Domain
* Password
* Username
* Host
* Hash

A way to build an URI base on the components.
It would be nice if there were methods for getting/setting the 
path component as an array. Also methods for getting/setting 
the query component as an associative array.


Thanks for the suggestions!
I've added many, if not all, of them to the repo:

- Identifying/separating the username, password (together the 
userinfo), the domain and the port number from the authority.
- The hash now also can be get/set and the same thing goes for 
the data in the query



On Wednesday, 24 October 2012 at 12:47:15 UTC, Adam D. Ruppe 
wrote:
On Wednesday, 24 October 2012 at 07:38:58 UTC, Jacob Carlborg 
wrote:
It would be nice if there were methods for getting/setting the 
path component as an array. Also methods for getting/setting 
the query component as an associative array.


BTW don't forget that this is legal:

?value&value=1&value=2

The appropriate type for the AA is

string[][string]


It does not yet take into account the fact that multiple query 
elements can have the same name. I'll be working on that next.



On Wednesday, 24 October 2012 at 07:38:58 UTC, Jacob Carlborg 
wrote:
A few stylistic issues. There are a lot of places where you 
haven't indented the code, at least how it looks like on github.


I wouldn't put the private methods at the top.


As for the indentations, I use tabs with the size of 4 spaces.
Viewing the code on Github (in Chromium) you'll see tabs of 8 
spaces.

I'm not sure what the phobos standard is?

As all my code is part of a single class and the file std/uri.d 
already existed, I decided to 'just' append my code to the file. 
Should I perhaps put it in another file as the private methods 
you mentioned are not relevant to my code?



You may be able to see the new getters by checking out this 
unittest:


uri = 
Uri.parse("foo://username:passw...@example.com:8042/over/there/index.dtb?type=animal&name=narwhal&novalue#nose");

assert(uri.scheme == "foo");
assert(uri.authority == "username:passw...@example.com:8042");
assert(uri.path == "over/there/index.dtb");
assert(uri.pathAsArray == ["over", "there", "index.dtb"]);
assert(uri.query == "type=animal&name=narwhal&novalue");
assert(uri.queryAsArray == ["type": "animal", "name": "narwhal", 
"novalue": ""]);

assert(uri.fragment == "nose");
assert(uri.host == "example.com");
assert(uri.port == 8042);
assert(uri.username == "username");
assert(uri.password == "password");
assert(uri.userinfo == "username:password");
assert(uri.queryAsArray["type"] == "animal");
assert(uri.queryAsArray["novalue"] == "");
assert("novalue" in uri.queryAsArray);
assert(!("nothere" in uri.queryAsArray));


Re: Passing static arrays to C

2012-10-24 Thread Andrej Mitrovic
On 10/24/12, bearophile  wrote:
> Isn't it possible to help the programmer avoid some similar
> mistakes with some warnings or errors?
>
> I think the extern(C) annotation, plus the function signatures,
> give the D compiler all the info it needs.

Agreed. File to bugzilla unless Walter disagrees?


Re: On D development

2012-10-24 Thread Jesse Phillips
On Wednesday, 24 October 2012 at 11:01:13 UTC, Robert Klotzner 
wrote:

In fact I am very happy with D's feature set, but as long

as D is
alive there will be improvements from time to time and having a 
way of
testing them thoroughly, can't really harm the language. But I 
don't
know. You and other people more involved in development are of 
course
better judges of usefulness of this proposal. Basically I was 
just

curious why it is not done this way.


It was, it created the D1 and D2 split. So to do it again, even 
if we don't call it D3 and just say it is experimental, it is 
still the same split.


As for testing the changes going in thoroughly. All source is 
public and can be compiled and verified by anyone at any time for 
any project they have access to. There is a Beta released prior 
to the official release, it is a time for and one to speak up of 
regressions and other issues before the release is finalized. 
Extending this period isn't going to add much value to having 
strong verification.


D2 is at/near/moving toward being stable so this is a good system 
at this time. Not to say it can't be improved, but the 
improvement will really be viable when more people see the 
stability and begin participating and adding to the quantity of 
verification that regressions are not being introduced.


Re: Passing static arrays to C

2012-10-24 Thread Andrej Mitrovic
On 10/24/12, Andrej Mitrovic  wrote:
> Agreed. File to bugzilla unless Walter disagrees?

Also, what should the error message look like? I've got a pull in works fwiw.


Re: [just talk] what if implicitly typed literals were disallowed

2012-10-24 Thread H. S. Teoh
On Wed, Oct 24, 2012 at 06:38:34PM +0200, Adam D. Ruppe wrote:
[...]
> The thread about string and rep had me bring up my library string
> implementation again, and it was shot down because of "auto a =
> "foo";" meaning a would not have the library type.
> 
> It made me wonder: what if we got rid of literals? Well, can't do
> that, we need some kind of building block. But, what if we required
> their use to have a clear type?
> 
> I'm tempted to say literals should only be used when there is an
> explicit type given somewhere

Well, completely getting rid of type inference for literals is a bit
extreme, I think, but I definitely agree with the spirit of your
proposal: literals should NOT be assigned a type beforehand; the
compiler should always look for the best fit in the given context first,
and THEN if nothing else says anything more about the type, fall back to
the default type.

So for example, "f(10)" will correctly infer the type based on f's
signature, and so will f([1,2,3]) where f's parameter may be typed, say,
ushort[] or even real[]. This is particular important when f is a
template function: the compiler should try to find all possible matches
BEFORE falling back to int[]. Currently, it doesn't always do this, so
sometimes you have to explicitly type the literal in order to get it to
match the desired template.

Only when nothing else works (say you wrote "auto x = [1,2,3]") should
the compiler fall back to int[], for example.


[...]
> Why does this matter? Well it gives you a lot of user defined
> capabilities here. Let's combine with the following:
> 
> * make the internal type of the literals a special word. _int
> instead of int for example. Now int is not a keyword - it is
> available to library redefinitions (surely in object.d, but you can
> import your own int if you wanted to)
> 
> * have the library give them the prettier names. this might be
> "alias int = _int;" or it might be struct int { this(_int i) { } /*
> custom functionality */}; in other words you can give complete user
> defined behavior without name conflicts. This can be replaced at any
> time by hacking up your druntime.
> 
> 
> * the requirement of being explicit ensures the internal types don't
> leak out somewhere unintentionally in templates or other auto types,
> so your behavior is always predictable, thus solving the problem of
> the library replacement for string
[...]

I think this is orthogonal to assigning a type to a literal. You could,
in theory, modify the compiler so that a literal like [1,2,3] is typed
Integer[], where Integer is aliased to int in druntime, and can be
overridden by a user-defined Integer. This does not require that
literals have no type at all.

Anyway, on a related topic: another thing that irks me about D literals
is that there is sometimes unexpected implicit copying.  Something like:

real[] x = [1,2,3];

contains an implicit runtime copy of a compile-time built array [1,2,3]
into x. Ideally, since literals are by definition used only in a single
place, the array being initialized should constructed in-place with the
specified values. The current compiler emits a call to a
literal-construction function at runtime, which is unnecessary overhead
when the literal is small (and literals are usually small, since
otherwise you wouldn't write things that way!) -- it could've been just
a handful of MOV's instead of an entire function call.


T

-- 
Маленькие детки - маленькие бедки.


Re: [just talk] what if implicitly typed literals were disallowed

2012-10-24 Thread Timon Gehr

On 10/24/2012 06:38 PM, Adam D. Ruppe wrote:

...
But how annoying? Ignoring the reality of the situation, is this a good
idea in theory?

destroy


I'd miss ifti on literals. If your goal is to be able to customize the
type of literals from druntime, it is also possible to make the compiler
invoke some predefined templates/functions in order to transform
literals to an arbitrary library-defined type.



Why D is annoying =P

2012-10-24 Thread Mehrdad

I couldn't find a better title, sorry.


But yeah, I've spent too many hours on hunting down problems like 
these...



Could someone explain what's going on? Thanks!

import std.stdio;
struct S { int[int] aa; }
void main()
{
writeln(  [1: 2]  ==   [1: 2] );  // true
writeln(S([1: 2]) == S([1: 2]));  // false
}

(I'm on Windows DMD v2.060.)


Re: Passing static arrays to C

2012-10-24 Thread Andrej Mitrovic
On 10/24/12, Andrej Mitrovic  wrote:
> On 10/24/12, Andrej Mitrovic  wrote:
>> Agreed. File to bugzilla unless Walter disagrees?
>
> Also, what should the error message look like? I've got a pull in works
> fwiw.

Small test-case:

extern(C) void fail(int[4] x);
extern(C) int[4] fail2();

extern(C) void c_ok1(ref int[4] x);
extern(C) void c_ok2(out int[4] x);
extern(C) void c_ok3(int[4]* x);
extern(C) ref int[4] c_ok4();
extern(C) int[4]* c_ok5();

Have I covered everything?


Re: Why D is annoying =P

2012-10-24 Thread Andrej Mitrovic
On 10/24/12, Mehrdad  wrote:
> Could someone explain what's going on? Thanks!

Struct fields are compared by address by default if no opEquals is
defined. http://d.puremagic.com/issues/show_bug.cgi?id=3789


Re: Why D is annoying =P

2012-10-24 Thread Andrej Mitrovic
On 10/24/12, Andrej Mitrovic  wrote:
> On 10/24/12, Mehrdad  wrote:
>> Could someone explain what's going on? Thanks!
>
> Struct fields are compared by address by default if no opEquals is
> defined. http://d.puremagic.com/issues/show_bug.cgi?id=3789
>

Well I mean for reference types. Or something like that. To put it
bluntly: It's brokeeen.


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 19:25:47 UTC, Timon Gehr wrote:

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



Ouch, bug since 2010...
(Thanks for the link.)



Re: Why D is annoying =P

2012-10-24 Thread Timon Gehr

On 10/24/2012 09:17 PM, Mehrdad wrote:

I couldn't find a better title, sorry.


But yeah, I've spent too many hours on hunting down problems like these...


Could someone explain what's going on? Thanks!

import std.stdio;
struct S { int[int] aa; }
void main()
{
 writeln(  [1: 2]  ==   [1: 2] );  // true
 writeln(S([1: 2]) == S([1: 2]));  // false
}

(I'm on Windows DMD v2.060.)


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


Re: Why D is annoying =P

2012-10-24 Thread H. S. Teoh
On Wed, Oct 24, 2012 at 09:17:09PM +0200, Mehrdad wrote:
[...]
> Could someone explain what's going on? Thanks!
> 
> import std.stdio;
> struct S { int[int] aa; }
> void main()
> {
>   writeln(  [1: 2]  ==   [1: 2] );  // true
>   writeln(S([1: 2]) == S([1: 2]));  // false
> }
[...]

I don't know if there is any struct-specific problem here, but AA
comparison right now is horribly horribly broken (search on the bug
tracker for "AA" and you'll see a bunch of issues on that end). You're
incredibly lucky that two AA literals actually compared equal. In some
cases, not even that is guaranteed.

I've tried to clean up the AA code but it's a tangled messy ugly
labyrinth with fragile hacks sprinkled in, and didn't get to the point
where it's ready to commit. One major obstacle is that parts of it are
implemented in compiler hacks, and part of it is schizophrenically
duplicated in object_.d, not necessarily consistently, and it's just Not
Nice in general. That it works at all is reason enough to be thankful. I
don't expect things to be pretty once you start poking into the
intricacies of AA's, sad to say.


T

-- 
People tell me I'm stubborn, but I refuse to accept it!


static and non-static version of the one function

2012-10-24 Thread Zhenya

Hi!
Tell me please,are there any way to declare two versions of one 
member function,

something like this:

int a;

int.init //static version
a.init //non-static version


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad
On Wednesday, 24 October 2012 at 19:28:36 UTC, Andrej Mitrovic 
wrote:

On 10/24/12, Andrej Mitrovic  wrote:

On 10/24/12, Mehrdad  wrote:

Could someone explain what's going on? Thanks!


Struct fields are compared by address by default if no 
opEquals is

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



Well I mean for reference types. Or something like that. To put 
it bluntly: It's brokeeen.



Yeah, and my attempts to get around it don't seem to help:

auto a = [1:1], b = [1:1];
writeln(a == b);   // true
writeln(a in [a:0]);   // null




Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 19:32:08 UTC, Mehrdad wrote:

Yeah, and my attempts to get around it don't seem to help:

auto a = [1:1], b = [1:1];
writeln(a == b);   // true
writeln(a in [a:0]);   // null



Harsh (but true, and perhaps useful) feedback...
I feel like this is a *perfect* example of the kinds of things 
that turn people off of D.


I don't know what to expect code like this to do (unlike in C++, 
where everything is clearly defined in the specs), and when it 
seems to do what I want, it really turns out to be a bug in the 
library that it seemed to work in the first place. :(


Re: Normal/Gaussian random number generation for D

2012-10-24 Thread jerro
Can you expand on this, and maybe provide a reference?  I don't 
doubt your code's effectiveness but I think where RNGs are 
concerned we really need to be able to justify our algorithmic 
choices.  There's too much literature out there showing how 
commonly-used algorithms actually carry statistical flaws.


The first change I made to the algorithm is shifting layer 
boundaries. Basic Ziggurat algorithm uses n layers with area A. 
Because computing samples from the bottom layer and the top layer 
is typically more expensive than computing samples from other 
layers, I shifted the layer boundaries so that the top and the 
bottom layers have areas A / 2 and other n - 1 layers have area 
A. That way we only need to draw half as many samples from the 
top and the bottom layer.


To better describe the second change, I drew a picture and 
uploaded it to http://i.imgur.com/bDRpP.png . The basic Ziggurat 
algorithm first chooses the layer randomly and then chooses a 
random number x between 0 and xavg. If x is below xmin, it 
returns it. The algorithm I use does this too. When x is above 
xmin, the basic Ziggurat algorithm chooses a random point in the 
outer layer area (see the picture), checks if y < f(y), returns 
its x coordinate if it is, and chooses a new point otherwise. My 
algorithm uses precomputed low and high x offsets for each layer. 
It chooses a point below the high diagonal, and checks if it is 
below the low diagonal. If it is (and it is in most cases), it 
returns its x coordinate without computing f(x). If only checks 
if y < f(x) when y is above the low diagonal. That way it doesn't 
need to make as many calls to f(x).


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 19:34:15 UTC, H. S. Teoh wrote:
I don't know if there is any struct-specific problem here, but 
AA comparison right now is horribly horribly broken (search on 
the bug tracker for "AA" and you'll see a bunch of issues on 
that end). You're incredibly lucky that two AA literals 
actually compared equal. In some cases, not even that is 
guaranteed.



Yeah, I was a little aware that AAs were semi-broken, but I 
thought, hey, if it seems to work then it obviously works.

Turns out that wasn't so true. :\



I've tried to clean up the AA code but it's a tangled messy 
ugly labyrinth with fragile hacks sprinkled in, and didn't get 
to the point where it's ready to commit. One major obstacle is 
that parts of it are implemented in compiler hacks, and part of 
it is schizophrenically duplicated in object_.d, not 
necessarily consistently, and it's just Not Nice in general. 
That it works at all is reason enough to be thankful. I don't 
expect things to be pretty once you start poking into the 
intricacies of AA's, sad to say.




Yeah, the trouble is, none of the set-based data types (including 
maps) in D seem to be working...


- AAs are broken
- AssociativeArray is the same as above, I think?
- RedBlackTree is useless (how do I keep a "set of sets"?)
etc.


So you can't really write a real program in D, to put it blunty.


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 19:41:42 UTC, Mehrdad wrote:
So you can't really write a real program in D, to put it 
bluntly.



Case in point: there's no way to tell an arbitrary object/struct 
to give you its hash code.


Re: Uri class and parser

2012-10-24 Thread Jacob Carlborg

On 2012-10-24 20:22, Mike van Dongen wrote:


Thanks for the suggestions!
I've added many, if not all, of them to the repo:

- Identifying/separating the username, password (together the userinfo),
the domain and the port number from the authority.
- The hash now also can be get/set and the same thing goes for the data
in the query



As for the indentations, I use tabs with the size of 4 spaces.
Viewing the code on Github (in Chromium) you'll see tabs of 8 spaces.
I'm not sure what the phobos standard is?


Ok, I'm using firefox and it doesn't look particular good on github. The 
Phobos standard is to use tabs as spaces with the size of 4.



As all my code is part of a single class and the file std/uri.d already
existed, I decided to 'just' append my code to the file. Should I
perhaps put it in another file as the private methods you mentioned are
not relevant to my code?


If the some methods aren't used by the URI parser you should remove the. 
If they're used I would suggested you move the further down in the code, 
possibly at the bottom.



You may be able to see the new getters by checking out this unittest:


Cool. It would be nice to have a way to set the query and path as an 
(associative) array as well.


Just a suggestion, I don't really see a point in having getters and 
setters that just forwards to the instance variables. Just use public 
instance variables. The only reason to use getters and setters would be 
to be able to subclass and override them. But I think you could just 
make Uri a final class.


About path and query. I wonder that's best to be default return an 
(associative) array or a string. I would think it's more useful to 
return an (associative) array and then provide rawPath() and rawQuery() 
which would return strings.


A nitpick, I'm not really an expert on URI's but is "fragment" really 
the correct name for that I would call the "hash"? That would be "nose" 
in the example below.



uri =
Uri.parse("foo://username:passw...@example.com:8042/over/there/index.dtb?type=animal&name=narwhal&novalue#nose");

assert(uri.scheme == "foo");
assert(uri.authority == "username:passw...@example.com:8042");
assert(uri.path == "over/there/index.dtb");
assert(uri.pathAsArray == ["over", "there", "index.dtb"]);
assert(uri.query == "type=animal&name=narwhal&novalue");
assert(uri.queryAsArray == ["type": "animal", "name": "narwhal",
"novalue": ""]);
assert(uri.fragment == "nose");
assert(uri.host == "example.com");
assert(uri.port == 8042);
assert(uri.username == "username");
assert(uri.password == "password");
assert(uri.userinfo == "username:password");
assert(uri.queryAsArray["type"] == "animal");
assert(uri.queryAsArray["novalue"] == "");
assert("novalue" in uri.queryAsArray);
assert(!("nothere" in uri.queryAsArray));



--
/Jacob Carlborg


Re: On D development

2012-10-24 Thread Jacob Carlborg

On 2012-10-24 09:38, Robert wrote:

When reading stuff, like: "Yes this is bad, but people use it already,
so we could only possible change this in D3 or something" and reading
endless discussions about a new feature (e.g. ref semantics) of how it
could break things and so on, I thought it might be a good idea to
implement new features in an experimental version, which can then be
thoroughly tested and only if nothing bad found they will be merged in
the stable branch. People simply have to be aware that they should not
rely on semantics implemented in experimental.

Discussions about new features before their are implemented would of
course still be a very good idea, but it would reduce the pressure a
bit, because you can simply try. This does not solve everything, because
some issues will only pop up if used for a long time or only in real
complicated production code, but I think it is better than the approach
of having no way back?

I don't believe this idea is entirely new or maybe I am missing
something. What do you think?


There has been some talk about this. I think we pretty much all agreed 
that we should have a stable branch/repository which we would 
cherry-pick changes from the master branch.


I don't remember who said he would be responsible for this stable 
branch/repository. I neither can remember the thread.


--
/Jacob Carlborg


Re: Why D is annoying =P

2012-10-24 Thread H. S. Teoh
On Wed, Oct 24, 2012 at 09:41:41PM +0200, Mehrdad wrote:
> On Wednesday, 24 October 2012 at 19:34:15 UTC, H. S. Teoh wrote:
> >I don't know if there is any struct-specific problem here, but AA
> >comparison right now is horribly horribly broken (search on the
> >bug tracker for "AA" and you'll see a bunch of issues on that
> >end). You're incredibly lucky that two AA literals actually
> >compared equal. In some cases, not even that is guaranteed.
> 
> 
> Yeah, I was a little aware that AAs were semi-broken, but I thought,
> hey, if it seems to work then it obviously works.
> Turns out that wasn't so true. :\

The AA implementation badly needs to be revamped. But the problem is
that it's non-trivial, may break existing code, etc.. I do have a (semi)
working version of a prospective AA replacement, though:

https://github.com/quickfur/New-AA-implementation

You might be able to make use of it if you're willing to live with
broken IFTI (which is no big deal if you just explicitly type what you
instantiate the AA with).


> >I've tried to clean up the AA code but it's a tangled messy ugly
> >labyrinth with fragile hacks sprinkled in, and didn't get to the
> >point where it's ready to commit. One major obstacle is that parts
> >of it are implemented in compiler hacks, and part of it is
> >schizophrenically duplicated in object_.d, not necessarily
> >consistently, and it's just Not Nice in general. That it works at
> >all is reason enough to be thankful. I don't expect things to be
> >pretty once you start poking into the intricacies of AA's, sad to
> >say.
> 
> Yeah, the trouble is, none of the set-based data types (including
> maps) in D seem to be working...
> 
> - AAs are broken
> - AssociativeArray is the same as above, I think?

Yes it's the same. It's not meant to be used directly by user code,
though. The two are supposed to be the same.


> - RedBlackTree is useless (how do I keep a "set of sets"?)

What's wrong with RedBlackTree? You can just do something like:

RedBlackTree!(RedBlackTree!MySet) setOfSets;


[...]
> So you can't really write a real program in D, to put it blunty.

That's a bit harsh. It's not hard to write your own hash implementation
in D, given the expressiveness of its templates and compile-time
features. The bugginess of the built-in AA is lamentable, definitely,
but it doesn't *prevent* you from writing your own data structures. All
programmers worth their salt should be able to roll their own where the
current implementation is inadequate, anyway. ;-) In any case, as they
say in the open source community, patches are always welcome.

Plus, you *can* use AA's for all sorts of stuff in general, if you just
avoid some of the most glaring bugs. It only takes 15 minutes to write
your own opEquals() in a struct that wraps around an AA, and it's
equally fast to parametrize that struct to take arbitrary types, and
provide wrapper functions that work around the current bugs. None of
the current issues are showstoppers, as annoying as they may be.


T

-- 
Do not reason with the unreasonable; you lose by definition.


Re: static and non-static version of the one function

2012-10-24 Thread Jacob Carlborg

On 2012-10-24 21:32, Zhenya wrote:

Hi!
Tell me please,are there any way to declare two versions of one member
function,
something like this:

int a;

int.init //static version
a.init //non-static version


No, not currently.

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

--
/Jacob Carlborg


Re: Why D is annoying =P

2012-10-24 Thread Jacob Carlborg

On 2012-10-24 21:37, Mehrdad wrote:


I don't know what to expect code like this to do (unlike in C++, where
everything is clearly defined in the specs), and when it seems to do
what I want, it really turns out to be a bug in the library that it
seemed to work in the first place. :(


Everything in C++ is specified as undefined behavior :)

--
/Jacob Carlborg


Re: [RFC] ColorD

2012-10-24 Thread Robik

On Tuesday, 23 October 2012 at 22:47:40 UTC, Walter Bright wrote:
On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 
9:47 AM, Jens Mueller wrote:

>> This is probably interesting for Phobos. But I'm not the one
to make a
>> decision. The core Phobos developers should decide.
>> Hopefully somebody is reading this.
>
> Off the top of my head something that is specific for only
certain systems
> (Unixen in this case) is decidedly of less Phobos interest.
We could,
> nevertheless, put such functionality in system-specific
modules.

A module that only sets the console color is a little too light 
to be a phobos entry.


A more comprehensive module that included:

1. getting mouse input
2. getting size of the console
3. moving the cursor around
4. drawing boxes in the console window
5. setting the contents of the title bar
6. supporting cut/paste
7. getting no-echo raw input
8. setting the size of the cursor

would be a definite candidate. I.e. a module that can support 
building a text mode screen app (like a text editor).



Thanks for your suggestions. I will try to do what I can, but I 
think there may be some problems because of differences in 
terminals. Although some of them should not be the problem :)


Re: Why D is annoying =P

2012-10-24 Thread H. S. Teoh
On Wed, Oct 24, 2012 at 09:50:18PM +0200, Mehrdad wrote:
> On Wednesday, 24 October 2012 at 19:41:42 UTC, Mehrdad wrote:
> >So you can't really write a real program in D, to put it bluntly.
> 
> 
> Case in point: there's no way to tell an arbitrary object/struct to
> give you its hash code.

Huh?  All objects implement toHash(). If the default toHash() doesn't
satisfy you, override it with your own.

You can just use rt.util.hash.hashOf for structs. Use UFCS to make it
callable as toHash(). Implement your own toHash() where hashOf isn't
good enough. Problem solved.


T

-- 
Once bitten, twice cry...


Re: static and non-static version of the one function

2012-10-24 Thread Zhenya
On Wednesday, 24 October 2012 at 20:02:20 UTC, Jacob Carlborg 
wrote:

On 2012-10-24 21:32, Zhenya wrote:

Hi!
Tell me please,are there any way to declare two versions of 
one member

function,
something like this:

int a;

int.init //static version
a.init //non-static version


No, not currently.

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


Thank you,understood.


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 20:07:49 UTC, H. S. Teoh wrote:

On Wed, Oct 24, 2012 at 09:50:18PM +0200, Mehrdad wrote:

On Wednesday, 24 October 2012 at 19:41:42 UTC, Mehrdad wrote:
>So you can't really write a real program in D, to put it 
>bluntly.



Case in point: there's no way to tell an arbitrary 
object/struct to

give you its hash code.


Huh?  All objects implement toHash().



Not Tuples, apparently. (I didn't mean Object, I mean "object" in
the general sense.)



You can just use rt.util.hash.hashOf for structs.


Will try, thanks for the pointer.


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad
On Wednesday, 24 October 2012 at 20:04:24 UTC, Jacob Carlborg 
wrote:

On 2012-10-24 21:37, Mehrdad wrote:

I don't know what to expect code like this to do (unlike in 
C++, where everything is clearly defined in the specs), and 
when it seems to do what I want, it really turns out to be a 
bug in the library that it seemed to work in the first place. 
:(


Everything in C++ is specified as undefined behavior :)




lol.


I meant more like, it's clear in C++ which operations need to be 
implemented in order for an object to be hashable, for instance.


I can't figure out how hashing works in D at all.


Re: Why D is annoying =P

2012-10-24 Thread H. S. Teoh
On Wed, Oct 24, 2012 at 10:09:36PM +0200, Mehrdad wrote:
> On Wednesday, 24 October 2012 at 20:07:49 UTC, H. S. Teoh wrote:
> >On Wed, Oct 24, 2012 at 09:50:18PM +0200, Mehrdad wrote:
> >>On Wednesday, 24 October 2012 at 19:41:42 UTC, Mehrdad wrote:
> >>>So you can't really write a real program in D, to put it
> >>>bluntly.
> >>
> >>
> >>Case in point: there's no way to tell an arbitrary object/struct to
> >>give you its hash code.
> >
> >Huh?  All objects implement toHash().
> 
> 
> Not Tuples, apparently. (I didn't mean Object, I mean "object" in
> the general sense.)

Well, Object implements toHash(). Other things don't, but with UFCS you
can endow them with toHash(). :)


> >You can just use rt.util.hash.hashOf for structs.
> 
> Will try, thanks for the pointer.

hashOf works for pretty much anything (it's just a byte-based algo). So
it's not just structs, you can pass anything to it. Using UFCS to map
toHash() to hashOf will give you toHash() for literally everything,
which is apparently what you want (though I question the wisdom of
wanting a hash value of *everything*, including objects representing
network resources, the OS, etc., but hey, you can do it if you *really*
want to).


T

-- 
It won't be covered in the book. The source code has to be useful for
something, after all. -- Larry Wall


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 20:03:44 UTC, H. S. Teoh wrote:

What's wrong with RedBlackTree? You can just do something like:

RedBlackTree!(RedBlackTree!MySet) setOfSets;



The last time I checked two RedBlackTrees for equality, they 
seemed to have reference semantics...





[...]
So you can't really write a real program in D, to put it 
blunty.


That's a bit harsh.


Sorry, just saying what I experienced :(


It's not hard to write your own hash implementation in D


I beg to differ, see below

given the expressiveness of its templates and compile-time 
features. The bugginess of the built-in AA is lamentable, 
definitely, but it doesn't *prevent* you from writing your own 
data structures.


It does. There's simply no mechanism to hash an arbitrary thing 
in D.


(hashOf, which Andrej just mentioned, is an internal thing, 
right? aka a hack, which I was not aware of)



All programmers worth their salt should be able to roll their 
own where the current implementation is inadequate, anyway. ;-)



Well, there's different issues involved...

- Can I? Yes.
- Will I? No, it takes more time than it's worth

In any case,  as they say in the open source community, patches 
are always welcome.


Yeah, it's just that I can't figure out even the basics of 
hashing in D (above), so I can't really patch something because 
then it'll turn out to be working in a different way than I 
expect.


It only takes 15 minutes to write your own opEquals() in a 
struct that wraps around an AA


I've spent longer than that right now and still haven't been able 
to (but I haven't tried the hashOf hack yet).




Maybe you can fill in the blanks?


struct Set(T)
{
int[T] dict;
hash_t toHash() const
{
typeof(return) r = 0;
foreach (item; this.dict.keys)
{
???   // what should be here?
}
return r;
}
}



Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 20:15:07 UTC, H. S. Teoh wrote:
hashOf works for pretty much anything (it's just a byte-based 
algo).



Byte-based?

what about


Set!(Tuple!(int, string)) s;
s[tuple(1, "hi")] = 1;
writeln(tuple(1, "hi".dup) in s);  // null or not?


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 20:18:07 UTC, Mehrdad wrote:

On Wednesday, 24 October 2012 at 20:15:07 UTC, H. S. Teoh wrote:
hashOf works for pretty much anything (it's just a byte-based 
algo).



Byte-based?

what about


Set!(Tuple!(int, string)) s;
s[tuple(1, "hi")] = 1;
writeln(tuple(1, "hi".dup) in s);  // null or not?


my bad, I mixed up AA and sets.

That was supposed to insert the item, not map it to 1. Would it 
work?


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad
On Wednesday, 24 October 2012 at 20:32:00 UTC, Walter Bright 
wrote:
The default compare for structs is a bit compare of the 
contents.



Thanks for the reply.


And hmm, that should be changed IMO. ;)
Bitwise comparison is nearly useless.


Re: Why D is annoying =P

2012-10-24 Thread Walter Bright

On 10/24/2012 12:17 PM, Mehrdad wrote:
> I couldn't find a better title, sorry.
>
>
> But yeah, I've spent too many hours on hunting down problems like these...
>
>
> Could someone explain what's going on? Thanks!
>
> import std.stdio;
> struct S { int[int] aa; }
> void main()
> {
>  writeln(  [1: 2]  ==   [1: 2] );  // true
>  writeln(S([1: 2]) == S([1: 2]));  // false
> }
>
> (I'm on Windows DMD v2.060.)

The compare for associative arrays is to compare the members.

The default compare for structs is a bit compare of the contents.


Re: Why D is annoying =P

2012-10-24 Thread H. S. Teoh
On Wed, Oct 24, 2012 at 10:16:27PM +0200, Mehrdad wrote:
[...]
> struct Set(T)
> {
>   int[T] dict;
>   hash_t toHash() const
>   {
>   typeof(return) r = 0;
>   foreach (item; this.dict.keys)
>   {
>   ???   // what should be here?
>   }
>   return r;
>   }
> }

Try this:

hash_t toHash() const
{
hash_t h = 0;
foreach (item; this.dict.keys)
{
// We use a commutative operation here (+) so
// that the order of keys don't matter.
h += hashOf(&item, item.sizeof);
}
return h;
}


T

-- 
What do you get if you drop a piano down a mineshaft? A flat minor.


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 20:38:08 UTC, Mehrdad wrote:

Wouldn't that do a bitwise comparison?


sorry, I mean bitwise _hash_


Re: Uri class and parser

2012-10-24 Thread Adam D. Ruppe
On Wednesday, 24 October 2012 at 19:54:54 UTC, Jacob Carlborg 
wrote:
A nitpick, I'm not really an expert on URI's but is "fragment" 
really the correct name for that I would call the "hash"? That 
would be "nose" in the example below.


Yes, that's the term in the standard.

http://en.wikipedia.org/wiki/Fragment_identifier

Javascript calls it the hash though, but it is slightly 
different: the # symbol itself is not part of the fragment 
according to the standard.


But javascript's location.hash does return it.

URL: example.com/

location.hash

""


location.hash = "test"

"test"

URL changes to: example.com/#test


location.hash;

"#test"



The fragment would technically just be "test" there.


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 20:37:08 UTC, H. S. Teoh wrote:

On Wed, Oct 24, 2012 at 10:16:27PM +0200, Mehrdad wrote:
[...]

struct Set(T)
{
int[T] dict;
hash_t toHash() const
{
typeof(return) r = 0;
foreach (item; this.dict.keys)
{
???   // what should be here?
}
return r;
}
}


Try this:

hash_t toHash() const
{
hash_t h = 0;
foreach (item; this.dict.keys)
{
// We use a commutative operation here (+) so
// that the order of keys don't matter.
h += hashOf(&item, item.sizeof);
}
return h;
}


T


Wouldn't that do a bitwise comparison?


Re: Why D is annoying =P

2012-10-24 Thread H. S. Teoh
On Wed, Oct 24, 2012 at 10:38:07PM +0200, Mehrdad wrote:
> On Wednesday, 24 October 2012 at 20:37:08 UTC, H. S. Teoh wrote:
> >On Wed, Oct 24, 2012 at 10:16:27PM +0200, Mehrdad wrote:
> >[...]
> >>struct Set(T)
> >>{
> >>int[T] dict;
> >>hash_t toHash() const
> >>{
> >>typeof(return) r = 0;
> >>foreach (item; this.dict.keys)
> >>{
> >>???   // what should be here?
> >>}
> >>return r;
> >>}
> >>}
> >
> >Try this:
> >
> > hash_t toHash() const
> > {
> > hash_t h = 0;
> > foreach (item; this.dict.keys)
> > {
> > // We use a commutative operation here (+) so
> > // that the order of keys don't matter.
> > h += hashOf(&item, item.sizeof);
> > }
> > return h;
> > }
> >
> >
> >T
> 
> Wouldn't that do a bitwise comparison?

Umm, the idea of a hash is to *quickly* compute a value that's (mostly)
unique for a given object. In most cases, the bit representation is good
enough. If you want a thorough recursive comparison of all subobjects,
you should overload opEquals and use that instead.

Or use compile-time reflection to iterate over every member of the given
object and recursively iterate and hash them. Though I fail to see the
point of it, since it defeats the purpose of a hash in the first place -
you might as well just do the usual recursive compare instead.


T

-- 
Never step over a puddle, always step around it. Chances are that whatever made 
it is still dripping.


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad
Is there any reason why we don't have something like this in 
Phobos?




hash_t toHash(T)(in T t) if (isIntegral!(T) || isSomeChar!(T))
{
return t;
}

hash_t toHash(T)(in T[] t)
{
typeof(return) h = 0;
foreach (item; t)
{ h = h * 37 + item.toHash(); }
return h;
}

hash_t toHash(T)(in T t) if (!isIntegral!(T) && !isSomeChar!(T) 
&& !isArray!(T))

{
typeof(return) h = 0;
foreach (ref a; t.tupleof)
{ h = h * 37 + a.toHash(); }
return h;
}

hash_t toHash(T...)(in Tuple!(T) t)
{
typeof(return) h = 0;
foreach (item; t)
{ h = h * 37 + item.toHash(); }
return h;
}



Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

Better example:



private import std.traits, std.typecons, std.typetuple;

hash_t toHash(T)(in T t)
if (isIntegral!(T) || isSomeChar!(T))
{ return t; }

hash_t toHash(T)(in T[] t)
{
typeof(return) h = 0;
foreach (item; t)
{ h = (h * 37) ^ item.toHash(); }
return h;
}

hash_t toHash(V, K)(in V[K] t)
{
typeof(return) h = 0;
foreach (k, v; t)
{ h ^= k.toHash(); }
return h;
}

hash_t toHash(T)(in T t)
if (!isIntegral!(T) &&
!isSomeChar!(T) &&
!isArray!(T) &&
!isAssociativeArray!(T))
{
typeof(return) h = 0;
foreach (ref a; t.tupleof)
{ h = (h * 37) ^ a.toHash(); }
return h;
}

void main()
{
import std.stdio;
writeln(tuple("hi", [[1: 2].keys.dup], [1: 2, 8: 4]).toHash());
	writeln(tuple("hi", [[1: 2].keys.dup], [1: 2, 8: 4]).toHash());  
// same thing as above

}





We really _need_ something like this in Phobos IMHO.


Re: Why D is annoying =P

2012-10-24 Thread Mehrdad

On Wednesday, 24 October 2012 at 20:47:30 UTC, H. S. Teoh wrote:
Umm, the idea of a hash is to *quickly* compute a value that's 
(mostly) unique for a given object. In most cases, the bit 
representation is good enough.


I don't understand what you're saying.

hash(tuple("foo".dup))  MUST be equal to  hash(tuple("foo".dup")).

Bitwise hashing makes no sense whatsoever.


Re: Very simple SIMD programming

2012-10-24 Thread Manu
On 24 October 2012 18:12, jerro  wrote:

>  Simple example:
>>   T opCompound(string seq)(T a, T b, T c) if(seq == "* +") { return
>> _madd(a, b, c); }
>>
>
> It may be useful to have a way to define compound operators for other
> things (although you can already write expression templates), but this is
> an optimization that the compiler back end can do. If you compile this code:
>
> float4 foo(float4 a, float4 b, float4 c){ return a * b + c; }
>
> With gdc with flags -O2 -fma, you get:
>
>  <_**D3tmp3fooFNhG4fNhG4fNhG4fZNhG4**f>:
>0:   c4 e2 69 98 c1  vfmadd132ps xmm0,xmm2,xmm1
>5:   c3  ret
>

Right, I suspected GDC might do that, but it was just an example. You can
extend that to many more complicated scenarios.
What does it do on less mature architectures like MIPS, PPC, ARM?


Re: On D development

2012-10-24 Thread bearophile

Andrei Alexandrescu:


That fosters balkanization.

At this point in D's evolution I very strongly think it's the 
time to put to good use its many features, instead of making it 
any easier to add more. Constraints are liberating. Innovation 
can be found in the minds of people, and the thought that 
there's always a new feature that can be added instead of an 
innovative solution within the existing language stifles 
creativity.


We should also think what's the purpose of D development, that is 
what does it mean for D to be "successful".


Its adoption patterns in more than ten years let me think that 
maybe D can't aim at becoming a very widely used language.


For a lot of time (15-20 years) Haskell has shown to seek for 
other meanings of the word "success". And indeed the GHC Haskell 
compiler contains many (I count 70) language extensions, some of 
them are major features:


http://www.haskell.org/ghc/docs/7.2.1/html/users_guide/flag-reference.html#id639065

There is plenty of creativity in inventing, improving, 
implementing and using such extensions too :-)


Bye,
bearophile


Re: Normal/Gaussian random number generation for D

2012-10-24 Thread jerro
It looks like it should be readily possible to integrate the 
core Ziggurat functionality and to convert the normal() 
function in your code to be a NormalRandomNumberEngine struct


I already have a NormalDist struct at 
https://github.com/jerro/phobos/blob/new-api/std/random.d#L2363 - 
converting that should be trivial.




For the other distributions, my feeling is that in some cases 
there's a value in also having this "engine" approach, e.g. for 
exponentially-distributed numbers one could use Ziggurat or one 
could use the approach


T u = uniform!("[)", T, T, 
UniformRandomNumberGenerator)(0.0, 1.0, urng);

return -log(1 - u)/lambda;

... which is not as fast but has a much lower memory footprint.


I agree that the it's a good thing to design the API so that we 
can use different engines


Can you expand on this, and maybe provide a reference?  I don't 
doubt your code's effectiveness but I think where RNGs are 
concerned we really need to be able to justify our algorithmic 
choices.  There's too much literature out there showing how 
commonly-used algorithms actually carry statistical flaws.


I have only tested a distribution of the output samples, which 
seems to be correct. I agree that we should try to avoid 
statistical flaws as much as possible. Do you know of any good 
tests for nonuniform random number generators?


Bigger picture on my approach to non-uniform random number 
distributions.  The goal is to have the following:


* Where useful, it should be possible to define and use 
multiple different
  internal "engines" for generating random numbers from the 
given

  distribution

* For each distribution, there should be a function 
interface and a struct

  interface.

* The struct implementation should store the distribution 
parameters and an

  instance of the internal engine (if any).

* The function implementation should have 2 versions: one 
which allows the
  user to pass an engine of choice as input, one which 
contains a static
  instance of the specified engine (hence, thread-safe, 
distinguished
  according to both engine type and underlying uniform RNG 
type).


* ... unless there's no call for distinct underlying 
engines, in which case
  the function version just takes parameters and uniform 
RNG :-)


* The struct version should be useful to couple with an RNG 
instance to
  create an arbitrary random-number range à la Boost's 
variate_generator

  class.


Seems OK to me. Maybe the function that uses a static engine 
should have one version that takes Rng as a parameter and one 
that uses rndGen, similar to how uniform() works now?


How would the static engines be initialized? They could be 
initialized on first use, but this would slow sample generation a 
bit. Another options is to initialize them in the static 
constructor. I think it would be best to make the engine a static 
field of a struct template, and initialize it in the structs 
static constructor (similar to what my ZigguratTable struct 
does). That way you don't need to check if the engine is 
initialized every time you generate a sample and the engine isn't 
initialized unless the function template that uses it is 
instantiated.


So, a nice way to expand on our respective approaches might be 
to incorporate your Ziggurat, adapt it to my Normal engine API, 
and for me to write a similar setup for 
exponentially-distributed random numbers that uses the simple 
approach above and can also use your Ziggurat implementation.


What do you think?


I think we should do that. Do you already have some code 
somewhere where I can see it? I need to know what API the 
NormalRandomNumberEngine struct should have.


Re: Passing static arrays to C

2012-10-24 Thread bearophile

Andrej Mitrovic:

The issue you have opened is:
http://d.puremagic.com/issues/show_bug.cgi?id=8887



Have I covered everything?


The implementation of D associative arrays is opaque, so why is 
this allowed?


extern(C) void foo(int[int] aa);
void main() {}

Bye,
bearophile


Re: On D development

2012-10-24 Thread Andrei Alexandrescu

On 10/24/12 5:21 PM, bearophile wrote:

Andrei Alexandrescu:


That fosters balkanization.

At this point in D's evolution I very strongly think it's the time to
put to good use its many features, instead of making it any easier to
add more. Constraints are liberating. Innovation can be found in the
minds of people, and the thought that there's always a new feature
that can be added instead of an innovative solution within the
existing language stifles creativity.


We should also think what's the purpose of D development, that is what
does it mean for D to be "successful".

Its adoption patterns in more than ten years let me think that maybe D
can't aim at becoming a very widely used language.


This reasoning is flawed. We're talking about an evolving process, with 
a lot happening in the past couple of years.


Andrei




Re: Why D is annoying =P

2012-10-24 Thread Timon Gehr

On 10/24/2012 10:16 PM, Mehrdad wrote:

...

Maybe you can fill in the blanks?




import std.stdio;
struct Set(T){
int[T] dict;
hash_t toHash() const{
typeof(return) r = 0;
foreach(item; this.dict.keys){
r+=typeid(T).getHash(&item);
}
return r;
}
}



Re: Very simple SIMD programming

2012-10-24 Thread bearophile

Manu:

The compiler would have to do some serious magic to optimise 
that;
flattening both sides of the if into parallel expressions, and 
then applying the mask to combine...


I think it's a small amount of magic.

The simple features shown in that paper are fully focused on SIMD 
programming, so they aren't introducing things clearly not 
efficient.



I'm personally not in favour of SIMD constructs that are 
anything less than

optimal (but I appreciate I'm probably in the minority here).


(The simple benchmarks of the paper show a 5-15% performance 
loss compared

to handwritten SIMD code.)



Right, as I suspected.


15% is a very small performance loss, if for the programmer the 
alternative is writing scalar code, that is 2 or 3 times slower 
:-)


The SIMD programmers that can't stand a 1% loss of performance 
use the intrinsics manually (or write in asm) and they ignore all 
other things.


A much larger population of system programmers wish to use modern 
CPUs efficiently, but they don't have time (or skill, this means 
their programs are too much often buggy) for assembly-level 
programming. Currently they use smart numerical C++ libraries, 
use modern Fortran versions, and/or write C/C++ scalar code (or 
Fortran), add "restrict" annotations, and take a look at the 
produced asm hoping the modern compiler back-ends will vectorize 
it. This is not good enough, and it's far from a 15% loss.


This paper shows a third way, making such kind of programming 
simpler and approachable for a wider audience, with a small 
performance loss compared to handwritten code. This is what 
language designers do since 60+ years :-)


Bye,
bearophile


Re: Why D is annoying =P

2012-10-24 Thread Era Scarecrow

On Wednesday, 24 October 2012 at 19:41:42 UTC, Mehrdad wrote:

So you can't really write a real program in D, to put it blunty.


 So should I drop a project I'm working on and go to C++? That 
isn't something I look forward to doing...





Re: Passing static arrays to C

2012-10-24 Thread Andrej Mitrovic
On 10/24/12, bearophile  wrote:
> Andrej Mitrovic:
>
> The issue you have opened is:
> http://d.puremagic.com/issues/show_bug.cgi?id=8887

And pull https://github.com/D-Programming-Language/dmd/pull/1215

> The implementation of D associative arrays is opaque, so why is
> this allowed?
>
> extern(C) void foo(int[int] aa);
> void main() {}

Well this is less dangerous than the OP case, but maybe it should be
disallowed. Another bug should be opened for this.


Re: Why D is annoying =P

2012-10-24 Thread Timon Gehr

On 10/24/2012 09:41 PM, Mehrdad wrote:

...
So you can't really write a real program in D, to put it blunty.


Yes I can.


  1   2   >