This argument kind of goes the other way as well - if you need a more compact bundle size you should use a minifier first and foremost.
I do agree with your argument, but I wonder what should be the limit for using “modern” JS features in the output. Maybe 93%/node version from 3 years ago is indeed too recent, though
Yeah this is definitively something we need to figure out a good strategy for, when it’s worth using newer features and what the bar for introducing them is. In my view, it’s a matter of doing thorough research in at least these areas:
- How widespread is support for the syntax and what’s our tolerance?
- Is it faster or at least as fast as the current thing it compiles to? If it’s slower, is it worth adding anyway? Why?
- What actual benefits does it bring and does the above justify the benefits?
Modern syntax can be great for sure (we compile async/await to actual async/await as an example) but we need to be quite careful and mindful about what we introduce, and why.
That sounds like a great approach to it!
Thanks for the great work you and the others have been doing in the language lately, btw. Every new feature makes me a bit jealous of people who work with ReScript
This code uses double options everywhere btw.
It should be { bar?: string }
The runtime representation of option chaining is something one can analyse separately.
For now, the focus should be on the ergonomics of the syntax extension, and whether there’s enough interest to support it.
I always vaguely assumed that there’d be a bsconfig
option for target ES version, to control the features used in the JS output. Then people could choose to involve a bundling-for-legacy step in their build setup or not. Is that not something that’s planned to be configurable at all?
Something I would LOVE to see, even more than optional chaining, automatic or otherwise, would be optional chaining with pipes…
let example = apple(_)?->orange?->grame("fruit")->basket
This basically allows to skip all the nested switch|None
cases and focus on the switch|Some
cases, in other words, converts the binary tree of switch|option
cases into a simpler linear sequence
I started new topic, but I guess I can say few words here. Note that majority of my experience comes from backend development, so I might have a bit different view from others.
I’m new to ReScript, but coming from other languages that utilize Option/Maybe type I find it hard to use due to missing actually convient syntax for unwrapping option types inside functions. I feel like I wrote implementation of Option in JavaScript directly, but it’s even harder to use.
Rust uses ? - Rust By Example with a caveat that the function using ?
operator becomes Result/Option automatically - which makes perfect sense. In that scenario ?
works like a short-circuit to a function.
Haskell’s do
notation is similar to Rust’s ?
but it is more powerful (as it handles all monadic types), at a cost of introducing “alternative” syntax to a function (Rust uses the same syntax, just introduces an operator).
All things considered I think Rust approach is superior here - albeit limited to few use cases, those use cases are contributing to all/almost all of potential use cases in ReScript. Rust developers are using ?
operator extensively.
Does it make you “ignore” errors? To some degree, yes. But after all code is properly failing. When it fails you might be asking yourself “why”. Then you go to the codebase, see bunch of ?
and say: “one of them failed”. If you wish you might have more explicit handling: you might remap your Option to Result to have explicit error handling, and continue using ?
syntax. Having explicit errors is a reason why ?
is much more common with Result type, and not the Option type.
I personally don’t buy the argument I’ve heard multiple times “not having a syntax makes me think about error handling”. From my experience in most cases you want to handle errors, but at the same time, don’t really care too much about them. In most cases errors are not part of a business logic. Thus errors should be non-obtrusive, thus any syntax sugar is welcomed. And usually, Option means “there is nothing more to do”, like you are looking for an item in an array, there is not item, you cannot proceed further, and if that’s correct behavior that the item is not there, you just quit the processing.
The syntax sugar is optional. Language is a tool, not a way of life - that should be left to particular developer’s/team’s opinion.
Furthermore, ?
behaves a bit like a controlled throw in a sense that it interrupts further processing. And some languages actually use throwing extensively. Not talking about >handling< part here, but it just tells, that “early quitting due to not having what program needs” is a pattern common-enough and useful-enough, that having a syntax for it makes sense.