5 ms·
Writing ReasonML Bindings for JavaScript APIs
- k__ 9y agoThe problem I see with the bindings at the moment is, JS uses very different data structures from Reason, so a simple conversion often doesn't give you the power pf Reasons type system. This requires people to bind to JS and then do some runtime-conversion to get idiomatic Reason out of it.
- hongbo_zhang 9y agoNot really. You can model complex js data type as abstract type, and only provide functions needed
- k__ 9y agoJS data structures are basically big objects with strings as differntiator. Reason works with lists, tupels and variants
- jasim 9y agoThere is no escaping the mapping. It doesn't matter if it is Reason or PureScript, Elm, or Fable - you have to parse the incoming data into a static type if you want to enjoy the benefits of types. The good thing is that you can build the rest of your system with a firm guarantee on the shape and structure of the data. No null checks, no missing keys. If you are careful with your parsing you can raise exceptions or return None if the incoming data is not well-formed (missing keys or even extra keys). Reason/BuckleScript when run on a Javascript runtime also has a `Js.t` type which is basically the Javascript object. You do have to define the shape of it similar to how you'd define a record type, but you don't need to convert it into a native record. JS arrays are also natively supported - it maps 1:1 to BuckleScript's array. I like to convert arrays into lists since they are better suited for value-based programming (pattern-matching over [head, ...tail] inside recursive functions). And if you create your types in a way that invalid states are impossible, you've just reduced the cognitive load needed to work on the system for the rest of its life by an order of magnitude. Here are some resources on this wonderful programming technique: - https://fsharpforfunandprofit.com/posts/designing-with-types-making-illegal-states-unrepresentable/ https://fsharpforfunandprofit.com/posts/designing-with-types... - https://www.youtube.com/watch?v=IcgmSRJHu_8 https://www.youtube.com/watch?v=IcgmSRJHu_8 - https://www.destroyallsoftware.com/talks/ideology https://www.destroyallsoftware.com/talks/ideology - https://blog.janestreet.com/effective-ml-revisited/ https://blog.janestreet.com/effective-ml-revisited/
- yawaramin 9y agoAnd records. You would typically define a record type to do the heavy lifting in, and do some lightweight conversions to and from JS. Here's an example: [@bs.deriving jsConverter] type person = {name: string, age: int}; let bob = {name: "Bob", age: 33}; let olderBob = {...bob, age: bob.age + 1}; let () = Js.log(personToJs(olderBob));
- k__ 9y agoBut the records wouldn't use variants.
- yawaramin 9y agoNope, you can definitely use variants in the records. BuckleScript (the compiler) will automatically convert them into JavaScript-friendly representations. Or you can also pick custom representations for each variant case.
- k__ 9y agoAh, yes if you only go from Reason to JS, becaue Reason is much richer. I was thinking about going from a JS library to Reason, where you basically get bags full of strings.