[HN Gopher] FSharpPacker - compile F# scripts to executables
___________________________________________________________________
FSharpPacker - compile F# scripts to executables
Author : neonsunset
Score : 79 points
Date : 2024-12-03 10:44 UTC (4 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| Multicomp wrote:
| Nice work shipping this! I enjoy and prefer f# to c# but never
| gave scripts much care because I could never do this, fsi and the
| repl was not enough. Now? Hmmm I have options !
| neonsunset wrote:
| A few of notes regarding AOT compilation if you would like to
| have the best experience:
|
| 1. print* functions with "%A" format do not work because
| "structured output" uses reflection patterns that the linker
| cannot analyze. You can easily replace them with string
| interpolation that F# now has. I carry around these bindings:
| open System let println s = Console.WriteLine s
| let print s = Console.Write(x: string)
|
| and use them as println $"Hello, {thing}"
|
| 2. AOT compilation is not a scripting environment so accessing
| fsi args does not work, here's the snippet that I use for it:
| open System // Detect fsi, if not - slice
| appropriately // You do not need this if you know that you
| will be // only compiling the script or only running it
| with fsi // just use the offset of 2 or 1 respectively :)
| let args = let args = Environment.GetCommandLineArgs()
| if args[0].Contains "fsi.dll" then args[2..] else args[1..]
| // Use args in some way args |> Array.iter println
|
| 3. For quickly publishing script files you may want to define a
| (fish) shell function like this: function fspk
| set name (string replace '.fsx' '' $argv[1]) fspack
| $argv[1] -f net9.0 --aot -o . \
| /p:InvariantGlobalization=true \
| /p:OptimizationPreference=Size && rm -rf ./$name.dbg
| ./$name.dSYM end
|
| This will reduce the binary size and will give you just a single
| executable for every `fspk my_script.fsx`. The binaries do start
| at ~4MB but beyond that - they scale efficiently with
| dependencies.
|
| 4. Except what is explicitly noted in repo, other scripting
| features work like referencing nuget packages or importing files.
| I did not expect to like this as much as I did, it's incredibly
| productive and you can just throw a few files together while
| having fully statically typed scripting environment and built-in
| package manager.
|
| You can also get Ionide for VS Code for language server,
| autocomplete and debugging support.
| fire_lake wrote:
| Given these limitations, isn't it easier to create a small
| dotnet project?
| neonsunset wrote:
| It might be! I'd expect that at some point this would be a
| natural progression.
|
| However, very often you don't need that - you can just
| compile individual script files which merge together code,
| package and file references. No need to maintain a separate
| folder with a separate .fsproj - simply #open some_utils.fsx,
| #r "nuget: FsHttp" or #r "SomePackage.dll" and 'fspk
| my_script.fsx'.
|
| Initially, I did not know this existed, but it turned out a
| friend of mine wrote this tool and I have been using it ever
| since.
| Alifatisk wrote:
| I am a huge fan of keeping things as standalone executable, good
| work!
| raphinou wrote:
| FSharpPacker works on scripts (with extension .fsx) written with
| F# and usually run with `dotnet fsi`. For the F# advent calendar
| [1] I recently blogged about how those scripts are a viable
| starting point for developing an application in F#. Actually,
| it's even possible to easily maintain a scripted version and a
| compiled version of the same F# app, with basically the same
| code. For those interested, it's at
| https://www.asfaload.com/blog/fsharp-fsx-starting-point/
|
| 1: https://sergeytihon.com/2024/10/26/f-advent-calendar-in-
| engl...
| nickpeterson wrote:
| Any reason to prefer this or fflat (bflat)?
| neonsunset wrote:
| Fflat does not work on macOS and does not support .NET 9. I
| had issues with making it work on Windows and Linux too
| unfortunately.
|
| This one works like a charm.
___________________________________________________________________
(page generated 2024-12-07 23:00 UTC)