Fable F # in Javascript: Parametric functions are set by a parameter when referenced

I'm having difficulty referencing functions without parameters in Fable.

In this example:

let f1 () = 1 let someRefTof1 = f1 

I expect the generated js to look something like this:

 function f1() { return 1; } var someRefTof1 = f1; 

but I really get:

 function f1() { return 1; } var someRefTof1 = exports.someRefTof1 = function someRefTof1(arg00_) { return f1(arg00_); }; 

I do not understand the purpose of arg00_ or how to avoid it?

(Like a bit of background, I struggle to call a function in an external js library that expects the function to be passed as a parameter)


Edit:

Background

The above is what I consider to be a minimal, verifiable reproduction of my question, but after the comments, I thought it might be useful to provide more context on why this is causing the problems. What I'm actually trying to do is use angularjs from Fable.

So my example looks something like this:

 let app = AngularFable.NgFable.angular.``module``("app",[||]) type TestCtrl() = member this.Val1() = "boom"; app?controller("test", TestCtrl) 

which compiled for:

 var app = exports.app = angular.module("app", []); var TestCtrl = exports.TestCtrl = function () { function TestCtrl() { _classCallCheck(this, TestCtrl); } TestCtrl.prototype.Val1 = function Val1() { return "boom"; }; return TestCtrl; }(); _fableCore.Util.setInterfaces(TestCtrl.prototype, [], "App.TestCtrl"); app.controller("test", function (unitVar) { return new TestCtrl(); }); 

with unitVar is the problematic parameter introduced in this example. When I use this in my html with something like:

  <div ng-app="app"> <div ng-controller="test as vm"> {{vm.Val1()}} </div> </div> 

I came across an unknown provider , whereas if I just changed the compiled javascript to remove the unitVar parameter from the last line like this

 app.controller("test", function () { return new TestCtrl(); }); 

then my example works as expected.

I would really like to know if there is a way to avoid compiling Fable with this parameter. I am 99% sure that this comes down to the same problem as in my original question, but I included this additional context to better explain why this is a problem.

+5
source share
1 answer

Thank you very much for your question and detailed explanations. There are two things here that are a bit complicated and caused by optimizations of both the F # compiler and Fable.

  • In AST, provided by the F # compiler, methods (functions that are members of a type or module) are compiled as normal methods, as in C #. This is for optimization.
  • However, when you create an anonymous lambda or make a reference to a method, the F # compiler will retain the semantics of F #, that is, all functions have one argument (as John Palmer says, unit also an argument) and may be curry.

Well, this information is only to understand why the F # / Fable compiler presents methods and lambdas differently. Let's look at the issue of conflict-free functions: the obvious solution would, of course, be to remove the generated F # compiler argument for functions that accept unit (as has already been done for methods). In fact, because of this, I also had problems with libraries like Mocha.

I tried to remove the unit argument at the beginning, but because of this, I got a failure in some scenarios. TBH, I don’t remember which tests failed, but because of the expectation that there will always be an argument, in some cases the composition or inlining was unsuccessful when the unit argument was deleted.

Other attempts to change the semantics of F # functions in the JS runtime have always failed because they do not cover all scenarios. However, we can be softer with delegates ( System.Func<> ) since they are usually safe to assume that they should behave like functions in languages ​​like C # or F #. I can try to remove the unit argument only for delegates and see what happens :)

For more information on sending F # functions to JS code, you can check the documentation .

UPDATE . Scratch all this, try fable-compiler@0.6.12 and fable-core@0.6.8. This version removes the unit arguments, the solution was actually simpler than I thought and (hopefully) should not create problems with existing projects. (An explanation of the methods and lambdas compiled differently still applies.)

+7
source

Source: https://habr.com/ru/post/1257785/


All Articles