# Cure Status Update

**URL:** <https://erlangforums.com/t/cure-status-update/5249>\
**Category:** Cure Forum\
**Tags:** fsm, dependent-types, cure-news\
**Created:** [November 16, 2025, 4:39pm UTC](https://erlangforums.com/t/cure-status-update/5249 "2025-11-16T16:39:13Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mudasobwa](https://erlangforums.com/user_avatar/erlangforums.com/mudasobwa/32/231_2.png) [@mudasobwa](https://erlangforums.com/u/mudasobwa)\
**Post date:** [November 16, 2025, 4:39pm UTC](https://erlangforums.com/t/cure-status-update/5249/1 "2025-11-16T16:39:13Z")

</div>

I am back, working on [Cure](https://cure-lang.org/).

The license (Apache2, same as Elixir) is added. To run examples do `make clean && make all` in the project folder and then `./run_cure.sh examples/14_pipe.cure`. The handy compilation/running is pending.

### What’s There

**▸** [Pipes](https://cure-lang.org/api/pipe_operator.html) are monadic (see [cure-lang/examples/14\_pipe.cure at main · am-kantox/cure-lang · GitHub](https://github.com/am-kantox/cure-lang/blob/main/examples/14_pipe.cure) ). `5 |> double()` would return `Ok(10)` assuming `def double(x: Int): Int = x * 2`, `Ok(5) |> double()` too. `Error(“Nah”)` as LHO would not attempts to call RHO and would be propagated.  
▸ **Peano arithmetics** `Nat` declared as `Succ(Succ(…(Zero)))` is there, although I am not sure I am to keep it. `Int` and `Float` are to be [most likely] ditched in favor of `Number`.  
▸ `List` and `Vector` are fully functional.  
▸ `Ok(T)`, `Error(E)`, `Result(T, E)`, etc.

### Questions

▸ Shall I create kinda google group in addition to [GH Discussions](https://github.com/am-kantox/cure-lang/discussions/13)? I am not a big fan of groups myself.  
▸ Shall I continue with typeclasses which are half-done or there is something more expected?  
▸ What kind of tooling should come first (now the compilation is awkward.)  
▸ Shall I make LSP fully robust before anything else (including SMT solver intergration)?

Thanks.

---

<div class="post-metadata">

**Author:** ![nzok](https://erlangforums.com/letter_avatar_proxy/v4/letter/n/4af34b/32.png) [@nzok](https://erlangforums.com/u/nzok)\
**Post date:** [November 16, 2025, 8:44pm UTC](https://erlangforums.com/t/cure-status-update/5249/2 "2025-11-16T20:44:44Z")

</div>

Why on earth would you “ditch” Int and Float “in Favour of Number”? Integers and floats do not satisfy the same laws. For example, addition of integers is associative, while addition of floats most definitely isn’t. X -Y + Y always gives X back in integer arithmetic, not in floating-point arithmetic. For Cure’s purposes, it would make sense to eliminate Float, but not to eliminate trustworthy arithmetic.

---

<div class="post-metadata">

**Author:** ![mudasobwa](https://erlangforums.com/user_avatar/erlangforums.com/mudasobwa/32/231_2.png) [@mudasobwa](https://erlangforums.com/u/mudasobwa)\
**Post date:** [November 17, 2025, 5:08am UTC](https://erlangforums.com/t/cure-status-update/5249/3 "2025-11-17T05:08:47Z")

</div>

I should have said `Decimal` not `Number` (andalso I am thinking about `Rational`.) I meant I want the trustworthy arithmetic only.

---

<div class="post-metadata">

**Author:** ![nzok](https://erlangforums.com/letter_avatar_proxy/v4/letter/n/4af34b/32.png) [@nzok](https://erlangforums.com/u/nzok)\
**Post date:** [November 17, 2025, 9:37am UTC](https://erlangforums.com/t/cure-status-update/5249/4 "2025-11-17T09:37:44Z")

</div>

But what does Decimal mean? Does it mean scaled decimal arithmetic (n x 10\*\*s)?  
I wrote and tried to get published a verified specification of scaled  
decimal arithmetic (there being no such thing in the LIA standards),  
and it’s a bit less simple to reason about than one might have hoped.  
For example, there are infinitely many _distinguishable_ zeros and of  
course infinitely many pairs X Y where X-Y is zero but X and Y  
are distinguishable nonzero numbers.  
For what it’s worth, having implemented both scaled decimal and  
rational arithmetic in more than one language,  
rational arithmetic seems to be somewhat easier to implement and a lot  
easier to reason about.

---

<div class="post-metadata">

**Author:** ![mudasobwa](https://erlangforums.com/user_avatar/erlangforums.com/mudasobwa/32/231_2.png) [@mudasobwa](https://erlangforums.com/u/mudasobwa)\
**Post date:** [November 17, 2025, 12:18pm UTC](https://erlangforums.com/t/cure-status-update/5249/5 "2025-11-17T12:18:07Z")

</div>

> [@nzok](#):
>
> it’s a bit less simple to reason about than one might have hoped

That’s why I hesitate to just jump in. I thought about **ISO/IEC 60559:2020** as a starting point, or even [Decimal v2.3.0 — Documentation](https://hexdocs.pm/decimal) .

> [@nzok](#):
>
> rational arithmetic seems to be somewhat easier to implement and a lot  
> easier to reason about

That was my gut feeling, but I frankly didn’t dig into to be able to argue about.

The only thing I can tell is I find it hostile to the 99.(9)% of users to keep in mind all the drawbacks of floating point arithmetics and to decide whether, say, currency exchange rates coming from the external source must be `List(Result(Int, _))` or `List(Result(Float, _))`.

---

<div class="post-metadata">

**Author:** ![nzok](https://erlangforums.com/letter_avatar_proxy/v4/letter/n/4af34b/32.png) [@nzok](https://erlangforums.com/u/nzok)\
**Post date:** [November 18, 2025, 10:52am UTC](https://erlangforums.com/t/cure-status-update/5249/6 "2025-11-18T10:52:53Z")

</div>

ISO 60599 is precisely what it says on the cover: a standard for FLOATING-POINT arithmetic.  
In fact it is a standard that covers both binary and decimal floating-point.  
Decimal floats have all the quirks of binary floats and add some of their own.

There are standards for programming languages with binary and decimal fixed-point  
arithmetic, notably COBOL, PL/I, SQL, and Ada. Several computers have had  
instruction-set-level support for decimal arithmetic, including the VAX computers  
of fond memory and the IBM System/360 series, whose latest incarnation, z/Series,  
is still with us.

We can classify fixed-point systems in several ways. One way is

- bounds and scale are part of the type (COBOL, PL/I, SQL, Ada).  
The size is known at compile time so variables can be stack-allocated or  
statically allocated like bounded integers. Arithmetic operations are  
loop-free. The scale adjustments needed for addition, subtraction, and  
comparison are known at compile time.
- bounds are not part of the type but the scale is (this can be done easily  
in any language with dependent types, like Agda and in fact Haskell and C++  
are just powerful enough to do it). Values have to be heap-allocated, and  
operations are not loop-free, but scale adjustments can be done at  
compile time.
- scale is an independent part of the value. That is, a number is (n / 10\*\*s)  
with no restrictions on n or s so that multiple (n,s) pairs represent  
numerically equal but distinguishable values.
- scale is a derived part of the value. That is, a number is still (n / 10\*\*s)  
but this is constrained in one way.  
Alternative II: n is 0 and s is 0 or n is not divisible by 10.  
Alternative I: s is 0 or (n is not zero, s \> 0, and n is not divisible by 10).  
Alternative I allows a fixed-point value that is integral to _be_ that integer.

I came into this area by way of Smalltalk. I wanted to implement the ANSI Smalltalk  
standard, and that includes a ScaledDecinal class. The standard appeals to the LIA  
standard for the semantics, which is unfortunate, because no part of the LIA standard  
has ever had anything to say about it, and the result is that different Smalltalk  
systems do different things.

- One Smalltalk bases its decimal arithmetic on IBM/360 hardware: numbers have up to  
31 decimal digits, a sign, and a scale.
- Two Smalltalk systems say “a ScaledDecimal number is _really_ a rational number,  
_any_ rational number, even one like 22/7, and the scale has no influence on how  
calculations are done but only on how values are printed”, which still has me shaking  
my head in disbelief that anyone ever thought that was a good idea.
- My Smalltalk follows the independent-part-of-the-value model, which seems forced by  
the ANSI interface, with the consequence that 0.00s2 and 0.000s3 are numerically equal  
but do not behave the same way.

As for the Elixir Decimal you linked to,

- having THREE numbers in the representation instead of two seems wasteful;  
worse than that, it creates a +0 vs -0 distinction, in the representation.
- the example

> D.div(1, 3)  
> Decimal.new(“0.3333333333333333333333333333”)  
> came as a very nasty shock. There is simply no way to justify this.  
> If x and y are decimal numbers, then x/y is a rational number, NOT a fixed point  
> number, and if there is any coherent rule for how many decimal places the  
> quotient should have, nobody seems to have found one.

- Decimal has something called a “context” which is stored in the  
process dictionary, meaning that its arithmetic is _state-dependent_ ,  
which is NOT something you want to have to include in your reasoning.  
This is because Decimal is yet another FLOATING-POINT arithmetic.

Note that I am not saying that Decimal isn’t _useful_ or that ISO 60559 isn’t _useful_.  
What I’m saying is that they are _floating-point_ systems and as such _messy_ and  
tricky to reason about.

Of course it depends on what calculations you need to reason about.  
Addition, subtraction, negation, absolute value, sign, multiplication,  
any of several variants of quotient and remainder to a specified precision,  
even square and cube roots to a specified precision, and comparison,  
these all fit _exact_ scaled decimal arithmetic very well, especially using  
alternative I. If you want trig functions, hyperbolic functions, Bessel functions,  
gamma, beta, exponentials and logarithms etc, then you must be satisfied with  
_inexact_ approximations and decimal floats may be a good choice.  
If you want financial calculations, where thanks to compound interest  
many functions have exponential or logarithmic aspects, a hybrid  
approach where calculations are either exact or have a degree of  
approximation explicit in the function call, may be the right  
approach.

As for currency exchange rates, it is always the case that you can  
find a positive integer for each currency such that  
Nx units of currency Cx convert to Ny units of currency Cy.  
There is no reason to involve floating-point numbers.  
(Why yes, my Smalltalk _does_ have currency conversion support.  
How ever did you guess?)

---

<div class="post-metadata">

**Author:** ![mudasobwa](https://erlangforums.com/user_avatar/erlangforums.com/mudasobwa/32/231_2.png) [@mudasobwa](https://erlangforums.com/u/mudasobwa)\
**Post date:** [November 18, 2025, 12:42pm UTC](https://erlangforums.com/t/cure-status-update/5249/7 "2025-11-18T12:42:41Z")

</div>

Thank you a ton for the insight, I cannot express how valuable it is for me. Can I take a look at your implementation or it’s closed source?—I would be extremely grateful.

> [@nzok](#):
>
> If you want financial calculations […]

Well, 10 years in FinTech taught me there are also weird, non-documented and possibly not widely-spread circumstances, when you want to divide an amount in three equal shares and then (past years) join them back to the whole without any shenanigans, which brings `Rationals`.

> [@nzok](#):
>
> it is always the case that you can  
> find a positive integer for each currency such that  
> Nx units of currency Cx convert to Ny units of currency Cy

Correct, but I was under [possibly wrong] impression there is a good solution that does not require a dedicated code explicitly for currency exchange.

In any case, I am still positive this particular topic deserves much more brain effort that it usually receives, that’s why I postponed it until I have a capacity to figure it out thoroughly. Your advice will be then of a great help, thanks again!
