fable-compiler / repl

Fable online REPL
http://fable.io/repl
MIT License
64 stars 37 forks source link

Including F#+ in the repl #116

Open gusty opened 4 years ago

gusty commented 4 years ago

I was wondering if it's possible to include F#+ in the repl, now that it compiles in Fable.

The reason is that there are some users wanting to play a bit with it, also I would be more than happy to try things in an interactive way as right now I need to build everything to try stuff and if something fails it's very hard to create a small repro to eventually report it to the Fable compiler.

MangelMaxime commented 4 years ago

Hello gusty,

some time ago I started a work to upgrade all the deps to their latest version and also include new library support in the REPL. #110

Unfortunately, I was facing some problem between the pre-compiled version of the library and the generated code from the REPL. I need to take a look again at it.

In order, to add a library to the REPL there are some requirements:

  1. It should be compatible with Fable
  2. Because we pre-compiled the library, the library can't expose inline function/methods. You can use FABLE_REPL_LIB constant in order to adapt the library if needed.
gusty commented 4 years ago

Thanks @MangelMaxime for the quick reply.

Of course the first requirement is met, although is not full compatible with Fable, half of the library it is, and that's the nice part to have in the repl.

I am not clear about this

Because we pre-compiled the library, the library can't expose inline function/methods. You can use FABLE_REPL_LIB constant in order to adapt the library if needed.

Does it mean, that the repl is more restrictive than the Fable compiler itself? So, code that normally runs in Fable won't run in the Fable repl?

MangelMaxime commented 4 years ago

Of course the first requirement is met, although is not full compatible with Fable, half of the library it is, and that's the nice part to have in the repl.

👍

Does it mean, that the repl is more restrictive than the Fable compiler itself? So, code that normally runs in Fable won't run in the Fable repl?

For performance reason and also because it was not ported yet, Fable REPL compiles only a single file.

When we publishing a new version of the REPL we pre-compile the library to JavaScript and include them in the deployment. That's what you can see in this folder

For example, here is the pre-compiled version of [Thoth.Json.Decode].

Then when the user asks for compiling something in the REPL we only compile the user file, not the library that it uses. For this reason, the REPL doesn't support exposed API that uses inline in it.

This example tries to explain what I am speaking about.

Library code

module AwesomeLib

let inline functionA arg1 = // ...

let functionB arg1 =
    // ...
    functionA arg1
    // ...

User code can be seen as the file you edit in the REPL

AwesomeLib.functionA "" // This line doesn't work

AwesomeLib.functionB // This line works because functionA has been inlined inside of functionB

As a shorter:

The REPL is indeed more restrictive than Fable compiler.

For example, people can't use Extra module from Thoth.Json because the exposed API for this module is inlined.

alfonsogarciacaro commented 4 years ago

Yes, it's going to be tricky with F#+ because inlining is required to solve the SRTP. As @MangelMaxime says, the REPL only compiles a single file at the moment. We were considering how to build full projects and/or add custom libraries but it hasn't been implemented yet.

Anyways, I'm watching closely the new witness feature in FCS: https://github.com/dotnet/fsharp/pull/9510. It may be an opportunity to expose the "with witness" version of members in libraries compiled for Fable so we don't need to collect all sources and compile them as a single project as we're doing now. That would make it possible to precompile (or at least cache) all libraries so they are the same for the Fable cli tool and REPL.

gusty commented 4 years ago

Thank you both for the info.

So, if there's currently no way to have inline functions, there's no point as what I wanted to do is to play a bit precisely with these kind of functions, to know which trait-calls are supported, which are not and which ones might reveal issues that could be reported and potentially solved in the Fable side.

Looks like at the moment the best I can do is to extract the whole library to a single file and paste it in the fable repl.

You can close this issue if you want, or keep it open, awaiting for F#5 and the new Fable features.

OnurGumus commented 3 years ago

@alfonsogarciacaro perhaps time to revisit this with Fable3?

alfonsogarciacaro commented 3 years ago

Yes, it should be possible (although it seems not the whole of F#+ is supported yet in Fable 3), but I still need to finish the mechanism to load libraries in the Fable 3 REPL to replace all the hacks and custom compilation we had in the previous repl :/