dotnet / interactive

.NET Interactive combines the power of .NET with many other languages to create notebooks, REPLs, and embedded coding experiences. Share code, explore data, write, and learn across your apps in ways you couldn't before.
MIT License
2.92k stars 389 forks source link

F# notebooks, the `fsi` object settings and the F# scripting programming model #646

Open dsyme opened 4 years ago

dsyme commented 4 years ago

A design principle for F# notebooks should be alignment between the F# scripting programming model and the F# notebook programming model where possible, with divergence and augmentation where it makes sense.

F# has a standard way of specifying a set of important parameters related to script programming, namely the fsi object. This provides the following, however currently the fsi object is not available in the notebook programming model.

fsi.FloatingPointFormat
fsi.CommandLineArgs
fsi.FormatProvider
fsi.PrintDepth
fsi.PrintLength
fsi.PrintSize
fsi.PrintWidth
fsi.ShowDeclarationValues
fsi.ShowIEnumerable
fsi.AddPrinter
fsi.AddPrintTransformer

Although this doesn't cover everything, it covers crucial functionality that is well understood in the F# community and really forms part of the F# standard scripting programming model. We should make this available in the F# programming model in .NET Interactive by default and document its use.

I don't mind if there are other extensions to the programming model in notebooks (e.g. display is fantastic!), but we should at least be respecting nearly all of the above.

There will be an interaction betweeen fsi.AddPrinter, fsi.AddPrintTransformer and Formatter<_>.Register and we can consider which we recommend, I don't mind that much as long as high quality customizable printing is possible.

dsyme commented 4 years ago

Note I don't actually mind if we have an actual fsi value nor do we have to use FSharp.Compiler.Interactive.Settings.dll, which has always had a slightly strange status as it is not an a nuget package. We can if it is helpful (I see it is available), but all I'm meaning at a minimum is that text such as

fsi.PrintDepth <- 100
fsi.ShowIEnumerable <- false
fsi.AddPrinter...
fsi.AddPrintTransformer...

be accepted in notebooks

dsyme commented 4 years ago

ref https://github.com/fsprojects/FSharp.Formatting/issues/534

abelbraaksma commented 4 years ago

that is well understood in the F# community and really forms part of the F# standard scripting programming model

I'm not sure about this part, many people using fsi think all of the above to be immutable constants, as they look for it in the commandline args or with #help, and these don't show these options. Often this is asked in Slack or SO, and people come up with workarounds, not with using the fsi object.

(but a suggestion for improvement should probably go in the fsharp repo)

dsyme commented 4 years ago

To help clarify, I wrote these two docs

I'm not sure about this part, many people using fsi think all of the above to be immutable constants, as they look for it in the commandline args or with #help, and these don't show these options.

Yes, agreed, the documentation has not been great for these (e.g. well documented in Expert F# but not on docs.microsoft.com until now)

brettfo commented 3 years ago

Talking with @jonsequitur and @colombod it would be beneficial to expose TryFindBoundValue on the fsi object that @dsyme mentioned. With this exposed, scenarios like those mentioned in #1264 could be enabled with the following:

let kernel = fsi.TryFindBoundValue("interactiveKernel") // name is up for debate
if isNotNull kernel then
    // we're in a .NET Interactive notebook, maybe register a formatter?
    kernel.AddFormatter(...)