Re: Wht std.complex is needed?

2009-04-06 Thread bearophile
Sam Hu:
 Doesn't  D already has the built-in types cfloat, cdouble, creal, ifloat, 
 idouble, and ireal?What's the advantage having complex class instead?

Some people have discussed/complained that complex types aren't worth being 
built-ins, so the *struct* Complex of std.complex of D2 will replace them. (I 
am not sure such complex struct is as good as the current built-ins, but it 
seems most D1 users don't use complex numbers much, so they don't care).

Bye,
bearophile


Re: Wht std.complex is needed?

2009-04-06 Thread bearophile
Sam Hu Wrote:
What's the disadvantage to have the built-in type of i-type?

I think the answer is: It's another type added to the language, with its 
specific semantics, so it adds a bit of complexity to the language. And most 
people today don't seem to use complex types in D1 much, so they think they 
don't want to pay for such extra complexity.

A better question can be: What's the advantage of having a built-in imaginary 
type? :-)
You can find an answer here, from page 11:
http://www.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf
But maybe those ideas aren't much true anymore today.

Bye,
bearophile


Re: Wht std.complex is needed?

2009-04-06 Thread Sam Hu
Thank you!
Anothe silly question then:What's the disadvantage to have the built-in type of 
i-type?

Regards,
Sam


Re: minimal evaluation

2009-04-06 Thread Qian Xu
 
 if (isNull(foo) ||
 isNull(foo.getBar) ||
 isNull(foo.getBar.getBar2)
 {
   return false;
 }

Update: If minimal evaluation is not always enabled, and foo.getBar is NULL.
I will get a segfault when evaluating foo.getBar.getBar2.



Re: minimal evaluation

2009-04-06 Thread torhu

On 06.04.2009 13:30, Qian Xu wrote:

Hi All,

Is minimal evaluation always enabled in D?

I want to write a function IsNull(), so that I can check the precondition as
follows:

   if (isNull(foo) ||
   isNull(foo.getBar) ||
   isNull(foo.getBar.getBar2)
   {
 return false;
   }
   // normal code goes here

If an argument is null, the IsNull() will return false. Internally it will
be logged to console as well.

But I am not sure, if dmd-compiler generates code without minimal evaluation
in some cases. If minimal evaluation is not always enabled. I cannot do
precodition check in my way.

--Qian


If you mean short-circuit evalutation, I'm pretty sure that's always 
what the compiler does.


Re: Wht std.complex is needed?

2009-04-06 Thread Steven Schveighoffer

On Mon, 06 Apr 2009 08:36:18 -0400, Don nos...@nospam.com wrote:


Sam Hu wrote:

Thank you!
Anothe silly question then:What's the disadvantage to have the built-in  
type of i-type?

 Regards,
Sam


It's a very nasty type. It supports *, but isn't closed under *.
Which is really annoying for generic programming.

idouble x = 2i;
x *= x; // oops, this isn't imaginary. (BTW this currently compiles :o).


This may be a dumb question, but aren't all real numbers also technically  
imaginary numbers with a 0i term?  that is, I would expect the above to  
evaluate to:


-4 + 0i

Which I would view as an imaginary number.  Am I completely wrong here?

That being said, I hope I never have to deal with imaginary numbers in my  
career, I had enough of them in school ;)  So I don't really care whether  
it's a builtin or not.


-Steve


Bit operator conversions

2009-04-06 Thread Kagamin
Is it valid for this to compile:
---
ushort a(ushort b) pure nothrow
{ return b10|b; }
---

And for this to not compile:
---
ushort a(ushort b) pure nothrow
{ return b10; }
---
?


Re: minimal evaluation

2009-04-06 Thread Qian Xu
torhu wrote:

 
 If you mean short-circuit evalutation, I'm pretty sure that's always
 what the compiler does.

Thanks. Somebody posted this link:
http://digitalmars.com/d/1.0/expression.html#OrOrExpression



Re: Wht std.complex is needed?

2009-04-06 Thread Daniel Keep


Steven Schveighoffer wrote:
 On Mon, 06 Apr 2009 08:36:18 -0400, Don nos...@nospam.com wrote:
 
 Sam Hu wrote:
 Thank you!
 Anothe silly question then:What's the disadvantage to have the
 built-in type of i-type?
  Regards,
 Sam

 It's a very nasty type. It supports *, but isn't closed under *.
 Which is really annoying for generic programming.

 idouble x = 2i;
 x *= x; // oops, this isn't imaginary. (BTW this currently compiles :o).
 
 This may be a dumb question, but aren't all real numbers also
 technically imaginary numbers with a 0i term?  that is, I would expect
 the above to evaluate to:
 
 -4 + 0i
 
 Which I would view as an imaginary number.  Am I completely wrong here?

You're thinking of complex.  -4 is real, 2i is imaginary, -4+2i is
complex.

Regarding Don's example, imaginary*imaginary always yields a real,
real*imaginary always yields an imaginary.  It's the only builtin type I
know of that changes type under multiplication with itself.

  -- Daniel


Re: Wht std.complex is needed?

2009-04-06 Thread Don

Steven Schveighoffer wrote:

On Mon, 06 Apr 2009 08:36:18 -0400, Don nos...@nospam.com wrote:


Sam Hu wrote:

Thank you!
Anothe silly question then:What's the disadvantage to have the 
built-in type of i-type?

 Regards,
Sam


It's a very nasty type. It supports *, but isn't closed under *.
Which is really annoying for generic programming.

idouble x = 2i;
x *= x; // oops, this isn't imaginary. (BTW this currently compiles :o).


This may be a dumb question, but aren't all real numbers also 
technically imaginary numbers with a 0i term?  that is, I would expect 
the above to evaluate to:


-4 + 0i

Which I would view as an imaginary number.  Am I completely wrong here?


It's a complex number.
(real OP real OP real) is real.
(complex OP complex OP complex) is complex.
BUT
(imaginary OP imaginary OP imaginary) is imaginary, or real, or complex.





That being said, I hope I never have to deal with imaginary numbers in 
my career, I had enough of them in school ;)  So I don't really care 
whether it's a builtin or not.


-Steve


Re: Wht std.complex is needed?

2009-04-06 Thread Steven Schveighoffer

On Mon, 06 Apr 2009 09:50:35 -0400, Don nos...@nospam.com wrote:


Steven Schveighoffer wrote:

On Mon, 06 Apr 2009 08:36:18 -0400, Don nos...@nospam.com wrote:


Sam Hu wrote:

Thank you!
Anothe silly question then:What's the disadvantage to have the  
built-in type of i-type?

 Regards,
Sam


It's a very nasty type. It supports *, but isn't closed under *.
Which is really annoying for generic programming.

idouble x = 2i;
x *= x; // oops, this isn't imaginary. (BTW this currently compiles  
:o).
 This may be a dumb question, but aren't all real numbers also  
technically imaginary numbers with a 0i term?  that is, I would expect  
the above to evaluate to:

 -4 + 0i
 Which I would view as an imaginary number.  Am I completely wrong here?


It's a complex number.
(real OP real OP real) is real.
(complex OP complex OP complex) is complex.
BUT
(imaginary OP imaginary OP imaginary) is imaginary, or real, or complex.


Yes, I meant to say complex, sorry.

Turns out I was not reading fully the previous posts.  I was not aware  
that there were two separate types for complex and imaginary.  I thought  
idouble was a complex number.


That's kind of... um weird?  Why do you need an imaginary AND a complex  
type?  Wouldn't just a complex type suffice?


Anyway, don't mind me, I just was confused.

-Steve


cast a LinkSeq

2009-04-06 Thread Qian Xu
Hi All,

can I cast a LinkSeq from inherited type to base type?

 code --
   class Fruit {}
   class Apple: Fruit {}

   auto apples = new LinkSeq!(Apple);
   apples.append(new Apple);
   assert(apples !is null);
   assert(apples.length == 1);
   
   auto fruits = cast(LinkSeq!(Fruit))(apples);
   assert(fruits !is null); // --- failed
   assert(fruits.length == 1);   
 code --


--Qian


Re: Wht std.complex is needed?

2009-04-06 Thread Don

Steven Schveighoffer wrote:

On Mon, 06 Apr 2009 09:50:35 -0400, Don nos...@nospam.com wrote:


Steven Schveighoffer wrote:

On Mon, 06 Apr 2009 08:36:18 -0400, Don nos...@nospam.com wrote:


Sam Hu wrote:

Thank you!
Anothe silly question then:What's the disadvantage to have the 
built-in type of i-type?

 Regards,
Sam


It's a very nasty type. It supports *, but isn't closed under *.
Which is really annoying for generic programming.

idouble x = 2i;
x *= x; // oops, this isn't imaginary. (BTW this currently compiles 
:o).
 This may be a dumb question, but aren't all real numbers also 
technically imaginary numbers with a 0i term?  that is, I would 
expect the above to evaluate to:

 -4 + 0i
 Which I would view as an imaginary number.  Am I completely wrong here?


It's a complex number.
(real OP real OP real) is real.
(complex OP complex OP complex) is complex.
BUT
(imaginary OP imaginary OP imaginary) is imaginary, or real, or complex.


Yes, I meant to say complex, sorry.

Turns out I was not reading fully the previous posts.  I was not aware 
that there were two separate types for complex and imaginary.  I thought 
idouble was a complex number.


That's kind of... um weird?  Why do you need an imaginary AND a complex 
type?  Wouldn't just a complex type suffice?


Yes, in 99.998% of cases. (1-real.epsilon g)
I think the argument is that a pure imaginary type means the real part 
is exactly zero, whereas a complex type with z.re == 0 means the real 
part is zero OR too small to represent. Which makes a difference when 
you multiply by infinity. Since dealing with this very obscure case 
requires THREE keywords, the bang-per-buck for each keyword is 
unbelievably low.


I strongly believe that ifloat, idouble, ireal should not be in the 
language. I like the fact the cfloat, cdouble, creal are -- but I 
recognize I'm in the minority.



Anyway, don't mind me, I just was confused.


It's intrinsically confusing. Imaginary types don't make much sense. No 
wonder there are so many compiler bugs with it.
(It's kind of like a 'fraction' type, where the fraction is not allowed 
to be an integer... The arithmetic's insane).




-Steve


Re: Factoring out looping structure

2009-04-06 Thread BCS

Reply to Doctor,


I'm new to template programming and I have a problem for which I think
it would be a good match, but I'd like to get some advice on how to go
about it.

I have a family of algorithms with the same looping structure, but
different particulars:


state_t state ;
for (int i = 0 ; i  imax ; ++i)
{
compute_i(state, i);
for (int j = 0 ; j  jmax ; ++j)
{
compute_j(state,i,j);
for (int k = 0 ; k  kmax ; ++k)
{
compute_k(state,i,j,k);
for (int m = 0 ; m  mmax ; ++m)
{
compute_m(state,i,j,k,m);
}
finish_k(state,i,j,k);
}
finish_j(state,i,j);
}
}
--

I'd like to factor out the particulars from the looping structure, so
I can write the loops once and then implement a bunch of variants with
different particulars (the looping structure is in fact more
complicated than the abstract example given).  Obviously I could do
this by passing in an object implementing an interface with all my
functions; however, the whole point of this exercise is to avoid the
overhead of function calls.  The code needs to be efficient, and
(especially the inner loop) functions need to be inlined.

So: what are my options in D?  Templates, delegates, mixins...?  I'd
like to avoid string mixins if possible because they're a bit ugly.

Thanks!




void Go(T)()
{
T.state_t state ;
for (int i = 0 ; i  imax ; ++i)
{
T.compute_i(state, i);
for (int j = 0 ; j  jmax ; ++j)
{
T.compute_j(state,i,j);
for (int k = 0 ; k  kmax ; ++k)
{
T.compute_k(state,i,j,k);
for (int m = 0 ; m  mmax ; ++m)
{
compute_m(state,i,j,k,m);
}
T.finish_k(state,i,j,k);
}
T.finish_j(state,i,j);
}
}
}

struct T_a
{
static struct state_t { ... } // or alias

static void compute_i(state_t, int i){ ... }
static void compute_j(state_t, int i, int j){ ... }
static void compute_k(state_t, int i, int j, int k){ ... }
static void compute_l(state_t, int i, int j, int k, int l){ ... }
}
Go!(T_a)();

struct T_b
{
static struct state_t { ... } // or alias

static void compute_i(state_t, int i){ ... }
static void compute_j(state_t, int i, int j){ ... }
static void compute_k(state_t, int i, int j, int k){ ... }
static void compute_l(state_t, int i, int j, int k, int l){ ... }
}
Go!(T_b)();


untested but you get the idea

A similar approach can be done replacing (T) with (alias T) and using 'template 
T_a()' in places of the structs





Re: cast a LinkSeq

2009-04-06 Thread Daniel Keep


Qian Xu wrote:
 Adam Burton wrote:
 I wouldn't think so, cos LinkSeq!(Apple) does not inherit
 LinkSeq!(Fruit), they are 2 separate types. However your apples
 automatically downcast (or up, depending which way you like to draw
 your diagrams :-) ) so unless you  intend to pass the LinkSeq!(Apple)
 into a function expecting LinkSeq!(Fruit)  it shouldn't be a problem.
 If you are passing about LinqSeq!(Fruit) and want  your
 LinkSeq!(Apple) to fit you might need to write some adapters and make
 use of the models available to you or something along them lines.

 That's my understanding anyway.
 

 
 yes. I can cast all Apple-object to Fruit-objects one by one. I hope
 there is an one-line-solution :-)

You can't do it.  Imagine you cast your LinkSeq!(Apple) to
LinkSeq!(Fruit).  You can now add a Banana to your LinkSeq!(Fruit), thus
corrupting the original object.

You get a similar problem with arrays.

The most direct way would probably be to create a LinkSeqView!(T) class
which did the cast on the fly and prohibited mutating operations.

  -- Daniel