On Mon, 29 Mar 2010 00:46:20 +0400, Don <nos...@nospam.com> wrote:
so wrote:
Hello Don, finally!
It is hard to explain yourself when you don't know the people you talk
have numeric coding background.
Since we know you have done much numeric and generic coding, it will be
enough for me if you understand what i mean/ask/want,
and say what i am talking is ridiculous, or think that i am trolling,
just say so and i shut up! :)
You're definitely not trolling! I'm not 100% sure of which issue you're
referring too, but I'm aware of a few, for example:
(1) Converting a floating point literal into a double literal is usually
not lossless.
0.5f, 0.5, and 0.5L are all exactly the same number, since they are
exactly representable.
But 0.1 is not the same as 0.1L.
So it's a bit odd that this silent lossless conversion is taking place.
It does have a very strong precedent from C, however.
(2) The interaction between implicit casting and template parameters is
quite poor. Eg, the fact that '0' is an int, not a floating point type,
means that something simple like:
add(T)(T x) if (isFloatingPoint!(T))
doesn't work properly. It is not the same as:
add(real x)
since it won't allow add(0).
Which is pretty annoying. Why can't 0 just mean zero???
At the beginning the question in my mind was, why can't we do this the way
it works in math :
[Real numbers] contains [Integers] contains [Natural numbers]
So, when a compiler see 0, which is the element of all above, it should
classify it as :
1st degree. [floating point type, integer, natural number]
When it encounters say, -3, it will be :
2nd degree. [floating point type and integer]
And finally when it encounters something like 4.0, it will be :
3rd degree. [floating point type]
With these in mind, the prototype :
T foo(T)(T m) {}, should be able to take all three degrees of types above.
We go abit further and see what it actually is :
T foo(T)(T m) {
T n = m * 5 - 4 * 7 / 2; // numbers belongs all the systems above, this
line should work for every T
T k = n / 20; // same.
return n + k; // same.
}
"T n = m * 5 - 4 * 7 / 2;"
m is here in the type of T,
* operator has a generic operand 5, convert it to T, if you can't, pop
error.
- operator has a generic operand (4 * 7 / 2), expect it in the and keep
parsing.
Again, in the code above, none of the constants is a native type, as in 5
is not int, it is a generic constant which belongs all systems above.
What this means?
calling foo(0.0f) is actually :
float foo(float m) {
float n = m * 5.0f - 4.0f * 7.0f / 2.0f;
float k = n / 20.0f;
return n + k;
}
m is here float and operation * has a generic operand
There wasn't a single implicit cast and the code was perfectly generic.
calling foo(0) will pass the "if(isFloatingPoint!(T))" contract, since 0
belongs to all,
but compiler will be unable to resolve the final type which is to be
instantiated.
But coming with something like this would be suicide since i already got
enough treatment for the lighter syntax :P
Sorry for the long post!
Thanks.
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/