3 ms·
I tried using ReasonML for a blockchain project, and I just couldn't get past being able to express this logic of interacting with a third party library: ``` c
by splintercell 8y ago
I tried using ReasonML for a blockchain project, and I just couldn't get past being able to express this logic of interacting with a third party library:
```
const contract = new web3.eth.Contract(ABI, contractAddress, {from})
```
in ReasonML easily, despite spending hours on trying to figure it out. At the end I finally reached to a feature request asking to be able to do 'new' on member functions, and it was in 'planning'.
On the other hand Elm's approach to JS interop seemed to be far superior for quirks like these. Javascript code lives on the other side of the border, and Elm code on this. You don't have to create a type for the whole class of the third party library, just the data you want Elm to manage.
- dwohnitmok 8y agoElm has its own infelicities with JS interop. Everything has to be done through ports, which means you have to contort your control flow to work with JS (which is extremely cumbersome if your JS is just pure functions). For those not familiar with Elm it means you basically have to interact with all JS code through a pub-sub model and can't ever directly call JS code. Elm's creator has his reasons for why he does this (https://guide.elm-lang.org/interop/ports.html https://guide.elm-lang.org/interop/ports.html), but it can make calling JS from Elm quite a pain.
- scns 8y agoYou can embed raw js in reason/BS easily with [%raw ] iirc. Check the bucklescript documentaton, where the interop docs are located.
- splintercell 8y agoBut then I don't get the benefit of ReasonML/BS. I can do that, but then I keep having to do that everywhere I interact with that library (which is essentially the core part of my app). I do the same thing in Elm, but all that code is living in a JS file, and it can be in Typescript/whatever.
- AlexCoventry 8y agoThe usual solution to that kind of interop issue is to use wrapper modules and functions.
- yawaramin 8y agoCan you point to the feature request where you asked for 'new' on member functions, please? I would like to correct whatever response said it was in 'planning', because it has been doable for a long time now. Here's some sample Reason that outputs pretty much exactly your above code: module Web3 = { module Eth = { module Contract = { type t; [@bs.module "web3"] [@bs.scope "eth"] [@bs.new] external make: (string, string, {. "from": string}) => t = "Contract"; }; }; }; let contract = Web3.Eth.Contract.make("ABI", "contactAddress", {"from": "from"}); You can try it out in the interactive playground. Also, regarding this: > You don't have to create a type for the whole class of the third party library, just the data you want Elm to manage. That's exactly how Reason JavaScript bindings work too.
- splintercell 8y agoJust to be clear (and I now remember more details), I wanted to do bs.new with bs.send, but it wouldn't work. I am going to try what you suggested, but keep in mind I did go to the slack channel and tried asking this, none of their solutions looked like yours. Either way, intuitively @bs.new and @bs.send should be able to work together. https://github.com/BuckleScript/bucklescript/issues/2659 https://github.com/BuckleScript/bucklescript/issues/2659
- yawaramin 8y agoI see your problem (which is btw quite different from your original comment ;-) ). In a statically-typed language like Reason it's difficult to model dynamically-generated types like `hello_proto.Greeter`. One way is to use a functor ( https://v1.realworldocaml.org/v1/en/html/functors.html https://v1.realworldocaml.org/v1/en/html/functors.html ) but they have their limitations. This is why we have things like graphql_ppx which is a compiler extension to generate types from GraphQL schemas at compile-time. You'd need something like this (or, easier, a ReasonML-targeting gRPC/Protobuf client generator) to solve the issue brought up in GitHub.