www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Initialising a class with a native datatype necessary for GMP

reply Matthias Walter <walter mail.math.uni-magdeburg.de> writes:
In this post I will try to explain a problem, which I encountered in my GMP
implementation. There are different approaches, how one may implement GMP, but
the main goal here is that GMP numbers (mpz, mpq, mpf for integer, rational,
floating point) can be used like normal ints and floats!

Especially, the following things should work (with T any of those types):

| T func (T a, T b = 0)
| {
|   T result = 10;
|   return result * a + b;
| }
|
| ...
|
| int main (char[][] args)
| {
|   T value = 2;
|   value = func (value, 1);
|   value = func (value);
|   Stdout.format ("value = {0}", value).newline;
| }

There are two things, which are AFAIK impossible to do with current D:
 (1) T can be a default parameter like in line 1.
 (2) T can be initialized with a type that is not T (e.g. mpz with an int)

Although, there are at least two different ways to implement GMP: either
classes (which is very elegant in D) or templated structs (like in C++), but
both cannot solve issues (1) or (2)!

With current D, the only solution, I found, was the following helper function:

| T num (T) (int n)
| {
|   static if (is (typeof(T) == mpz))
|   {
|     return new mpz (n);
|   }
|   else
|   {
|     return n;
|   }
|}

With this template, one can write

| T func (T a, T b = num !(T) (0))
| {
|   T result = num !(T) (10);
|   ...
| }

But this is ugly code and I'm lazy to add all those calls when refactoring an
int-based program to a template/GMP-based one!

I have the following ideas, how one could make this more pretty:

1. Make an implicit cast from a type to a class equivalent to a constructor,
taking the type as the only parameter.

2. Let the expression "new int (10)" be semantically the same as "10" (Although
I think this would be very inconsistent behavior)

Any other ideas?

I believe that there is the necessarity for something to happen, because GMP is
a very important choice for computing in science and the current status seems
to dissatisfactory to me!

best regards
Matthias Walter
Nov 27 2007
next sibling parent 0ffh <frank frankhirsch.youknow.what.todo.net> writes:
Matthias Walter wrote:
 In this post I will try to explain a problem, which I encountered in my
 GMP implementation. There are different approaches, how one may
 implement GMP, but the main goal here is that GMP numbers (mpz, mpq, mpf
 for integer, rational, floating point) can be used like normal ints and
 floats!
 
 Especially, the following things should work (with T any of those
 types):
 
 | T func (T a, T b = 0)
In case if T is a class, I'd suggest T func (T a, T b = null) { if (b is null) b=new b(defaultvalue); ... } In case if T is a struct, I'd suggest const T uninit={foo:0 ... }; T func (T a, T b = uninit) { if (b==uninit) b={ ... }; ... } I know they're not perfect, but I wanted to suggest 'em anyway. =) regards, frank
Nov 27 2007
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Matthias Walter wrote:
 In this post I will try to explain a problem, which I encountered in my GMP
implementation. There are different approaches, how one may implement GMP, but
the main goal here is that GMP numbers (mpz, mpq, mpf for integer, rational,
floating point) can be used like normal ints and floats!
 
 Especially, the following things should work (with T any of those types):
 
 | T func (T a, T b = 0)
 | {
 |   T result = 10;
 |   return result * a + b;
 | }
 |
 | ...
 |
 | int main (char[][] args)
 | {
 |   T value = 2;
 |   value = func (value, 1);
 |   value = func (value);
 |   Stdout.format ("value = {0}", value).newline;
 | }
 
 There are two things, which are AFAIK impossible to do with current D:
  (1) T can be a default parameter like in line 1.
  (2) T can be initialized with a type that is not T (e.g. mpz with an int)
 
 Although, there are at least two different ways to implement GMP: either
classes (which is very elegant in D) or templated structs (like in C++), 
Classes cannot give you something that can be used "just like ints and floats". They can't have a default value because the "default" value is always a null pointer. You have to 'new' them somewhere. Also a=b always copies the reference not the data. So structs are really your only choice if you want behavior similar to a built-in type.
but both cannot solve issues (1) or (2)!
 
 With current D, the only solution, I found, was the following helper function:
 
 | T num (T) (int n)
 | {
 |   static if (is (typeof(T) == mpz))
 |   {
 |     return new mpz (n);
 |   }
 |   else
 |   {
 |     return n;
 |   }
 |}
 
 With this template, one can write
 
 | T func (T a, T b = num !(T) (0))
 | {
 |   T result = num !(T) (10);
 |   ...
 | }
 
 But this is ugly code and I'm lazy to add all those calls when refactoring an
int-based program to a template/GMP-based one!
 
 I have the following ideas, how one could make this more pretty:
 
 1. Make an implicit cast from a type to a class equivalent to a constructor,
taking the type as the only parameter.
 
 2. Let the expression "new int (10)" be semantically the same as "10"
(Although I think this would be very inconsistent behavior)
 
 Any other ideas?
 
 I believe that there is the necessarity for something to happen, because GMP
is a very important choice for computing in science and the current status
seems to dissatisfactory to me!
 
 best regards
 Matthias Walter
I think what you describe is the same issue as this one: http://d.puremagic.com/issues/show_bug.cgi?id=1547 If you agree then maybe you can attach your summary of the problem to that report. --bb
Nov 27 2007
parent Matthias Walter <walter mail.math.uni-magdeburg.de> writes:
Bill Baxter Wrote:

 Matthias Walter wrote:
 In this post I will try to explain a problem, which I encountered in my GMP
implementation. There are different approaches, how one may implement GMP, but
the main goal here is that GMP numbers (mpz, mpq, mpf for integer, rational,
floating point) can be used like normal ints and floats!
 
 Especially, the following things should work (with T any of those types):
 
 | T func (T a, T b = 0)
 | {
 |   T result = 10;
 |   return result * a + b;
 | }
 |
 | ...
 |
 | int main (char[][] args)
 | {
 |   T value = 2;
 |   value = func (value, 1);
 |   value = func (value);
 |   Stdout.format ("value = {0}", value).newline;
 | }
 
 There are two things, which are AFAIK impossible to do with current D:
  (1) T can be a default parameter like in line 1.
  (2) T can be initialized with a type that is not T (e.g. mpz with an int)
 
 Although, there are at least two different ways to implement GMP: either
classes (which is very elegant in D) or templated structs (like in C++), 
Classes cannot give you something that can be used "just like ints and floats". They can't have a default value because the "default" value is always a null pointer. You have to 'new' them somewhere. Also a=b always copies the reference not the data. So structs are really your only choice if you want behavior similar to a built-in type.
but both cannot solve issues (1) or (2)!
 
 With current D, the only solution, I found, was the following helper function:
 
 | T num (T) (int n)
 | {
 |   static if (is (typeof(T) == mpz))
 |   {
 |     return new mpz (n);
 |   }
 |   else
 |   {
 |     return n;
 |   }
 |}
 
 With this template, one can write
 
 | T func (T a, T b = num !(T) (0))
 | {
 |   T result = num !(T) (10);
 |   ...
 | }
 
 But this is ugly code and I'm lazy to add all those calls when refactoring an
int-based program to a template/GMP-based one!
 
 I have the following ideas, how one could make this more pretty:
 
 1. Make an implicit cast from a type to a class equivalent to a constructor,
taking the type as the only parameter.
 
 2. Let the expression "new int (10)" be semantically the same as "10"
(Although I think this would be very inconsistent behavior)
 
 Any other ideas?
 
 I believe that there is the necessarity for something to happen, because GMP
is a very important choice for computing in science and the current status
seems to dissatisfactory to me!
 
 best regards
 Matthias Walter
I think what you describe is the same issue as this one: http://d.puremagic.com/issues/show_bug.cgi?id=1547 If you agree then maybe you can attach your summary of the problem to that report. --bb
Okay, commented your bug-report, pointing out my example and the area, where the bug applies here. best regards Matthias Walter
Nov 28 2007