F# to JavaScript compiler Fable has reached version 1.0 beta, bringing tooling improvements, a streamlined project format, and better code generation.
Fable is now integrated with dotnet SDK, which means that it is now available through nuget
and developers can use the dotnet
CLI tool to manage projects. For example, this is how you would create a new Fable project:
mkdir myfableapp
cd myfableapp
dotnet new fable ## create the project files from a template
dotnet restore ## install nuget deps
npm install ## install nmp deps
dotnet fable add <library> ## add a library to the project
Additionally, Fable now comes with Webpack integration. In fact, the JavaScript component of the Fable compiler has become a Webpack loader and thus allows developers to define and build workflows that cooperate with loaders for other languages, such as TypeScript. The Fable Webpack loader communicates with the Fable server, which can be started with dotnet fable start
.
As mentioned, another important change brought by release 1.0 is a new project format, which is now a simple XML file that lists in an orderly way all dependencies and files that compose a project. The main advantage of this new format is the possibility of it being easily modified without much risk of breaking things as it was the case with the old, over bloated format. At the moment, though, the only editor that supports the new format is Ionide.
Fable 1.0 also sports improved code generation, based on the work that ncave did to port the F# compiler to JavaScript using Fable. Besides powering the all-in-browser Fable REPL, using Fable for such a large project highlighted many optimizations and bugs.
InfoQ has spoken with Alfonso García-Caro, Fable creator and maintainer, and co-author of PACKT Mastering F#.
InfoQ covered Fable in Aug, 2016. Could you summarize for our readers what has changed in the language since then?
Fable is compatible with standard F# so most of new Fable language features come from F# itself. However Fable also adds a few additional features to improve interaction with JS, like erased unions, string enums or dynamic programming. One of the main changes in code generation Fable 1.0 is F# curried lambdas are not represented as JS nested functions anymore, which will improve a lot the interaction with JS libraries and prevent some of the confusions developers had when sending lambdas to JS code.
The main changes in Fable 1.0 are around tooling and workflow, which has been vastly improved thanks to the integration with dotnet SDK and Webpack, as well as the use of the new simpler F# project format. Users are encouraged to check the blog post announcing Fable 1.0 beta to know more. Fable docs will also be updated to the latest version soon.
What is fable model of interaction with JavaScript code? How does it allow to manage the typed/non-typed boundary?
One of Fable guidelines is to make interaction with JS as easy as possible. Because of this, there’s no barrier between code generated from F# and JS native code. It’s true that this sacrifices a bit the type safety you may find in other functional programs compiling to JS, but at the same time it makes it possible to take advantage of many existing tools and target any JS environment, not only the browser. Since its early days, Fable has supported Node, Github Electron, React Native, Fuse or Visual Studio Code extensions. Interaction with JS can be done by using ES2015 imports in combination with dynamic programming or typed interfaces, either custom-defined or generated from Typescript declaration files with the ts2fable parser.
In general, Fable has a similar principle that F# in .NET: it gives you high type safety in F# code with the absence of nulls, advanced types like discriminated unions to represent states and the preference for immutability; but at the same time it doesn’t get on you way when you need to get your hands dirty and interact with a C# or JS library. I think this greatly increases productivity and allows you to leverage existing tools without having to rewrite everything in F#.
Any success story worth telling?
There are already several companies, like msu solutions GmbH or NSYNK in Germany and Prolucid in Canada, and many independent developers with Fable apps in production. A particularly impressive site is the Gamma Project by Tomas Petricek, and one of the best F# IDEs out there, Ionide (a VS Code and Atom extension), is also built with Fable. Another interesting example is the Fable REPL which runs entirely on the browser with no backend by converting the F# compiler itself to JS using Fable.
How would you deem Fable 1.0 maturity? Is it ready for production? What is on Fable roadmap?
The currently released version, Fable 0.7, is indeed ready for production since it was released several months ago and no serious issue has been reported so far. Fable 1.0 is currently in beta status and it’s mainly intended for Fable power users to try out and provide feedback. Once we are sure the latest issues in tooling and code generation are ironed out we will release it as a stable version, hopefully in a few weeks.
After releasing Fable 1.0 RTM, we’ll move the focus to the Fable ecosystem: more and better libraries, samples and tutorials, as well as improving the ts2fable parser. Of course, we will keep working on Fable to add compatibility with the new features in F# (like the promising anonymous records). We also plan to combine the Fable REPL with Ionide-web to enable a full F# IDE running entirely on the browser with no backend and zero installation.
You can start using Fable by installing the dotnet SDK and then running:
dotnet new -i Fable.Template::*
This will install Fable templates, which you can use to create a project as outlined above.