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.8k stars 371 forks source link

variable sharing on notebook created types #3565

Open novitk opened 3 weeks ago

novitk commented 3 weeks ago

Version: 1.0.522904+cdfa48b2ea1a27dfe0f545c42a34fd3ec7119074

is there something fundamental why the below doesn't work? Due to the fact that vars are shared but their types are not? It would be a killer feature, as you can test language interop quickly. Thx, KN

!fsharp

type U = One let y = One

!csharp

!share --from fsharp y

y Error: (1,1): error CS0103: The name 'y' does not exist in the current context

jonsequitur commented 3 weeks ago

Type U isn't defined in the C# kernel so I wouldn't expect this to work.

If that's why it's not working, the error message incorrect. There might be an exception being swallowed somewhere.

jonsequitur commented 3 weeks ago

As for whether sharing new types transparently should be supported, I'd say it makes intuitive sense. But it implies sharing the dependency graph from e.g. F# into C#, including NuGet packages. And in some cases the F# and C# kernels might already have conflicting versions loaded. So this gets complicated and also hard for people to reason about.

novitk commented 2 weeks ago

agreed, dependency walk is definitely "too hard and fragile". How about non-transparent, i.e. explicit "#!share --from fsharp U"? Would this work, assuming stuff below U exists in both kernels?

jonsequitur commented 2 weeks ago

The type definition itself would need to be shared, which requires referencing the in-memory assembly where it was defined. That assembly's dependency graph transitively includes the previous submissions' dependency graphs. I don't think this would work around the problem.

Another approach could potentially be to transparently create an isomorphic type in C#, serialize the F# type, and deserialize it to the C# type. Of course this would break all references to specific instances.

Is there a specific thing you're trying to accomplish?