What is the difference in practice? Why would you use one over the other? It seems like both types would be used to solve same problems.
My question is regarding only functional F# code. For F# components that are exposed to external parties I found that Component Design Guidelines suggests preferring interfaces approach over the record of functions.
A function is a type of functional interface in Java that receives only a single argument and returns a value after the required processing. There are many versions of Function interfaces because a primitive type can't imply a general type argument, so we need these versions of function interfaces.
The main difference between class and record type in C# is that a record has the main purpose of storing data, while class define responsibility. Records are immutable, while classes are not.
It's legal to implement an interface with a record.
A record in C# is a class or struct that provides special syntax and behavior for working with data models.
series ( link ) An important aspect of functional programming is that, in a sense, all functions are “interfaces”, meaning that many of the roles that interfaces play in object-oriented design are implicit in the way that functions work.
As functions are first class values in f#, we can define records of functions in the same way we declare records of values. And create instances of in the exact same. And pass our instances in the exact same way. Basically, if we understand records of values, we understand records of functions.
The interface is a blueprint that can be used to implement a class. The interface does not contain any concrete methods (methods that have code). All the methods of an interface are abstract methods. An interface cannot be instantiated.
Type of methods: Interface can have only abstract methods. An abstract class can have abstract and non-abstract methods. From Java 8, it can have default and static methods also. Final Variables: Variables declared in a Java interface are by default final.
Conceptually, records of functions are very similar to interfaces and most of the time, you could use both of them to solve a given problem (so this is a great & valid question).
If you look just at the technical aspects, then the biggest difference is that interfaces can have generic methods. This is something that cannot be done using records - for example, there is no way to define a simple record of functions that would correspond to the following:
type IFoo<'T> =
abstract Bar<'R> : 'R -> 'T
However, in practice, I think the more important differences are related to interoperability and design:
{ oldValue with NewFunction = newFunction }
construction to replace one function.In general, I mostly use records when I need to keep some state during e.g. recursive processing of some data structure and I need the with
construct. For public API, I believe that using interfaces and simple classes is better abstraction than using records.
There are two very important differences between records and objects/interfaces. One is that records have no "self/this" concept. The other is that records support with
operations. Combined, it makes records of functions awkward for implementing a service reference.
For instance if you want to create a PrintX service, using records a first attempt might look like this.
let createService x = { X = x; PrintX = fun () -> printfn x }
let myService = createService 1
let twoService = { myService with X = 2 }
twoService.PrintX()
It prints 1, not 2. Sure you can say “well don’t do this”. And sure you can "fix" it by closing over a mutable x
and providing a SetX(x)
function in your record. But the fact that the construct allows the user to do something nonsensical indicates maybe the construct itself isn’t quite right for representing your intention. It's really a square hole for a round peg.
So the recognition I’ve come to is that, for things that are nothing more than the sum of their parts, including bags of independent functions, records are perfect. But for things that together form a coherent whole, objects/interfaces are really more appropriate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With