简体   繁体   中英

Guidelines to design a C# library well usable from F#

I just want to point out that this is question is not the reverse of

Best approach for designing F# libraries for use from both F# and C#

Here I'm not asking how to design a functional library written C# to be used in both worlds.

I'd like to know good practices on what design choices embrace or avoid to get a reasonable compromise for make this library usable from F# .

Practices like (for example):

  • keep object hierarchy as simple as possible

  • avoid mutating state of objects, but return new ones

  • etc...

Anyone that already done it, can share it's experience?

Side note

It's interesting note this OSS project, IronJS . Yes, it's written in F#, but the author expose two specialized host IronJS.Hosting.FSharp and IronJS.Hosting.CSharp .

Interop with existing .NET libraries was a major design goal of F#, so there aren't any constraints on the libraries to be consumed.

That said, because of F#'s stricter typing, there are some patterns that result in slightly clunkier code. The builder pattern is one.

var bldr = new StringBuilder();
bldr.Append("abc"); //ignoring return value

vs.

bldr.Append("abc") |> ignore //must be explicitly ignored

But this is easily worked around using an extension method or let-bound function. Bottom line: interop is one of F#'s strengths and greatest achievements.

Imagine one day you would like to rewrite your C# library in F# for better usability. Here are the paths you are likely to take:

在此输入图像描述

I focus on the path "Imperative C# --> Functional C# --> Functional F# --> Idiomatic F#". The more functional your C# library is, the more usable your library is in F# . Functional style helps increase composability and is closer to idiomatic F# code. Along these lines, you can:

  • Embrace immutability by default principle. If you don't know whether you need to update a field/property later, just mark it readonly first.
  • Follow expression-based and declarative programming style. LINQ operations are good examples.
  • Use immutable collections or mutable collections in an immutable way. With the introduction of C# immutable collections , it should be easier than ever before.

The picture above is taken from F# for fun and profit 's Porting from C# to F# series . They are very helpful; knowing how C# concepts are expressed in F# will improve usability of your library.

It's hard to avoid C#'s object-oriented features. Remember that F# type inference doesn't work very well with these features. Along the line of keeping object hierarchy simple, you should reduce number of member overloads. A big number of member overloads will easily confuse F# type checker. Moreover, it doesn't hurt to distribute a thin F# wrapper with your C# library . Certain things you need to do are turning some methods into module functions and creating Active Patterns to decompose object hierarchy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM