Skip to content

Commit 89132f6

Browse files
authored
Update docs (#76)
* Start fixing * Update docs * Update docs
1 parent 3cb0332 commit 89132f6

31 files changed

+302
-419
lines changed

Build.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ Target.create "Build" (fun _ ->
2323
)
2424

2525
Target.create "Docs" (fun _ ->
26-
run poetry "run jb build docs-src --path-output docs" "."
26+
run poetry $"run jb build docs-src --path-output {buildPath}/docs" "."
27+
Fake.IO.Shell.copyDir "docs" $"{buildPath}/docs/_build/html" (fun _ -> true)
2728
)
2829

2930
Target.create "Run" (fun _ ->

docs-src/dotnet/numbers.md

Lines changed: 20 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,43 @@
11
# Numeric types
22

3-
In Fable, we use F# numeric types, which are all translated to Python integers at the exception of `float`, `double`, and `decimal`.
3+
In Fable, we use F# numeric types, which are all translated to Python integers except for `float`, `double`, and
4+
`decimal`.
45

56
Fable numbers are very nearly compatible with .NET semantics, but translating into Python types has consequences:
67

7-
* (non-standard) All floating point numbers are implemented as 64 bit (`double`). This makes `float32` numbers more accurate than expected.
8-
* (non-standard) Arithmetic integers of 32 bits or less are implemented with different truncation from that expected, as whole numbers embedded within `double`.
8+
* (non-standard) All floating point numbers are implemented as 64 bit (`double`). This makes `float32` numbers more
9+
accurate than expected.
10+
* (non-standard) Arithmetic integers of 32 bits or less are implemented with different truncation from that expected, as
11+
whole numbers embedded within `double`.
912
* (OK) Conversions between types are correctly truncated.
1013
* (OK) Bitwise operations for 64 bit and 32 bit integers are correct and truncated to the appropriate number of bits.
11-
* (non-standard) Bitwise operations for 16 bit and 8 bit integers use the underlying JavaScript 32 bit bitwise semantics. Results are not truncated as expected, and shift operands are not masked to fit the data type.
12-
* (OK) Longs have a custom implementation which is identical in semantics to .NET and truncates in 64 bits, although it is slower.
14+
* (non-standard) Bitwise operations for 16 bit and 8 bit integers use the underlying JavaScript 32 bit bitwise
15+
semantics. Results are not truncated as expected, and shift operands are not masked to fit the data type.
16+
* (OK) Longs have a custom implementation which is identical in semantics to .NET and truncates in 64 bits, although it
17+
is slower.
1318

1419
32 bit integers thus differ from .NET in two ways:
1520

16-
* Underlying 52 bit precision, without expected truncation to 32 bits on overflow. Truncation can be forced if needed by `>>> 0`.
17-
* On exceeding 52 bits absolute value floating point loses precision. So overflow will result in unexpected lower order 0 bits.
21+
* Underlying unlimited precision, without expected truncation to 32 bits on overflow. Truncation can be forced if needed
22+
by `>>> 0`.
1823

1924
The loss of precision can be seen in a single multiplication:
2025

2126
```fsharp
2227
((1 <<< 28) + 1) * ((1 <<< 28) + 1) >>> 0
2328
```
2429

25-
The multiply product will have internal double representation rounded to `0x0100_0000_2000_0000`. When it is truncated to 32 bits by `>>> 0` the result will be `0x2000_0000` not the .NET exact lower order bits value of `0x2000_0001`.
26-
27-
The same problem can be seen where repeated arithmetic operations make the internal (non-truncated) value large. For example a linear congruence random number generator:
28-
29-
```fsharp
30-
let rng (s:int32) = 10001*s + 12345
31-
```
32-
33-
The numbers generated by repeated application of this to its result will all be even after the 4th pseudo-random number, when `s` value exceeds 2^53:
34-
35-
```fsharp
36-
let rec randLst n s =
37-
match n with
38-
| 0 -> [s]
39-
| n -> s :: randLst (n-1) (rng s)
40-
41-
List.iter (printfn "%x") (randLst 7 1)
42-
```
43-
44-
The resulting printed list of pseudo-random numbers does not work in Fable:
45-
46-
| Fable | .NET |
47-
|-------:|------:|
48-
|1|1|
49-
|574a|574a
50-
|d524223|d524223|
51-
|6a89e98c|6a89e98c|
52-
|15bd0684|15bd0685|
53-
|3d8b8000|3d8be20e|
54-
|50000000|65ba5527|
55-
|0|2458c8d0|
30+
The multiply product will have internal double representation rounded to `0x0100_0000_2000_0000`. When it is truncated
31+
to 32 bits by `>>> 0` the result will be `0x2000_0000` not the .NET exact lower order bits value of `0x2000_0001`.
5632

5733
## Workarounds
5834

59-
* When accurate low-order bit arithmetic is needed and overflow can result in numbers larger than 2^53 use `int64`, `uint64`, which use exact 64 bits, instead of `int32`, `uint32`.
60-
* Alternately, truncate all arithmetic with `>>> 0` or `>>> 0u` as appropriate before numbers can get larger than 2^53: `let rng (s:int32) = 10001*s + 12345 >>> 0`
35+
* When accurate low-order bit arithmetic is needed and overflow can result in numbers larger than 2^53 use `int64`,
36+
`uint64`, which use exact 64 bits, instead of `int32`, `uint32`.
37+
* Alternately, truncate all arithmetic with `>>> 0` or `>>> 0u` as appropriate before numbers can get larger than 2^53:
38+
`let rng (s:int32) = 10001*s + 12345 >>> 0`
6139

6240
## Printing
6341

64-
One small change from .NET in `printf`, `sprintf`, `ToString`. Negative signed integers are printed in hexadecimal format as sign + magnitude, in .NET they are printed as two's complement bit patterns.
42+
One small change from .NET in `printf`, `sprintf`, `ToString`. Negative signed integers are printed in hexadecimal
43+
format as sign + magnitude, in .NET they are printed as two's complement bit patterns.

docs-src/index.md

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Fable supports the <a href="docs/dotnet/compatibility.html">F# core library and
3838
::::
3939

4040
```{seealso}
41-
[Try online](https://fable.io/repl")
41+
[Try online](https://fable.io/repl)
4242
```
4343

4444
## Features
@@ -130,21 +130,23 @@ let thisWorks = distance / time
130130
Build your types using real-world conditions and make the compiler warn you if those conditions change.
131131

132132
```fsharp
133-
[<Literal>]
134-
let JSON_URL = "https://jsonplaceholder.typicode.com/todos"
135-
136-
// Type is created automatically from the url
137-
type Todos = Fable.JsonProvider.Generator<JSON_URL>
138-
139-
async {
140-
let! (_, res) = Fable.SimpleHttp.Http.get url
141-
let todos = Todos.ParseArray res
142-
for todo in todos do
143-
// Compilation fail if the JSON schema changes
144-
printfn "ID %i, USER: %i, TITLE %s, COMPLETED %b"
145-
todo.id
146-
todo.userId
147-
todo.title
148-
todo.completed
149-
}
133+
open Zanaptak.TypedCssClasses
134+
135+
type Bulma = CssClasses<"https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css", Naming.PascalCase>
136+
137+
let hero (model: Model) body =
138+
Html.section [
139+
prop.classes [ Bulma.Hero; Bulma.IsFullheightWithNavbar ]
140+
prop.style [
141+
style.backgroundImageUrl (model.Banner)
142+
style.backgroundPosition "center"
143+
style.backgroundSize.cover
144+
]
145+
prop.children [
146+
Html.div [
147+
prop.classes [ Bulma.HeroBody; Bulma.IsDark ]
148+
prop.children [ Html.div [ prop.classes [ Bulma.Container ]; prop.children body ] ]
149+
]
150+
]
151+
]
150152
```

docs-src/intro.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@ printfn $"The area of the square is {getArea square}"
1818

1919
## What is F#?
2020

21-
F# (pronounced f-sharp) is a strongly typed Functional programming language which offers many great features to build robust and maintable code such as:
21+
F# (pronounced f-sharp) is a strongly typed Functional programming language which offers many great features to build
22+
robust and maintable code such as:
2223

2324
- Lightweight syntax
2425
- Immutability baked into the language by default
2526
- Rich types which let you represent easily your data or your domain
2627
- Powerful pattern matching to define complex behaviors
2728
- And so much more...
2829

29-
F# is already used on the server for web and cloud apps, and it's also used quite a lot for data science and machine learning. It's a great general-purpose language, and also a great fit for building beautiful UIs that run in the browser.
30+
F# is already used on the server for web and cloud apps, and it's also used quite a lot for data science and machine
31+
learning. It's a great general-purpose language, and also a great fit for building beautiful UIs that run in the
32+
browser.
3033

3134
## Why use F# for your next Python project?
3235

@@ -39,4 +42,6 @@ F# is a great choice to build beautiful apps that run in the browser. F# is:
3942

4043
When compared with Python, F# is safer, more robust, and more pleasant to read and write.
4144

42-
F# is a mature language with functional programming and object programming capabilities, but it doesn't sacrifice readability or simplicity to offer these things. Because of that, we think it's a great choice for your next Python application.
45+
F# is a mature language with functional programming and object programming capabilities, but it doesn't sacrifice
46+
readability or simplicity to offer these things. Because of that, we think it's a great choice for your next Python
47+
application.

docs-src/introduction/dotnet-users-read-this.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,24 @@ For starters, using F# for fable apps is very similar to using F# for .NET apps:
1313
1. Fable projects use standard `.fsproj` project files (which can also be part of `.sln` solutions) or `.fsx` scripts
1414
2. You can use well-known .NET/F# tools like NuGet, Paket or Fake to manage dependencies or your build
1515
3. You can use any F# editor like Visual Studio, Ionide or Rider
16-
4. Many common classes and routines from the **System** namespace have been mapped to Fable to provide a familiar interface for very common things, such as `DateTime`, `Math`, `String`, etc.
16+
4. Many common classes and routines from the **System** namespace have been mapped to Fable to provide a familiar
17+
interface for very common things, such as `DateTime`, `Math`, `String`, etc.
1718
5. Most of **FSharp.Core** is also supported. Check the ".NET and F# Compatibility" section.
1819

1920
## Fable is Python
2021

21-
Although Fable brings a lot of familiarity for F# and .NET developers, the target runtime is Python. This difference impacts several important areas:
22+
Although Fable brings a lot of familiarity for F# and .NET developers, the target runtime is Python. This difference
23+
impacts several important areas:
2224

2325
* Your dependencies will be Python (e.g PyPI) dependencies, not .NET dependencies
2426
* Runtime behavior will be based on Python semantics, not .NET semantics
2527

26-
There are some NuGet packages you can add into an F# project, but these packages have to also target Fable Python. Otherwise, your dependencies will directly be Python dependencies. Please check the "Author a Fable library" section to learn more, especially if you are a library author and would like to make your package compatible with Fable Python.
28+
There are some NuGet packages you can add into an F# project, but these packages have to also target Fable Python.
29+
Otherwise, your dependencies will directly be Python dependencies. Please check the "Author a Fable library" section to
30+
learn more, especially if you are a library author and would like to make your package compatible with Fable Python.
2731

28-
These differences may seem like a lot to take in at once, but they're important for building robust applications. There have been efforts in the past to try and "magically" turn .NET code into JS, and these all tend to fail. The reality is that your target runtime environment will affect how your app runs and how you build it. However, once you internalize this, you'll find that using F# for web apps with Fable is incredibly productive, making web programming a lot more joyful than just using Python!
32+
These differences may seem like a lot to take in at once, but they're important for building robust applications. There
33+
have been efforts in the past to try and "magically" turn .NET code into JS, and these all tend to fail. The reality is
34+
that your target runtime environment will affect how your app runs and how you build it. However, once you internalize
35+
this, you'll find that using F# for web apps with Fable is incredibly productive, making web programming a lot more
36+
joyful than just using Python!

docs-src/your-fable-project/build-and-run.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,27 @@
22

33
Your project is ready? Then it's time to build and run it.
44

5+
## Setup environment
6+
7+
```console
8+
> dotnet new tool-manifest
9+
> dotnet tool install fable --prerelease
10+
```
11+
512
## Build
613

14+
If you are buliding an F# script:
15+
716
```console
817
> dotnet fable --lang py project.fsx
918
```
1019

20+
If you are buliding an F# project:
21+
22+
```console
23+
> dotnet fable --lang py project.fsproj
24+
```
25+
1126
## Run
1227

1328
```console

docs-src/your-fable-project/project-file.md

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@ Many F# IDEs already provide commands to perform operations like creating a proj
1010
below are only necessary if you want to do this manually.
1111
:::
1212

13-
<ul class="textual-steps">
14-
<li>
13+
## Create an .fsproj file
1514

16-
**Create an .fsproj file**
17-
18-
`.fsproj` files are in XML format. This may look a bit old-fashioned, but luckily the basic schema for F# projects has become much simpler in recent versions. Now the skeleton for most projects looks like this:
15+
`.fsproj` files are in XML format. This may look a bit old-fashioned, but luckily the basic schema for F# projects has
16+
become much simpler in recent versions. Now the skeleton for most projects looks like this:
1917

2018
```xml
2119
<Project Sdk="Microsoft.NET.Sdk">
@@ -31,21 +29,19 @@ below are only necessary if you want to do this manually.
3129
</Project>
3230
```
3331

34-
</li>
35-
36-
<li>
37-
38-
**Add an .fs file to the project**
32+
## Add an .fs file to the project
3933

40-
F# source files end with the `.fs` extension. To include a new one in the project, you only need to add it to the `.fsproj` using a relative path with the following tag:
34+
F# source files end with the `.fs` extension. To include a new one in the project, you only need to add it to the
35+
`.fsproj` using a relative path with the following tag:
4136

4237
```xml
4338
<ItemGroup>
4439
<Compile Include="path/to/my/File.fs" />
4540
<ItemGroup>
4641
```
4742

48-
For example, if we have have an app with two files, named `MyAwesomeFeature.fs` and `App.fs` (the last one contains the entry point), it will look like this
43+
For example, if we have have an app with two files, named `MyAwesomeFeature.fs` and `App.fs` (the last one contains the
44+
entry point), it will look like this
4945

5046
```xml
5147
<ItemGroup>
@@ -55,12 +51,15 @@ For example, if we have have an app with two files, named `MyAwesomeFeature.fs`
5551
```
5652

5753
:::{note}
58-
Please be aware that in F#, **file order is important.** For instance, if `App.fs` calls `MyAwesomeFeature.fs`, then you must place `MyAwesomeFeature.fs` above `App.fs`.
54+
Please be aware that in F#, **file order is important.** For instance, if `App.fs` calls `MyAwesomeFeature.fs`, then you
55+
must place `MyAwesomeFeature.fs` above `App.fs`.
5956
:::
6057

61-
Let's add another file, `Authentication.fs`, located in another folder `Shared` which is at the same depth as our `src` folder (this can happen, for example, if the file is shared with another project, like a server). Let's see the current state of our project tree:
58+
Let's add another file, `Authentication.fs`, located in another folder `Shared` which is at the same depth as our `src`
59+
folder (this can happen, for example, if the file is shared with another project, like a server). Let's see the current
60+
state of our project tree:
6261

63-
```
62+
```text
6463
myproject
6564
|_ src
6665
|_ MyAwesomeFeature.fs
@@ -80,7 +79,7 @@ This can be expressed in the project file as:
8079
<ItemGroup>
8180
```
8281

83-
</li>
84-
</ul>
85-
86-
An important thing to note is Fable will translate F# source files to [ES2015 modules](https://exploringjs.com/es6/ch_modules.html) using JS `import`. This means that files which are not referenced by any other **will be ignored** (except the last file) including side effects. This is different behavior from .NET, where all files are compiled and executed, regardless of their relationship with the rest of the project.
82+
An important thing to note is Fable will translate F# source files to [ES2015
83+
modules](https://exploringjs.com/es6/ch_modules.html) using JS `import`. This means that files which are not referenced
84+
by any other **will be ignored** (except the last file) including side effects. This is different behavior from .NET,
85+
where all files are compiled and executed, regardless of their relationship with the rest of the project.

docs-src/your-fable-project/testing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Testing
22

3-
You can use all tools of the JS ecosystem.
3+
You can use all tools of the Python ecosystem.
44

55
Several js libs already have a Fable binding:
66
- mocha: [https://github.com/Zaid-Ajaj/Fable.Mocha](https://github.com/Zaid-Ajaj/Fable.Mocha)

0 commit comments

Comments
 (0)