开发者

Defining functions pointfree-style in functional programming. What are the cons/pros?

开发者 https://www.devze.com 2023-04-04 09:22 出处:网络
Every time I write something of the form let scorePopulation f population = Array.map (fun i -> f i) population

Every time I write something of the form

let scorePopulation f population =
  Array.map (fun i -> f i) population

I end up asking myself if wouldn't I be better writing

let scorePopulation f =
  Array.map (fun i -> f i)

instead. Is there any advantage of writing it in the first form as opposed to the second?

Also, how would you call a function definition in the first form and in the second form?开发者_JAVA技巧


You could go even further:

let scorePopulation = Array.map

In terms of advantages/disadvantages, I think that the main concern will typically be readability. Sometimes it's easier to understand what a function does when all of the arguments are present. Other times, the fact that you don't need to make up extraneous variable names wins out.


Actually, the pros and cons are the same: naming.

The reason for this is the old saying by Phil Karlton:

There are only two hard problems in computer science. Cache invalidation and naming things.

If naming things is hard (i.e. expensive), then names shouldn't be wasted on irrelevant things. And conversely, if something has a name, then it is important.

Point-free style allows you to omit names.

The pro is that it allows you to omit irrelevant names.

The con is that it allows you to omit relevant names.


I would argue partial application is a benefit of functional programming. Why not take advantage of it? It results in less redundancy.

Another thing to keep in mind is value restriction[MSDN]. A partially-applied function without parameters is a function value. True functions can be generalized, but values cannot.


You should be able to call it in just the same way in the first and second example. This technique is typically called point-free style.

It might be better. It's shorter, so that's a plus by default. I agree with this warning from the link above:

As higher-order functions are chained together, it can become harder to mentally infer the types of expressions. The mental cues to an expression's type (explicit function arguments, and the number of arguments) go missing.

You also lose the opportunity to give the parameter a meaningful name, which might sometimes aid understanding.


Personally I hate point-free style, I always find it unreadable. As someone else mentioned,

You also lose the opportunity to give the parameter a meaningful name, which might sometimes aid understanding.

Overall, if I am defining a named function on the left, I usually want to see all the 'expected' params listed. (In contrast, partial application is great for anonymous call sites and local lambdas, but I like more explicitness/documentation when authoring top-level code - the larger the scope, the more 'software engineering' concerns play in.)

As someone else mentioned, the 'value restriction' kicks in if you get rid of all the parameters from a generic function, which is a technical limitation which also minorly discourages point-free style in F#.


I often provide the parameter even if I could omit it for clarity. When I omit the parameter it is usually because the function body immediately makes it obvious: i) that there is an omitted parameter and ii) what the nature of the parameter is. For example, I find it sufficient to write

let f = function [] -> "empty" | x::_ -> "not empty"

instead of

let f l = match l with [] -> "empty" | x::_ -> "not empty"

A more interesting example is to write

let f = List.map g |> List.fold_left h

instead of

let f l = List.map g (List.fold_left h l)

I find the first one more clear. The benefit here arises from the availability of intuitive higher-order operators such as |>, which is provided in Batteries.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号