I am creating an ampify.js binding for the WebSharper. (https://github.com/aph5nt/websharper.amplifyjs). While testing my extension I found one issue with publish / subscribe implementation.
I declared a subscription handler:
let subscribeFn (data:obj) = JS.Alert(data :?> string)
I created a subscription:
Amplify.Amplify.Subscribe("tryPubSub", subscribeFn)
When I want to unsubscribe then I do:
Amplify.Amplify.Unsubscribe("tryPubSub", subscribeFn)
the problem is that, the subscribeFn is was translated into 2 different functions. If I debug the js code and check what's happening under amplify.js lib, then I get the following:
//this is what has been saved when I created a subscription
subscriptions[ topic ][ i ].callback
(L){return i.subscribeFn(L);}
.
//this is what was passed as a callback for the unsubscribe function
callback
(S){return i.subscribeFn(S);}
There is no difference in the logic, but the args are different and because of that I'm unable to unsubscribe.
WebSharper 3 can't optimize calls to module functions as a function value (which are represented in the quotation as a lambda), so it becomes a new function on every call site.
A solution is to capture the module function as a local function value:
let subscribeFn = fun (o: obj) -> subscribeFn o
(WebSharper 4 beta already has this optimization.)