The issue is specific to @as in @obj externals. In uncurried mode, this does not erase the parameter from the function definition leading to weird errors that say more arguments are required than the error specifies (try changing the playground link above to 11.0.0-rc.7).
Perhaps as a symptom of this, in uncurried mode when @as is used with @obj it claims to require all arguments to be specified (which defeats the purpose of optional arguments). Here’s another playground link that better demonstrates this issue.
I assumed @obj was not long for this world as it’s functionality was completely replaced by optional record fields (although as it turns out there is this weird edge case that isn’t covered). Perhaps I should be logging a bug against @obj instead?
Well I have no idea how complex a fix would be, but it might be worth it! @obj is no longer the default technique for object bindings but it does have a few use cases remaining.
We have almost finished the migration, it remains a case that I don’t know the fix.
We’re using ppx-lenses, a ppx that produces functions. But I think the ppx doesn’t output uncurried functions so there is a mismatch like this :
Hi, I just noticed that @ocaml.doc doesn’t work anymore. Is there a way in v11 to write a comment in a .res file and have it show up in the compiled .js file?
I don’t think there’s any other workaround than migrating the PPX to support uncurried. Most of uncurried is at the syntax level, and the heavy lifting is done in the parser. PPX:es transform the AST after the parser has parsed it, so they need to account for the internal representation of uncurried to work properly.
There are however quite a few PPX:es that has migrated already so there’s plenty of inspirational material to look at someone decides it’s worth taking a stab at it.
Did anyone else encounter an issue with recursive module while migrating?
I described the issue which is blocking me from completing the migration here:
I think it’s a ligit regression, you’re just the only one who used recursive modules. I guess the team will take a look when they breath out after v11 release.
I just started migrating our codebase to v11 by bumping the versions and seeing what breaks, and the first breakage is in rescript-jzon (a heavily used dependency):
We've found a bug for you!
<snip>/node_modules/rescript-jzon/src/Jzon.res:84:47-52
82 ┆
83 ┆ let encode = codec => codec.encode
84 ┆ let encodeString = (codec, value) => codec->encode(value)->Js.Json.stri
┆ ngify
85 ┆
86 ┆ let decode = codec => codec.decode
This uncurried function has type t<'a> => encode<'a>
It is applied with 2 arguments but it requires 1.
Are we supposed to report this as a compatibility issue to the library, or is(/will) there be a way to make compilation use the old (I guess curried?) mode? Or is this a different bug entirely?
Ideally the libraries would publish a new major version that is compatible with v11’s new uncurried conventions. At least for this particular library it would be easy to vendor and fix up the Jzon.res and Jzon.resi until the issues have been resolved on upstream.
I have an opaque type that I want to create an immutable set for. In order to do that in a type safe manner I’ve defined a module type for Belt.Set (since one isn’t provided out-of-the-box). This worked fine in v10 and v11 with uncurrying disabled, but in uncurried mode it breaks with the cryptic error seen below. I understand there’s a curried/uncurried function type mismatch, and I’m guessing the compiler is trying to tell me that I need to make the function type curried somehow, but I have no idea how to specify a curried function of arity 1.
tl;dr: How can I fix the module type so that it matches the actual type of Belt.Set?
Minimal reproducible example:
module type S = {
type value
type t
let fromArray: array<value> => t
}
module Id: {
type id
module Set: S with type value = id
} = {
type id = int
module Set = Belt.Set.Int
}
yields
[E] Line 11, column 4:
Signature mismatch:
...
In module Set:
Values do not match:
let fromArray: array<value> => t (curried)
is not included in
let fromArray: array<value> => t (uncurried)
playground.res:5:3-34: Expected declaration
playground.res: Actual declaration
You need to wrap it manually with another function and it’ll work: ReScript Playground
This has to do with uncurried mode being able to compile external dependencies as either curried or uncurried, but not internal dependencies (things that ship with the compiler). @cristianoc can probably expand a bit if needed.
Yeah simply vendoring the module should mean you don’t need to make any changes at all, since it can be compiled in uncurried mode directly if that’s the mode that’s configured in your project. So when it’s possible, vendoring is the way to go.