I'm very new to F#. One of the first things I noticed was that collection operations are defined as functions rather than as methods.
As an experiment, I defined a couple of methods on list
:
type List<'a> with
member this.map f = List.map f this
member this.filter f = List.filter f this
Then, given these helpers:
let square x = x * x
let isEven n = n % 2 = 0
here's an example of using the methods:
[1 .. 10].filter(isEven).map(square)
And here's the traditional way:
[1 .. 10] |> List.filter isEven |> List.map square
So concision clearly wasn't a reason to choose functions over methods. :-)
From a library design perspective, why were functions chosen over methods?
My guess is that it's because you can pass List.filter
around, but can't really pass the filter
method around unless it's "tied" to a list or wrapped in an anonymous function (i.e. (fun (ls : 'a list) -> ls.filter)
effectively turns the filter
method back into a function on list
).
However, even with that reason, it seems the most common case of invoking an operation directly would give favor to methods since they are more concise. So I'm wondering if there's another reason.
Edit:
My second guess is function specialization. I.e. it's straightforward to specialize List.filter
(e.g. let evens List.filter isEven
). It seems more verbose to have to define an evens
method.
What functions have over methods is function specialization and the easy factoring it enables.
Here's the example expression involving functions:
let square x = x * x
let isEven n = n % 2 = 0
[1 .. 10] |> List.filter isEven |> List.map square
Let's factor out a function called evens
for filtering evens:
let evens = List.filter isEven
And now let's factor out a function which squares a list of ints:
let squarify = List.map square
Our original expression is now:
[1 .. 10] |> evens |> squarify
Now let's go back to the original method based expression:
[1 .. 10].filter(isEven).map(square)
Factoring out a filter on evens isn't as trivial in this case.
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