I am building a small Domain Specific Language (spreadsheet style calculations) called FlatLang with some interesting properties.
These are my notes.
FlatLang is a functional, pure, total, statically typed language. To simplify,
1) (almost) everything is a function
2) each function's 'functionality' is described completely by its inputs and outputs
3) each function will produce an output in finite time
4) input and output types are checked at compile time
We can run a program with various operations, that will not error, as long as the inputs are of the correct type.
p = \ a -> \ b -> a + b
will sum numbers and output a number.
"*" and "-" operations will also work as expected, as long as our inputs are numbers, and not strings (which we know is not a problem because we check at compile time).
Division however is problematic.
d = \ a -> \ b -> a / b
if "b" is zero we cannot rely on mathematics to return a number. Mathematics gives us a way to apply reasoning in a consistent way.
Let's see how various programming languages handle division by zero.
1 / 0 Infinity
1 / 0 == Infinity 2 / 0 == Infinity 2 / 0 == 1 / 0 2 == 1
Not very consistent!
Also, last I checked, infinity is not actually a number, but we expect only numbers as output to our function..
1 / 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: integer division or modulo by zero
Elixir / Erlang
1 / 0 ** (ArithmeticError) bad argument in arithmetic expression :erlang./(1, 0)
1 / 0 uncaught exception: Division_by_zero,-5
System.Console.WriteLine(1 / 0) Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero. at <StartupCode$main>.$Main.main@ () <0x41ddfe00 + 0x0000c> in <filename unknown>:0 [ERROR] FATAL UNHANDLED EXCEPTION: System.DivideByZeroException: Attempted to divide by zero. at <StartupCode$main>.$Main.main@ () <0x41ddfe00 + 0x0000c> in <filename unknown>:0 exit status 1
The previous examples show 'exception' errors.
This violates one of our goals, that we get a "result" (e.g. a valid number) for every function.
Perhaps we could relax our goal, say failures or exceptions are acceptable, and include them as a result, but I want FlatLang to be unbreakable. I do not want to run a FlatLang program and receive an error back, I want to make sure I get a result every time!
Also, if I allow exceptions as output, then I need some exception handling logic. This is complicated and error prone, best avoided.
Programming languages have not reached a consensus on how to handle something as simple as division by zero, which shows how immature the field is.
Furthermore many popular approaches lead to inconsistencies or necessitate adding complicated often error prone exception handling logic.
Next up: how we can augment exception handling in a consistent, easy way.