Comparison operators (<, <=, >=, >, ==)

I just got bitten by a surprising behavior when trying to write some bindings for luxon.

if dt1 > dt2 {
  stuff
} else {
  otherStuff
}

This was compiling to

if (Caml_obj.caml_greaterthan(dt1, dt2)) {
  return stuff
} else {
  return otherStuff
}

I looked at the implementation of caml_greaterthan and it was giving incorrect comparisons. The thing is that luxon DateTime’s implement valueOf: t => float. This is common in the JS ecosystem to enable comparison operators to work smoothly. I’m wondering if the caml_greaterthan function should make use of it? What do you think?

In the meantime I’ve worked around it by using undocumented extension points

external isBefore: (t, t) => bool = "%ltint"
external isAfter: (t, t) => bool = "%gtint"
external isSameOrBefore: (t, t) => bool = "%leint"
external isSameOrAfter: (t, t) => bool = "%geint"
1 Like

You could define your own operators - like https://github.com/jacobp100/technicalc-core/blob/284485a89d1a3d32477455a1388d556fa8d5c9cd/packages/technicalc-calculator/src/Decimal/Decimal.res#L78

Then open the module to use those operators in place of the default OCaml operators - https://github.com/jacobp100/technicalc-core/blob/63a55b2b6edbaf1affe752c5c6bc29ffd6bf40ba/packages/technicalc-calculator/src/Formatting/Formatting_Scalar.res#L136

2 Likes

The thing is that luxon DateTime’s implement valueOf: t => float . This is common in the JS ecosystem to enable comparison operators to work smoothly.

You are right, there is no ad-hoc polymorphism in rescript. So that you can not have type a use a_equal and type b use b_equal automatically, it has to be passed explicitly.

Instead of relying on undocumented extensions, you can always use raw, something like below:

let  isBefore : (t,t)=> bool = %raw(`(a,b)=> a < b`)
3 Likes