Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler bug in applying an uncurried function when the function has a signature #6742

Open
jfrolich opened this issue Apr 26, 2024 · 4 comments

Comments

@jfrolich
Copy link

This causes a compile error that the interface doesn't match the signature even though the types are exactly the same in the error. Without the signature it compiles just fine.

Some pointers:

So it seems to be a bug in using externals in uncurried mode because the issue is not present when the map function is not an external

@tsnobip
Copy link
Contributor

tsnobip commented Apr 26, 2024

You can even simplify it down to this:

module Bla: {
  let array: ('a => 'b, Js.Array.t<'a>) => Js.Array.t<'b>
} = {
  let array = (encoder, arr) => Js.Array.map(encoder, arr)
}

I think the issue comes from the fact that Js.Array.map is curried and expects its mapper function to be curried, the error message is right, it should just mention the difference in the curried state of the function between expected and actual. Basically some cases (especially when the faulty function is a parameter of a function) is not fixed by #6414. Given we're sunsetting Js lib in v12, I'm not sure we have to do anything here.

The right error message should be like this:

Signature mismatch:
  ...
  Values do not match:
    let array: ('a => 'b (curried), Js.Array.t<'a>) => Js.Array.t<'b>
  is not included in
    let array: ('a => 'b (uncurried), Js.Array.t<'a>) => Js.Array.t<'b>
  playground.res:2:3-57: Expected declaration
  playground.res:4:7-11: Actual declaration

@jfrolich
Copy link
Author

I am trying to wrap my brain around this, but if we have a function with one argument what is the difference between curried and uncurried. Is it that the function is potentially partially applied?

And I thought the stdlib would be all uncurried with the uncurried setting turned on. How would I know what is curried vs uncurried? Isn't the switch just compiling everything as uncurried? I think it's strange that there is a possibility of anything being curried when the flag is turned on - I think it's way more consistent that this is a system-wide thing.

About deprecating Js. Will that remove the possibility of directly using functions in the Js stdlib, or is / will that be included in Core?

@cristianoc
Copy link
Collaborator

A unary curried function that returns a unary curried function is what's called a binary curried function.
With uncurried, a binary function is another thing.
So curried and uncurried are always different things, whatever the arity.

@jfrolich
Copy link
Author

A unary curried function that returns a unary curried function is what's called a binary curried function. With uncurried, a binary function is another thing. So curried and uncurried are always different things, whatever the arity.

Understood. I didn't know that the stdlib is still curried in uncurried mode, perhaps we can do something to make this clear? I think it's pretty weird to be honest, why would you want this to be curried?

But at least it would be great to fix the error so that it's clear that the difference is that one function is curried and the other is not. That would make me track down this bug way easier :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants