reason icon indicating copy to clipboard operation
reason copied to clipboard

Confusing external behavior with type alias and currying

Open wlitwin opened this issue 4 years ago • 2 comments

I tried looking at the docs on rescript-lang.org but I didn't see anything mentioning this behavior, which I find odd. I'm trying to write some external definitions for a JS library that uses a lot of thunks and it seems I need to add an extra level of type indirection in order to get the correct generated code (or use a %raw escape hatch).

Here's example code:

%raw("
window.someFunc = function someFunc() {
    console.log('someFunc called');
    return () => {
        console.log('thunk called');
    }
}
");

Js.log("Attempt 1");

@bs.val external someFunc : unit => (unit => unit) = "someFunc"
someFunc()();

Js.log("Attempt 2");

type result = unit => unit
@bs.val external someFunc2 : unit => result = "someFunc"
someFunc2()();

Js.log("Attempt 3");

let someFunc3 : unit => (unit => unit) = (_a) => {
    Js.log("someFunc3 called");
    (_b) => {
        Js.log("someFunc3 thunk called!")
    }
}

someFunc3()();

Js.log("Attempt 4");
@bs.val external someFuncBool : unit => (bool => unit) = "someFunc"
someFuncBool()(true);

Generated JS:

// Generated by BUCKLESCRIPT, PLEASE EDIT WITH CARE
'use strict';

var Curry = require("bs-platform/lib/js/curry.js");

((window.someFunc = function someFunc() {
    console.log('someFunc called');
    return () => {
        console.log('thunk called');
    }
}));

console.log("Attempt 1");

someFunc();

console.log("Attempt 2");

Curry._1(someFunc(), undefined);

console.log("Attempt 3");

function someFunc3(_a) {
  console.log("someFunc3 called");
  return function (_b) {
    console.log("someFunc3 thunk called!");
    
  };
}

someFunc3(undefined)(undefined);

console.log("Attempt 4");

someFunc(true);

exports.someFunc3 = someFunc3;
/*  Not a pure module */

Output:

Attempt 1
someFunc called
Attempt 2
someFunc called
thunk called
Attempt 3
someFunc3 called
someFunc3 thunk called!
Attempt 4
someFunc called

I don't understand why all the definitions generate different code. It seems someFunc and someFunc3 should generate similar code as they share the same definition, but the generated JS for someFunc leaves out the extra application, even though it's present in the source, but someFunc3 doesn't have that issue, despite appearing to be the same.

Also I'm not sure why adding the result type alias works, and generates the extra calls to the curry module. It seems there's at least a bug in the JS generation with someFunc missing the application.

If I missed something special with regards to currying and external I apologize.

wlitwin avatar Aug 25 '20 02:08 wlitwin

Hey @wlitwin I don't have the answer to your question, but I would recommend re-opening it here because there @bobzhang will be able to answer much faster.

bsansouci avatar Aug 25 '20 14:08 bsansouci

@wlitwin your question is answered here:https://github.com/rescript-lang/syntax/issues/117

bobzhang avatar Aug 26 '20 02:08 bobzhang