Re: Floating point in the type system

2015-09-12 Thread via Digitalmars-d

On Saturday, 12 September 2015 at 19:02:16 UTC, Robert wrote:
For what it's worth, I was investigating this initially as a 
discussion about adding type-level values in Rust, and how to 
handle unusual cases like this.


C++ does not allow it. And frankly, having more than a single 
integer value type as a value parameter in C++ templates is a 
pointless PITA.


I think Go got literal constant values right: make them untyped 
until bound.




Re: Floating point in the type system

2015-09-12 Thread Robert via Digitalmars-d

On Saturday, 12 September 2015 at 15:13:27 UTC, Robert wrote:

Hi all,

I came across this example, and wondered what your thoughts on 
it are:





It seems a little unusual to me.

Robert


For what it's worth, I was investigating this initially as a 
discussion about adding type-level values in Rust, and how to 
handle unusual cases like this. In the process we've managed to 
break the Idris type system: 
https://github.com/idris-lang/Idris-dev/issues/2609. There's been 
quite a lot of interesting discussion about it on the IRC 
channels for all three languages :) I'd be interested to know how 
other languages handle this, if anyone knows.


Re: Floating point in the type system

2015-09-12 Thread Ola Fosheim Grostad via Digitalmars-d

On Saturday, 12 September 2015 at 16:08:31 UTC, Robert wrote:
assert and runtime assert failing. I'm just curious to 
understand the reasoning behind this, whether it's intentional, 
and whether it matters at all.


Types need to mangle to the same name, but using floats in a type 
name is usually not a good idea. Try pi... How many decimals? A 
roundoff error and you get a new type.


Re: Floating point in the type system

2015-09-12 Thread via Digitalmars-d

On Saturday, 12 September 2015 at 19:02:16 UTC, Robert wrote:
handle unusual cases like this. In the process we've managed to 
break the Idris type system: 
https://github.com/idris-lang/Idris-dev/issues/2609.


I don't know Idris, but you can't easily unify over floats, 
because they are samples on an interval, and don't behave like 
real numbers, but more like underspecified intervals from 
interval arithmetics.


If you want to unify over reals, you probably should do it 
symbolically.


Or just treat float values as literal symbols in the type system. 
It is useful for configuration: Frequency!342.234


Sometimes it is worthwhile to have an unsound type system. Both D 
and Dart have somewhat unsound type systems. It puts a burden on 
the programmer, but can be useful.




Re: Floating point in the type system

2015-09-12 Thread Xinok via Digitalmars-d

On Saturday, 12 September 2015 at 16:08:31 UTC, Robert wrote:
On Saturday, 12 September 2015 at 15:49:23 UTC, Atila Neves 
wrote:

What do think is unusual?

Atila


It's unusual, because `float.nan != float.nan`, so one might 
expect that `typeof(Foo!(float.nan) != Foo!(float.nan))`, 
whereas this is clearly not the case, even with both the static 
assert and runtime assert failing. I'm just curious to 
understand the reasoning behind this, whether it's intentional, 
and whether it matters at all.


(1) f = f2; // This is assignment, not comparison
(2) alias VAL = f; // This is not a data member so is not 
involved in comparisons or assignments


change "alias VAL" to "float VAL" and then you might see the 
behavior you expect.


Re: Floating point in the type system

2015-09-12 Thread anonymous via Digitalmars-d
On Saturday 12 September 2015 18:08, Robert wrote:

> It's unusual, because `float.nan != float.nan`, so one might 
> expect that `typeof(Foo!(float.nan) != Foo!(float.nan))`, whereas 
> this is clearly not the case, even with both the static assert 
> and runtime assert failing. I'm just curious to understand the 
> reasoning behind this, whether it's intentional, and whether it 
> matters at all.

I don't know what the compiler actually does, but it looks like the 
comparison of template value arguments doesn't use equality, but something 
more akin to `is` instead (bitwise equality).

If that's right, then `is(Foo!(float.nan) == Foo!(float.nan))` holds because 
`float.nan is float.nan` holds.

Same behavior with a struct instead of float:

struct S
{
bool opEquals(S other) {return false;}
}
struct Foo(S s)
{
}
static assert(S.init != S.init); /* not equal */
static assert(S.init is S.init); /* but bit for bit identical */
static assert(is(Foo!(S.init) == Foo!(S.init)));




Re: Floating point in the type system

2015-09-12 Thread Atila Neves via Digitalmars-d

On Saturday, 12 September 2015 at 15:13:27 UTC, Robert wrote:

Hi all,

I came across this example, and wondered what your thoughts on 
it are:



```
void main(string[] args)
{
struct Foo(float f) {
alias VAL = f;
float getF() {
return f;
}
}

Foo!(float.nan) f;
Foo!(float.nan) f2;

// This will fail at compile time
static assert(f.VAL == f2.VAL);

// This will fail at run time
assert(f.getF() == f2.getF());

// But this is ok
f = f2;
}
```

It seems a little unusual to me.

Robert


What do think is unusual?

Atila



Re: Floating point in the type system

2015-09-12 Thread Robert via Digitalmars-d

On Saturday, 12 September 2015 at 15:49:23 UTC, Atila Neves wrote:

On Saturday, 12 September 2015 at 15:13:27 UTC, Robert wrote:

Hi all,

I came across this example, and wondered what your thoughts on 
it are:



```
void main(string[] args)
{
struct Foo(float f) {
alias VAL = f;
float getF() {
return f;
}
}

Foo!(float.nan) f;
Foo!(float.nan) f2;

// This will fail at compile time
static assert(f.VAL == f2.VAL);

// This will fail at run time
assert(f.getF() == f2.getF());

// But this is ok
f = f2;
}
```

It seems a little unusual to me.

Robert


What do think is unusual?

Atila


It's unusual, because `float.nan != float.nan`, so one might 
expect that `typeof(Foo!(float.nan) != Foo!(float.nan))`, whereas 
this is clearly not the case, even with both the static assert 
and runtime assert failing. I'm just curious to understand the 
reasoning behind this, whether it's intentional, and whether it 
matters at all.