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.91k stars 389 forks source link

Extension scripts fail when imported from F# context (or written in F# and imported from C# context) #1808

Open cyberillithid opened 2 years ago

cyberillithid commented 2 years ago

Preface: I recently got inspired to try F# again when I learned that this tool exists (and overall I guess you're doing a great job). Thus I am sorry if I use the terminology I haven't grokked yet incorrectly, or even if some things I expect to work are actually incongruent with the tool as it is now.

Bug description

Referencing packages with extension scripts from F# context execution block

What I expected: If you reference an assembly (i.e., NuGet package of the RandomNumber extension from dotnet/interactive samples/extension/RandomNumber) with extension script from an F# context execution block, #r succeds and extension scripts works normally. What I got: The namespaces are inaccessible whether the extension script is written in F# or C#. (In the RandomNumber example you get CS0246 for "types/namespaces" RandomNumberExtension and RandomNumberGenerator, and so no commands are registered.

Referencing packages with F# extension scripts from C# context execution block

What I expected: You can use the magic commands written in F# when working from C# mode. What I got: DotNet (in Microsoft.DotNet.Interactive) and thus KernelInvocationContext are inaccessible from the F# script invoked from running #r in C#-mode, which thus fails to typecheck.

Steps to reproduce

With a NuGet-available package

The only one I found is Interactive.Journey from this same repo. So, the minimal reproduction of the bug is to run:

#!fsharp
#r "nuget:Microsoft.DotNet.Interactive.Journey,1.0.0-beta.21602.1"

which fails with CS0234, as demonstrated on the picture attached While the same #r command in #!csharp mode executes the extension script successfully.

Other reproductions

The same behaviour can be observed (and debugged a bit more easily) with the RandomNumber extension from dotnet/interactive samples/extension/RandomNumber.

If you add the following to the beginning of the extension.dib of the RandomNumber extension:

!fsharp
open Microsoft.DotNet.Interactive
open RandomNumberExtension

and try to import the RandomNumber package from either F# or C# contexts, F# invocation will fail with F# typecheck error around RandomNumberExtension, while C# invocation will fail with F# typecheck error around DotNet.

Environment info

Windows 10:

Binder: started from link from the docs/NotebooksOnBinder.md

Things that look tangentially relevant

Issue #1307 Also probably the fact about split of C# and F# kernels, as described in variable-sharing.md

Since I performed most of the experiments locally, not to clutter screenshots with non-English compiler output, the only picture attached is the reproduction in Binder. image

WhiteBlackGoose commented 2 years ago

Another repro.

Consumer.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <None Include="extension.dib" Pack="true" PackagePath="interactive-extensions/dotnet" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="AngouriMath" Version="1.3.0" />
  </ItemGroup>

</Project>

Class1.cs:

namespace Consumer;

public class Foo
{
    public void Method2() => Console.WriteLine(AngouriMath.MathS.FromString("1 + 1"));
}

(Class1.cs is needed to verify that the dep is correct)

Extension.dib:

#!csharp

using AngouriMath;

Console.WriteLine("Hello, world");
Console.WriteLine(AngouriMath.MathS.FromString("sqrt(s)").Latexise());

To pack, I do

rm -r ~/.nuget/packages/consumer
dotnet pack -c release -p:Version=10.0.0

Now, this notebook cell:

#i "/main/tmp/repro/cs2cs/Consumer/bin/release"
#r "nuget:Consumer"

(of course replace the path to yours)

C# context image

F# context image