Taking inspiration from the tinygo project.
F# for WebAssembly.
TinyFS is a F# to Wasm Compiler.
Leveraging the FSharp.Compiler.Service nuget package to generate an Abstract Syntax Tree (AST). Then walking the AST to generate Wasm bytes.
Current feature status:
- Support for
int32
,int64
,float32
,float64
andbool
primitives - The basic mathematical operators (
+
,-
,*
,/
,%
) are supported%
- modulo not supported by floating point primitives
- The basic boolean operators (
=
,<>
,>
,>=
,<
,<=
) are supported - Local parameters are supported, as well as mutable parameters.
if/else
expression is supported- No
elif
yet
- No
while...do
The fastest way to get started is to install via nuget tool.
- Install a recent flavor of .NET 9 from microsoft (>9.0.102).
- Run the following command:
dotnet tool install --global TinyFS.Cli
- To update if already installed:
dotnet tool update -g TinyFS.Cli
- To update if already installed:
- You now have access to the
tinyfs
cli tool
How to compile and use.
- Write a valid .fs program containing the supported fs syntax listed above/below
- See examples to get started
- Currently every *.fs file requires main function with a single unit parameter to exist
- All code must be in a single .fs file, TinyFS does not currently support importing across files.
- Run
tinyfs compile <.fs file>
to generate a wasm file - Run
tinyfs run <.wasm file>
to run the generated wasm- Can also run in any other wasm compliant runtime.
- This leverages the wasmtime nuget package.
- You can also use
tinyfs compile -r <.fs file>
to compile and run in one command.
This is still alpha software, bugs are to be expected. The more complex the code, the more likely it will break.
By day I mainly program in C#, so I won't claim this library is optimized or error free. I mainly undertook this as a learning opportunity. There are currently no concrete plans for what this project will look like moving forward.
Feel free to raise an issue if you see something could be improved.
What makes TinyFS different than Blazor?
These are the two primary differences at the moment:
Blazor | TinyFS | |
---|---|---|
Maturity | Supported in Production | Alpha Software |
Architectural Approach | Ship an entire dotnet runtime in Wasm | Compiles F# to Wasm concepts |
Since this is a night and weekend project, there's roughly a 0% chance this library ends up competing with Blazor.
So if you want to run something in dotnet in WebAssembly, choose Blazor. If you want to explore an interesting library, take a look at TinyFS.
Below lists the following language features that are supported.
The easier a language construct is able to be mapped into WebAssembly the more likely it is to be implemented.
Please see the examples folder for examples of compileable F# syntax that is ready to be used.
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/basic-types
-
bool
- by converting to WebAssembly'si32
-
byte
-
sbyte
- by up converting to WebAssembly'si32
-
int16
- by up converting to WebAssembly'si32
-
uint16
-
int/int32
-
uint/uint32
-
long/int64
-
ulong/uint64
-
nativeint
- probably never -
unativeint
- probably never -
decimal
-
float32/single
(32 bit) -
float/double
(64 bit) -
char
-
string
-
unit
- WebAssembly provides builtin support for
int32
,int64
,float32
andfloat64
. Everything else comes extra.
-
let
bindings -
if...then...else
-
while...do loops
-
for...to loops
-
match expression
- arrays
- exception handling
- generics
- collections
- types
- tuples, options, results
- records and unions
- structs
- object oriented programming (class, interfaces, etc)
- reflection - probably never
- computation expressions
- async/task expressions
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/
Arithmetic Operators
-
+
-
-
-
*
-
/
-
%
-
**
For currently supported primitive types
Comparison Operators
-
=
-
<>
-
<
-
<=
-
>
-
>=
For currently supported primitive types
Boolean Operators
-
&&
-
||
For currently supported primitive types
Bitwise Operators
-
&&&
-
|||
-
<<<
-
>>>
-
^^^
-
~~~
Function Symbols and Operators
-
->
-
|>
-
||>
-
|||>
-
>>
-
<<
-
<|
-
<||
-
<|||
- Importing code across files
- Building an entire *.fsproj file
- Using standard library
I'm using the FSharp.Compiler.Service nuget package to generate a usable Abstract Syntax Tree (AST) given F# code.
Then using what I learned in WebAssembly from the Ground Up for converting the F# AST to Wasm.