Skip to content

Commit

Permalink
Workaround Fable issue with active patterns
Browse files Browse the repository at this point in the history
Issue: In some cases, Fable 2.1.12 hangs at compile time even as
dotnet.exe grows to a a multi-gigabyte footprint.

After consulting with Fable's creator, Alfonso Garcia-Caro, I
decided to remove the reliance on F# compiler's magic for
defining recursive data structures (via delayed initiatization).
Even though the magic worked fine in .NET, it seemed to be
confusing Fable, so I replaced it with code that explicitly did
the same thing as the compiler magic: used stateful variables
to implement recursive definitions.

This was enough to prevent Fable from blowing up to multi-gigabyte
footprints, and it was even though to allow compilation to terminate
eventually (after 10x longer than usual), but I wanted to solve the
perf problem too and make Fable compile my project quickly (~45
seconds instead 10 minutes). It turned out that the key here was
*long* grammar productions, i.e. deeply-nested recursive active
patterns. The solution was to define local, helper active patterns
and reference those. For example, in Dice.fs, the (|SimpleRoll|_|)
active pattern now has two helper patterns, LongSimpleRoll and
MidSimpleRoll. Extracting LongSimpleRoll saved ~35 seconds of
compile time, and extracting MidSimpleRoll saved ~4 seconds.
(Prior to extraction, it was taking ~49 seconds to compile the
project. Afterwards, it took ~11 seconds.)

I also updated Fable version and Babel/Webpack versions in the
process. This may have helped some; it's hard to tell, but it
didn't hurt any so I'm checking it in.
  • Loading branch information
MaxWilsonMS committed Mar 5, 2019
1 parent f996e78 commit 1c56935
Show file tree
Hide file tree
Showing 9 changed files with 1,404 additions and 8,329 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,4 @@ docs/tools/FSharp.Formatting.svclog
.ionide.debug
*.bak
project.lock.json
deploy
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ Very much in-progress.
* Install JS dependencies: `npm install`
* **Move to `src` folder**: `cd src`
* Install F# dependencies: `dotnet restore`
* Start Fable daemon and [Webpack](https://webpack.js.org/) dev server: `dotnet fable npm-start`
* Run webpack dev server: `yarn start`
* In your browser, open: http://localhost:8080/

> `dotnet fable yarn-start` (or `npm-start`) is used to start the Fable daemon and run a script in package.json concurrently. It's a shortcut of `yarn-run [SCRIP_NAME]`, e.g. `dotnet fable yarn-run start`.
> `yarn webpack` (or `npm-start`) will internally start the Fable daemon and run a script in package.json concurrently.
If you are using VS Code + [Ionide](http://ionide.io/), you can also use the key combination: Ctrl+Shift+B (Cmd+Shift+B on macOS) instead of typing the `dotnet fable yarn-start` command. This also has the advantage that Fable-specific errors will be highlighted in the editor along with other F# errors.
If you are using VS Code + [Ionide](http://ionide.io/), you can also use the key combination: Ctrl+Shift+B (Cmd+Shift+B on macOS) instead of typing the `yarn webpack` command. This also has the advantage that Fable-specific errors will be highlighted in the editor along with other F# errors.

Any modification you do to the F# code will be reflected in the web page after saving. When you want to output the JS code to disk, run `dotnet fable yarn-build` (or `npm-build`) and you'll get a minified JS bundle in the `public` folder.
Any modification you do to the F# code will be reflected in the web page after saving. When you want to output the JS code to disk, run `yarn build` (or `npm build`) and you'll get a minified JS bundle in the `public` folder.

Loading

0 comments on commit 1c56935

Please sign in to comment.