Better support for OOP?

It would be nice if ReScript had better support for OOP. The reason being is that there are lots of JS APIs use an OOP style and if ReScript also supported OOP then it should be easier to write bindings for APIs without having to create wrapper functions around for each method. Instead we could just call the method on the object.

This can be done today using a record type with function properties I think. Where does this fall short?

I am not sure if you mean something different, but we usually use abstract types / modules and @send functions to express method calls… something like this:

module Moment = {
  type t
  
  @module("moment")
  @new external fromString: string => t = "default"

@send external seconds: (t, int) => float = "seconds"
}

let obj = Moment.fromString("")

obj->Moment.seconds(20)->Js.log

Which does translate to your typical OOP call without any wrapper code:

var obj = new Moment("");

console.log(obj.seconds(20));

But I guess you are talking about something like having a type obj = {..} definition where all the methods are defined in?

3 Likes

I didn’t realize that that’s what @send did. That’s pretty neat.

The other nice thing about OCaml objects is that you don’t have to prefix the method name with the module name. That means that calling the seconds method would look like:

obj#seconds(20)

I know that you can use open to avoid having to write Moment. I’m not sure what happens if you open multiple modules that use the same identifier though. It seems like enabling some of OCaml’s OOP features in ReScript could make using methods on objects a bit more ergonomic.

The last open shadows the identifiers from the previously opened module. That’s why you are supposed to open a module on the closest call site possible to prevent name clashes.

The OCaml object system is different in ReScript. We actually used to have two ways of doing objects… JS objects and OCaml objects. The maintenance overhead was non-trivial, that’s why it has been unified to JS objects only (as seen here).

I am not sure if the syntax will provide ways to express methods in the current structural object system, since the original idea was to have one general way on doing things (modules and functions) and keep things simple. Having a bunch of functions that operate on a data structure is definitely more tree-shakable than having data / methods mixed together.

5 Likes