This is hard to answer because an honest answer is "practically everywhere". First class functions, used properly, will take over every aspect of a program.
Here's a neat example from a paper which tried to compare programming speed between functional, oo, imperative languages [0]. We'd like to build a "shape server" which allows you to build geometries of overlapping shapes and query as to whether a given point (in longitude/latitude) is covered by your shapes. The idea was to model a radar or early engagement system or something like that.
The obvious way might be to build a whole nest of objects which communicate among one another to consider the formation of the geometry. Another method is to just use functions from points to booleans which model the eventual question "is this point covered".
type Geometry = (Lat, Long) -> Bool
type Radius = Double
type Length = Double
circle :: Radius -> (Lat, Long) -> Geometry
circle rad (x0, y0) (x1, y1) = sqrt (dx*dx + dy*dy) where
dx = x0 - x1
dy = y0 - y1
square :: Length -> Length -> (Lat, Long) -> Geometry
square width height (top, left) (x, y) =
y < top
&& y > top - height
&& x > left
&& x < left + width
So here we build our geometry straight out of lambdas. A Geometry is just a function from (Lat, Long) to Bool and we generate them through partial application. We can also combine them
This example is not very different from an object oriented approach (an opaque interface with a "contains" method). That said, in a functional setting the tail recursion is great for functions like union and intersect.
Sure, and functions can feel a lot like OO. I often think of it as though OO were blown apart into all of its constituent parts and those parts were made available. Then, further, those parts "hang together" better than the variety of OO formalisms ever did anyway.
Here's a neat example from a paper which tried to compare programming speed between functional, oo, imperative languages [0]. We'd like to build a "shape server" which allows you to build geometries of overlapping shapes and query as to whether a given point (in longitude/latitude) is covered by your shapes. The idea was to model a radar or early engagement system or something like that.
The obvious way might be to build a whole nest of objects which communicate among one another to consider the formation of the geometry. Another method is to just use functions from points to booleans which model the eventual question "is this point covered".
So here we build our geometry straight out of lambdas. A Geometry is just a function from (Lat, Long) to Bool and we generate them through partial application. We can also combine them and then using all of these "combinators" build a sophisticated geometry which describes the final question "is a point covered by this geometry".The ultimate modeling tool was just lambdas. They are used so pervasively here I'd have a hard time pointing out each and every application.
[0] The comparison itself is sort of stupid, but the paper is still neat http://cpsc.yale.edu/sites/default/files/files/tr1049.pdf