- Functional programming is programming through the definition and composition of objects.
- Object-oriented programming is programming through the definition and compositon of objects.
- In Scala, functions are objects. Programs can be constructed through both the definition and composition of objects or functions. This gives Scala the ability to focus on
nouns
orverbs
in a program, depending on what is the most prominent.
-
functional programming and object-oriented programming are two different ways of looking at a problem
*Funtional programming puts special emphasis on the
verbs
of a program and ways to combine and manipulate them.*Object-oriented programming is a top-down approach to code design. It approaches software by dividing code into nouns or objects. Each object has some form of:
- Identity (self/this)
- Behavior (methods) and
- State (members)
-
Consder the following story: "A cat catches a bird and eats it."
-
An object-oriented programmer would look at this sentence and see two nouns: cat and bird. The cat has two verbs associated with it: catch and eat. The following program is a more object-oriented approach:
class Bird
class Cat {
def catch(b: Bird): Unit = ...
def eat(): Unit = ...
}
val cat = new Cat
val bird = new Bird
cat.catch(bird)
cat.eat()
-
The code focuses on the nouns and their actions: Cat.eat(), Cat.catch(...). In functional programming, the focus is on the verbs.
-
Functional programming approaches software as the combination and application of functions. It tends to decompose software into behaviours, or actions that need to be performed, usually in a
bottom-up
fashion. Functions are viewed in a mathematical fashion, purely operations on their input.All variables are considered immutable
which aids concurrent programming. -
Functional programming attempts to defer all side effects in a program as long as possible. Removing side effects makes reasoning through a program simpler, in a formal sense. It also provides much more power in how things can be abstracted and combined.
In the story "A cat catches a bird and eats it", a functional program would see the two verbs catch and eat
. A program would create these two functions and compose them to create the program. The following code is a more functional approach?
trait Cat
trait Bird
trait Catch
trait FullTummy
def catch (hunter: Cat, prey: Bird): Cat with Catch
def eat (consumer: Cat with Catch): Cat with FullTummy
val story = (catch _) andThen (eat _)
story (new Cat, new Bird)
Many modern API have been incorporating functional ideas without ascribing them to functional programming.
To illustrate, you will do a simple translation of the methods on the popular Spring Jdbc-Template
class and see what it starts to look like in Scala
public interface JdbcTemplate {
List query (PreparedStatemenCreator psc,
RowMapper rowMapper)
...
}
Now for a simple tranlation into Scala, you'll convert the interface into a trait having same method(s):
trait JdbcTemplate {
def query(psc: PreparedStatementCreator,
rowMapper: RowMapper): List[_]
}
The simple translation makes a lot of sense, but it's still designed with a distinct Java flair. Let's start digging deeper into this design. Specifically, let's look at the PreparedStatementCreator
and the RowMapper
interfaces
public interface PreparedStatementCreator {
PreparedStatement createPreparedStatement (Connection con)
throws SQLException;
}
The updated Scala version of the JdbcTemplate interface would look as follows:
trait JdbcTemplate {
def query(psc: Connection => PreparedStatement,
rowMapper: (ResultSet, Int) => AnyRef
): List[AnyRef]
}