Skip to content

Commit

Permalink
feat: improve Js.Int and change some functions to pipe-last (#966)
Browse files Browse the repository at this point in the history
* feat: improve Js.Int and change some functions to pipe-last

* chore: add changelog entry

* fix tests and consolidate functions

* fix docstring for toPrecision

* fix docstring for toPrecision relating to number of digits

* Update Changes.md

Co-authored-by: Javier Chávarri <[email protected]>

---------

Co-authored-by: Javier Chávarri <[email protected]>
  • Loading branch information
anmonteiro and jchavarri authored Dec 11, 2023
1 parent 521c40f commit cd6e9fa
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 109 deletions.
2 changes: 2 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ Unreleased
[#956](https://github.com/melange-re/melange/pull/956),
[#958](https://github.com/melange-re/melange/pull/958),
[#961](https://github.com/melange-re/melange/pull/961))
- BREAKING(runtime): Improve `Js.Int` and change some of its functions to pipe-last
([#966](https://github.com/melange-re/melange/pull/966))

2.2.0 2023-12-05
---------------
Expand Down
119 changes: 30 additions & 89 deletions jscomp/runtime/js_int.ml
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,17 @@ open Melange_mini_stdlib

(** Provides functions for inspecting and manipulating [int]s *)

type t = int

(** If we use number, we need coerce to int32 by adding `|0`,
otherwise `+0` can be wrong.
Most JS API is float oriented, it may overflow int32 or
comes with [NAN]
*)
(* + conversion*)

external toExponential : int -> string = "toExponential"
[@@mel.send]
(** Formats an [int] using exponential (scientific) notation
{b Returns} a [string] representing the given value in exponential notation
@raise RangeError if digits is not in the range \[0, 20\] (inclusive)
{[
(* prints "7.7e+1" *)
let _ = Js.log (Js.Int.toExponential 77)
]}
@see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential> MDN
*)

external toExponentialWithPrecision : int -> digits:int -> string
= "toExponential"
[@@mel.send]
external toExponential : ?digits:t -> string = "toExponential"
[@@mel.send.pipe: t]
(** Formats an [int] using exponential (scientific) notation
{b digits} specifies how many digits should appear after the decimal point. The
Expand All @@ -64,84 +49,44 @@ The output will be rounded or padded with zeroes if necessary.
@raise RangeError if digits is not in the range \[0, 20\] (inclusive)
{[
(* prints "7.70e+1" *)
let _ = Js.log (Js.Int.toExponentialWithPrecision 77 ~digits:2)
(* prints "5.68e+3" *)
let _ = Js.log (Js.Int.toExponentialWithPrecision 5678 ~digits:2)
Js.Int.toExponential 77 = "7.7e+1"
Js.Int.toExponential ~digits:2 77 = "7.70e+1"
Js.Int.toExponential ~digits:2 5678 = "5.68e+3"
]}
@see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential> MDN
*)

external toPrecision : int -> string = "toPrecision"
[@@mel.send]
(** Formats a [int] using some fairly arbitrary rules
{b Returns} a [string] representing the given value in fixed-point (usually)
[toPrecision] differs from [toFixed] in that the former will format the number
with full precision, while the latter will not output any digits after the
decimal point.
@raise RangeError if digits is not in the range accepted by this function (what do you mean "vague"?)
{[
(* prints "123456789" *)
let _ = Js.log (Js.Int.toPrecision 123456789)
]}
@see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision> MDN
*)
(* equivalent to `toString` I think *)

external toPrecisionWithPrecision : int -> digits:int -> string = "toPrecision"
[@@mel.send]
external toPrecision : ?digits:t -> string = "toPrecision"
[@@mel.send.pipe: t]
(** Formats an [int] using some fairly arbitrary rules
{b digits} specifies how many digits should appear in total. The
value must between 0 and some arbitrary number that's hopefully at least larger
than 20 (for Node it's 21. Why? Who knows).
{b digits} specifies how many digits should appear in total. The value must
between 1 and some 100.
{b Returns} a [string] representing the given value in fixed-point or scientific notation
The output will be rounded or padded with zeroes if necessary.
[toPrecisionWithPrecision] differs from [toFixedWithPrecision] in that the former
will count all digits against the precision, while the latter will count only
the digits after the decimal point. [toPrecisionWithPrecision] will also use
scientific notation if the specified precision is less than the number for digits
before the decimal point.
[toPrecision] differs from {!Js.Float.toFixed} in that the former will count
all digits against the precision, while the latter will count only the digits
after the decimal point. [toPrecision] will also use scientific notation if the
specified precision is less than the number for digits before the decimal
point.
@raise RangeError if digits is not in the range accepted by this function (what do you mean "vague"?)
@raise RangeError if digits is not between 1 and 100.
{[
(* prints "1.2e+8" *)
let _ = Js.log (Js.Int.toPrecisionWithPrecision 123456789 ~digits:2)
(* prints "0.0" *)
let _ = Js.log (Js.Int.toPrecisionWithPrecision 0 ~digits:2)
Js.Int.toPrecision 123456789 = "123456789"
Js.Int.toPrecision ~digits:2 123456789 = "1.2e+8"
Js.Int.toPrecision ~digits:2 0 = "0.0"
]}
@see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision> MDN
*)

external toString : int -> string = "toString"
[@@mel.send]
(** Formats a [int] as a string
{b Returns} a [string] representing the given value in fixed-point (usually)
{[
(* prints "123456789" *)
let _ = Js.log (Js.Int.toString 123456789)
]}
@see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString> MDN
*)

external toStringWithRadix : int -> radix:int -> string = "toString"
[@@mel.send]
external toString : ?radix:t -> string = "toString"
[@@mel.send.pipe: t]
(** Formats an [int] as a string
{b radix} specifies the radix base to use for the formatted number. The
Expand All @@ -152,21 +97,17 @@ value must be in the range \[2, 36\] (inclusive).
@raise RangeError if radix is not in the range \[2, 36\] (inclusive)
{[
(* prints "110" *)
let _ = Js.log (Js.Int.toStringWithRadix 6 ~radix:2)
(* prints "deadbeef" *)
let _ = Js.log (Js.Int.toStringWithRadix 3735928559 ~radix:16)
(* prints "2n9c" *)
let _ = Js.log (Js.Int.toStringWithRadix 123456 ~radix:36)
Js.Int.toString 123456789 = "123456789"
Js.Int.toString ~radix:2 6 = "110"
Js.Int.toString ~radix:16 3735928559 = "deadbeef"
Js.Int.toString ~radix:36 123456 = "2n9c"
]}
@see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString> MDN
*)

external toFloat : int -> float = "%floatofint"
external toFloat : t -> float = "%floatofint"

let equal (x : int) y = x = y
let max : int = 2147483647
let min : int = -2147483648
let equal (x : t) y = x = y
let max : t = 2147483647
let min : t = -2147483648
2 changes: 1 addition & 1 deletion jscomp/runtime/js_promise.ml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ external then_ : (('a -> 'b t)[@mel.uncurry]) -> 'b t = "then"

external catch : ((error -> 'a t)[@mel.uncurry]) -> 'a t = "catch"
[@@mel.send.pipe: 'a t]
(* [ p|> catch handler]
(* [ p |> catch handler]
Note in JS the returned promise type is actually runtime dependent,
if promise is rejected, it will pick the [handler] otherwise the original promise,
to make it strict we enforce reject handler
Expand Down
6 changes: 3 additions & 3 deletions jscomp/test/dist/jscomp/test/js_int_test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 16 additions & 16 deletions jscomp/test/js_int_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,43 @@ let suites = Mt.[
("toExponential", (fun _ ->
Eq("1.23456e+5", toExponential 123456)));
("toExponentialWithPrecision - digits:2", (fun _ ->
Eq("1.23e+5", toExponentialWithPrecision 123456 ~digits:2)));
Eq("1.23e+5", toExponential 123456 ~digits:2)));
("toExponentialWithPrecision - digits:4", (fun _ ->
Eq("1.2346e+5", toExponentialWithPrecision 123456 ~digits:4)));
Eq("1.2346e+5", toExponential 123456 ~digits:4)));
("toExponentialWithPrecision - digits:20", (fun _ ->
Eq("0.00000000000000000000e+0", toExponentialWithPrecision 0 ~digits:20)));
Eq("0.00000000000000000000e+0", toExponential 0 ~digits:20)));
(__LOC__, (fun _ ->
ThrowAny(fun () -> ignore @@ toExponentialWithPrecision 0 ~digits:101)));
ThrowAny(fun () -> ignore @@ toExponential 0 ~digits:101)));
("toExponentialWithPrecision - digits:-1", (fun _ ->
ThrowAny(fun () -> ignore @@ toExponentialWithPrecision 0 ~digits:(-1))));
ThrowAny(fun () -> ignore @@ toExponential 0 ~digits:(-1))));

("toPrecision", (fun _ ->
Eq("123456", toPrecision 123456)));
("toPrecisionWithPrecision - digits:2", (fun _ ->
Eq("1.2e+5", toPrecisionWithPrecision 123456 ~digits:2)));
Eq("1.2e+5", toPrecision 123456 ~digits:2)));
("toPrecisionWithPrecision - digits:4", (fun _ ->
Eq("1.235e+5", toPrecisionWithPrecision 123456 ~digits:4)));
Eq("1.235e+5", toPrecision 123456 ~digits:4)));
("toPrecisionWithPrecision - digits:20", (fun _ ->
Eq("0.0000000000000000000", toPrecisionWithPrecision 0 ~digits:20)));
Eq("0.0000000000000000000", toPrecision 0 ~digits:20)));
(__LOC__, (fun _ ->
ThrowAny(fun () -> ignore @@ toPrecisionWithPrecision 0 ~digits:101)));
ThrowAny(fun () -> ignore @@ toPrecision 0 ~digits:101)));
("toPrecisionWithPrecision - digits:-1", (fun _ ->
ThrowAny(fun () -> ignore @@ toPrecisionWithPrecision 0 ~digits:(-1))));
ThrowAny(fun () -> ignore @@ toPrecision 0 ~digits:(-1))));

("toString", (fun _ ->
Eq("123", toString 123)));
("toStringWithRadix - radix:2", (fun _ ->
Eq("11110001001000000", toStringWithRadix 123456 ~radix:2)));
Eq("11110001001000000", toString 123456 ~radix:2)));
("toStringWithRadix - radix:16", (fun _ ->
Eq("1e240", toStringWithRadix 123456 ~radix:16)));
Eq("1e240", toString 123456 ~radix:16)));
("toStringWithRadix - radix:36", (fun _ ->
Eq("2n9c", toStringWithRadix 123456 ~radix:36)));
Eq("2n9c", toString 123456 ~radix:36)));
("toStringWithRadix - radix:37", (fun _ ->
ThrowAny(fun () -> ignore @@ toStringWithRadix 0 ~radix:37)));
ThrowAny(fun () -> ignore @@ toString 0 ~radix:37)));
("toStringWithRadix - radix:1", (fun _ ->
ThrowAny(fun () -> ignore @@ toStringWithRadix 0 ~radix:1)));
ThrowAny(fun () -> ignore @@ toString 0 ~radix:1)));
("toStringWithRadix - radix:-1", (fun _ ->
ThrowAny(fun () -> ignore @@ toStringWithRadix 0 ~radix:(-1))));
ThrowAny(fun () -> ignore @@ toString 0 ~radix:(-1))));
]

;; Mt.from_pair_suites __MODULE__ suites

0 comments on commit cd6e9fa

Please sign in to comment.