Why do we need to use functions to get property values?

To rephrase this question in better detail, why do we need to do Js.Array2.length(arr) as opposed to arr.length?

This question also applies to any other properties of objects such as strings where we do not have access to instance methods (like str.slice()).

Is this a pattern that’s part of functional programming as a whole and are there any performance benefits of grabbing values in this way?

Perhaps this will help: https://github.com/yawaramin/bucklescript-bindings-cookbook/blob/master/ReScript.md#classes-and-oop

1 Like

This is somewhat helpful in seeing implementation details but I was wondering why we do things this way, it is just to achieve a cleaner syntax or is there some deeper meaning behind it?

Oh, OK. Well at its core, ReScript is a functional programming language. So basically it uses modules, types, and functions to express the equivalent concepts that OOP languages would express with classes and methods.


Gotcha so this is something inherit in FP, it would be helpful in a beginner’s guide to ReScript to include a snippet about this since someone transitioning from an OOP approach (such as myself) would probably be confused why this approach is used and why something like str.substring() just straight up doesn’t exist.

Yeah that might be a helpful point to add to their intro blurb. You could send a PR.

There is some good news - in the time since the Js modules were written ReScript added something called “records as objects”. The effect of this is that for simple properties we can use records do property access like arr.length (although not for Array since it’s a built-in type). For functions like str.substring() this approach isn’t recommended due to runtime implications, but that’s getting a bit beyond the scope of your question.

I don’t know if the existing types can be converted to use records without breaking existing applications, but I find it quite useful in my own custom bindings.

No, because Js.Array2.length(arr) compiles to arr.length in JS.

To answer the “why,” it may help to think about how functional languages like ReScript keep data separate from the functions that use data. In an OOP language like JavaScript, you may be used to data carrying around various properties or methods which allow you to do stuff with it. In ReScript, the data is just data, and you do everything with functions.

Because the compiler targets JS, it automatically compiles some functions into object property access (i.e. Js.Array2.length(arr) -> arr.length), but that’s just a special feature of the compiler. The language itself doesn’t have a concept of properties the same way that JS does.

(Yes, there are record and object types with fields similar to JS objects, but they don’t use all of the OOP features that built-in JS types have.)