Fable: Locally inline function fails at runtime

Created on 27 Sep 2017  路  8Comments  路  Source: fable-compiler/Fable

Description

I'm trying to port Chessie to Fable. Things are compiling good. But while trying to run it, I am facing issue in given function.

Repro code

let inline bind f result =
        let inline fSuccess (x, msgs) = f x |> mergeMessages msgs
        let inline fFailure (msgs) = Bad msgs
        either fSuccess fFailure result

Expected and actual results

It should bind two function but not working.

Related information

  • dotnet --info 2.0.0
  • dotnet fable --version 1.2.3

You can find complete code at Fable.Chessie

Error Message while at the combination of function
Uncaught TypeError: (intermediate value)(...) is not a function

Let me know if any further info is required. I was trying to write test code but paket died on me with message Unable to connect to the remote server (Github - cached (temporarily ignore updates))

Most helpful comment

Thanks @alfonsogarciacaro and @inosik for help. I removed inline function and updated Fable.Chessie version is there https://www.nuget.org/packages/Fable.Chessie/

All 8 comments

It would be very helpful if you could also add an actual test, a piece of code I can run with an expected result (e.g. what you get when running in FSI) but which fails o gives a different value instead.

This is the minimal non-working code:

type Result<'TSuccess, 'TMessage> =
  | Ok of 'TSuccess * 'TMessage list
  | Bad of 'TMessage list

let inline ok<'TSuccess,'TMessage> (x:'TSuccess) : Result<'TSuccess,'TMessage> = Ok(x, [])
let inline fail<'TSuccess,'Message> (msg:'Message) : Result<'TSuccess,'Message> = Bad([ msg ])

let inline either fSuccess fFailure trialResult =
  match trialResult with
  | Ok(x, msgs) -> fSuccess (x, msgs)
  | Bad(msgs) -> fFailure (msgs)

let inline mergeMessages msgs result =
  let inline fSuccess (x, msgs2) = Ok(x, msgs @ msgs2)
  let inline fFailure errs = Bad(errs @ msgs)
  either fSuccess fFailure result

let inline bind f result =
  let inline fSuccess (x, msgs) = f x |> mergeMessages msgs
  let inline fFailure (msgs) = Bad msgs
  either fSuccess fFailure result

type Request = 
  { Name : string
    EMail : string }

let validateInput input = 
  if input.Name = "" then fail "Name must not be blank"
  elif input.EMail = "" then fail "Email must not be blank"
  else ok input // happy path

let validate1 input = 
  if input.Name = "" then fail "Name must not be blank"
  else ok input

let validate2 input = 
  if input.Name.Length > 50 then fail "Name must not be longer than 50 chars"
  else ok input

let validate3 input = 
  if input.EMail = "" then fail "Email must not be blank"
  else ok input

let combinedValidation = 
  validate1
  >> bind validate2
  >> bind validate3

let r = combinedValidation { Name = "John Doe"; EMail = "[email protected]" }
printfn "%A" r

You can try it in the REPL. I can make it work by removing the inline keyword from fSuccess function in mergeMessages. Is the inline keyword necessary here at all? Also, I'm actually not sure if it's even necessary in .NET. If I remove it everywhere, the generated JS code looks much cleaner.

Ah great, thanks a lot for that @inosik, it's really helpful! Hmm, so the problem seems to be locally inlined functions, I'll have a look into that (there are other working examples of locally inlined functions so this may be a special case). For now, yes, probably the best solution is not to use locally inlined functions, or maybe even no inlining at all (except for ok and fail) as it doesn't seem to be very beneficial here.

@alfonsogarciacaro I ll give a try by removing inline functions. I ll remove them all. Thanks @inosik for putting up example.

@alfonsogarciacaro @inosik I have removed every inline function and it works like charm. No issues. At least for current testing. I don't know what difference it is making there. Even generic warnings are not coming now.

PS: Should I be keeping this issue open for future reference or if you like you can close it.

I'm happy to hear that @kunjee17, thanks for the confirmation and thank you @inosik for narrowing down the issue.

Let's keep the issue open so I can have a look when I have a moment :)

Thanks @alfonsogarciacaro and @inosik for help. I removed inline function and updated Fable.Chessie version is there https://www.nuget.org/packages/Fable.Chessie/

The example from @inosik seems to work in latest Fable so let's close this. Please reopen if you still have problems.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

et1975 picture et1975  路  3Comments

funlambda picture funlambda  路  4Comments

nozzlegear picture nozzlegear  路  3Comments

tomcl picture tomcl  路  4Comments

alfonsogarciacaro picture alfonsogarciacaro  路  3Comments