Reputation: 22133
I've noticed that static methods seem more popular in F# than C#. In C#, you'd always add an element to a collection by calling an instance method:
mySet.Add(elem);
But in F# there is usually an equivalent static method:
mySet.Add(elem)
// OR
Set.Add elem mySet
And I've seen the latter form quite often in samples. Both appear to me completely identical both semantically and functionally, but coming from a C# background, using the instance method feels more natural. Which is better style in F# and why?
Upvotes: 7
Views: 763
Reputation: 26204
In addition to the reasons mentioned in that answer related to type inference, in functional style is more natural to send a function as a parameter. If it is an instance method you will have to write something like this:
myHigherOrderFunction (fun (x:MyType) -> x.myFunctionAsMethod)
But if it is defined as a static method you can write:
myHigherOrderFunction MyType.myFunctionAsMethod
which is more elegant, easier to write (to read as well) and is almost the same syntax as when sending a regular let bound function.
An instance method requires an instance of the type in order to access the function (the method), in OOP this is not an issue because you think in sending messages to objects but in FP, functions alone (without instances) are first class citizens.
To access a static method you need to specify the Class, you can see the Class as a kind of container (like modules or namespaces) with functions.
Upvotes: 8
Reputation: 4724
While static methods in F# are very common, I find that instance methods make a lot of sense for component development.
The reason? F# module system lacks functors. In other flavors of ML such as SML or OCaml, you develop components as simple modules. If you later decide to parameterize the module, you can promote it to a functor without rewriting too much of your source code. In F# you can't.
To create a parameterized "module" in F#, you have to resort to a class and turn your methods into instance methods, passing in parameters during instance construction. Unfortunately going from a module to a class involves quite a bit of mechanical but annoying source code changes. Therefore, a hard-core component programmer might opt to work with classes and instance methods by default, just as in C#. This is reminiscent of a "functor-only" style sometimes employed in SML.
Upvotes: 2
Reputation: 19231
Most of the standard F# types are immutable. When working with immutable objects, static methods better portray what is going on, for instance:
mySet.Add(elem);
Looks like mySet
is mutated to include elem
, when an F# set would return a new mySet
. Luckily F# fails to compile to make sure you don't make this mistake, it still leads to confusing code. In contrast:
mySet |> Set.Add elm
Is distinct in form and looks like it will be returning something new, without being too far away from the original.
Upvotes: 5
Reputation: 11964
In f# as functional language more native to separate variables that are immutable and functions that is operations. This functions similar to static methods in c#, but there is one advantage of functions befor c# methods. It is partial application. You can pass to function some (not all) parameters and this function with part of parameters will be new function that need other parameters.
Upvotes: 0