ScalaInDepth+Index.pdf
(
4271 KB
)
Pobierz
Scala—
a blended language
In this chapter
Short introduction to Scala
Insights into Scala’s design
Scala was born from the mind of Martin Odersky, a man who had helped introduce
generics into the Java programming language. Scala was an offshoot from the Fun-
nel language, an attempt to combine functional programming and Petri nets. Scala
was developed with the premise that you could mix together object orientation,
functional programming, and a powerful type system and still keep elegant, suc-
cinct code. It was hoped that this blending of concepts would create something
that real developers could use and that could be studied for new programming idi-
oms. It was such a large success that industry has started adopting Scala as a viable
and competitive language.
Understanding Scala requires understanding this mixture of concepts. Scala
attempts to blend three dichotomies of thought into one language. These are:
Functional programming and object-oriented programming
Expressive syntax and static typing
Advanced language features and rich Java integration
1
2
C
HAPTER
1
Scala— a blended language
Functional programming is programming through the definition and composition of
functions. Object-oriented programming is programming through the definition and
composition 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” or “verbs” in a program, depending on what is the most
prominent.
Scala also blends expressive syntax with static typing. Mainstream statically typed
languages tend to suffer from verbose type annotations and boilerplate syntax. Scala
takes a few lessons from the
ML
programming language and offers static typing with a
nice expressive syntax. Code written in Scala can look as expressive as dynamically
typed languages, like Ruby, while retaining type safety.
Finally, Scala offers a lot of advanced language features that are not available in
Java. But Scala runs on the Java virtual machine (
JVM
) and has tight integration with
the Java language. This means that developers can make direct use of existing Java
libraries and integrate Scala into their Java applications while also gaining the addi-
tional power of Scala. This integration makes Scala a practical choice for any
JVM
-
based project.
Let’s take a deeper look at the blending of paradigms in Scala.
1.1
Functional programming meets object orientation
Functional programming and object-oriented programming are two different ways of
looking at a problem. Functional programming puts special emphasis on the “verbs”
of a program and ways to combine and manipulate them. Object-oriented program-
ming puts special emphasis on “nouns” and attaches verbs to them. The two
approaches are almost inverses of each other, with one being “top down” and the
other “bottom up.”
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). After identify-
ing nouns and defining their behaviors, interactions between nouns are defined. The
problem with implementing interactions is that the interactions need to live inside an
object. Modern object-oriented designs tend to have
service classes,
which are a collec-
tion of methods that operate across several domain objects. Service classes, although
objects, usually don’t have a notion of state or behavior independent of the objects on
which they operate.
A good example is a program that implements 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 = ...
Functional programming meets object orientation
}
val cat = new Cat
val bird = new Bird
cat.catch(bird)
cat.eat()
3
In the example, when a
Cat
catches a
Bird
, it converts the bird to a type of
Food
,
which it can then
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 behaviors, or actions that need to be
performed, usually in a bottom-up fashion. Functions are viewed in a mathematical
sense, purely operations on their input. All variables are considered immutable. This
immutability aids concurrent programming. Functional programming attempts to
defer all side effects in a program as long as possible. Removing side effects makes rea-
soning 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 program is a more functional approach:
trait
trait
trait
trait
Cat
Bird
Catch
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)
In the example, the
catch
method takes a
Cat
and a
Bird
and returns a new value of
type
Cat with Catch
. The eat method is defined as taking a
CatWithPrey
(a cat needs
something to eat) and returns a
FullCat
(because it’s no longer hungry). Functional
programming makes more use of the type system to describe what a function is doing.
The
catch
and
eat
methods use the type signatures to define the expected input and
output states of the function. The
with
keyword is used to combine a type with
another. In this example, the traits Catch and FullTummy are used to denote the
current state
of a Cat. The methods
eat
and
catch
return new instances of Cat
attached to different state types. The
story
value is created by composing the func-
tions
catch
and
eat
. This means that the
catch
method is called and the result is fed
into the
eat
method. Finally, the
story
function is called with a
Cat
and a
Bird
and
the result is the output of the story: a full cat.
Functional programming and object orientation offer unique views of software. It’s
these differences that make them useful to each other. Object orientation can deal
with composing the nouns and functional programming can deal with composing
4
Table 1.1
C
HAPTER
1
Scala— a blended language
Attributes commonly ascribed to object-oriented and functional programming
Functional programming
Composition of functions (verbs)
Deferred side effects
Recursive algorithms and continuations
Lazy evaluation
Pattern matching
Object-oriented programming
Composition of objects (nouns)
Encapsulated stateful interaction
Iterative algorithms
Imperative flow
N/A
verbs. In the example, the functional version was built by composing a set of functions
that encompassed a story and then feeding the initial data into these functions. For the
object-oriented version, a set of objects was created and their internal state was manip-
ulated. Both approaches are useful in designing software. Object orientation can focus
on the nouns of the system and functional programming can compose the verbs.
In fact, in recent years, many Java developers have started moving toward splitting
nouns and verbs. The Enterprise Java-Beans (
EJB
) specification splits software into
Ses-
sion beans,
which tend to contain behaviors, and
Entity beans,
which tend to model the
nouns in the system. Stateless Session beans start looking more like collections of
functional code (although missing most of the useful features of functional code).
This push of functional style has come along much further than the
EJB
specifica-
tions. The Spring Application Framework promotes a functional style with its Tem-
plate classes, and the Google Collections library is very functional in design. Let’s look
at these common Java libraries and see how Scala’s blend of functional programming
with object orientation can enhance these Application Program Interfaces (
API
s).
1.1.1
Discovering existing functional concepts
Many modern
API
designs have been incorporating functional ideas without ascribing
them to functional programming. For Java, things such as Google Collections or the
Spring Application Framework make popular functional concepts accessible to the
Java developer. Scala takes this further and embeds them into the language. To illus-
trate, you’ll 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(PreparedStatementCreator psc,
RowMapper rowMapper)
...
}
Query for list of objects
Now for a simple translation into Scala, you’ll convert the interface into a trait having
the same method(s):
trait JdbcTemplate {
def query(psc: PreparedStatementCreator,
rowMapper: RowMapper): List[_]
}
Functional programming meets object orientation
5
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
Prepared-
StatementCreator
and the
RowMapper
interfaces.
public interface PreparedStatementCreator {
PreparedStatement createPreparedStatement(Connection con)
throws SQLException;
}
The
PreparedStatementCreator
interface contains only one method:
create-
PreparedStatement
. This method takes a
JDBC
connection and returns a
Prepared-
Statement
. The
RowMapper
interface looks similar:
public interface RowMapper {
Object mapRow(ResultSet rs, int rowNum)
throws SQLException;
}
Scala provides first-class functions. This feature lets us change the
JdbcTemplate
query method so that it takes functions instead of interfaces. These functions should
have the same signature as the sole method defined on the interface. In this case, the
PreparedStatementCreator
argument can be replaced by a function that takes a con-
nection and returns a
PreparedStatement
. The
RowMapper
argument can be replaced
by a function that takes a
ResultSet
and an integer and returns some type of object.
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]
}
Use first-class
functions
The query method is now more functional. It’s using a technique known as the
loaner
pattern.
This technique involves some controlling entity (the
JdbcTemplate
) creating a
resource and delegating the use of it to another function. In this case, there are two
functions and three resources. Also, as the name implies,
JdbcTemplate
is part of a
template method in which pieces of the behavior were deferred for the user to imple-
ment. In pure object-orientation, this is usually done via inheritance. In a more func-
tional approach, these behavioral pieces become arguments to the controlling
function. This provides more flexibility by allowing mixing/matching arguments with-
out having to continually use subclasses.
You may be wondering why you’re using
AnyRef
for the second argument’s return
value.
AnyRef
is equivalent in Scala to java.lang.Object. Because Scala has supported
generics, even when compiling for 1.4
JVM
s, we should modify this interface further to
remove the AnyRef and allow users to return specific types.
trait JdbcTemplate {
def query[ResultItem](psc: Connection => PreparedStatement,
rowMapper: (ResultSet, Int) => ResultItem
): List[ResultItem]
}
Typed
return list
Plik z chomika:
freka
Inne pliki z tego folderu:
Oreilly.XMPP.The.Definitive.Guide.May.2009.pdf
(3544 KB)
Photoshop_CS4_Companion_for_Photographers.pdf
(31376 KB)
StevensUnixNetworkProgrammingVol.pdf
(12976 KB)
Open Source ESBS in Action.pdf
(8401 KB)
Open Source Journal 2011 Issue 3.pdf
(56658 KB)
Inne foldery tego chomika:
Pliki dostępne do 08.07.2024
Pliki dostępne do 19.01.2025
Andrzej Jagodzinski Trio - Christmas 1984r
Bukowski Charles
Galeria
Zgłoś jeśli
naruszono regulamin