Re: floats default to NaN... why?

2012-04-14 Thread F i L

Jonathan M Davis wrote:
No. You always have a bug if you don't initialize a variable to 
the value that
it's supposed to be. It doesn't matter whether it's 0, NaN, 
527.1209823, or
whatever. All having a default value that you're more likely to 
use means is
that you're less likely to have to explicitly initialize the 
variable. It has

to be initialized to the correct value regardless.


Yes, I'm in favor of default values. That's not my argument here. 
I'm saying it makes more sense to have the default values be 
_usable_ (for convenience) rather than designed to catch 
(**cause**) bugs.




And if you're in the habit
of always initializing variables and never relying on the 
defaults if you can

help it,


That seams like a very annoying habit requirement for a languages 
with a focus on "modern convenience". What's more bug prone, I 
think, is forcing developers to remember that unset floats 
(specifically) will cause bugs while it's neighboring int works 
perfectly without a explicit value.



then the cases where variables weren't initialized to what they 
were

supposed to be stand out more.


Usable defaults don't need to stand out because they're usable 
and deterministic. If you want to make sure a constructor/method 
produces expected results, unittest it.. it makes more sense to 
catch errors at compile time anyways.






D's approach is to say that
it's _still_ a bug to not initialize a variable, since you 
almost always need

to initialize a variable to something _other_ than a default.


Not always, but that's besides the point. The point is that in 
the places where you do want zero values (Vector/Matrix/etc, 
Polygon structs, counters, etc..) it's better to have consistent 
expected behavior from the default value. Not some value that 
causes runtime bugs.




I don't see how it's an
issue, since you almost always need to initialize variables to 
something other
than the default, and so leaving them as the default is almost 
always a bug.


To me, it's not a huge issue, only an annoyance. However I 
wouldn't underestimate the impact of bad marketing. When people 
are trying out the language, and they read "variables are 
defaulted, not garbage" do you think they're going to expect ints 
and floats to work in different ways?


And it doesn't cause bugs to default value types to zero. I have 
enough experience with C# to know that it doesn't. All it does is 
make the language more consistent.



The only point of dispute that I see in general is whether it's 
better to rely
on the default or to still explicitly initialize it when you 
actually want the

default.


This sounds like an argument for C++. Explicit declaration isn't 
a guard against bugs, you'll still be hunting through code if 
something is incorrectly set.


The fact of the matter is default initialization _does_ happen in 
code, no matter how philosophically correct "always explicitly 
define value" might be. Unless that's enforced, it can and should 
be expected to happen. That given, it's more convenient to have 
consistent value type behavior. Float is a Value type and 
shouldn't be subjective to the security concerns of Reference 
types.



Regardless, the _entire_ reason for default-initialization in D 
revolves
around making buggy initializations deterministic and more 
detectable.


The same way string, and int are defaulted to usable values, 
float should be as well. Catching code that works with null 
pointers is one thing. Working with a value type without 
requiring the programmer have deeper knowledge about D's 
asymmetrical features is another.


If D doesn't accommodate entering Laymen, how does it expect to 
gain popularity in any major way? Efficiency puts D on the map, 
convenience is what brings the tourists.


I'm not trying to convince you that the sky is falling because I 
disagree with D's direction with floats.. just if the goal is to 
increase D's popularity, little things may turn heads away 
quicker than you think. My original post was inspired by me 
showing my D code to another C# guy earlier, and coming up with 
poor explanations as to why floats where required to be defaulted 
in my math lib. His reaction what along the lines of my first 
post.


Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 06:43:11 UTC, Manfred Nowak wrote:

F i L wrote:


It sounds like circular reasoning.


Several considerations pressed the design into the current form:
1) always changing output on unchanged input is hard to debug
2) GC needs to be saved from garbage, that looks like pointers
3) missed explicit initializations should not create syntax 
errors

4) use hardware signalling to overcome some of the limitations
impressed by 3).
5) more???

For me the only questionable point is numer three.

-manfred


1) Good argument.
2) Don't know enough about the GC. Can't comment.
3) I agree. I just disagree with how they are expected to be used 
without explicit definition.

4) I have no idea what you just said... :)
5) profit??


Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 06:29:40 UTC, Ali Çehreli wrote:

On 04/13/2012 09:00 PM, F i L wrote:

> default is NaN

Just to complete the picture, character types have invalid 
initial values as well: 0xFF, 0x, and 0x for char, 
wchar, and dchar, respectively.


Ali


That's interesting, but what effect does appending an invalid 
char to a valid one have? Does the resulting string end up being 
"NaS" (Not a String)? Cause if not, I'm not sure that's a fair 
comparison.


Re: floats default to NaN... why?

2012-04-14 Thread Jonathan M Davis
On Saturday, April 14, 2012 09:45:57 F i L wrote:
> If D doesn't accommodate entering Laymen, how does it expect to
> gain popularity in any major way? Efficiency puts D on the map,
> convenience is what brings the tourists.

I believe that you are the first person that I have ever heard complain that D 
tries to default to error values. I think that some have asked why the types 
default to what they default to, but it's not something that people normally 
complain about. I've explained the reasoning behind it. You can like it or 
not, but as far as I can tell, this is a complete non-issue.

- Jonathan M Davis


Re: floats default to NaN... why?

2012-04-14 Thread Jonathan M Davis
On Saturday, April 14, 2012 09:58:42 F i L wrote:
> On Saturday, 14 April 2012 at 06:29:40 UTC, Ali Çehreli wrote:
> > On 04/13/2012 09:00 PM, F i L wrote:
> > > default is NaN
> > 
> > Just to complete the picture, character types have invalid
> > initial values as well: 0xFF, 0x, and 0x for char,
> > wchar, and dchar, respectively.
> > 
> > Ali
> 
> That's interesting, but what effect does appending an invalid
> char to a valid one have? Does the resulting string end up being
> "NaS" (Not a String)? Cause if not, I'm not sure that's a fair
> comparison.

You can't append a char to a char. You can append them to strings, but not 
each other.

Appending an invalid char results in a string with an invalid char. It won't 
blow up on its own. But any function which attempts to decode the string 
(which includes the vast majority of functions which would be called on a 
string) would result in a UTFException. So, you'll generally know that you 
have a bad string very quickly.

- Jonathan M Davis


Re: floats default to NaN... why?

2012-04-14 Thread F i L
On Saturday, 14 April 2012 at 07:59:25 UTC, Jonathan M Davis 
wrote:

On Saturday, April 14, 2012 09:45:57 F i L wrote:

If D doesn't accommodate entering Laymen, how does it expect to
gain popularity in any major way? Efficiency puts D on the map,
convenience is what brings the tourists.


I believe that you are the first person that I have ever heard 
complain that D
tries to default to error values. I think that some have asked 
why the types
default to what they default to, but it's not something that 
people normally
complain about. I've explained the reasoning behind it. You can 
like it or

not, but as far as I can tell, this is a complete non-issue.


Well my testimonial evidence against yours, eh? :) I'm not trying 
to get under anyone's skin here. You've explained the logic 
behind the decision and I think I've made some valid points 
against that logic. You obviously don't feel like arguing the 
point further, so I'll just leave it at that.





Re: floats default to NaN... why?

2012-04-14 Thread Silveri

On Saturday, 14 April 2012 at 07:52:51 UTC, F i L wrote:

On Saturday, 14 April 2012 at 06:43:11 UTC, Manfred Nowak wrote:

F i L wrote:

4) use hardware signalling to overcome some of the limitations
impressed by 3).


4) I have no idea what you just said... :)


On Saturday, 14 April 2012 at 07:58:44 UTC, F i L wrote:
That's interesting, but what effect does appending an invalid 
char to a valid one have? Does the resulting string end up 
being "NaS" (Not a String)? Cause if not, I'm not sure that's a 
fair comparison.


The initialization values chosen are also determined by the 
underlying hardware implementation of the type. Signalling NANs 
(http://en.wikipedia.org/wiki/NaN#Signaling_NaN) can be used with 
floats because they are implemented by the CPU, but in the case 
of integers or strings their aren't really equivalent values.


On Saturday, 14 April 2012 at 07:45:58 UTC, F i L wrote:
My original post was inspired by me showing my D code to 
another C# guy earlier, and coming up with poor explanations as 
to why floats where required to be defaulted in my math lib. 
His reaction what along the lines of my first post.


I think the correct mindset when working in D is to think that 
"all variables should be initialized" and if you get incorrect 
calculations with zero values, division by zero errors or nan 
errors the most likely mistake is often that this guideline was 
not followed.




Re: floats default to NaN... why?

2012-04-14 Thread dennis luehring

Am 14.04.2012 07:48, schrieb F i L:

On Saturday, 14 April 2012 at 05:19:38 UTC, dennis luehring wrote:

 Am 14.04.2012 06:00, schrieb F i L:

  struct Foo {
int x, y;// ready for use.
float z, w;  // messes things up.
float r = 0; // almost always...
  }


 how often in your code is 0 or 0.0 the real starting point?
 i can't think of any situation except counters or something
 where 0 is a proper start - and float 0.0 is in very very few
 cases a normal start - so whats your point?


Every place that a structure property is designed to be mutated
externally. Almost all Math structures, for instance.


if a float or double is initalized with nan - all operations on them 
will result to nan - that is a very good sign for missing "proper" 
initialisation


what does make float default to 0.0 better - does it just feel better?


"shared" status

2012-04-14 Thread Luis Panadero Guardeño
What is the status of "shared" types ?

I try it with gdmd v4.6.3
And I not get any warring/error when I do anything over a shared variable 
without using atomicOp. It's normal ?

shared ushort ram[ram_size];


ram[i] = cast(ushort) (bytes[0] | bytes[1] << 8);

-- 
I'm afraid that I have a blog: http://zardoz.es 


Re: floats default to NaN... why?

2012-04-14 Thread Jerome BENOIT



On 14/04/12 09:45, F i L wrote:

Jonathan M Davis wrote:

No. You always have a bug if you don't initialize a variable to the value that
it's supposed to be. It doesn't matter whether it's 0, NaN, 527.1209823, or
whatever. All having a default value that you're more likely to use means is
that you're less likely to have to explicitly initialize the variable. It has
to be initialized to the correct value regardless.


Yes, I'm in favor of default values. That's not my argument here. I'm saying it 
makes more sense to have the default values be _usable_ (for convenience) 
rather than designed to catch (**cause**) bugs.



Why would a compiler set `real' to 0.0 rather then 1.0, Pi,  ?
The more convenient default set certainly depends on the underlying mathematics,
and a compiler  cannot (yet) understand the encoded mathematics.
NaN is certainly the certainly the very choice as whatever the involved 
mathematics,
they will blow up sooner or later. And, from a practical point of view, blowing 
up
is easy to trace.





Re: floats default to NaN... why?

2012-04-14 Thread bearophile

F i L:


So basically, it's for debugging?


To avoid bugs it's useful for all variables to be initialized 
before use (maybe with an explicit annotation for the uncommon 
cases where you want to use uninitialized memory, like: 
http://research.swtch.com/sparse ). Having a variable not 
initialized is a common source of bugs.


C# solves this requiring explicit initialization all variables 
before use. Walter doesn't believe that flow analysis is flexible 
enough in a system language like D (or he doesn't want to 
implement it) so he has not used this idea in D.


So D uses a different worse strategy, it initializes the 
variables to something unusable, so if you try to use them, your 
program fails clearly.


The idea of setting the variables to something useful, like 
setting initialized chars to 'a' and floating point values to 0.0 
looks handy, but on the long run it's not an improvement. You 
sometimes don't initialize a char variable because you are fine 
for it to be 'a', and some other times you don't set it just 
because you forget to initialize it. The compiler can't tell 
apart the two cases, and this is may be a bug in your code.


In practice I think having FP variables initialized to NaN has 
not avoided me significant bugs in the last years. On the other 
hand I have ported some C code that uses global floating point 
arrays/variables to D, and I have had to remove some bugs caused 
by the assumption in the C code that those global FP variables 
are initialized to zero, that's false in D.


Another source of troubles is large fixed-sized FP global arrays, 
that inflate the binary a *lot*. You have to remember to 
initialize them to zero explicitly:


double[100_000] foo; // bad, inflates binary.
double[100_000] bar = 0.0; // good.
void main() {}

In D I'd like the solution used by C# + an annotation to not 
initialize a variable or array.


Bye,
bearophile


Re: floats default to NaN... why?

2012-04-14 Thread Andrej Mitrovic
On 4/14/12, bearophile  wrote:
> Having a variable not initialized is a common source of bugs.

I'm going to argue that this was true for C/C++ but is much less true
for D. One benefit of having integrals initialized to 0 is that you
now have a defined default that you can rely on (just as you can rely
on pointers being null by default). Personally I find this to be a big
win in productivity. If the language/runtime does something defined
for me then I can focus on more important things.

But NaN might be a good thing for all I know.. I rarely use
floating-point so I'll stay out of that, but I'd like to have this
fixed: http://d.puremagic.com/issues/show_bug.cgi?id=6303


Re: floats default to NaN... why?

2012-04-14 Thread F i L

Jerome BENOIT wrote:
Why would a compiler set `real' to 0.0 rather then 1.0, Pi, 
 ?


Because 0.0 is the "lowest" (smallest, starting point, etc..) 
numerical value. Pi is the corner case and obviously has to be 
explicitly set.


If you want to take this further, chars could even be initialized 
to spaces or newlines or something similar. Pointers/references 
need to be defaulted to null because they absolutely must equal 
an explicit value before use. Value types don't share this 
limitation.


The more convenient default set certainly depends on the 
underlying mathematics,

and a compiler  cannot (yet) understand the encoded mathematics.
NaN is certainly the certainly the very choice as whatever the 
involved mathematics,
they will blow up sooner or later. And, from a practical point 
of view, blowing up is easy to trace.


Zero is just as easy for the runtime/compiler to default to; and 
bugs can be introduce anywhere in the code, not just definition. 
We have good ways of catching these bugs in D with unittests 
already.


Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 10:38:45 UTC, Silveri wrote:

On Saturday, 14 April 2012 at 07:52:51 UTC, F i L wrote:
On Saturday, 14 April 2012 at 06:43:11 UTC, Manfred Nowak 
wrote:

F i L wrote:

4) use hardware signalling to overcome some of the limitations
impressed by 3).


4) I have no idea what you just said... :)


On Saturday, 14 April 2012 at 07:58:44 UTC, F i L wrote:
That's interesting, but what effect does appending an invalid 
char to a valid one have? Does the resulting string end up 
being "NaS" (Not a String)? Cause if not, I'm not sure that's 
a fair comparison.


The initialization values chosen are also determined by the 
underlying hardware implementation of the type. Signalling NANs 
(http://en.wikipedia.org/wiki/NaN#Signaling_NaN) can be used 
with floats because they are implemented by the CPU, but in the 
case of integers or strings their aren't really equivalent 
values.


I'm sure the hardware can just as easily signal zeros.



On Saturday, 14 April 2012 at 07:45:58 UTC, F i L wrote:
My original post was inspired by me showing my D code to 
another C# guy earlier, and coming up with poor explanations 
as to why floats where required to be defaulted in my math 
lib. His reaction what along the lines of my first post.


I think the correct mindset when working in D is to think that 
"all variables should be initialized" and if you get incorrect 
calculations with zero values, division by zero errors or nan 
errors the most likely mistake is often that this guideline was 
not followed.


Like I said before, this is backwards thinking. At the end of the 
day, you _can_ use default values in D. Given that ints are 
defaulted to usable values, FP Values should be as well for the 
sake of consistency and convenience.


You can't force new D programmers to follow a 'guidline' no 
matter how loudly the documentation shouts it (which is barely 
does at this point), so said guideline is not a dependable 
practice all D will follow (unless it's statically enforced)... 
nor _should_ the learning curve be steepened by enforcing 
awareness of this idiosyncrasy.


The correct mindset from the compilers perspective should be: 
"people create variables to use them. What do they want if they 
didn't specify a value?"


therefor our mindset can be: "I defined a variable to use. Should 
be zero so I don't need to set it."


Re: floats default to NaN... why?

2012-04-14 Thread F i L

dennis luehring wrote:
what does make float default to 0.0 better - does it just feel 
better?


Not just. It's consistent with Int types, therefor easier for 
newbs to pick up since all numeric value types behave the same.


I even think char should default to a usable value as well. Most 
likely a space character. But that's another point.




Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 12:48:01 UTC, Andrej Mitrovic wrote:

On 4/14/12, bearophile  wrote:

Having a variable not initialized is a common source of bugs.


I'm going to argue that this was true for C/C++ but is much 
less true
for D. One benefit of having integrals initialized to 0 is that 
you
now have a defined default that you can rely on (just as you 
can rely
on pointers being null by default). Personally I find this to 
be a big
win in productivity. If the language/runtime does something 
defined

for me then I can focus on more important things.


Amen! This is exactly what I'm trying to get at. The compiler 
provides defaults as a convince feature (mostly) so that there's 
no garbage and so values are reliable. It's incredibly 
inconvenient at that point to have to remember to always 
explicitly init one specific type..


This feels very natural in C#.


Re: floats default to NaN... why?

2012-04-14 Thread Andrej Mitrovic
On 4/14/12, F i L  wrote:
> This is exactly what I'm trying to get at.

Anyway it's not all bad news since we can use a workaround:

struct Float {
float payload = 0.0;
alias payload this;
}

void main() {
Float x;  // acts as a float, is initialized to 0.0
}

Not pretty, but it comes in handy.


Re: floats default to NaN... why?

2012-04-14 Thread Jerome BENOIT



On 14/04/12 16:47, F i L wrote:

Jerome BENOIT wrote:

Why would a compiler set `real' to 0.0 rather then 1.0, Pi,  ?


Because 0.0 is the "lowest" (smallest, starting point, etc..)


quid -infinity ?

numerical value. Pi is the corner case and obviously has to be explicitly set.


If you want to take this further, chars could even be initialized to spaces or 
newlines or something similar. Pointers/references need to be defaulted to null 
because they absolutely must equal an explicit value before use. Value types 
don't share this limitation.



CHAR set are bounded, `real' are not.



The more convenient default set certainly depends on the underlying mathematics,
and a compiler cannot (yet) understand the encoded mathematics.
NaN is certainly the certainly the very choice as whatever the involved 
mathematics,
they will blow up sooner or later. And, from a practical point of view, blowing 
up is easy to trace.


Zero is just as easy for the runtime/compiler to default to;


Fortran age is over.
D compiler contains a lot of features that are not easy to set up by the 
compiler BUT meant for easing coding.


 and bugs can be introduce anywhere in the code, not just definition.

so the NaN approach discard one source of error.

 We have good ways of catching these bugs in D with unittests already.

Zero may give a value that sounds reasonable, NaN will give a NaN value ... 
which is not reasonable: this is NaN blow up and it can been seen right the way.

Note that the NaN approach is used in some numerical libraries as CLN.



Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 15:44:46 UTC, Jerome BENOIT wrote:



On 14/04/12 16:47, F i L wrote:

Jerome BENOIT wrote:
Why would a compiler set `real' to 0.0 rather then 1.0, Pi, 
 ?


Because 0.0 is the "lowest" (smallest, starting point, etc..)


quid -infinity ?


The concept of zero is less meaningful than -infinity. Zero is 
the logical starting place because zero represents nothing 
(mathematically), which is inline with how pointers behave (only 
applicable to memory, not scale).



numerical value. Pi is the corner case and obviously has to be 
explicitly set.


If you want to take this further, chars could even be 
initialized to spaces or newlines or something similar. 
Pointers/references need to be defaulted to null because they 
absolutely must equal an explicit value before use. Value 
types don't share this limitation.




CHAR set are bounded, `real' are not.


Good point, I'm not so convinced char should default to " ". I 
think there are arguments either way, I haven't given it much 
thought.



The more convenient default set certainly depends on the 
underlying mathematics,
and a compiler cannot (yet) understand the encoded 
mathematics.
NaN is certainly the certainly the very choice as whatever 
the involved mathematics,
they will blow up sooner or later. And, from a practical 
point of view, blowing up is easy to trace.


Zero is just as easy for the runtime/compiler to default to;


Fortran age is over.
D compiler contains a lot of features that are not easy to set 
up by the compiler BUT meant for easing coding.



 and bugs can be introduce anywhere in the code, not just 
definition.


so the NaN approach discard one source of error.


Sure, the question then becomes "does catching bugs introduced by 
inaccurately defining a variable outweigh the price of 
inconsistency and learning curve." My opinion is No, expected 
behavior is more important. Especially when I'm not sure I've 
ever heard of someone in C# having bugs that would have been 
helped by defaulting to NaN. I mean really, how does:


float x; // NaN
...
x = incorrectValue;
...
foo(x); // first time x is used

differ from:

float x = incorrectValue;
...
foo(x);

in any meaning full way? Except that in this one case:

float x; // NaN
...
foo(x); // uses x, resulting in NaNs
...
x = foo(x); // sets after first time x is used

you'll get a "more meaningful" error message, which, assuming you 
didn't just write a ton of FP code, you'd be able to trace to 
it's source faster.


It just isn't enough to justify defaulting to NaN, IMO. I even 
think the process of hunting down bugs is more straight forward 
when defaulting to zero, because every numerical bug is pursued 
the same way, regardless of type. You don't have to remember that 
FP specifically causes this issues in only some cases.


Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 15:35:13 UTC, Andrej Mitrovic wrote:

On 4/14/12, F i L  wrote:

This is exactly what I'm trying to get at.


Anyway it's not all bad news since we can use a workaround:

struct Float {
float payload = 0.0;
alias payload this;
}

void main() {
Float x;  // acts as a float, is initialized to 0.0
}

Not pretty, but it comes in handy.


Lol, that's kinda an interesting idea:

struct var(T, T def) {
T payload = def;
alias payload this;
}

alias var!(float,  0.0f) Float;
alias var!(double, 0.0)  Double;
alias var!(real,   0.0)  Real;
alias var!(char,   ' ')  Char;

void main() {
Float f;
assert(f == 0.0f);
}

a Hack though, since it doesn't work with 'auto'. I still think 
it should be the other way around, and this should be used to 
Default to NaN.


Re: floats default to NaN... why?

2012-04-14 Thread Andrej Mitrovic
On 4/14/12, F i L  wrote:
> a Hack though, since it doesn't work with 'auto'.

What do you mean?


Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 17:30:19 UTC, Andrej Mitrovic wrote:

On 4/14/12, F i L  wrote:

a Hack though, since it doesn't work with 'auto'.


What do you mean?


Only that:

auto f = 1.0f; // is float not Float


Re: floats default to NaN... why?

2012-04-14 Thread Andrej Mitrovic
On 4/14/12, F i L  wrote:
>  auto f = 1.0f; // is float not Float

UFCS in 2.059 to the rescue:

struct Float
{
float payload = 0.0;
alias payload this;
}

@property Float f(float val) { return Float(val); }

void main()
{
auto f = 1.0.f;
}


Re: floats default to NaN... why?

2012-04-14 Thread Jerome BENOIT



On 14/04/12 18:38, F i L wrote:

On Saturday, 14 April 2012 at 15:44:46 UTC, Jerome BENOIT wrote:



On 14/04/12 16:47, F i L wrote:

Jerome BENOIT wrote:

Why would a compiler set `real' to 0.0 rather then 1.0, Pi,  ?


Because 0.0 is the "lowest" (smallest, starting point, etc..)


quid -infinity ?


The concept of zero is less meaningful than -infinity. Zero is the logical 
starting place because zero represents nothing (mathematically)


zero is not nothing in mathematics, on the contrary !

0 + x = 0 // neutral for addition
0 * x = 0 // absorbing for multiplication
0 / x = 0 if  (x <> 0) // idem
| x / 0 | = infinity if (x <> 0)
0 / 0 = NaN // undefined


, which is inline with how pointers behave (only applicable to memory, not 
scale).

pointer value are also bounded.





numerical value. Pi is the corner case and obviously has to be explicitly set.


If you want to take this further, chars could even be initialized to spaces or 
newlines or something similar. Pointers/references need to be defaulted to null 
because they absolutely must equal an explicit value before use. Value types 
don't share this limitation.



CHAR set are bounded, `real' are not.


Good point, I'm not so convinced char should default to " ". I think there are 
arguments either way, I haven't given it much thought.



The more convenient default set certainly depends on the underlying mathematics,
and a compiler cannot (yet) understand the encoded mathematics.
NaN is certainly the certainly the very choice as whatever the involved 
mathematics,
they will blow up sooner or later. And, from a practical point of view, blowing 
up is easy to trace.


Zero is just as easy for the runtime/compiler to default to;


Fortran age is over.
D compiler contains a lot of features that are not easy to set up by the 
compiler BUT meant for easing coding.


and bugs can be introduce anywhere in the code, not just definition.

so the NaN approach discard one source of error.


Sure, the question then becomes "does catching bugs introduced by inaccurately 
defining a variable outweigh the price of inconsistency and learning curve."  My 
opinion is No, expected behavior is more important.


From a numerical point of view, zero is not a good default (see above), and as 
such setting 0.0 as default for real is not an expected behaviour.
Considering the NaN blow up behaviour, for a numerical folk the expected 
behaviour is certainly setting NaN as default for real.
Real number are not meant here for coders, but for numerical folks: D applies 
here a rule gain along experiences from numerical people.
So your opinion is good, but you misplaced the inconsistency: 0 is inaccurate 
here and NaN is accurate, not the contrary.

 Especially when I'm not sure I've ever heard of someone in C# having bugs that 
would have been helped by defaulting to NaN. I mean really, how does:


float x; // NaN
...
x = incorrectValue;
...
foo(x); // first time x is used

differ from:

float x = incorrectValue;
...
foo(x);

in any meaning full way? Except that in this one case:

float x; // NaN
...
foo(x); // uses x, resulting in NaNs
...
x = foo(x); // sets after first time x is used

you'll get a "more meaningful" error message, which, assuming you didn't just 
write a ton of FP code, you'd be able to trace to it's source faster.

It just isn't enough to justify defaulting to NaN, IMO. I even think the 
process of hunting down bugs is more straight forward when defaulting to zero, 
because every numerical bug is pursued the same way, regardless of type. You 
don't have to remember that FP specifically causes this issues in only some 
cases.


For numerical works, because 0 behaves nicely most of the time, non properly 
initialized variables may not detected because the output data can sound 
resoneable;
on the other hand, because NaN blows up, such detection is straight forward: 
the output will be a NaN output which will jump to your face very quickly.
This is a numerical issue, not a coding language issue. Personally in my C 
code, I have taken the habit to initialise real numbers (doubles) with NaN:
in the GSL library there is a ready to use macro: GSL_NAN. (Concerning, 
integers I used extreme value as INT_MIN, INT_MAX, SIZE_MAX. ...).
I would even say that D may go further by setting a kind of NaN for integers 
(and for chars).


Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 18:02:57 UTC, Andrej Mitrovic wrote:

On 4/14/12, F i L  wrote:

 auto f = 1.0f; // is float not Float


UFCS in 2.059 to the rescue:

struct Float
{
float payload = 0.0;
alias payload this;
}

@property Float f(float val) { return Float(val); }

void main()
{
auto f = 1.0.f;
}


You're a scholar and and gentlemen!


Calling delegate properties without parens

2012-04-14 Thread Piotr Szturmaj

I have following code:

import std.array, std.range, std.stdio;

struct CommonInputRange(E)
{
@property bool delegate() empty;
@property E delegate() front;
void delegate() popFront;
}

void main(string[] args)
{
alias CommonInputRange!dchar DCRange;
static assert(isInputRange!DCRange);
DCRange dc;
auto dcr = "abcdefg";
auto t = dcr.takeExactly(3);
dc.empty = &t.empty;
dc.front = &t.front;
dc.popFront = &t.popFront;

for ( ; !dc.empty(); dc.popFront())
writeln(dc.front());
}

As you can see in the for loop, range primitives must be called using 
parens (), otherwise they don't work.


Do you know if there are plans to implement @property for delegates and 
function pointers?


Re: floats default to NaN... why?

2012-04-14 Thread F i L

On Saturday, 14 April 2012 at 18:07:41 UTC, Jerome BENOIT wrote:

On 14/04/12 18:38, F i L wrote:
On Saturday, 14 April 2012 at 15:44:46 UTC, Jerome BENOIT 
wrote:

On 14/04/12 16:47, F i L wrote:

Jerome BENOIT wrote:
Why would a compiler set `real' to 0.0 rather then 1.0, Pi, 
 ?


Because 0.0 is the "lowest" (smallest, starting point, etc..)


quid -infinity ?


The concept of zero is less meaningful than -infinity. Zero is 
the logical starting place because zero represents nothing 
(mathematically)


zero is not nothing in mathematics, on the contrary !

0 + x = 0 // neutral for addition
0 * x = 0 // absorbing for multiplication
0 / x = 0 if  (x <> 0) // idem
| x / 0 | = infinity if (x <> 0)


Just because mathematical equations behave differently with zero 
doesn't change the fact that zero _conceptually_ represents 
"nothing"


It's default for practical reason. Not for mathematics sake, but 
for the sake of convenience. We don't all study higher 
mathematics but we're all taught to count since we where 
toddlers. Zero makes sense as the default, and is compounded by 
the fact that Int *must* be zero.



0 / 0 = NaN // undefined


Great! Yet another reason to default to zero. That way, "0 / 0" 
bugs have a very distinct fingerprint.



, which is inline with how pointers behave (only applicable to 
memory, not scale).


pointer value are also bounded.


I don't see how that's relevant.


Considering the NaN blow up behaviour, for a numerical folk the 
expected behaviour is certainly setting NaN as default for real.
Real number are not meant here for coders, but for numerical 
folks:


Of course FP numbers are meant for coders... they're in a 
programming language. They are used by coders, and not every 
coder that uses FP math *has* to be well trained in the finer 
points of mathematics simply to use a number that can represent 
fractions in a conceptually practical way.



D applies here a rule gain along experiences from numerical 
people.


I'm sorry I can't hear you over the sound of how popular Java and 
C# are. Convenience is about productivity, and that's largely 
influence by how much prior knowledge someone needs before being 
able to understand a features behavior.


(ps. if you're going to use Argumentum ad Verecundiam, I get to 
use Argumentum ad Populum).



For numerical works, because 0 behaves nicely most of the time, 
non properly initialized variables may not detected because the 
output data can sound resoneable;
on the other hand, because NaN blows up, such detection is 
straight forward: the output will be a NaN output which will 
jump to your face very quickly.


I gave examples which address this. This behavior is only 
[debatably] beneficial in corner cases on FP numbers 
specifically. I don't think that sufficient justification in 
light of reasons I give above.




This is a numerical issue, not a coding language issue.


No, it's both. We're not Theoretical physicists we're Software 
Engineers writing a very broad scope of different programs.



Personally in my C code, I have taken the habit to initialise 
real numbers (doubles) with NaN:
in the GSL library there is a ready to use macro: GSL_NAN. 
(Concerning, integers I used extreme value as INT_MIN, INT_MAX, 
SIZE_MAX. ...).


Only useful because C defaults to garbage.


I would even say that D may go further by setting a kind of NaN 
for integers (and for chars).


You may get your with if Arm64 takes over.


Re: floats default to NaN... why?

2012-04-14 Thread Andrej Mitrovic
On 4/14/12, Jerome BENOIT  wrote:
> I would even say that D may go further by setting a kind of NaN for integers.

That's never going to happen.


Re: floats default to NaN... why?

2012-04-14 Thread Manfred Nowak
F i L wrote:

> You can't force new D programmers to follow a 'guidline'

By exposing a syntax error for every missed explicit initialization the 
current guideline would be changed into an insurmountable barrier, 
forcing every "new D programmers to follow" the 'guidline'.

-manfred


D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread ReneSac
I have this simple binary arithmetic coder in C++ by Mahoney and 
translated to D by Maffi. I added "notrow", "final" and "pure"  
and "GC.disable" where it was possible, but that didn't made much 
difference. Adding "const" to the Predictor.p() (as in the C++ 
version) gave 3% higher performance. Here the two versions:


http://mattmahoney.net/dc/  <-- original zip

http://pastebin.com/55x9dT9C  <-- Original C++ version.
http://pastebin.com/TYT7XdwX  <-- Modified D translation.

The problem is that the D version is 50% slower:

test.fpaq0 (16562521 bytes) -> test.bmp (33159254 bytes)

Lang| Comp  | Binary size | Time (lower is better)
C++  (g++)  -  13kb   -  2.42s  (100%)   -O3 -s
D(DMD)  - 230kb   -  4.46s  (184%)   -O -release -inline
D(GDC)  -1322kb   -  3.69s  (152%)   -O3 -frelease -s


The only diference I could see between the C++ and D versions is 
that C++ has hints to the compiler about which functions to 
inline, and I could't find anything similar in D. So I manually 
inlined the encode and decode functions:


http://pastebin.com/N4nuyVMh  - Manual inline

D(DMD)  - 228kb   -  3.70s  (153%)   -O -release -inline
D(GDC)  -1318kb   -  3.50s  (144%)   -O3 -frelease -s

Still, the D version is slower. What makes this speed diference? 
Is there any way to side-step this?


Note that this simple C++ version can be made more than 2 times 
faster with algoritimical and io optimizations, (ab)using 
templates, etc. So I'm not asking for generic speed 
optimizations, but only things that may make the D code "more 
equal" to the C++ code.


A "general" tag

2012-04-14 Thread Xan

Hi,

I try to translate a script I wrote in Fantom [www.fantom.org]. 
In my script, I have a type "Tag" defined as a triple of:

- String (the name of the tag),
- Type (the type of the tag: could be Str, Date, Int, etc.)
- Obj (the value of the tag; Fantom has Objects of Top-Class 
hierachy).


(normally the tag has Type = Obj.Type, but you can manually set).

For example,
you could have:
(name, Str#, "John")

or

(date, Date#, 2011-09-02)


(# is the Fantom way for specifying type: Str# is the sys::Str 
type)



Is there any way for emulating this? My main trouble is how to 
define Type and Object in D.


Thanks in advance,
Xan.

PS: Please, be patient, I'm a newbee.


Re: floats default to NaN... why?

2012-04-14 Thread Joseph Rushton Wakeling

On 14/04/12 16:52, F i L wrote:

The initialization values chosen are also determined by the underlying
hardware implementation of the type. Signalling NANs
(http://en.wikipedia.org/wiki/NaN#Signaling_NaN) can be used with floats
because they are implemented by the CPU, but in the case of integers or
strings their aren't really equivalent values.


I'm sure the hardware can just as easily signal zeros.


The point is not that the hardware can't deal with floats initialized to zero. 
The point is that the hardware CAN'T support an integer equivalent of NaN.  If 
it did, D would surely use it.



Like I said before, this is backwards thinking. At the end of the day, you
_can_ use default values in D. Given that ints are defaulted to usable values,
FP Values should be as well for the sake of consistency and convenience.


Speaking as a new user (well, -ish), my understanding of D is that its design 
philosophy is that _the easy thing to do should be the safe thing to do_, and 
this concept is pervasive throughout the design of the whole language.


So, ideally (as bearophile says) you'd compel the programmer to explicitly 
initialize variables before using them, or explicitly specify that they are not 
being initialized deliberately.  Enforcing that may be tricky (most likely not 
impossible, but tricky, and there are bigger problems to solve for now), so the 
next best thing is to default-initialize variables to something that will scream 
at you "THIS IS WRONG!!" when the program runs, and so force you to correct the 
error.


For floats, that means NaN.  For ints, the best thing you can do is zero.  It's 
a consistent decision -- not consistent as you frame it, but consistent with the 
language design philosophy.



You can't force new D programmers to follow a 'guidline' no matter how loudly 
the documentation shouts it


No, but you can drop very strong hints as to good practice.  Relying on default 
values for variables is bad programming.  The fact that it is possible with 
integers is a design fault forced on the language by hardware constraints.  As a 
language designer, do you compound the fault by making floats also init to 0 or 
do you enforce good practice in a way which will probably make the user 
reconsider any assumptions they may have made for ints?


Novice programmers need support, but support should not extend to pandering to 
bad habits which they would be better off unlearning (or never learning in the 
first place).


Re: floats default to NaN... why?

2012-04-14 Thread Jerome BENOIT



On 14/04/12 20:51, F i L wrote:

On Saturday, 14 April 2012 at 18:07:41 UTC, Jerome BENOIT wrote:

On 14/04/12 18:38, F i L wrote:

On Saturday, 14 April 2012 at 15:44:46 UTC, Jerome BENOIT wrote:

On 14/04/12 16:47, F i L wrote:

Jerome BENOIT wrote:

Why would a compiler set `real' to 0.0 rather then 1.0, Pi,  ?


Because 0.0 is the "lowest" (smallest, starting point, etc..)


quid -infinity ?


The concept of zero is less meaningful than -infinity. Zero is the logical 
starting place because zero represents nothing (mathematically)




zero is not nothing in mathematics, on the contrary !

0 + x = 0 // neutral for addition
0 * x = 0 // absorbing for multiplication
0 / x = 0 if (x <> 0) // idem
| x / 0 | = infinity if (x <> 0)


Just because mathematical equations behave differently with zero doesn't change the fact 
that zero _conceptually_ represents "nothing"


You are totally wrong: here we are dealing with key concept of the group theory.



It's default for practical reason. Not for mathematics sake, but for the sake 
of convenience. We don't all study higher mathematics  but we're all taught to 
count since we where toddlers. Zero makes sense as the default, and is 
compounded by the fact that Int *must* be zero.



The sake of convenience here is numerical practice, not coding practice: this 
is the point:
from numerical folks, zero is a very bad choice; NaN is a very good one.



0 / 0 = NaN // undefined


Great! Yet another reason to default to zero. That way, "0 / 0" bugs have a 
very distinct fingerprint.


While the other (which are by far more likely) are bypassed: here you are 
making a point against yourself:

NaN + x = NaN
NaN * x = NaN
x / NaN = NaN
NaN / x = NaN





, which is inline with how pointers behave (only applicable to memory, not 
scale).

pointer value are also bounded.


I don't see how that's relevant.


Because then zero is a meaningful default for pointers.





Considering the NaN blow up behaviour, for a numerical folk the expected 
behaviour is certainly setting NaN as default for real.
Real number are not meant here for coders, but for numerical folks:


Of course FP numbers are meant for coders... they're in a programming language. 
They are used by coders, and not every coder that uses FP math *has* to be well 
trained in the finer points of mathematics simply to use a number that can 
represent fractions in a conceptually practical way.


The above is not finer points, but basic ones.
Otherwise, float and double are rather integers than by fractions.




D applies here a rule gain along experiences from numerical people.


I'm sorry I can't hear you over the sound of how popular Java and C# are.


Sorry, I can't hear you over the sound of mathematics.

 Convenience is about productivity, and that's largely influence by how much 
prior knowledge someone needs before being able to understand a features 
behavior.

Floating point calculus basics are easy to understand.



(ps. if you're going to use Argumentum ad Verecundiam, I get to use Argumentum 
ad Populum).


So forget coding !





For numerical works, because 0 behaves nicely most of the time, non properly 
initialized variables may not detected because the output data can sound 
resoneable;
on the other hand, because NaN blows up, such detection is straight forward: 
the output will be a NaN output which will jump to your face very quickly.


I gave examples which address this. This behavior is only [debatably] 
beneficial in corner cases on FP numbers specifically. I don't think that 
sufficient justification in light of reasons I give above.


This is more than sufficient because the authority for floating point (aka 
numerical) stuff is hold by numerical folks.





This is a numerical issue, not a coding language issue.


No, it's both.


So a choice has to be done: the mature choice is NaN approach.


 We're not Theoretical physicists

I am

 we're Software Engineers writing a very broad scope of different programs.

Does floating point calculation belong to the broad scope ?
Do engineers relay on numerical mathematician skills  when they code numerical 
stuff, or on pre-calculus books for grocers ?





Personally in my C code, I have taken the habit to initialise real numbers 
(doubles) with NaN:
in the GSL library there is a ready to use macro: GSL_NAN. (Concerning, 
integers I used extreme value as INT_MIN, INT_MAX, SIZE_MAX. ...).


Only useful because C defaults to garbage.


It can be initialized by 0.0 as well.




I would even say that D may go further by setting a kind of NaN for integers 
(and for chars).


You may get your with if Arm64 takes over.


Re: A "general" tag

2012-04-14 Thread Aleksandar Ružičić

On Saturday, 14 April 2012 at 19:17:52 UTC, Xan wrote:

Hi,

I try to translate a script I wrote in Fantom [www.fantom.org]. 
In my script, I have a type "Tag" defined as a triple of:

- String (the name of the tag),
- Type (the type of the tag: could be Str, Date, Int, etc.)
- Obj (the value of the tag; Fantom has Objects of Top-Class 
hierachy).


(normally the tag has Type = Obj.Type, but you can manually 
set).


For example,
you could have:
(name, Str#, "John")

or

(date, Date#, 2011-09-02)


(# is the Fantom way for specifying type: Str# is the sys::Str 
type)



Is there any way for emulating this? My main trouble is how to 
define Type and Object in D.


Thanks in advance,
Xan.

PS: Please, be patient, I'm a newbee.



For "Type" look at enum (http://dlang.org/enum.html) and for 
"Object" look at std.variant 
(http://dlang.org/phobos/std_variant.html).


And since Variant can tell you what type it contains you might no 
longer need that "Type" parameter.


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Joseph Rushton Wakeling

On 14/04/12 21:05, ReneSac wrote:

Lang| Comp | Binary size | Time (lower is better)
C++ (g++) - 13kb - 2.42s (100%) -O3 -s
D (DMD) - 230kb - 4.46s (184%) -O -release -inline
D (GDC) - 1322kb - 3.69s (152%) -O3 -frelease -s


Try using extra optimizations for GDC.  Actually, GDC has a "dmd-like" 
interface, gdmd, and


   gdmd -O -release -inline

corresponds to

   gdc -O3 -fweb -frelease -finline-functions

... so there may be some optimizations you were missing.  (If you call gdmd with 
the -vdmd flag, it will tell you exactly what gdc statement it's using.)



The only diference I could see between the C++ and D versions is that C++ has
hints to the compiler about which functions to inline, and I could't find
anything similar in D. So I manually inlined the encode and decode functions:


GDC has all the regular gcc optimization flags available IIRC.  The ones on the 
GDC man page are just the ones specific to GDC.



Still, the D version is slower. What makes this speed diference? Is there any
way to side-step this?


In my (brief and limited) experience GDC produced executables tend to have a 
noticeable but minor gap compared to equivalent g++ compiled C++ code -- nothing 
on the order of 150%.


E.g. I have some simulation code which models a reputation system where users 
rate objects and are then in turn judged on the consistency of their ratings 
with the general consensus.  A simulation with 1000 users and 1000 objects takes 
~22s to run in C++, ~24s in D compiled with gdmd -O -release -inline.


Scale that up to 2000 users and 1000 objects and it's 47s (C++) vs 53s (D).
2000 users and 2000 objects gives 1min 49s (C++) and 2min 4s (D).

So, it's a gap, but not one to write home about really, especially when you 
count that D is safer and (I think) easier/faster to program in.


It's true that DMD is much slower -- the GCC backend is much better at 
generating fast code.  If I recall right the DMD backend's encoding of floating 
point operations is considerably less sophisticated.



Note that this simple C++ version can be made more than 2 times faster with
algoritimical and io optimizations, (ab)using templates, etc. So I'm not asking
for generic speed optimizations, but only things that may make the D code "more
equal" to the C++ code.


I'm sure you can make various improvements to your D code in a similar way, and 
there are some things that improve in D when written in idiomatic "D style" as 
opposed to a more C++ish way of doing things (e.g. if you want to copy 1 vector 
to another, as happens in my code, write x[] = y[] instead of doing any kind of 
loop).


Best wishes,

-- Joe


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread q66

On Saturday, 14 April 2012 at 19:05:40 UTC, ReneSac wrote:
I have this simple binary arithmetic coder in C++ by Mahoney 
and translated to D by Maffi. I added "notrow", "final" and 
"pure"  and "GC.disable" where it was possible, but that didn't 
made much difference. Adding "const" to the Predictor.p() (as 
in the C++ version) gave 3% higher performance. Here the two 
versions:


http://mattmahoney.net/dc/  <-- original zip

http://pastebin.com/55x9dT9C  <-- Original C++ version.
http://pastebin.com/TYT7XdwX  <-- Modified D translation.

The problem is that the D version is 50% slower:

test.fpaq0 (16562521 bytes) -> test.bmp (33159254 bytes)

Lang| Comp  | Binary size | Time (lower is better)
C++  (g++)  -  13kb   -  2.42s  (100%)   -O3 -s
D(DMD)  - 230kb   -  4.46s  (184%)   -O -release -inline
D(GDC)  -1322kb   -  3.69s  (152%)   -O3 -frelease -s


The only diference I could see between the C++ and D versions 
is that C++ has hints to the compiler about which functions to 
inline, and I could't find anything similar in D. So I manually 
inlined the encode and decode functions:


http://pastebin.com/N4nuyVMh  - Manual inline

D(DMD)  - 228kb   -  3.70s  (153%)   -O -release -inline
D(GDC)  -1318kb   -  3.50s  (144%)   -O3 -frelease -s

Still, the D version is slower. What makes this speed 
diference? Is there any way to side-step this?


Note that this simple C++ version can be made more than 2 times 
faster with algoritimical and io optimizations, (ab)using 
templates, etc. So I'm not asking for generic speed 
optimizations, but only things that may make the D code "more 
equal" to the C++ code.


I wrote a version http://codepad.org/phpLP7cx based on the C++ 
one.


My commands used to compile:

g++46 -O3 -s fpaq0.cpp -o fpaq0cpp
dmd -O -release -inline -noboundscheck fpaq0.d

G++ 4.6, dmd 2.059.

I did 5 tests for each:

test.fpaq0 (34603008 bytes) -> test.bmp (34610367 bytes)

The C++ average result was 9.99 seconds (varying from 9.98 to 
10.01)
The D average result was 12.00 seconds (varying from 11.98 to 
12.01)


That means there is 16.8 percent difference in performance that 
would be cleared out by usage of gdc (which I don't have around 
currently).


Thread join behaviour

2012-04-14 Thread Russel Winder
I thought the following would terminate gracefully having printed 0..9
in some (random) order:

#! /usr/bin/env rdmd

import std.algorithm ;
import std.range ;
import std.stdio ;
import core.thread ;

int main ( immutable string[] args ) {
  auto threads = map ! ( ( int a ) {
  void delegate ( ) f ( ) {
return delegate ( ) { writeln ( a ) ; } ; 
  }
  return new Thread ( f )  ;
} ) ( iota ( 10 ) ) ;
  foreach ( t ; threads ) { t.start ( ) ; }
  foreach ( t ; threads ) { t.join ( ) ; }
  return 0 ;
}

However, this does not happen, at least with 2.059 on Linux as per
Debian Unstable.  Instead I get:

1
2
4
5
8
3
7
6
9
0
core.thread.ThreadException@src/core/thread.d(906): Unable to join 
thread


/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(_Dmain+0x83)
 [0x425edb]

/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
 (C) int rt.dmain2.main(int, char**).void runMain()+0x17) [0x429bab]

/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
 (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate())+0x23) 
[0x42952b]

/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
 (C) int rt.dmain2.main(int, char**).void runAll()+0x3d) [0x429bf9]

/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
 (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate())+0x23) 
[0x42952b]

/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(main+0xd3)
 [0x4294c3]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x7f1ed17f8ead]


I think I must be having a dumb moment as my reaction continues to be
WTF.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


signature.asc
Description: This is a digitally signed message part


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread q66
Forgot to mention specs: Dualcore Athlon II X2 240 (2.8GHz), 4GB 
RAM, FreeBSD 9 x64, both compilers are 64bit.


Re: Calling delegate properties without parens

2012-04-14 Thread Artur Skawina
On 04/14/12 20:47, Piotr Szturmaj wrote:
> I have following code:
> 
> import std.array, std.range, std.stdio;
> 
> struct CommonInputRange(E)
> {
> @property bool delegate() empty;
> @property E delegate() front;
> void delegate() popFront;
> }
> 
> void main(string[] args)
> {
> alias CommonInputRange!dchar DCRange;
> static assert(isInputRange!DCRange);
> DCRange dc;
> auto dcr = "abcdefg";
> auto t = dcr.takeExactly(3);
> dc.empty = &t.empty;
> dc.front = &t.front;
> dc.popFront = &t.popFront;
> 
> for ( ; !dc.empty(); dc.popFront())
> writeln(dc.front());
> }
> 
> As you can see in the for loop, range primitives must be called using parens 
> (), otherwise they don't work.
> 
> Do you know if there are plans to implement @property for delegates and 
> function pointers?

@property is for functions masquerading as data, i'm not sure extending it
to pointers and delegates would be a good idea. What you are asking for is
basically syntax sugar for:

   struct CommonInputRange(E)
   {
   bool delegate() _empty;
   @property auto empty() { return _empty(); };
   @property auto empty(typeof(_empty) dg) { _empty = dg; };
   E delegate() _front;
   @property auto front() { return _front(); };
   @property auto front(typeof(_front) dg) { _front = dg; };
   void delegate() popFront;
   }

// [1]

artur

[1] which could also /almost/ be expressed as:

   struct PropDeleg(T) {
  T dg;
  @property auto get() { return dg(); };
  alias get this;
  void opAssign(T d) { dg = d; };
   }

   struct CommonInputRange(E)
   {
  PropDeleg!(bool delegate()) empty;
  PropDeleg!(E delegate()) front;
  void delegate() popFront;
   }

except this one would need an (implicit) conversion to get the same
behavior. IOW it should work everywhere, as long as the result is
assigned to a different type; ie you'd need 
"{ dchar c = dc.front; writeln(c); }" in the above example, because
otherwise the writeln template will accept the struct, but never
really use it, so the dchar conversion does not happen.


Re: A "general" tag

2012-04-14 Thread Xan
On Saturday, 14 April 2012 at 19:40:06 UTC, Aleksandar Ružičić 
wrote:

On Saturday, 14 April 2012 at 19:17:52 UTC, Xan wrote:

Hi,

I try to translate a script I wrote in Fantom 
[www.fantom.org]. In my script, I have a type "Tag" defined as 
a triple of:

- String (the name of the tag),
- Type (the type of the tag: could be Str, Date, Int, etc.)
- Obj (the value of the tag; Fantom has Objects of Top-Class 
hierachy).


(normally the tag has Type = Obj.Type, but you can manually 
set).


For example,
you could have:
(name, Str#, "John")

or

(date, Date#, 2011-09-02)


(# is the Fantom way for specifying type: Str# is the sys::Str 
type)



Is there any way for emulating this? My main trouble is how to 
define Type and Object in D.


Thanks in advance,
Xan.

PS: Please, be patient, I'm a newbee.



For "Type" look at enum (http://dlang.org/enum.html) and for 
"Object" look at std.variant 
(http://dlang.org/phobos/std_variant.html).


And since Variant can tell you what type it contains you might 
no longer need that "Type" parameter.


I think it's not what I expect. Can I have a generic object type? 
Something like an assigment like:


Any a


?

With templates?

Please, guide me. I'm a newbee



Re: Thread join behaviour

2012-04-14 Thread Alex Rønne Petersen

On 14-04-2012 18:04, Russel Winder wrote:

I thought the following would terminate gracefully having printed 0..9
in some (random) order:

 #! /usr/bin/env rdmd

 import std.algorithm ;
 import std.range ;
 import std.stdio ;
 import core.thread ;

 int main ( immutable string[] args ) {
   auto threads = map ! ( ( int a ) {
   void delegate ( ) f ( ) {
 return delegate ( ) { writeln ( a ) ; } ;
   }
   return new Thread ( f )  ;
 } ) ( iota ( 10 ) ) ;
   foreach ( t ; threads ) { t.start ( ) ; }
   foreach ( t ; threads ) { t.join ( ) ; }
   return 0 ;
 }

However, this does not happen, at least with 2.059 on Linux as per
Debian Unstable.  Instead I get:

 1
 2
 4
 5
 8
 3
 7
 6
 9
 0
 core.thread.ThreadException@src/core/thread.d(906): Unable to join 
thread
 
 
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(_Dmain+0x83)
 [0x425edb]
 
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
 (C) int rt.dmain2..main(int, char**).void runMain()+0x17) [0x429bab]
 
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
 (C) int rt.dmain2..main(int, char**).void tryExec(scope void delegate())+0x23) 
[0x42952b]
 
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
 (C) int rt.dmain2..main(int, char**).void runAll()+0x3d) [0x429bf9]
 
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
 (C) int rt.dmain2..main(int, char**).void tryExec(scope void delegate())+0x23) 
[0x42952b]
 
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(main+0xd3)
 [0x4294c3]
 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) 
[0x7f1ed17f8ead]
 

I think I must be having a dumb moment as my reaction continues to be
WTF.



http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html#ERRORS

We can rule out these:

EDEADLK: Can't happen with your code.
EINVAL (second case): No other thread is trying to join.
ESRCH: Shouldn't happen since druntime registers threads with libpthread.

So, the first case of EINVAL (thread is not a joinable thread) must be 
the cause. I have no clue *why* though...


--
- Alex


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Somedude
Le 14/04/2012 21:53, q66 a écrit :
> On Saturday, 14 April 2012 at 19:05:40 UTC, ReneSac wrote:
>> I have this simple binary arithmetic coder in C++ by Mahoney and
>> translated to D by Maffi. I added "notrow", "final" and "pure"  and
>> "GC.disable" where it was possible, but that didn't made much
>> difference. Adding "const" to the Predictor.p() (as in the C++
>> version) gave 3% higher performance. Here the two versions:
>>
>> http://mattmahoney.net/dc/  <-- original zip
>>
>> http://pastebin.com/55x9dT9C  <-- Original C++ version.
>> http://pastebin.com/TYT7XdwX  <-- Modified D translation.
>>
>> The problem is that the D version is 50% slower:
>>
>> test.fpaq0 (16562521 bytes) -> test.bmp (33159254 bytes)
>>
>> Lang| Comp  | Binary size | Time (lower is better)
>> C++  (g++)  -  13kb   -  2.42s  (100%)   -O3 -s
>> D(DMD)  - 230kb   -  4.46s  (184%)   -O -release -inline
>> D(GDC)  -1322kb   -  3.69s  (152%)   -O3 -frelease -s
>>
>>
>> The only diference I could see between the C++ and D versions is that
>> C++ has hints to the compiler about which functions to inline, and I
>> could't find anything similar in D. So I manually inlined the encode
>> and decode functions:
>>
>> http://pastebin.com/N4nuyVMh  - Manual inline
>>
>> D(DMD)  - 228kb   -  3.70s  (153%)   -O -release -inline
>> D(GDC)  -1318kb   -  3.50s  (144%)   -O3 -frelease -s
>>
>> Still, the D version is slower. What makes this speed diference? Is
>> there any way to side-step this?
>>
>> Note that this simple C++ version can be made more than 2 times faster
>> with algoritimical and io optimizations, (ab)using templates, etc. So
>> I'm not asking for generic speed optimizations, but only things that
>> may make the D code "more equal" to the C++ code.
> 
> I wrote a version http://codepad.org/phpLP7cx based on the C++ one.
> 
> My commands used to compile:
> 
> g++46 -O3 -s fpaq0.cpp -o fpaq0cpp
> dmd -O -release -inline -noboundscheck fpaq0.d
> 
> G++ 4.6, dmd 2.059.
> 
> I did 5 tests for each:
> 
> test.fpaq0 (34603008 bytes) -> test.bmp (34610367 bytes)
> 
> The C++ average result was 9.99 seconds (varying from 9.98 to 10.01)
> The D average result was 12.00 seconds (varying from 11.98 to 12.01)
> 
> That means there is 16.8 percent difference in performance that would be
> cleared out by usage of gdc (which I don't have around currently).

The code is nearly identical (there is a slight difference in update(),
where he accesses the array once more than you), but the main difference
I see is the -noboundscheck compilation option on DMD.


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread q66

On Saturday, 14 April 2012 at 20:58:01 UTC, Somedude wrote:

Le 14/04/2012 21:53, q66 a écrit :

On Saturday, 14 April 2012 at 19:05:40 UTC, ReneSac wrote:
I have this simple binary arithmetic coder in C++ by Mahoney 
and
translated to D by Maffi. I added "notrow", "final" and 
"pure"  and

"GC.disable" where it was possible, but that didn't made much
difference. Adding "const" to the Predictor.p() (as in the C++
version) gave 3% higher performance. Here the two versions:

http://mattmahoney.net/dc/  <-- original zip

http://pastebin.com/55x9dT9C  <-- Original C++ version.
http://pastebin.com/TYT7XdwX  <-- Modified D translation.

The problem is that the D version is 50% slower:

test.fpaq0 (16562521 bytes) -> test.bmp (33159254 bytes)

Lang| Comp  | Binary size | Time (lower is better)
C++  (g++)  -  13kb   -  2.42s  (100%)   -O3 -s
D(DMD)  - 230kb   -  4.46s  (184%)   -O -release 
-inline

D(GDC)  -1322kb   -  3.69s  (152%)   -O3 -frelease -s


The only diference I could see between the C++ and D versions 
is that
C++ has hints to the compiler about which functions to 
inline, and I
could't find anything similar in D. So I manually inlined the 
encode

and decode functions:

http://pastebin.com/N4nuyVMh  - Manual inline

D(DMD)  - 228kb   -  3.70s  (153%)   -O -release 
-inline

D(GDC)  -1318kb   -  3.50s  (144%)   -O3 -frelease -s

Still, the D version is slower. What makes this speed 
diference? Is

there any way to side-step this?

Note that this simple C++ version can be made more than 2 
times faster
with algoritimical and io optimizations, (ab)using templates, 
etc. So
I'm not asking for generic speed optimizations, but only 
things that

may make the D code "more equal" to the C++ code.


I wrote a version http://codepad.org/phpLP7cx based on the C++ 
one.


My commands used to compile:

g++46 -O3 -s fpaq0.cpp -o fpaq0cpp
dmd -O -release -inline -noboundscheck fpaq0.d

G++ 4.6, dmd 2.059.

I did 5 tests for each:

test.fpaq0 (34603008 bytes) -> test.bmp (34610367 bytes)

The C++ average result was 9.99 seconds (varying from 9.98 to 
10.01)
The D average result was 12.00 seconds (varying from 11.98 to 
12.01)


That means there is 16.8 percent difference in performance 
that would be
cleared out by usage of gdc (which I don't have around 
currently).


The code is nearly identical (there is a slight difference in 
update(),
where he accesses the array once more than you), but the main 
difference

I see is the -noboundscheck compilation option on DMD.


He also uses a class. And -noboundscheck should be automatically 
induced by -release.


Re: Thread join behaviour

2012-04-14 Thread Matt Soucy

On 04/14/2012 04:56 PM, Alex Rønne Petersen wrote:

On 14-04-2012 18:04, Russel Winder wrote:

I thought the following would terminate gracefully having printed 0..9
in some (random) order:

#! /usr/bin/env rdmd

import std.algorithm ;
import std.range ;
import std.stdio ;
import core.thread ;

int main ( immutable string[] args ) {
auto threads = map ! ( ( int a ) {
void delegate ( ) f ( ) {
return delegate ( ) { writeln ( a ) ; } ;
}
return new Thread ( f ) ;
} ) ( iota ( 10 ) ) ;
foreach ( t ; threads ) { t.start ( ) ; }
foreach ( t ; threads ) { t.join ( ) ; }
return 0 ;
}

However, this does not happen, at least with 2.059 on Linux as per
Debian Unstable. Instead I get:

1
2
4
5
8
3
7
6
9
0
core.thread.ThreadException@src/core/thread.d(906): Unable to join thread

/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(_Dmain+0x83)
[0x425edb]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
(C) int rt.dmain2..main(int, char**).void runMain()+0x17) [0x429bab]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
(C) int rt.dmain2..main(int, char**).void tryExec(scope void
delegate())+0x23) [0x42952b]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
(C) int rt.dmain2..main(int, char**).void runAll()+0x3d) [0x429bf9]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
(C) int rt.dmain2..main(int, char**).void tryExec(scope void
delegate())+0x23) [0x42952b]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(main+0xd3)
[0x4294c3]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x7f1ed17f8ead]


I think I must be having a dumb moment as my reaction continues to be
WTF.



http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html#ERRORS


We can rule out these:

EDEADLK: Can't happen with your code.
EINVAL (second case): No other thread is trying to join.
ESRCH: Shouldn't happen since druntime registers threads with libpthread.

So, the first case of EINVAL (thread is not a joinable thread) must be
the cause. I have no clue *why* though...

If you merge the two foreach loops into one, doing t.start();t.join(); 
it doesn't have this issue. Also, when I run your code repeatedly the 
number of successful numbers printed changes a lot.

I'm assuming that you're trying to join a thread that already exited...
-Matt


Re: Thread join behaviour

2012-04-14 Thread Artur Skawina
On 04/14/12 18:04, Russel Winder wrote:
> I thought the following would terminate gracefully having printed 0..9
> in some (random) order:
> 
> #! /usr/bin/env rdmd
> 
> import std.algorithm ;
> import std.range ;
> import std.stdio ;
> import core.thread ;
> 
> int main ( immutable string[] args ) {
>   auto threads = map ! ( ( int a ) {
>   void delegate ( ) f ( ) {
> return delegate ( ) { writeln ( a ) ; } ; 
>   }
>   return new Thread ( f )  ;
> } ) ( iota ( 10 ) ) ;
>   foreach ( t ; threads ) { t.start ( ) ; }
>   foreach ( t ; threads ) { t.join ( ) ; }
>   return 0 ;
> }
> 
> However, this does not happen, at least with 2.059 on Linux as per
> Debian Unstable.  Instead I get:
> 
> 1
> 2
> 4
> 5
> 8
> 3
> 7
> 6
> 9
> 0
> core.thread.ThreadException@src/core/thread.d(906): Unable to join 
> thread
> 
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(_Dmain+0x83)
>  [0x425edb]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
>  (C) int rt.dmain2.main(int, char**).void runMain()+0x17) [0x429bab]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
>  (C) int rt.dmain2.main(int, char**).void tryExec(scope void 
> delegate())+0x23) [0x42952b]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
>  (C) int rt.dmain2.main(int, char**).void runAll()+0x3d) [0x429bf9]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
>  (C) int rt.dmain2.main(int, char**).void tryExec(scope void 
> delegate())+0x23) [0x42952b]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(main+0xd3)
>  [0x4294c3]
> /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) 
> [0x7f1ed17f8ead]
> 
> 
> I think I must be having a dumb moment as my reaction continues to be
> WTF.

'threads' is a (lazy) range; 

   auto threads = array(map ! ( ( int a ) {
   void delegate ( ) f ( ) {
 return delegate ( ) { writeln ( a ) ; } ; 
   }
   return new Thread ( f )  ;
 } ) ( iota ( 10 ) )) ;

artur


Re: Thread join behaviour

2012-04-14 Thread Somedude
Le 14/04/2012 18:04, Russel Winder a écrit :
> I thought the following would terminate gracefully having printed 0..9
> in some (random) order:
> 
> #! /usr/bin/env rdmd
> 
> import std.algorithm ;
> import std.range ;
> import std.stdio ;
> import core.thread ;
> 
> int main ( immutable string[] args ) {
>   auto threads = map ! ( ( int a ) {
>   void delegate ( ) f ( ) {
> return delegate ( ) { writeln ( a ) ; } ; 
>   }
>   return new Thread ( f )  ;
> } ) ( iota ( 10 ) ) ;
>   foreach ( t ; threads ) { t.start ( ) ; }
>   foreach ( t ; threads ) { t.join ( ) ; }
>   return 0 ;
> }
> 
> However, this does not happen, at least with 2.059 on Linux as per
> Debian Unstable.  Instead I get:
> 
> 1
> 2
> 4
> 5
> 8
> 3
> 7
> 6
> 9
> 0
> core.thread.ThreadException@src/core/thread.d(906): Unable to join 
> thread
> 
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(_Dmain+0x83)
>  [0x425edb]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
>  (C) int rt.dmain2.main(int, char**).void runMain()+0x17) [0x429bab]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
>  (C) int rt.dmain2.main(int, char**).void tryExec(scope void 
> delegate())+0x23) [0x42952b]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
>  (C) int rt.dmain2.main(int, char**).void runAll()+0x3d) [0x429bf9]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern
>  (C) int rt.dmain2.main(int, char**).void tryExec(scope void 
> delegate())+0x23) [0x42952b]
> 
> /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(main+0xd3)
>  [0x4294c3]
> /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) 
> [0x7f1ed17f8ead]
> 
> 
> I think I must be having a dumb moment as my reaction continues to be
> WTF.
> 

This works:

int main ( immutable string[] args ) {

  auto threadgroup = new ThreadGroup();

  void delegate ( ) f (int a ) {
return delegate ( ) { writeln ( a ) ; } ;
  }

  for ( int n = 0; n < 10; n++ ) {
threadgroup.create(f(n));
  }
  threadgroup.joinAll( );
  return 0 ;
}

Threads are tracked by the threadgroup, which knows who can be joined.


Re: Calling delegate properties without parens

2012-04-14 Thread Piotr Szturmaj

Artur Skawina wrote:

@property is for functions masquerading as data, i'm not sure extending it
to pointers and delegates would be a good idea. What you are asking for is
basically syntax sugar for:

struct CommonInputRange(E)
{
bool delegate() _empty;
@property auto empty() { return _empty(); };
@property auto empty(typeof(_empty) dg) { _empty = dg; };
E delegate() _front;
@property auto front() { return _front(); };
@property auto front(typeof(_front) dg) { _front = dg; };
void delegate() popFront;
}

>

Yes, I was thinking about this, but it adds unnecessary overhead. I want 
to call delegates directly.


I think the whole idea is harmless because semantically, from the user 
perspective, delegates and function pointers works just like normal 
functions. So, why not?


Re: Calling delegate properties without parens

2012-04-14 Thread Jonathan M Davis
On Saturday, April 14, 2012 20:47:20 Piotr Szturmaj wrote:
> I have following code:
> 
> import std.array, std.range, std.stdio;
> 
> struct CommonInputRange(E)
> {
>  @property bool delegate() empty;
>  @property E delegate() front;
>  void delegate() popFront;
> }
> 
> void main(string[] args)
> {
>  alias CommonInputRange!dchar DCRange;
>  static assert(isInputRange!DCRange);
>  DCRange dc;
>  auto dcr = "abcdefg";
>  auto t = dcr.takeExactly(3);
>  dc.empty = &t.empty;
>  dc.front = &t.front;
>  dc.popFront = &t.popFront;
> 
>  for ( ; !dc.empty(); dc.popFront())
>  writeln(dc.front());
> }
> 
> As you can see in the for loop, range primitives must be called using
> parens (), otherwise they don't work.
> 
> Do you know if there are plans to implement @property for delegates and
> function pointers?

front returns an element in the range. In your case, it's returning a 
delegate, because you have a range of delegates. If front returned a class or 
struct with a member function called foo, which you wanted to call, then you'd 
be doing something like

for(; !dc.empty; dc.popFront())
writeln(dc.front.foo());

But in your case, it's a delegate, so operating on that delegate means calling 
it, which means using the parens. dc.front just gives you the delegate, and it 
would be horrible if it did anything else. If front also called the delegate, 
the doing something like

auto arr = arr(dc);

would call each and every one of the delegates in the range, because it uses 
front to access the element _without calling it_. If there were some way to 
indicate that a delegate was called with property syntax, then you could no 
longer distinguish between simply returning the delegate and returning and 
call it.

Not to mention, properties are supposed to be an abstraction that mimicks 
member variables. That makes no sense whatsoever with a delegate. And in this 
case, the member variable which _is_ being mimicked (front) happens to be a 
delegate. So, it makes perfect sense that you'd have to use parens on it to 
actually call it.

- Jonathan M Davis


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread ReneSac
I tested the q66 version in my computer (sandy bridge @ 4.3GHz). 
Repeating the old timmings here, and the new results are marked 
as "D-v2":


test.fpaq0 (16562521 bytes) -> test.bmp (33159254 bytes)

Lang| Comp  | Binary size | Time (lower is better)
C++  (g++)  -  13kb   -  2.42s  (100%)   -O3 -s
D(DMD)  - 230kb   -  4.46s  (184%)   -O -release -inline
D(GDC)  -1322kb   -  3.69s  (152%)   -O3 -frelease -s
D-v2 (DMD)  - 206kb   -  4.50s  (186%)   -O -release -inline
D-v2 (GDC)  - 852kb   -  3.65s  (151%)   -O3 -frelease -s

So, basically the same thing... Not using clases seems a little 
slower on DMD, and no difference on GDC. The "if (++ct[cxt][y] > 
65534)" made a very small, but measurable difference (those .04s 
in GDC). The "if ((cxt += cxt + y) >= 512)" only made the code 
more complicated, with no speed benefit.


But the input file is also important. The file you tested seems 
to be an already compressed one, or something not very 
compressible. Here a test with an incompressible file:


pnad9huff.fpaq0 (43443040 bytes) -> test-d.huff (43617049 bytes)

C++  (g++)  -  13kb   -  5.13   (100%)   -O3 -s
D-v2 (DMD)  - 206kb   -  8.03   (156%)   -O -release -inline
D-v2 (GDC)  - 852kb   -  7.09   (138%)   -O3 -frelease -s
D-inl(DMD)  - 228kb   -  6.93   (135%)   -O -release -inline
D-inl(GDC)  -1318kb   -  6.86   (134%)   -O3 -frelease -s

The C++ advantage becomes smaller in this file. D-inl is my 
manual inline version, with your small optimization on 
"Predictor.Update()".


On Saturday, 14 April 2012 at 19:51:21 UTC, Joseph Rushton 
Wakeling wrote:
GDC has all the regular gcc optimization flags available IIRC.  
The ones on the GDC man page are just the ones specific to GDC.
I'm not talking about compiler flags, but the "inline" keyword in 
the C++ source code. I saw some discussion about "@inline" but it 
seems not implemented (yet?). Well, that is not a priority for D 
anyway.



About compiler optimizations, -finline-functions and -fweb are 
part of -O3. I tried to compile with -no-bounds-check, but made 
no diference for DMD and GDC. It probably is part of -release as 
q66 said.


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Jonathan M Davis
On Sunday, April 15, 2012 03:51:59 ReneSac wrote:
> About compiler optimizations, -finline-functions and -fweb are
> part of -O3. I tried to compile with -no-bounds-check, but made
> no diference for DMD and GDC. It probably is part of -release as
> q66 said.

Not quite. -noboundscheck turns off _all_ array bounds checking, whereas -
release turns it off in @system and @trusted functions, but not in @safe 
functions. But unless you've marked your code with @safe or it uses templated 
functions which get inferred as @safe, all of your functions are going to be 
@system functions anyway, in which case, it makes no difference.

- Jonathan M Davis


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Joseph Rushton Wakeling

On 14/04/12 23:03, q66 wrote:

He also uses a class. And -noboundscheck should be automatically induced by
-release.


Ahh, THAT probably explains why some of my numerical code is so markedly 
different in speed when compiled using DMD with or without the -release switch. 
 It's a MAJOR difference -- between code taking say 5min to run, compared to 
half an hour or more.


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Joseph Rushton Wakeling

On 14/04/12 23:03, q66 wrote:

He also uses a class. And -noboundscheck should be automatically induced by
-release.


... but the methods are marked as final -- shouldn't that substantially reduce 
any speed hit from using class instead of struct?




Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Jonathan M Davis
On Sunday, April 15, 2012 04:21:09 Joseph Rushton Wakeling wrote:
> On 14/04/12 23:03, q66 wrote:
> > He also uses a class. And -noboundscheck should be automatically induced
> > by
> > -release.
> 
> ... but the methods are marked as final -- shouldn't that substantially
> reduce any speed hit from using class instead of struct?

In theory. If they don't override anything, then that signals to the compiler 
that they don't need to be virtual, in which case, they _shouldn't_ be 
virtual, but that's up to the compiler to optimize, and I don't know how good 
it is about that right now. Certainly, if you had code like

class C
{
final int foo() { return 42;}
}

and benchmarking showed that it was the same speed as

class C
{
int foo() { return 42;}
}

when compiled with -O and -inline, then I'd submit a bug report (maybe an 
enhancement request?) on the compiler failing to make final functions non-
virtual.

Also, if the function is doing enough work, then whether it's virtual or not 
really doesn't make any difference, because the function itself costs so much 
more than the extra cost of the virtual function call.

- Jonathan M Davis


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Jonathan M Davis
On Saturday, April 14, 2012 19:31:40 Jonathan M Davis wrote:
> On Sunday, April 15, 2012 04:21:09 Joseph Rushton Wakeling wrote:
> > On 14/04/12 23:03, q66 wrote:
> > > He also uses a class. And -noboundscheck should be automatically induced
> > > by
> > > -release.
> > 
> > ... but the methods are marked as final -- shouldn't that substantially
> > reduce any speed hit from using class instead of struct?
> 
> In theory. If they don't override anything, then that signals to the
> compiler that they don't need to be virtual, in which case, they
> _shouldn't_ be virtual, but that's up to the compiler to optimize, and I
> don't know how good it is about that right now. Certainly, if you had code
> like
> 
> class C
> {
> final int foo() { return 42;}
> }
> 
> and benchmarking showed that it was the same speed as
> 
> class C
> {
> int foo() { return 42;}
> }
> 
> when compiled with -O and -inline, then I'd submit a bug report (maybe an
> enhancement request?) on the compiler failing to make final functions non-
> virtual.

Actually, if you try and benchmark it, make sure that the code can't know that 
the reference is exactly a C. In theory, the compiler could be smart enough to 
know in a case such as

auto c = new C;
auto a = c.foo();

that c is exactly a C and that therefore, it can just inline the call to foo 
even if it's virtual. If c is set from another function, it can't do that. 
e.g.

auto c = bar();
auto a = c.foo();

The compiler _probably_ isn't that smart, but it might be, so you'd have to be 
careful about that.

- Jonathan M Davis


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread jerro
On Sunday, 15 April 2012 at 02:20:34 UTC, Joseph Rushton Wakeling 
wrote:

On 14/04/12 23:03, q66 wrote:
He also uses a class. And -noboundscheck should be 
automatically induced by

-release.


Ahh, THAT probably explains why some of my numerical code is so 
markedly different in speed when compiled using DMD with or 
without the -release switch.
 It's a MAJOR difference -- between code taking say 5min to 
run, compared to half an hour or more.


I know this isn't what your post was about, but you really should 
compile numerical code with GDC instead of DMD if you care about 
performance. It generates much faster floating point code.


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Joseph Rushton Wakeling

On 15/04/12 04:37, jerro wrote:

I know this isn't what your post was about, but you really should compile
numerical code with GDC instead of DMD if you care about performance. It
generates much faster floating point code.


It's exactly what I do. :-)


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Joseph Rushton Wakeling

On Saturday, 14 April 2012 at 19:51:21 UTC, Joseph Rushton Wakeling wrote:

GDC has all the regular gcc optimization flags available IIRC. The ones on the
GDC man page are just the ones specific to GDC.

I'm not talking about compiler flags, but the "inline" keyword in the C++ source
code. I saw some discussion about "@inline" but it seems not implemented (yet?).
Well, that is not a priority for D anyway.

About compiler optimizations, -finline-functions and -fweb are part of -O3. I
tried to compile with -no-bounds-check, but made no diference for DMD and GDC.
It probably is part of -release as q66 said.


Ah yes, you're right.  I do wonder if your seeming speed differences are 
magnified because the whole operation is only 2-4 seconds long: if your 
algorithm were operating over a longer timeframe I think you'd likely find the 
relative speed differences decrease.  (I have a memory of a program that took 
~0.004s with a C/C++ version and 1s with D, and the difference seemed to be just 
startup time for the D program.)


What really amazes me is the difference between g++, DMD and GDC in size of the 
executable binary.  100 orders of magnitude!


3 remarks about the D code.  One is that much of it still seems very "C-ish"; 
I'd be interested to see how speed and executable size differ if things like the 
file opening, or the reading of characters, are done with more idiomatic D code. 
 Sounds stupid as the C stuff should be fastest, but I've been surprised 
sometimes at how using idiomatic D formulations can improve things.


Second remark is more of a query -- can Predictor.p() and .update really be 
marked as pure?  Their result for a given input actually varies depending on the 
current values of cxt and ct, which are modified outside of function scope.


Third remark -- again a query -- why the GC.disable ... ?


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread jerro

(I have a memory of a program that took
~0.004s with a C/C++ version and 1s with D, and the difference 
seemed to be just startup time for the D program.)


I have never seen anything like that. Usually the minimal time to 
run a D program is something like:


j@debian:~$ time ./hello
Hello world!

real0m0.001s
user0m0.000s
sys 0m0.000s


What really amazes me is the difference between g++, DMD and 
GDC in size of the executable binary.  100 orders of magnitude!


With GDC those flags(for gdmd):

-fdata-sections -ffunction-sections -L--gc-sections -L-l

help a lot if you want to reduce a size of executable. Besides, 
this overhead is the standard library and runtime and won't be 
much larger in larger programs.


Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread jerro

On Sunday, 15 April 2012 at 03:41:55 UTC, jerro wrote:

(I have a memory of a program that took
~0.004s with a C/C++ version and 1s with D, and the difference 
seemed to be just startup time for the D program.)


I have never seen anything like that. Usually the minimal time 
to run a D program is something like:


j@debian:~$ time ./hello
Hello world!

real0m0.001s
user0m0.000s
sys 0m0.000s


What really amazes me is the difference between g++, DMD and 
GDC in size of the executable binary.  100 orders of magnitude!


With GDC those flags(for gdmd):

-fdata-sections -ffunction-sections -L--gc-sections -L-l

help a lot if you want to reduce a size of executable. Besides, 
this overhead is the standard library and runtime and won't be 
much larger in larger programs.


The last flag should be -L-s



Re: D 50% slower than C++. What I'm doing wrong?

2012-04-14 Thread Joseph Rushton Wakeling

On 15/04/12 05:41, jerro wrote:

I have never seen anything like that. Usually the minimal time to run a D
program is something like:

j@debian:~$ time ./hello
Hello world!

real 0m0.001s
user 0m0.000s
sys 0m0.000s


Yea, my experience too in general.  I can't remember exactly what I was testing 
but if it's what I think it was (and have just retested:-), the difference may 
have been less pronounced (maybe 0.080s for D compared to 0.004 for C++) and 
that would have been due to not enabling optimizations for D.


I have another pair of stupid D-vs.-C++ speed-test files where with 
optimizations engaged, D beats C++: the dominant factor is lots of output to 
console, so I guess this is D's writeln() beating C++'s cout.



What really amazes me is the difference between g++, DMD and GDC in size of
the executable binary. 100 orders of magnitude!


With GDC those flags(for gdmd):

-fdata-sections -ffunction-sections -L--gc-sections -L-l

help a lot if you want to reduce a size of executable. Besides, this overhead is
the standard library and runtime and won't be much larger in larger programs.


Ahh! I hadn't realized that the libphobos package on Ubuntu didn't install a 
compiled version of the library.  (DMD does.)