Open DunetsNM opened 1 year ago
Not sure if there are any technical reasons behind this design, maybe it's not a bug but feature? Then this behavior needs to be documented.
Currently https://learn.microsoft.com/en-us/dotnet/fsharp/tools/fsharp-interactive/ simply states that #load
Reads a source file, compiles it, and runs it.
a bit of background, I switched my project from fake-cli tool (dotnet fake) to plain F# interactive and ran into this bug. Scripts that fake-cli runs fine started to fail in dotnet fsi
so I had to create extra wrapper script for each entry-point script
Yeah, this is a by design behaviour. Not a bug
I don't know the underpinnings, but I overall think it fits something akin to #4772
few things to consider:
;;
(say you can write a script which outputs a .dll, and then load it, to showcase something a bit "ill")the message which deals with showing "type A was expected but type A was given" was improved to carry the assembly name.
so this is by design that running the very same .fsx script file directly via dotnet fsi
and indirectly via #load
(see the workaround) results in different behavior?
As mentioned above docs simply say that #load
just
Reads a source file, compiles it, and runs it.
This sounds very much the same as what dotnet fsi
meant to do : read the source file, compile it and run it.
I didn't read the fsi source code but my hunch is that when #load
invoked from the entry point script it spawns a separate compilation dynamically , so if two #load directives happen to declare same types they'll end up in two separate dynamic assemblies.
However each individual #load
directive is clever enough to fetch all the transient dependencies (nested #load directives in loaded script) and compile it once as a whole thing - hence why described workaround works.
The question is, why dotnet fsi
does not simply do the same? And why is it a feature rather than a bug?
The most naive fix would be if under the hood fsi simply createad a temp .fsx script with a single #load
line and compiled that instead of the supplied .fsx file (but probably it's also not hard to achieve without a temp file)
I have a hierarchy of .fsx scripts where entry point script
#load
a few helper scripts. Some of the leaf-level scripts loaded twice or more times which F# interactive refuses to compile.Repro steps
1_SharedType.fsx
file with this code2_Func1_Return_SharedType.fsx
file with this code2_Func2_Return_SharedType.fsx
file with this code3_Main.fsx
file with this code:dotnet fsi ./3_Main.fsx
Expected behavior
Script compiles runs and prints "Are x and y equal? False"
Actual behavior
Compilation fails with the error:
Known workarounds
Need to create yet another top level script that has one line
#load "./3_Main.fsx"
and run it.This way F# interactive somehow properly deduplicates repeated #load directives during compilation and runs script successfully
Related information
Provide any related information (optional):