The Reason team is not motivated by hate, rather they have a different POV than the TypeScript team. They are focused on full soundness instead of full JS ergonomics.
I think they describe well that Typescript needs a lot of complexity by supporting all of JS. That's both a strength and a weakness, easy to get started for people who know JS, but typings can get crazy complex.
Rescript has a different approach which has lots of benefits, it is much better in terms of type inference, it's much faster, and I think it's fair to say safer. The tradeoff is that it's not JS, making it harder to adopt.
I do think they are doing a great job in taking steps to present the ocaml origins in more JS friendly patterns and syntax, but it still requires learning some new concepts.
I think a somewhat good comparison is; If Typescript is like C# for JS, Rescript is like F#/ocaml for JS. Different technologies have different tradeoffs.
I wrote whole frontend with its predecessor ReasonML. Once you get used to ocaml type sytem it's a great experience especially that compiler is incredibly fast. The biggest surprise - no need of any importing commands (a lot clearer source files). Rescript split unfortunately caused ReasonML to stopped evolving and changes they introduced in the syntax were not convincing to me to switch to it.
IT's a META project based/fork of ReasonML (https://reasonml.github.io/). They are ocalm dialects thats compile to Javascript. Advantage vs Typescript is a strict type system.
No need to look at google trend, Typescript is too big by now, many libraries client and server use it out of the box, and the possible advantages of this competitor look very small in comparison.
I even don't understand why browser don't start to work on supporting it directly, maybe google/chrome have something in mind and slowing down its integration, or it's because of performance issues.
It will take a while, I even doubt it will make to a stage were it will be worth implementing, don't get me wrong, I like the idea, ditch more tools (transpilers mostly) and work with plain new JS will make my life easier.
With only a quick look into this project it looks very interesting and appealing, but I'm afraid it might be an evolutionary dead-end in the Javascript world similar to Facebook's Flow and CoffeeScript. Any opinions to the contrary?
I think they are more at the opposite side of the spectrum, languages like Flow, CoffeeScript and TypeScript are more akin to supersets of JavaScript (with potentially "simpler" syntax). Languages like ReScript and PureScript come from the functional world that as a feature compile to JS, but where the type system are sound without any of the baggage from JS and features that are (at least as of now) not available in JS like pattern matching. They are not an evolution of JS like Flow or CoffeeScript, but are rather for developers who want something more than just "JavaScript with types".
Why does it (and ts) put “?” only at a name? I’d expect the above to define an optional key, and (type|undefined) but always existing key, as well as an optional argument, to have a type of
age: int?
As a result, an optional key with an optional value would be
I can’t test type narrowing right now, but I suspect that (“age” in obj) or a similar hasOwn() etc wouldn’t narrow it to just (type) in neither of these languages. It is correct to write “age?” under your assumption, e.g. for settings objects, but sometimes a property is or must be always there.
Maybe the reason is that this distinction creates an unnecessary complexity at matching semi-optional types together, because programs do not usually care about exists/defined distinction.
Without exact optional properties enabled, the type `{ age?: number }` will accept both `{}` and `{ age: undefined }`. With `exactOptionalPropertyTypes` enabled `{ age: undefined }` is illegal.
So `{ age?: number }` does mean the key is optional. If you want optional and supporting undefined then type you're after is `{ age?: undefined | number }`.
Doesn't need type annotations. Annotate as much or as little as you'd like. The types are inferred by the language (and, again, are guaranteed correct)
How is this achieved? E.g. you npm install module ‘foo’ which has no types and takes no part in a rescript compilation process. Does it force you to type-narrow all the values returned from foo.funcname()?
You skipped over the first part "Has no pitfalls, aka the type system is "sound" (the types will always be correct). E.g. If a type isn't marked as nullable, its value will never lie and let through some undefined value silently. ReScript code has no null/undefined errors."
E.g., if a type returned from a function is nullable then you will be forced to handle that explicitly via pattern matching I imagine, rather than being able to dereference it without checking.
My question is how this sound is made, omitted it for citation reasons. Does this mean that a developer has to create sound wrappers for all external interfaces, which aren’t aware of rescript? It may be viewed as a burdensome perspective. Language bridges usually try to auto-wrap this and throw when something doesn’t match expectations, but it comes at a runtime cost.
The type inferrence only applies to ReScript code, it's not a magic compiler that can statically analyse JS code and generate interfaces for any arbitrary npm package. For Typescript interop, it can "trust" the TS declaration files, but there is no real guarantee when you're crossing language boundaries. ReScript is it's own language, with it's own type system that compiles down to JS. I don't think there's a reasonable alternative to this.
Take Rust, calls to C code are inherently unsafe, and must be marked as so. You're leaving Rust's source code and type system and calling into external functions that you may not even have access to source code for and that the compiler just can't feasibly vouch for.
The JS interop requires you to manually type the function or object, similar to how PureScript does it. There is no magic interop with JS, though one could potentially imagine a TS-to-ReScript converter.
I don't understand why ReScript is trying to sell itself as a language for React. React is already "kind of" functional, has a rich JS/TS ecosystem and there are fantastic alternatives such as Elm.
I think this would have huge potential in the backend space if it had good interop with Node.js and TS, with perhaps a functional framework similar to Elixir's Phoenix. Elixir proved it can have fantastic integration with Erlang.
* More robust applications with the Result type
* An actual integer type (for 64-bit database keys, Prisma uses BigInt)
* Finite state machines for stateful logic, games, websockets (enums and a sound type system)
* Benefit from the JS-centric serverless ecosystem
We've already been "compiling" or "transpiling" JS for years, most of written JS code has little in common with what is actually run.
In its current state, I don't even want to imagine what it would be like to set this up alongside ESM, TS, Prettier, ESLint, Jest, Storybook, ESBuild, Vite, (insert cool tool here). I've already spent literal days trying to setup a "modern" Node.js project, only to give up and go back to CJS for simplicity and import older non-ESM versions of packages[1], wish I wasn't using Node.js, then remember how many things I miss from JS when trialing another language.
The BEAM VM, the virtual machine which runs Erlang and Elixir, is very opinionated. It provides primitives which every language must support. The primitives require the languages to be functional. I don't see how ReScript and Node can have such tight interoperability having the differences in the languages.
JS ecosystem is really a joke, you need to put too much work on configuring, maintaining the tooling, just to write a "modern" JS project you need to setup a bundler, linter, test, etc. I think Vite with Vitest is going in the right direction, so you have just one tool, not a lot of tools, just check how hard is to test your code with jest (maybe there's a better library, it was at least from my knowledge widely used), you need to configure almost a separate building pipeline so your code can use ESM and typescript, or you also need to install ts-jest.
Deno also has an interesting approach (you have all the tooling officially shipped like Rust does), but sadly most of the official libraries will not work or does not work with it (maybe I'm wrong and there's a work about), but also I think that not having a manifest with your dependencies makes all harder (will import maps be a thing soon enough? is up to the task?).
Also there is rome.tools, but seems far from being usable yet, besides the formatter.
ReScript was advertised to be a great language for powering up React in the years of ReasonML. It may be opinionated, but people grew interest in ReScript along with React.
It looks similar to just writing F# via the Fable compiler, which has been iterated on for years, has an ecosystem, and now has (beta) compilation targets to Dart, Python, and Rust. Can anyone make an arg for rescript over Fable?
Not that I've tried ReScript but it advertises fast builds, which the (sample size of one) large scala codebase I've worked on was really slow to compile.
Yes, it pretty much depends on what and how you're trying to compile. Incremental complication helps a lot, as does keeping sbt shell open and not restarting sbt each time.
Ocaml is a wicked fast compiler and a simple language. Having done both, I’d rather not do Scala again, but would happily do Ocaml if it had a better ecosystem.
41 comments
[ 5.6 ms ] story [ 34.8 ms ] threadhttps://rescript-lang.org/docs/manual/latest/introduction#di...
Seems like a type system for Javascript, built with a differing set of opinions than Typescript.
Looks like they also offer some form of TS interop:
https://rescript-lang.org/docs/gentype/latest/introduction
> TypeScript's (admittedly noble) goal is to cover the entire JavaScript feature set and more. ReScript covers only a curated subset of JavaScript.
Rescript has a different approach which has lots of benefits, it is much better in terms of type inference, it's much faster, and I think it's fair to say safer. The tradeoff is that it's not JS, making it harder to adopt.
I do think they are doing a great job in taking steps to present the ocaml origins in more JS friendly patterns and syntax, but it still requires learning some new concepts.
I think a somewhat good comparison is; If Typescript is like C# for JS, Rescript is like F#/ocaml for JS. Different technologies have different tradeoffs.
So very different semantics to JS/TS but you gain a sound type system and great compile speed.
I even don't understand why browser don't start to work on supporting it directly, maybe google/chrome have something in mind and slowing down its integration, or it's because of performance issues.
https://github.com/tc39/proposal-type-annotations
Maybe the reason is that this distinction creates an unnecessary complexity at matching semi-optional types together, because programs do not usually care about exists/defined distinction.
Without exact optional properties enabled, the type `{ age?: number }` will accept both `{}` and `{ age: undefined }`. With `exactOptionalPropertyTypes` enabled `{ age: undefined }` is illegal.
So `{ age?: number }` does mean the key is optional. If you want optional and supporting undefined then type you're after is `{ age?: undefined | number }`.
ReScript aims to be a strictly typed JS, simpler and faster than TS - https://news.ycombinator.com/item?id=30181349 - Feb 2022 (23 comments)
From TypeScript to ReScript - https://news.ycombinator.com/item?id=29903631 - Jan 2022 (175 comments)
I Switched from TypeScript to ReScript - https://news.ycombinator.com/item?id=25845147 - Jan 2021 (45 comments)
Confused about ReScript? ReScript, Reason, ReasonML, and BuckleScript explained - https://news.ycombinator.com/item?id=25842141 - Jan 2021 (1 comment)
ReScript 8.4 - https://news.ycombinator.com/item?id=25424034 - Dec 2020 (63 comments)
ReScript (previously BuckleScript and Reason) - https://news.ycombinator.com/item?id=24160424 - Aug 2020 (13 comments)
BuckleScript Is Rebranding - https://news.ycombinator.com/item?id=24119838 - Aug 2020 (71 comments)
BuckleScript: An OCaml to JavaScript compiler - https://news.ycombinator.com/item?id=15111265 - Aug 2017 (84 comments)
BuckleScript: write JavaScript faster, safer and smaller - https://news.ycombinator.com/item?id=13448769 - Jan 2017 (90 comments)
Announcing BuckleScript 1.0 - https://news.ycombinator.com/item?id=12400397 - Aug 2016 (75 comments)
Bloomberg/bucklescript: A back end for the OCaml compiler which emits JavaScript - https://news.ycombinator.com/item?id=11477238 - April 2016 (12 comments)
BuckleScript – A JavaScript Back End for the OCaml Compiler - https://news.ycombinator.com/item?id=11370968 - March 2016 (1 comment)
Doesn't need type annotations. Annotate as much or as little as you'd like. The types are inferred by the language (and, again, are guaranteed correct)
How is this achieved? E.g. you npm install module ‘foo’ which has no types and takes no part in a rescript compilation process. Does it force you to type-narrow all the values returned from foo.funcname()?
E.g., if a type returned from a function is nullable then you will be forced to handle that explicitly via pattern matching I imagine, rather than being able to dereference it without checking.
Take Rust, calls to C code are inherently unsafe, and must be marked as so. You're leaving Rust's source code and type system and calling into external functions that you may not even have access to source code for and that the compiler just can't feasibly vouch for.
I think this would have huge potential in the backend space if it had good interop with Node.js and TS, with perhaps a functional framework similar to Elixir's Phoenix. Elixir proved it can have fantastic integration with Erlang.
* More robust applications with the Result type
* An actual integer type (for 64-bit database keys, Prisma uses BigInt)
* Finite state machines for stateful logic, games, websockets (enums and a sound type system)
* Benefit from the JS-centric serverless ecosystem
We've already been "compiling" or "transpiling" JS for years, most of written JS code has little in common with what is actually run.
In its current state, I don't even want to imagine what it would be like to set this up alongside ESM, TS, Prettier, ESLint, Jest, Storybook, ESBuild, Vite, (insert cool tool here). I've already spent literal days trying to setup a "modern" Node.js project, only to give up and go back to CJS for simplicity and import older non-ESM versions of packages[1], wish I wasn't using Node.js, then remember how many things I miss from JS when trialing another language.
[1]: https://github.com/ai/nanoid/issues/365
Deno also has an interesting approach (you have all the tooling officially shipped like Rust does), but sadly most of the official libraries will not work or does not work with it (maybe I'm wrong and there's a work about), but also I think that not having a manifest with your dependencies makes all harder (will import maps be a thing soon enough? is up to the task?).
Also there is rome.tools, but seems far from being usable yet, besides the formatter.
Am I missing something?
In other news: now, there's scala-cli for smaller projects — https://scala-cli.virtuslab.org/docs/guides/scala-js