Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve Js.Int and change some functions to pipe-last #966

Merged
merged 6 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,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.1.0 2023-10-22
---------------
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" *)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't comment on them, but there are some refs to toPrecisionWithPrecision that are now obsolete:

[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.

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
Loading