Compile F# to Rust 🦀

jkone27
3 min readJun 15, 2023

--

Via Fable

how my directory looks like

Questioning weather or not is legit to compare F# to Rust, I decided to give fable rust a go, and show that F# can also compile to Rust, other than being similar and affine in synthax and typesystem regards.

Here is a previous article comparing the 2 languages if you are interested!

Let’s Go

dotnet new tool-manifest
dotnet tool install fable --prerelease

Once we have a folder with dotnet fable installed, we can start from an F# script that we want to convert, let’s call it testRust.fsx

module fableRust

let ``I am a super cool F# Sum`` a b =
a + b


// rust requires a main function
[<EntryPoint>]
let main args =
let res =
(1,2)
||> ``I am a super cool F# Sum``

printfn $"{nameof(``I am a super cool F# Sum``)} returned {res}"
0

now let’s add a Cargo.toml file specifying the only dependency needed by fable rust:

[package]
name = "fable-rust-sample"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "testRust" // change this with your script name without .rs
path = "testRust.rs" // change this with your script name

[dependencies]
fable_library_rust = { path = "./fable_modules/fable-library-rust" }

Now le’ts convert our script to Rust via Fable! We specify our extension -e to be .rs and our target language to be Rust via the lang flag!

dotnet fable testRust.fsx --lang rust -e rs

This command will output out beautiful testRust.rs in our folder

#![allow(dead_code,)]
#![allow(non_camel_case_types,)]
#![allow(non_snake_case,)]
#![allow(non_upper_case_globals,)]
#![allow(unreachable_code,)]
#![allow(unused_attributes,)]
#![allow(unused_imports,)]
#![allow(unused_macros,)]
#![allow(unused_parens,)]
#![allow(unused_variables,)]
use fable_library_rust::NativeArray_::array_from;
use fable_library_rust::String_::fromString;
pub mod fableRust {
use super::*;
use fable_library_rust::Native_::Any;
use fable_library_rust::NativeArray_::Array;
use fable_library_rust::String_::string;
pub fn I_am_a_super_cool_F_0023_Sum(a: i32, b: i32) -> i32 { a + b }
pub fn main(args: Array<string>) -> i32 {
let res: i32 = fableRust::I_am_a_super_cool_F_0023_Sum(1_i32, 2_i32);
println!("{} returned {}", &string("I am a super cool F# Sum"),
&res,);
0_i32
}
}
pub fn main() {
let args = std::env::args().skip(1).map(fromString).collect();
fableRust::main(array_from(args));
}

Now let’s build with cargo clean (to cleanup any leftovers if you already ran this command before) and cargo build

output of cargo clean and cargo build

Now let’s run our app via cargo run

output of cargo run

It works! we Wrote our code in F#, compiled it to Rust and then to 101001101101010 (binary), isn’t that awesome?

Run as Script?

Usually in rust is not easy to execute code as script, but thanks to this rust package (crate) we could ease the linking process and make a rust script execution possible in a one line command! But after a few tries I couldn’t make it work, but I am a rustacean 🦀 newbie I probably have to study more!

cargo install cargo-script
cargo script -D fable_library_rust testRust.rs

Let me know anything in the comment, and have a really nice day!

Support Fable Project, it is just awesome 💙

Refs

--

--