Fsharp: Netstandard1.6 build of FSharp.Core nuget does not have `serializable` flag in its contained types

Created on 17 Jan 2018  Â·  17Comments  Â·  Source: dotnet/fsharp

I noticed an interesting behaviour while attempting to port FsPickler to .NET standard. By default F# will add the serializable flag to all types unless declared otherwise (via the AutoSerializableAttribute). It seems that in the netstandard1.6 build of the FSharp.Core nuget many types seem to be lacking the serializable flag. This includes types like

  • F# options, lists, choice, etc
  • Microsoft.FSharp.Control.FSharpAsync
  • Microsoft.FSharp.Quotations.FSharpExpr
  • Microsoft.FSharp.Core.OptimizedClosures+Invoke@3253
  • Microsoft.FSharp.Core.ExtraTopLevelOperators+dictValueType@98

which are serializable in the net45 build of the same nuget package version (4.2.3).

Repro steps

  1. Create and run a nestandard2.0 console application with the following code
[<EntryPoint>]
let main argv =
    printfn "%b" typeof<int option>.IsSerializable
    0

Expected behavior

Should print true to console.

Actual behavior

Prints false to console.

Related information

This issue doesn't seem to affect user-defined F# types. For instance the following program

type Foo = class end

[<EntryPoint>]
let main argv =
    printfn "%b" typeof<Foo>.IsSerializable
    0

will print true for a netcoreapp2.0 application. The same holds for types defined in F# netstandard2.0 types.

Most helpful comment

Adding netstandard2.0 would still be super important because it would allow
us to get rid of many transitive deps - independent of this issue here

Am 18.01.2018 06:42 schrieb "Eirik Tsarpalis" notifications@github.com:

Why the different outcomes in the two platforms? I'd assume that
MailboxProcessor should be serializable in neither.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/visualfsharp/issues/4207#issuecomment-358543948,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AADgNIFxYMtINOVEAW3KWMjzATs-fOETks5tLtnbgaJpZM4Rgus4
.

All 17 comments

@KevinRansom @cartermp This may necessitate a netstandard 2.0 build of FSharp.Core? The types used at runtime should have that flag.

Really looking forward to a netstandard2.0 build of FSharp.Core
On Wed, 17 Jan 2018 at 03:56, Don Syme notifications@github.com wrote:

@KevinRansom https://github.com/kevinransom @cartermp
https://github.com/cartermp This may necessitate a netstandard 2.0
build of FSharp.Core? The types used at runtime should have that flag.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/visualfsharp/issues/4207#issuecomment-358238567,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACrtsyWHPxGpJOV61to1oW76e42pznuVks5tLbW9gaJpZM4Rgus4
.

We all do ;-)

Am 17.01.2018 13:13 schrieb "Eirik Tsarpalis" notifications@github.com:

Really looking forward to a netstandard2.0 build of FSharp.Core
On Wed, 17 Jan 2018 at 03:56, Don Syme notifications@github.com wrote:

@KevinRansom https://github.com/kevinransom @cartermp
https://github.com/cartermp This may necessitate a netstandard 2.0
build of FSharp.Core? The types used at runtime should have that flag.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
issuecomment-358238567>,
or mute the thread
ACrtsyWHPxGpJOV61to1oW76e42pznuVks5tLbW9gaJpZM4Rgus4>
.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/visualfsharp/issues/4207#issuecomment-358286546,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AADgNJPksM4_sowW2SKHQQNwod623aPdks5tLePfgaJpZM4Rgus4
.

@dsyme Agreed. @KevinRansom thoughts?

@cartermp
Thinking about the problem ...

Folks,

I don't think there is anyway to avoid it. It seems as if we are going to have to ship a netstandard 2.0 version of FSharp.Core serializable is just too useful. It is not yet scheduled, more info when we have it.

FWIW it looks like the number of public, non-serializable, non-static types in FSharp.Core classic is surprisingly small. The query

typeof<int option>.Assembly.GetTypes() 
|> Array.filter (fun t -> t.IsPublic && not (t.IsAbstract && t.IsSealed))
|> Array.filter (fun t -> not t.IsSerializable)

shows that only MailboxProcessor falls in that category. So creating a workaround might be easy.

Actually, I now think it's a compiler bug ...

This variant on your query with the current netstandard1.6 fsharp.core produces this as the list of non serializable types on netcoreapp2.0

With a minor compiler fix:

Microsoft.FSharp.Core.Unit Microsoft.FSharp.Core.SealedAttribute Microsoft.FSharp.Core.AbstractClassAttribute Microsoft.FSharp.Core.EqualityConditionalOnAttribute Microsoft.FSharp.Core.ComparisonConditionalOnAttribute Microsoft.FSharp.Core.AllowNullLiteralAttribute Microsoft.FSharp.Core.VolatileFieldAttribute Microsoft.FSharp.Core.DefaultAugmentationAttribute Microsoft.FSharp.Core.CLIEventAttribute Microsoft.FSharp.Core.CLIMutableAttribute Microsoft.FSharp.Core.AutoSerializableAttribute Microsoft.FSharp.Core.DefaultValueAttribute Microsoft.FSharp.Core.EntryPointAttribute Microsoft.FSharp.Core.ReferenceEqualityAttribute Microsoft.FSharp.Core.StructuralComparisonAttribute Microsoft.FSharp.Core.StructuralEqualityAttribute Microsoft.FSharp.Core.NoEqualityAttribute Microsoft.FSharp.Core.CustomEqualityAttribute Microsoft.FSharp.Core.CustomComparisonAttribute Microsoft.FSharp.Core.NoComparisonAttribute Microsoft.FSharp.Core.ReflectedDefinitionAttribute Microsoft.FSharp.Core.CompiledNameAttribute Microsoft.FSharp.Core.StructAttribute Microsoft.FSharp.Core.MeasureAttribute Microsoft.FSharp.Core.MeasureAnnotatedAbbreviationAttribute Microsoft.FSharp.Core.InterfaceAttribute Microsoft.FSharp.Core.ClassAttribute Microsoft.FSharp.Core.LiteralAttribute Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute Microsoft.FSharp.Core.CompilationMappingAttribute Microsoft.FSharp.Core.CompilationSourceNameAttribute Microsoft.FSharp.Core.CompilationRepresentationAttribute Microsoft.FSharp.Core.ExperimentalAttribute Microsoft.FSharp.Core.CompilationArgumentCountsAttribute Microsoft.FSharp.Core.CustomOperationAttribute Microsoft.FSharp.Core.ProjectionParameterAttribute Microsoft.FSharp.Core.StructuredFormatDisplayAttribute Microsoft.FSharp.Core.CompilerMessageAttribute Microsoft.FSharp.Core.UnverifiableAttribute Microsoft.FSharp.Core.NoDynamicInvocationAttribute Microsoft.FSharp.Core.OptionalArgumentAttribute Microsoft.FSharp.Core.GeneralizableValueAttribute Microsoft.FSharp.Core.RequiresExplicitTypeArgumentsAttribute Microsoft.FSharp.Core.RequireQualifiedAccessAttribute Microsoft.FSharp.Core.AutoOpenAttribute Microsoft.FSharp.Core.FSharpChoice`2 Microsoft.FSharp.Core.FSharpChoice`3 Microsoft.FSharp.Core.FSharpChoice`4 Microsoft.FSharp.Core.FSharpChoice`5 Microsoft.FSharp.Core.FSharpChoice`6 Microsoft.FSharp.Core.FSharpChoice`7 Microsoft.FSharp.Core.MatchFailureException Microsoft.FSharp.Core.FSharpTypeFunc Microsoft.FSharp.Core.FSharpFunc`2 Microsoft.FSharp.Core.FSharpRef`1 Microsoft.FSharp.Core.FSharpOption`1 Microsoft.FSharp.Core.FSharpResult`2 Microsoft.FSharp.Collections.FSharpList`1 Microsoft.FSharp.Control.IDelegateEvent`1 Microsoft.FSharp.Control.IEvent`2 Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 Microsoft.FSharp.Collections.FSharpMap`2 Microsoft.FSharp.Collections.FSharpSet`1 Microsoft.FSharp.Reflection.UnionCaseInfo Microsoft.FSharp.Control.FSharpDelegateEvent`1 Microsoft.FSharp.Control.FSharpEvent`2 Microsoft.FSharp.Control.FSharpEvent`1 Microsoft.FSharp.Core.PrintfFormat`4 Microsoft.FSharp.Core.PrintfFormat`5 Microsoft.FSharp.Quotations.FSharpVar Microsoft.FSharp.Quotations.FSharpExpr Microsoft.FSharp.Quotations.FSharpExpr`1 Microsoft.FSharp.Control.FSharpAsync`1 Microsoft.FSharp.Control.FSharpAsyncBuilder Microsoft.FSharp.Control.FSharpAsync Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1 Microsoft.FSharp.Control.FSharpMailboxProcessor`1 Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1 Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2 Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3 Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4 Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5 Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6 Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7 Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8 Microsoft.FSharp.Linq.RuntimeHelpers.Grouping`2 Microsoft.FSharp.Linq.QuerySource`2 Microsoft.FSharp.Linq.QueryBuilder Microsoft.FSharp.Data.UnitSystems.SI.UnitNames.metre Microsoft.FSharp.Data.UnitSystems.SI.UnitNames.kilogram Microsoft.FSharp.Data.UnitSystems.SI.UnitNames.second Microsoft.FSharp.Data.UnitSystems.SI.UnitNames.ampere Microsoft.FSharp.Data.UnitSystems.SI.UnitNames.kelvin Microsoft.FSharp.Data.UnitSystems.SI.UnitNames.mole Microsoft.FSharp.Data.UnitSystems.SI.UnitNames.candela Microsoft.FSharp.Core.CompilerServices.MeasureProduct`2 Microsoft.FSharp.Core.CompilerServices.MeasureInverse`1 Microsoft.FSharp.Core.CompilerServices.MeasureOne Microsoft.FSharp.Core.CompilerServices.TypeProviderAttribute Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute Microsoft.FSharp.Core.CompilerServices.TypeProviderEditorHideMethodsAttribute Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace Microsoft.FSharp.Core.CompilerServices.ITypeProvider Microsoft.FSharp.Core.CompilerServices.ITypeProvider2
With a minor compiler fix it produces this:
C:\temp\foo>dotnet run --framework netcoreapp2.0 Microsoft.FSharp.Core.MatchFailureException

This is the net45 output:
C:\temp\foo>dotnet run --framework net45 Microsoft.FSharp.Control.FSharpMailboxProcessor`1

So I think the fix is a pretty decent one, and doesn't require a netstandard 2.0 FSharp.Core. What's more it will allow third party netstandard 1.6 libraries to participate in serialization on netcoraep2.+ runtimes.

Why the different outcomes in the two platforms? I'd assume that MailboxProcessor should be serializable in neither.

Adding netstandard2.0 would still be super important because it would allow
us to get rid of many transitive deps - independent of this issue here

Am 18.01.2018 06:42 schrieb "Eirik Tsarpalis" notifications@github.com:

Why the different outcomes in the two platforms? I'd assume that
MailboxProcessor should be serializable in neither.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/visualfsharp/issues/4207#issuecomment-358543948,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AADgNIFxYMtINOVEAW3KWMjzATs-fOETks5tLtnbgaJpZM4Rgus4
.

Adding netstandard2.0 would still be super important because it would allow
us to get rid of many transitive deps - independent of this issue here.

+100 the state of the netstandard1.6 build is definitely inhibiting our migration to .NET core since we use paket everywhere. Regardless of this issue, we would love to see a netstandard2.0 build available in the near term. I might be pitching anecdotal evidence here, but I don't know many F# users that are particularly invested with netstandard1.x. The future is 2.0

@eiriktsarpalis this has nothing to do with paket ;-)

I know, but it's hard to explain to my colleagues why our netcore projects have >1 kLoC paket lockfiles.

It's mostly contributed to by the FSharp.Core package, whose netstandard1.6 target references the entire universe.

@eiriktsarpalis yes. but the same happens with vanilla nuget. it's just not visible

I guess people tend to think that it's a paket bug. In nuget it would be a feature.

@eiriktsarpalis the difference was that the fix I was looking at wasn't complete. Now I have the complete fix they produce the same output. And it was a copy and paste error mailboxprocessor appeared in both lists. The netcopreapp had 2 types in it.

Was this page helpful?
0 / 5 - 0 ratings