Skip to content
Discussions/App Development/How does the REPL handle floats, and how can you perform Mathematical functions on them?Forum ↗

How does the REPL handle floats, and how can you perform Mathematical functions on them?

App Development8 posts710 views13 likesLast activity Mar 2021
QU
quidagisOP
Mar 2021
With the new DAML SDK v 1.4.0, the DAML REPL can be used as an interactive IDE, without connecting to any ledger. I know that @cocreature and @Gary_Verhaegen were working on it, thanks for them and any other contributor for this great feature! This new feature means that you don’t have to resort to GHCi, the Haskell interactive IDE, if you want to experiment with a more complex DAML function in order to deeper understanding it. One example where I formerly had to use GHCi to understand what’s …

Thanks for that write-up, I like experimenting with REPLs, all types.

It took me a bit to discover some helpful features, and I was able to write some simple Physics formulae using fake information.

However I note this:

daml> let X = 20
daml> let y = 5
daml> let q = 10
daml> let z = (x*y)/q
daml> z
10

However if I assign a variable to a Float, there are issues:

daml> let w = 26.0
parse error on input ‘=’
daml> let w = "26.0"
26.0
daml> w
"26.0"

If I try a simple equation using a Float, the REPL throws errors.

As a Haskell/DAML novice, how does the REPL handle floats, and how can you perform Mathematical functions on them? Does this require the import of a specific Module/Library?

GA
Gary_Verhaegen
Mar 2021

The Daml language simply des not have floating point numbers. This is a design choice.

If you still want decimal numbers, you can have them with the Numeric type, which is a family of fixed-point decimal number types. The Decimal type is the member of that family with 10 decimal places. Here is an example:

$ daml repl
daml> let w = 26.0 : Decimal
daml> w + 1.0
27.0
daml> w + 0.5
26.5
daml> w + 0.0000000000000000005
File:     Line3.daml
Hidden:   no
Range:    6:1-6:5
Source:   Core to DAML-LF
Severity: DsError
Message: 
  Failure to process DAML program, this feature is not currently supported.
  Rational is out of bounds: 5.0e-19. It cannot be represented without loss of precision. Maximum
  precision for the Numeric 10 type is 10^-10.
  (1, 2000000000000000000)
daml> let x = 1.0 : Numeric 2
daml> x + w
File:     Line4.daml
Hidden:   no
Range:    7:21-7:22
Source:   typecheck
Severity: DsError
Message: 
  Line4.daml:7:21: error:
  • Couldn't match type ‘10’ with ‘2’
  Expected type: Numeric 2
  Actual type: Decimal
  • In the second argument of ‘(+)’, namely ‘w’
  In the first argument of ‘show’, namely ‘(x + w)’
  In the first argument of ‘return’, namely ‘(show (x + w))’
daml> 

You have to specify the type of decimal numbers because you have to specify their scale. Decimal numbers need to have to same scale to operate on them.

CO
cocreature
Mar 2021

I think it’s also worth pointing out that

let w = 26.0

does not produce a parse error, it produces a type error because it cannot infer the scale of the Numeric:

daml> let x = 26.0
File:     Line1.daml
Hidden:   no
Range:    7:14-7:18
Source:   typecheck
Severity: DsError
Message: 
  Line1.daml:7:14: error:
  • Ambiguous type variable ‘n0’ arising from the literal ‘26.0’
  prevents the constraint ‘(NumericScale n0)’ from being solved.
  Relevant bindings include
  x : Numeric n0 (bound at Line1.daml:7:10)
  expr : Int -> Script (Numeric n0) (bound at Line1.daml:6:1)
  Probable fix: use a type annotation to specify what ‘n0’ should be.
  These potential instances exist:
  instance NumericScale 0 -- Defined in ‘GHC.Classes’
  instance NumericScale 1 -- Defined in ‘GHC.Classes’
  instance NumericScale 10 -- Defined in ‘GHC.Classes’
  ...plus 35 others
  (use -fprint-potential-instances to see them all)
  • In the expression: 26.0
  In an equation for ‘x’: x = 26.0
  In the expression:
  do let x = 26.0
  return x
QU
quidagis
Mar 2021

Thank you for the reply, I will do some experimenting and reading.

That solution makes sense but it sure looks a little ‘clunky’ :grinning:

SH
Shaul
Mar 2021

To give a bit more background on this, using floating point numbers can cause unexpected and dangerous errors, especially in the type of software which Daml is commonly used for.

Here are a few links which explain this much better than I can:

  1. Why You Should Never Use Float and Double for Monetary Calculations - DZone Java
  2. floating point - Why not use Double or Float to represent currency? - Stack Overflow
QU
quidagis
Mar 2021

Thank you for the extra information, I will read more on this.

GA
Gary_Verhaegen
Mar 2021

There is a lot to say about floating point arithmetics and all the ways it can go wrong, and all the tricks and techniques you can use to still make it produce “close enough” results.

I find the simplest way to convince yourself they should not be used when counting money is to just do 0.1 + 0.2 in your favourite language.

Here’s a line of Javascript I just executed in my browser console:

> 0.1 + 0.2 == 0.3
< false

Though, of course:

$ daml repl
> 0.1 + 0.2 == (0.3 : Decimal)
True
>
QU
quidagis
Mar 2021
Gary_Verhaegen:

Here’s a line of Javascript I just executed in my browser console:

> 0.1 + 0.2 == 0.3
< false

It is the same using the REPL from Python3 … I am convinced :grinning:

← Back to Discussions