Favorite missing features

I have no idea if there’s a thread similar to this one. I love ReScript, but it also feels somewhat clunky and limited to work with compared to TypeScript. There are a few reasons that I have identified so far: a) I suck at ReScript b) ReScript is not as mature as TypeScript and c) the language is missing a few of my favorite features. Let me list them below, and come up with an idea of how to circumvent the issue or maybe link to some discussion on that particular feature, maybe there’s already a PR pending or whatever.

  1. Early returns. I’ve tried railway oriented programming and Future but it just doesn’t sit as nice as a if (notOk) return on the first line of a function. For functions of 40-50 lines, a couple of early return checks makes so much sense.It’s basically a “for the rest of the function, this is a case that never has to be considered” note. Long switches and railways do not remedy this, in my opinion.

  2. “Meta typing”, e.g., Partial, Omit and so on. For example, I might want to update an object in a database. I know the specified fields have to be a subset of X. In typescript, Partial.

  3. Macros. I really want macros. Instead of let log = Log.get(MODULE) I would love to be able to just do Log.get!() and have the above inserted automatically.

  4. An automatically built @rescript-bindings/ repository (like @types). Hey, I can dream, right? Doing bindings isn’t really interesting, and I realize that I suck so much that I do them ad hoc for every project, so I never end up reusing them. Failure on my part (as every other problem in my life, heh).

What are your thoughts and what features do you miss the most?

1 Like

I’ve been using ReScript on a hobby project for a year and recently tried some TypeScript with SolidJS. I know TypeScript pretty well and all about conditional types, computed types etc. I found TypeScript to be incredibly frustrating to work with compared to ReScript. There are the endless import and export commands. In ReScript everything is easily accessible by just typing the name of the module. There are no sub-modules so I found the TypeScript code very hard to organize. You must explicitly specify type parameters on every function. In ReScript you can get away with not manually typing any of that. TypeScript only warns you about errors in files you have open in the editor while ReScript gives errors on everything in your project. Piping is super helpful but in TypeScript you’ve got to hack it with the pipe function (that must be imported). I looked at a bunch of TypeScript and ReScript code side by side and the TypeScript is so much more verbose/noisy. Functors are super useful - I use them to make nominal primitive types with validation, serialization, equality and comparison. It is just harder for me to go from my thoughts to code with TypeScript.

Yes it doesn’t have Omit or Partial etc. And you can’t debug from source. And you’ve got to write bindings. And it didn’t actually work with SolidJs because of proxies and the generated code broke them.

So no perfect solution right now. But I can say I much prefer using ReScript over TypeScript.

6 Likes

One of the reasons ReScript can provide this simpler experience is because it doesn’t have TS things like meta-types.

5 Likes

@jmagaram Just noticed your new library regarding TaskEither functionality, which is exactly what I am looking for. Thanks for making it.

@renegade @jmagaram
Could you share a link to this library?

I built my own (GitHub - dkirchhof/rescript-async-result) but always curious about other implementations.

1 Like

Sure:

1 Like

Thanks. I would like to see something like this in the core, cause I’m using it in multiple libraries and projects.
Don’t know, what the rescript team think about it, but I remember a discussion about the same thing in F#, where the developers were against it, because everyone would expect slightly different apis / behaviours.

Your library is cool, and I believe more of what I’m looking for (or at least the API is intuitive). I am trying to achieve railway oriented architecture, but having issues.

validateQuery()
->then(mapBoth(fetchUser, respondToError))
->then(mapBoth(updateRequest, respondToError))
->then(mapBoth(generateNewAddress, respondToError))
->then(mapBoth(updateRequest, respondToError))

In your library, can I write the above code like this?

let onSuccess = tapBoth(_, respondToError)

validateQuery()
->onSuccess(fetchUser)
->onSuccess(updateRequest)
->onSuccess(generateNewAddress)
->onSuccess(updateRequest)

I should write a readme and some example snippets :roll_eyes:

A quick response: you shouldn’t use the mapBoth inside then. Just use map / flatMap directly. If you have to handle the error as well, use the variants with “both”.

If validateQuery returns a native promise, wrap it inside asyncresult by using “fromPromise”

1 Like