Skip to content

Commit

Permalink
Merge b59ee5e into 134e620
Browse files Browse the repository at this point in the history
  • Loading branch information
bobzhang committed Feb 6, 2018
2 parents 134e620 + b59ee5e commit 4e69621
Show file tree
Hide file tree
Showing 25 changed files with 1,326 additions and 370 deletions.
108 changes: 99 additions & 9 deletions jscomp/others/bs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,97 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)


(** A stdlib shipped with BuckleScript *)
(** A stdlib shipped with BuckleScript
This stdlib is still in beta status, but we encourage you to try it out and
provide feedback.
{b Motivation }
The motivation of creating such library is to provide BuckleScript users a
better end-to-end user experience, since the original OCaml stdlib was not
writte with JS platform in mind, below are a list of areas this lib aims to
improve: {ol
{- 1. Consistency in name convention: camlCase, and arguments order}
{- 2. Exception thrown functions are all suffixed with {i Exn}, e.g, {i getExn}}
{- 3. Beter peformance and smaller code size running on JS platform}
}
{b Name Convention}
For higher order functions, it will be suffixed {b U} if it takes uncurried
callback.
{[
val forEach : 'a t -> ('a -> unit) -> unit
val forEachU : 'a t -> ('a -> unit [\@bs]) -> unit
]}
In general, uncurried version will be faster, but it is less familiar to
people who have a background in functional programming.
{b A special encoding for collection safety}
When we create a collection library for a custom data type, take {i Set} for
example, suppose its element type is a pair of ints,
it needs a custom {i compare} function. However, the {i Set} could not
just be typed as [ Set.t (int * int) ],
its customized {i compare} function needs to be
manifested in the signature, otherwise, if the user create another
customized {i compare} function, and the two collection would mix which
would result in runtime error.
The original OCaml stdlib solved the problem using {i functor} which is a big
closure in runtime; it makes dead code elimination much harder.
We introduced a phantom type to solve the problem
{[
type t = int * int
module I0 =
(val Bs.Dict.comparableU ~cmp:(fun[\@bs] ((a0,a1) : t) ((b0,b1) : t) ->
match compare a0 b0 with
| 0 -> compare a1 b1
| c -> c
))
let s0 = Bs.Set.make (module I0)
module I1 =
(val Bs.Dict.comparableU ~cmp:(fun[\@bs] ((a0,a1) : t) ((b0,b1) : t) ->
match compare a1 b1 with
| 0 -> compare a0 b0
| c -> c
))
let s1 = Bs.Set.make (module I1)
]}
Here the compiler would infer [s0] and [s1] having different type so that
it would not mix.
{[
val s0 : Bs.Set.t ((int * int), I0.id)
val s1 : Bs.Set.t ((int * int), I1.id)
]}
{b Collection Hierachy}
In general, we provide a generic collection module, but also create specialized
modules for commonly used data type, take {i Bs.Set} for example
{[
Bs.Set
Bs.Set.Int
Bs.Set.String
]}
The specialized module {i Bs.Set.Int}, {i Bs.Set.String} is in general more
efficient.
Currently, both {i Bs_Set} and {i Bs.Set} are accessible to users for some
technical rasons,
we {b strongly recommend} users stick to qualified import, {i Bs.Sort}, we may hide
the internal, {i i.e}, {i Bs_Set} in the future
*)

(** {!Bs.Dict}
Expand All @@ -37,8 +127,8 @@
module Dict = Bs_Dict

(** {!Bs.Array}
Utililites for Array functions
{b mutable array}: Utililites functions
*)
module Array = Bs_Array

Expand Down Expand Up @@ -77,7 +167,7 @@ module Range = Bs_Range

(** {!Bs.Set}
The toplevel provides generic immutable set operations.
The toplevel provides generic {b immutable} set operations.
It also has three specialized inner modules
{!Bs.Set.Int} and {!Bs.Set.String}
Expand All @@ -90,7 +180,7 @@ module Set = Bs_Set

(** {!Bs.Map},
The toplevel provides generic immutable map operations.
The toplevel provides generic {b immutable} map operations.
It also has three specialized inner modules
{!Bs.Map.Int} and {!Bs.Map.String}
Expand All @@ -102,7 +192,7 @@ module Map = Bs_Map

(** {!Bs.MutableSet}
The toplevel provides generic mutable set operations.
The toplevel provides generic {b mutable} set operations.
It also has two specialized inner modules
{!Bs.MutableSet.Int} and {!Bs.MutableSet.String}
Expand All @@ -111,7 +201,7 @@ module MutableSet = Bs_MutableSet

(** {!Bs.MutableMap}
The toplevel provides generic mutable map operations.
The toplevel provides generic {b mutable} map operations.
It also has two specialized inner modules
{!Bs.MutableMap.Int} and {!Bs.MutableMap.String}
Expand All @@ -122,7 +212,7 @@ module MutableMap = Bs_MutableMap

(** {!Bs.HashSet}
The toplevel provides generic mutable hash set operations.
The toplevel provides generic {b mutable} hash set operations.
It also has two specialized inner modules
{!Bs.HashSet.Int} and {!Bs.HashSet.String}
Expand All @@ -132,7 +222,7 @@ module HashSet = Bs_HashSet

(** {!Bs.HashMap}
The toplevel provides generic mutable hash map operations.
The toplevel provides generic {b mutable} hash map operations.
It also has two specialized inner modules
{!Bs.HashMap.Int} and {!Bs.HashMap.String}
Expand Down
41 changes: 33 additions & 8 deletions jscomp/others/bs_Array.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ let getExn arr i =
[%assert i >= 0 && i < length arr] ;
getUnsafe arr i
let set arr i v =
if i >= 0 && i < length arr then setUnsafe arr i v
if i >= 0 && i < length arr then (setUnsafe arr i v; true) else false

let setExn arr i v =
[%assert i >= 0 && i < length arr];
Expand Down Expand Up @@ -311,29 +311,54 @@ let rec everyAux arr i b len =
everyAux arr (i + 1) b len
else false

let rec someAux arr i b len =
if i = len then false
else
if b (getUnsafe arr i) [@bs] then true
else someAux arr (i + 1) b len

let everyU arr b =
let len = length arr in
everyAux arr 0 b len

let every arr f = everyU arr (fun[@bs] b -> f b)

let someU arr b =
let len = length arr in
someAux arr 0 b len
let some arr f = someU arr (fun [@bs] b -> f b)

let rec everyAux2 arr1 arr2 i b len =
if i = len then true
else if b (getUnsafe arr1 i) (getUnsafe arr2 i) [@bs] then
everyAux2 arr1 arr2 (i + 1) b len
else false

let rec someAux2 arr1 arr2 i b len =
if i = len then false
else if b (getUnsafe arr1 i) (getUnsafe arr2 i) [@bs] then
true
else someAux2 arr1 arr2 (i + 1) b len


let every2U a b p =
let lena = length a in
let lenb = length b in
if lena <> lenb then false
else
everyAux2 a b 0 p lena
everyAux2 a b 0 p (min (length a) (length b))

let every2 a b p = every2U a b (fun[@bs] a b -> p a b)

let some2U a b p =
someAux2 a b 0 p (min (length a) (length b))

let some2 a b p = some2U a b (fun [@bs] a b -> p a b)

let eqU = every2U
let eq = every2
let eqU a b p =
let lena = length a in
let lenb = length b in
if lena = lenb then
everyAux2 a b 0 p lena
else false

let eq a b p = eqU a b (fun [@bs] a b -> p a b )

let rec everyCmpAux2 arr1 arr2 i b len =
if i = len then 0
Expand Down

0 comments on commit 4e69621

Please sign in to comment.