More of a discussion than an issue:
Looking at how BuckleScript has reached 1.0, should we (eventually) strive to be able to compile Fable to JS as well, so we can have both native and purely javascript version of the compiler? Or is a native cross-platform Fable compiler with a Suave.io client sufficient?
This has also been proposed sometimes and it would be very nice to have to have Fable running on the browser. I guess it wouldn't be that difficult to compile Fable itself with Fable but I'm not sure about its main dependency: FCS. I haven't actually tried myself but I'm afraid it won't be an easy feat. Maybe if we could extract the minimal parts to read the AST from the F# source it could be a bit easier, but I'm not sure.
This would come under some of the things Ive suggested, build a minimal FSharp.Core and mscorlib dependencies, that way you keep the dependencies really low.
You can also cut the compiler at the IL gen phase to further reduce and provide future alternative compilers. Don and I discussed this several months back.
This would be FANTASTIC and is a really important long term goal for F#.
I started looking at this briefly a while back. I took the first two files in the FSharp.Compiler.Service DLL code and put them through Fable, hit a couple of bugs and reported them. I think they are fixed.
So the way forward is to just repeatedly try to compile chunks of FCS using Fable and fix all the bugs/incompletenesses in Fable (and perhaps add some new unit tests as we go to check things are beginning to work). You'd have to iterate on this many times, and put in a fair few #if/#endif sections into FCS.
But it would be really, really worth it!!!
After giving this a thought, there're probably two things which could make this task more feasible:
I don't know if there're some tools to make 2. easier, but it's probably possible to compile FCS with FCS itself in order to navigate the AST and capture the calls (something I could do). So if someone could take care of 1. that would already be tremendously helpful.
Thats the pain point, currently you have to do a full compile to get the tast, you don't have to to get the uast, you can compile up to that part.
Its the same with getting the metadata from a dll, you have to do an empty compile with just the references added, then traverse the FSharpAssembly. API needs some componentisation love.
Following Don's advice and without knowing much about the API, I'm trying my hand at (1) by slowly progressing down the project file and yes, for (2) there are some areas not yet supported in Fable, although easy to add, like Unicode support etc., but that can be added later.
@7sharp9 You mentioned a previous discussion on the topic, can you find a link? Any additional details on where we want to stop (before tast?) would be very helpful.
We would want to stop after the tast has been generated but before the IL/ILX
One thing that is missing that I never got round to is adding this: https://github.com/fsharp/FSharp.Compiler.Service/blob/master/src/fsharp/vs/SimpleServices.fs#L158
To the full sourcecodeservices
That lets you compile from a uast (ParseTree) fragment into an assembly or dynamic assembly.
What we need is something that lets you compile fragments of code to the tast. If you follow the code above you should be able to see that various stages of the compiler.
I think we need to do some processing at or around here: https://github.com/fsharp/FSharp.Compiler.Service/blob/e3afab2ebf7d5611dc8b5d96b872ede7e9381904/src/fsharp/fsc.fs#L2166 to get the results into something we can use.
I think we need generatedCcu and typedAssembly to create the tast container, from a quick glance anyway.
Maybe we could make our efforts more efficient by scoping our needs. Let's name this hypothetical compiler FableJS v1, what would be its purpose?
With that in mind, we can then reply:
FableJS v1 need to support .NET dll references (besides FSharp.Core, Fable.Core and the supported BCL)?FableJS v1 is meant to run only in the browser, does it need to support projects or just code strings (scripts)? For an initial minimally viable implementation (imo): 1.1 - Yes, 1.2 - Yes, 2.1 - No, 2.2 - No (just scripts), but everything's possible in theory.
Once you get to dll's things get more tricky as you might not have the full ast
I think v1 should be FSharp.Core minimal(maybe only pcl259/netcore) and minimal BCL with just scripts.
I need to check with the dll issue and ast's, in soothsayer I was doing that but I cant remember the detail I get back.
Closing for now, as this issue requires a lot of work and there's been no contributions in this regard so far. Furthermore, Fable is going towards more integration with dotnet sdk and it's already including some operations that are difficult to translate to JS (like loading assemblies dynamically for plugins).
Most helpful comment
This would be FANTASTIC and is a really important long term goal for F#.
I started looking at this briefly a while back. I took the first two files in the FSharp.Compiler.Service DLL code and put them through Fable, hit a couple of bugs and reported them. I think they are fixed.
So the way forward is to just repeatedly try to compile chunks of FCS using Fable and fix all the bugs/incompletenesses in Fable (and perhaps add some new unit tests as we go to check things are beginning to work). You'd have to iterate on this many times, and put in a fair few
#if/#endifsections into FCS.But it would be really, really worth it!!!