1 + 1 -- Int plus 1 + "1" -- Type error: "String is not an instance of Num" "1" +  -- Type error
Fun with Numbers
Many programming languages - especially the "practical" ones - have their weird corner cases and inconsistencies when dealing with numbers as nicely pointed out by this xkcd comic.
This comes to a large extend from using numerical operators with non-numerical values
+ for String concatenation) and automatic coercion
between numbers and Strings. These issues do not occur in Frege (nor in Haskell) where
operators never work on a mixture of types.
However, there is some clever inference going on at compile time to make a programmer’s life easier. The type system would in principle not allow to write
1 + 1.0
1 is an
1.0 is a
+ requires both operands
to be of the same type.
The compiler is smart enough to not insist on you writing
1.0 + 1.0 for this
simple case of number literals. It sees what you meant by resolving the
type constraints in the expression that
1 is used in.
Let’s see another example that is a just a bit more advanced:
1 / 2
2 would be
Int literals but the division operator is not
defined for the
Int type (or any other Integral type) in Frege.
It requires a number type of the
typeclass for both operands and Frege chooses the concrete type
for you in this case (unlike Haskell, this default is fix).
1 / 2 == 0.5 -- type is Double
This is very much unlike Java where
This has some interesting consequences since the Java
handles many special cases in a nice manner.
Double is nice
The most common special case is division by zero. How is this handled in Frege?
1 / 0 -- Infinity
The String representation of a number is not always made up from
digits only. Developers are usually aware that there are dots, minus, and the
And how do we calculate with Infinity? Well, when you add to infinity, the result is equally infinite. You can even add infinities to infinities. Division is not defined, though.
(1/0) + 1 -- Infinity (1/0) * 3 -- Infinity (1/0) + (1/0) -- Infinity (1/0) * (1/0) -- Infinity (1/0) / (1/0) -- NaN
And what do we gain from having
Infinity as opposed to
Infinity you have a chance of coming back to numbers that you
can do normal calculations with:
1 / (1/0) -- 0.0
Wow, this is now definitely interesting and makes us ask for other corner cases of mathematics:
0 / 0 -- NaN (1/0) / 0 -- Infinity 0 ^ 0 -- 1
This looks like we have violated some rules of mathematics.
Have we broken math?
In mathematics, division by zero is undefined. Likewise is division by infinity or zero to the power of zero.
However, computers calculate with approximations, they do applied numeric math at best.
Math.E with limited precision. Heck, even square roots are only
import frege.prelude.Math Math.sqrt 2 * Math.sqrt 2 -- 2.0000000000000004
And given that we have to deal with limited precision anyway, we can just as well take liberty to make operations like division by zero not blowing up our programs but behaving reasonably well within computational bounds.