I’m curious about how many of you really crrate interface files for your rescript files. This is a way for us to hide some details of your program, another way is to use %%private or writting the module type inlined after where your module’s name is defined. I’m from java/js/ts/rust side, creating an interface file is not so ergonomic for me, so i want to know how many of you will create this interface files, and in what way you will choose?
I have read some OCaml books, they said i should design the interface first, and then, write the details.
Just a digression, will rescript eventually lead us to OCaml and never come back?
So I have a few components in my project that use a useReducer
with a bunch of actions and selectors, defined in the same module as the component. I’ve started making an interface file for these components using the command palette, removing everything but the component, that way the VSC extension can tell me which selectors are unused which help me keep the module a bit cleaner
Do you think whether it is too trivial to create an interface file for writting the definition again?
What do you mean?
Coming from the JS/TS world, I’m not too fan of interface files and would prefer an explicit private (or better, an explicit public). But I do try to make use of them when I can, and that’s just one example I find them useful
I actually rarely use interface file in rescript or OCmal, i would choose to use %%private
to wrap the things i want to hide, interface file or module type are too weight for me.
They are very useful to make an opaque type.
I despise ideas like that. If you have a well-defined problem that you understand, then it is a good idea.
- Problem must be complete and well-defined (otherwise interface will likely change)
- Problem must be fixed (if you expect it to grow to cover new input or output domains, interface will likely change)
- You must understand the entire problem domain boundaries (if you don’t, interface will likely change)
How often do these three occur in real life? It only ever happens for trivial problems and maybe rarely for fairly simple problems that are mathematically well-defined.
In reality, you always end up doing interfaces last, because in any practical application, you will be exploring the problem domain as you implement it. “Oh, I should add this. Oh that didn’t look good, I should change it to this. But maybe sometimes this doesn’t matter, so that should be optional” Etc, ad infinitum.
I usually create an interface file as soon as the prototyping phase is done. Having an interface file brings a lot of benefits to maintain the code.
I actually have a side project with almost 50k lines of rescript. I used several %%private
and inlined module type in my project, but zero interface file. The reason i don’t use interface file is that i dislike to write the definition again.
A side note for this discussion - we’ve experimented some + thought a bit about what we can do on the tooling side to make working with interface files easier. Nothing that’s currently prioritized, but we’ve had ideas along the lines of:
- Interactively sync definitions from implementation to interface
- Fill in stubs for missing types/functions etc that’s present in the interface, but not in the implementation yet
- Improve the compiler errors when implementation and interface differs
Happy to hear more ideas in this area. Might be worth thinking about even if it’s not something that’s likely to happen soon.
It would be nice to have the feature mentioned here Using the compiler stack for editor tooling was the single worst decision in Rescript, although it’s on the compiler side, I think.
The author of the post is a bit rude, but you can get an idea
The details should follow the interface, why we want to make the interface follow the details?
I would say: reduce the number of files needed. It’s better to introduce %%private (and clean it up) than have an extra file. It could even be that you have to put everything public at the top of the file, then privates at the bottom.
Introducing an extra file creates nothing but more complexity in terms of grasping the code, writing the code, maintaining the code, debugging the code, etc.
Note that my message was just about editor tooling. The “be or not be” of interface files is a much larger discussion with many nuances, that I believe also has deeper implications in the compiler.
Yes and that’s fine and normal. Code changes over time, there’s no law that says interface files must never change
Before someone mentions API backwards compatibility–sure, if you’re publishing a library then you do need to care about API compatibility. But you’d have to do that with or without interface files, and at least with interface files you get a quick way to review exactly how the API changed. But a lot of the time you’re not working on a library that you want to publish, it’s more likely an app and you don’t need to care about backwards compatibility of the interfaces because you can just update them in the app.
I see people don’t like interface files because of the duplication and the effort of re-typing definitions. But in any programming project code is read much more often than it’s written, and actual keyboarding is the smallest time investment relative to thinking. And besides, the duplication is checked by the compiler. You will instantly know if anything is incorrect.
I’m actually a fan of interface files and use them extensively. Sometimes only to clean up what is output on the JavaScript side but also often to define how I want my other code to interact with smaller pieces.
In that sense I do usually make the interface file after I’ve implemented the code to actually solidify what is private vs public. So I do it as a sort of API stabilization step.
Yawar beat me to mentioning API backwards compatibility. I do use it for this, even within applications sometimes. Even if I want to change the API though, that’s easily done.
I will admit that you’ll need a familiarity with the type system and writing out interfaces was difficult when I started. Mostly because I didn’t often know what explicit types my function without type signature had. However the editor tooling has already improved to a point there’s that’s not a problem and my own knowledge of being able to predict types and resolve type errors has also made that a moot point for me personally.