Fable: F# to JavaScript Compiler

repository·main·Indexed 25 days ago

https://github.com/fable-compiler/fable

Fable is an F# to JavaScript compiler powered by FSharp Compiler Services (FCS) that allows F# developers to target the JavaScript ecosystem. It includes support for various targets including JavaScript, Python (beta), PHP (experimental), and Rust. The project provides tools such as fable-compiler-js for Node.js environments, fable-standalone for JS-only environments, and the Fable.Core library for core utilities.

Tokens
29.8K
Snippets
35
Records
246
Agent score
84%

What's inside Fable

  1. Overview of Fable: F# to JavaScript Compiler

    main
    Fable is an F# to JavaScript compiler powered by FSharp Compiler Services (FCS). It is designed to enable F# to function as a first-class citizen within the JavaScript ecosystem. For detailed documentation and setup guides, visit fable.io.
  2. Overview of Fable.Cli

    main

    Fable.Cli contains the source files used when Fable is compiled as a command-line interface (CLI) tool. It is currently distributed embedded within the fable-compiler npm package.

    Important Compatibility Note: This component assumes a netcoreapp target and utilizes APIs that are not compatible with Fable itself.

  3. Overview of Fable Python support

    main

    Fable Python provides beta support for transforming F# code into Python. The compiler transforms the F# AST into a Python AST and then generates typed Python source code.

    Key design mappings include:

    • F# List: Translated to List.fs (immutable).
    • F# ResizeArray: Translated to Python list.
    • F# Record: Translated to dataclasses.dataclass decorated types in types.py.
    • F# Option: None is translated to Python None; Some is erased.
    • F# Arrays: Various numeric arrays (e.g., int[], float[]) are implemented as FSharpArray using a custom pyo3 wrapper. FSharpArray stores elements unboxed and returns them in their Python representation (e.g., int[] yields plain ints).
  4. Fable.Beam Target Overview

    main

    Fable.Beam allows compiling F# to the BEAM (Erlang VM). It targets Erlang source code and follows several design principles to ensure idiomatic BEAM performance while maintaining F# semantics:

    • Target Language: Erlang source.
    • Minimum OTP Version: 25.
    • Module Naming: Uses snake_case derived from the filename (e.g., MyModule.fs becomes my_module.erl).
    • String Representation: Uses modern Erlang binaries (<<"hello">>) for efficiency.
    • Equality: Uses Erlang's exact equality (=:=, /=:=) to match F#'s value equality semantics.
    • Records: Compiled to Erlang maps (#{}) with snake_case atom field names.
    • Library Layout: Fable library files are placed in fable_modules/fable-library-beam/ within the output directory. Erlang resolves these via the code path (-pa).
  5. Fable.Beam Language Feature Support

    main

    Fable.Beam maps core F# features to Erlang primitives. Key mappings include:

    • Records & DUs: Records map to Erlang maps (#{field => value}). Discriminated Unions (DUs) map to tagged tuples (e.g., {atom_tag, Field1, ...}).
    • Collections:
      • list<T> maps to Erlang lists.
      • Map<K,V> maps to Erlang maps.
      • Set<T> maps to Erlang ordsets (sorted lists).
      • array<T> maps to Erlang lists wrapped in dict refs (byte arrays use atomics).
    • Async & Task: Implemented via Continuation-Passing Style (CPS). Async<T> is a function fun(Ctx) -> ok end. Task is an alias for Async.
    • Error Handling: try/with maps to try/catch using erlang:error. Custom exceptions are represented as maps with an exn_type tag.
    • MailboxProcessor: Implemented as an in-process CPS model using the process dict for state management.
  6. Understand the Fable Library for Python architecture

    main

    The Fable Python target is designed to provide F# type support (such as uint8) and high performance in Python. It uses a two-tier architecture:

    1. Python components: The core Fable library functionality written in Python.
    2. Rust extensions: Native code used for performance and to support types not natively available in Python (e.g., unsigned integers).

    When using libraries compiled with Fable, this architecture ensures cross-platform compatibility and proper type fidelity.

  7. Use fable-standalone for JS-only environments

    main

    Use fable-standalone to bootstrap Fable in environments that only support JavaScript, such as the browser or Node.js.

    Important Note: This package does not output JavaScript code directly. Instead, it outputs a JSON AST (Abstract Syntax Tree) which must then be transformed into JavaScript using Babel.