.NET and F# compatibility
Contents
.NET and F# compatibility#
Fable provides support for some classes of .NET BCL (Base Class Library) and most of FSharp.Core library. When possible, Fable translates .NET types and methods to native JavaScript APIs for minimum overhead.
.NET Base Class Library#
The following classes are translated to JS and most of their methods (static and instance) should be available in Fable.
.NET |
Python |
---|---|
Numeric Types |
int |
Arrays |
array / bytearray |
Events |
fable-core/Event |
System.Boolean |
bool |
System.Char |
str |
System.String |
str |
System.Guid |
guid |
System.TimeSpan |
timedelta |
System.DateTime |
datetime |
System.DateTimeOffset |
timedelta |
System.Timers.Timer |
fable-core/Timer |
System.Collections.Generic.List |
List |
System.Collections.Generic.HashSet |
Set |
System.Collections.Generic.Dictionary |
dict |
System.Text.RegularExpressions.Regex |
re |
System.Lazy |
fable-core/Lazy |
System.Random |
{} |
System.Math |
math |
The following static methods are also available:
System.Console.WriteLine
(also with formatting)System.Diagnostics.Debug.WriteLine
(also with formatting)System.Diagnostics.Debug.Assert(condition: bool)
System.Diagnostics.Debugger.Break()
System.Activator.CreateInstance<'T>()
There is also support to convert between numeric types and to parse strings, check the conversion tests.
Caveats#
All numeric types become Python
int
(64-bit floating type), except fordecimal
. Check the Numeric Types section to learn more about the differences between .NET and Python.Numeric arrays are compiled to array when possible. Numeric arrays of
uint8
are compiled to bytearray in order to support libraries that expect e.gbytes
as input.No bound checks for numeric types (unless you do explicit conversions like
byte 500
) nor for array indices.
FSharp.Core#
Most of FSharp.Core operators are supported, as well as formatting with sprintf
, printfn
or failwithf
(String.Format
is also available). The following types and/or corresponding modules from FSharp.Core lib will likewise
translate to JS:
.NET |
Python |
---|---|
Tuples |
tuple |
Option |
(erased) |
Choice |
fable-core/Choice |
Result |
fable-core/Result |
String |
fable-core/String (module) |
Seq |
|
List |
fable-core/List |
Map |
fable-core/Map |
Set |
fable-core/Set |
Async |
fable-core/Async |
Task |
|
Event |
fable-core/Event (module) |
Observable |
fable-core/Observable (module) |
Arrays |
array / bytearray |
Events |
fable-core/Event |
MailboxProcessor |
fable-core/MailboxProcessor (limited support) |
Caveats II#
Options are erased in Python (
Some 5
becomes just5
in Python andNone
translates toNone
). This is needed for example, to represent Python optional properties. However in a few cases (like nested options) there is an actual representation of the option in the runtime.Async.RunSynchronously
is not supported.MailboxProcessor
is single-threaded in Python and currently onlyStart
,Receive
,Post
andPostAndAsyncReply
are implemented (cancellationToken
ortimeout
optional arguments are not supported).
Object Oriented Programming#
Most of F# OOP features are compatible with Fable: interfaces and abstract classes, structs, inheritance, overloading, etc. However, please note that instance members are not attached to the prototype, which means they won’t be accessible from native JS code. The exception to this rule are the implementations of interface and abstract members.
Caveats III#
It’s not possible to type test against interfaces or generic types.
Reflection and Generics#
There is some reflection support in Fable, you can check the reflection tests to see what is currently possible.
Generics are erased by default in the generated Python code. However, it is still possible to access generic information
(like typeof<'T>
) at runtime by marking functions with inline
:
let doesNotCompileInFable(x: 'T) =
typeof<'T>.FullName |> printfn "%s"
let inline doesWork(x: 'T) =
typeof<'T>.FullName |> printfn "%s"
doesWork 5