By Developers, For Developers

Historical errata for Functional Programming Patterns in Scala and Clojure

PDF PgPaper PgTypeDescriptionFixed onComments
16ERROR

I think this is not what you wanted:

HttpRequest currentRequest = httpRequest;

for (Filter filter : filters) {
currentRequest = filter.doFilter(httpRequest);
}

I think you wanted “filter.doFilter(currentRequest)”, otherwise only the last filter has any impact.

2013-04-10Yep, thanks for catching that.
19TYPO

At the last paragraph, second line, under 2.3 Tinyweb in Scala: I guess you meant “piece by piece” instead of just “piece by”

2013-03-27Yep thanks, perils of it not being copyedited yet. Will be fixed in the next beta.
20TYPO

I guess you meant CommandView instead of FunctionView in the snippet after paragraph: “let’s take a look at the body of CommandView…”

2013-03-27Yep thanks, just fixed it, should be in the next beta.
25SUGGEST

In the code snippet starting this page, I guess the “scala-way” would be to map over the controllerOption:

controllerOption map { controller => controller.handleRequest(filteredRequest) }

2013-04-10Ah right, good point, what I've got is actually probably borderline offensive to experienced Scala devs, it's not idiomatic at all. \n \nThanks!
64ERROR

It is said that case classes can not implement methods, I think that it is incorrect.

2013-03-27Thanks yes this is about as incorrect as you can get, It'll be fixed in the next beta. Thanks much.
13ERROR

CommandView, which swallows the exection that ViewRenderer can throw, its a Decorator. It has the same interface as the object to which delegates (well, in your implementation you have two interfaces with the same method signatura which is kind of a smell).

2013-04-10I see your point, those two interface didn't start off the same but I ended up simplifying the example so much that they ended up there... Thanks for pointing that out, I'll take a look at seeing how I can fix up that example, should be in the beta after next. \n \n--- \n \nOkay, I tried to clarify this a bit. FWIW, the original example used CommandView as an integration point for rendering engines, so the overall structure was quite different (including the method signatures you mention). Unfortunately, that was a bit to complicated and off point, so I simplified it to the current example.
15TYPO

“Both the Template Method pattern we used for our controllers and the Com- mand pattern we used for our views support similar tasks…”

I think you are mistaking the Command pattern for the Strategy pattern. Command pattern is about encapsulating a method call as an object.

2013-04-10Hmm yeah I see what you're saying, Strategy would be a better choice than Command. FWIW I think what I've got is both Strategy and Command (Commands can be smart enough to implement all their logic without delegating to a receiver), but it's more generally Strategy. Thanks much! Will fix it. \n \n-- \n \nOkay fixed up in the next beta. Thanks for catching it, it made more sense with the original example :-/
15ERROR

“Both the Template Method pattern we used for our controllers and the Com- mand pattern we used for our views support similar tasks…”

I think you are mistaking the Command pattern for the Strategy pattern. Command pattern is about encapsulating a method call as an object.

2013-04-10Seems to be a duplicate of #51086.
1ERROR

“The introduction of foreach loops to Java 1.5 greatly reduced the usefulness of the classic Iterator pattern described in ….”

It is just the opposite: the foreach loop uses internally iterator so you have now more reasons to define iterators for your classes to be used in the context of a foreach loop. You don’t see the iterator explicitely but it exists.

2013-03-27Thanks, yep I'm aware that Java's foreach loop operates on instances of Iterator (as well as arrays). The point I was trying to make is that it removes the need to use the Iterator pattern in any explicit way, which leads to simpler code. Basically, the Iterator is reduced to an implementation detail of the foreach loop. I've attempted to clarify in the next beta, if you get a chance let me know if you think it works better!
82?TYPO

ScalaExamples/src/main/scala/com/bblinn/mbfpp/oo/fi/personexanded/ClosureExample.scala

def lastNameComparison(p1: Person, p2: Person) =
p2.lastName.compareTo(p2.lastName)

compares p2 to p2

2013-04-06Ack thanks! Will fix it.
16ERROR

Where you execute the following line in TinyWeb:
currentRequest = filter.doFilter(httpRequest);

I believe it should actually should be:
currentRequest = filter.doFilter(currentRequest);

Otherwise you lose any transforms that occur other than the final one.

2013-04-10Ungh thanks, missing a few unit tests... Thanks for catching that.
1SUGGEST

The font used for code fragments is very small (and the space betweeb lines too large) using the kindle app for iPad.

2013-04-11Thanks for reporting this, I don't think I actually have any control over that. Looking into what can be done... \n \n-- \n \nOkay turns out this is something that the team at the Prags is looking into, but unfortunately there's nothing I can tweak on my end to help...
43SUGGEST

You often use a pattern like (p1 :first-name) to get data from maps. That is okay, very similar to Java or Scala - that’s why I did it when I started with Clojure -, but unfortunately somewhat error prone. E.g. if p1 is nil you get a NullPointerException.

I would like to suggest that you use (:first-name p1) instead, due to the fact that :first-name is also a function (and never nil) you never get NullPointer issues that way. As far as I can tell it’s more common in the Clojure community.

2013-04-10Thanks, I have it on my list to change my map lookups to use that form (unless I want the null pointer for a particular example), it is the most commonly used form. For whatever reason I tend to prefer it the other way round though... \n \n--- \n \nOkay fixed everything I could find to use the more idomatic (:keyword map), should be in the next beta. Thanks for finding this!
13TYPO

“It’s a instance of a Command class…” should read “…an instance…”

2013-04-15
26TYPO

“If an individual Filter need to do something” should read “…needs to do…”

2013-04-15
27TYPO

Looping through the filter list, it looks like the parameter of the doFilter() should be “currentRequest” instead of “httpRequest”:

HttpRequest currentRequest = httpRequest;
for (Filter filter : filters) {
currentRequest = filter.doFilter(httpRequest);
}

2013-04-15
44SUGGEST

The sorting example might be better understandable by defining a function with def instead of a val carrying an anonymus function.

def complicatedSort(p1: Person, p2: Person): Boolean =
\tif (p1.firstName != p2.firstName)
\t\tp1.firstName < p2.firstName
\telse if (p1.lastName != p2.lastName)
\t p1.firstName < p2.lastName
\telse
\t p1.middleName < p2.middleName

Calling the function without the dots would improve readability:

people sortWith complicatedSort

//res4: scala.collection.immutable.Vector[Person] = Vector(Person(Aaron,Bailey,Zanthar), Person(Aaron,Jeffrey,Smith), Person(Brian,Adams,Smith))

2013-07-14Thanks, agree! Will fix it in the next revision.
21TYPO

In the first line and in the example after it says “FunctionView” where it must say “CommandView” as the code in the previous page.

2013-07-14
75SUGGEST

The Scala implementation of sum will cause an error when used on an empty Collection.
The equivalent solution in Clojure checks for empty collections wheras the Scala solution lacks the check.

scala> sumSequence(Vector.empty[Int])
java.lang.UnsupportedOperationException: empty.reduceLeft
\tat scala.collection.TraversableOnce$class.reduceLeft

// 1. Functional using fold

scala> def sumSequenceFold(sequence : Seq[Int]) = sequence.foldLeft(0)(_ + _)
sumSequenceFold: (sequence: Seq[Int])Int

scala> sumSequenceFold(Seq())
res1: Int = 0

scala> sumSequenceFold(1 to 10)
res2: Int = 55

// Solution 2. like the Clojure Solution, checking for empty Sequence
def sumSequenceWithCheck(sequence : Seq[Int]) =
if (sequence isEmpty) 0 else sequence.reduce(_ + _)

scala> sumSequenceWithCheck( Seq.empty[Int] )
res6: Int = 0

scala> sumSequenceWithCheck( Seq(1,2,3,4) )
res7: Int = 10

// 3. Solution: Use standard function defined in Collection Library
scala> List[Int]().sum
res4: Int = 0

scala> (1 to 10).sum
res5: Int = 55

2013-07-14Thanks much! I'll fix it for the released version.
110ERROR

Problem with the class diagram:
The arrow from “Concrete Class” to “Decorator” is misleading (or even wrong), as it looks like an uni-directional association from “Concrete Class” to “Decorator”.

2013-07-14
123TYPO

inheritence / inheritance

2013-07-14
40TYPO

Last paragraph begins “To simply things” but should be “To simplify things”

2013-07-14
33TYPO

“We’ll do this final step in a namespace called called core”

(“called” written twice)

2013-07-23
204ERROR

Missing paren for rand-int call:
def randoms (repeatedly (fn [] rand-int Integer/MAX_VALUE)))

Should be:
def randoms (repeatedly (fn [] (rand-int Integer/MAX_VALUE) )))

(take 5 randoms) and (take 6 randoms) examples always returning MAX_VALUE …

=> (take 5 randoms)
(2147483647 2147483647 2147483647 2147483647 2147483647)

=> (take 6 randoms)
(2147483647 2147483647 2147483647 2147483647 2147483647 2147483647)

2013-09-14
62ERROR

The text figure 2 and the code do not match up. The figure uses Scope 1
bar = “second bar”
foo = “second foo”

The code in closure_example.clj uses

def foo “first foo”
def bar “first bar”
def baz “first baz”

I am not sure if this was the intent. But if it is, it should be explained why the figure and the code do not match.

Very confusing!

2014-07-01
14TYPO

From the last sentence in the Preface:
“Also, for ebook buyers, clicking on the box above the code extracts
downloads the code for that extract for you.”

2014-07-01
57TYPO

“Keeping track of changing stack is especially tricky.”

“stack” should likely be “state”

2014-07-01
73TYPO

“We’ll look at these examples first in an iterative style written in Java, and then we’ll collapse them into a more declarative style in Scala and Clojure.”

“iterative” is likely to be “imperative”, as it is contrasting to declarative.

2014-07-01
73TYPO

“If it’s in the set of all vowels, we add it to ​vowelsInWorld​ and return it.”

vowelsInWord is the name

2014-07-01
81ERROR

“Here we use ​doseq​ to print our list of greetings”

doseq does not appear in the following code snippet, or for the next 8 pages.

2014-07-07
85ERROR

“Figure 5—Grade Reporter Template. Using Template Method to report grades”

This figure shows validators, which seems to be from the next example.

2014-07-07This is a layout oddity, the figure should really go with the Classic Java section, in place of a code example...
86TYPO

“Here we pass in the identify function, which just returns whatever was passed in”

Should be `identity`

2014-07-07
107TYPO

“Let’s take one last look at handling nothing by examining a case in which”

This appears directly before the discussion section at the end of the pattern.

2014-07-07
110TYPO

“The ​Calculator​ interface is implemented by both ​CalculatorImp​ and ​LoggingCalculator​.”

Impl is missing the ‘l’

2014-07-07
121TYPO

“Extending the shape type to have additional implementations is easy. We create a ​Shape​ interface with multiple implementations.

If we want to extend ​Shape​ so that it has new implementations, it’s a bit more difficult,”

Likely that the second sentence meant to say “methods”

2014-07-07
129TYPO

“To stub out functions for testing purposes, we can use a macro named ​with-redfs​”

Should be `with-redefs`

2014-07-07
146SUGGEST

Mutual recursion has no even/odd example for Clojure.

2014-07-07This one was actually intentional, for once! There are a few places in the Overview section where I'll sketch something out in code to illustrate the general idea, without providing samples in the two or three different languages.
189ERROR

“To take a few, we can use take again:”

These examples all have 2147483647 as the random number. While possible, I’m guessing it wasn’t intentional.

2014-07-07
201SUGGEST

“Comparing the shortest and longest runs of both versions gives us a speedup of about 1.5 ”

The Scala example uses percentages, Clojure uses a factor. It would be nice to keep consistent.

2014-07-07
212TYPO

“The macroexpansion step as described in the diagram”

Should be two words.

2014-07-07
214TYPO

“From there, we use ​sum​ to calculate the sum off all runtimes”

Likely to be “of”

2014-07-07
27SUGGEST

In file Example.scala “random” and “greetings” should be declared using “val” (and not “def”):
private val random = new Random()
private val greetings = Vector(“Hello”, “Greetings”, “Salutations”, “Hola”)

When declared with “def” new object instance is created on each call to random/greetings. With immutable Vector this is just slight performance overhead, but with mutable Random semantics is different.

2014-07-01
23TYPO

In the 2nd paragraph “Switching over to use the try-catch as a statement…” should probably be “… to use the try-catch as an expression…”

2014-07-01
24TYPO

In the paragraph below the code fragment for Controller.scala:

“… to understand which HttpRequest we’re returning…” should likely be “… to understand which HttpResponse we’re returning…”

2014-07-01
18TYPO

namesCommaSepErated -> namesCommaSepArated

2014-07-01
21ERROR

Model seems to suddenly have become a map of “string to string” instead of “string to list of string”:
trait View {
def render(model: Map[String, String]): String

2014-07-07
71TYPO

In the code example where NoisyCat and NoisyDog are defined, the two `str` calls are missing a space character before the sound. So the two outputs are each missing a space between the animal name and the sound: “Fuzzy McBootingsmeows!” and “Brown Dogbarks!”.

The definitions should contain `(str (:name this) " meows!“)` and `(str (:name this) ” barks!")`.

2014-07-01
49ERROR

I may be wrong, but it seems that the final response on this page should be:

Friendly Greetings:

Mike

,

Joe

,

John>

,

Steve

instead of:

Friendly Greetings:

Mike

,

Nam

,

John>

64TYPO

At the beginning of the “Sample Code: Immutable Data” section, the sentence “Then we’ll take a look at three ways of replacing them in Clojure: regular classes with immutable attributes, case classes, and tuples.” should have Clojure replaced by Scala, as in: “Then we’ll take a look at three ways
of replacing them in Scala: regular classes with immutable attributes, case classes, and tuples.”

31TYPO

5 lines from bottom, the text:
“return an instance of HttpResult”
Should read:
“return an instance of HttpRequest”

41ERROR

The statement “In functional languages, functions are higher-order: they can be returned from functions and used as arguments to others” is incorrect. Higher-order functions are functions that can take a function as an argument or return one as a result. Not all functions are higher-order. The functions so returned or used as arguments are often not higher-order. Thus “map”, “filter”, “reduce”, etc are higher-order (they take functions as arguments), but the functions passed into them are not normally higher-order.

85TYPO

Figure 5 is referring to the “validator” examples from the Strategy Pattern section instead of the grading examples.

138TYPO

2 lines from the bottom, “tailRecursive()” should be “sumRecursive()”.

141TYPO

In the definition of the Person case class, the properties are given names which are plural. Presumably, these should be in the singular?

142TYPO

In the paragraph starting “One closing note on the syntax” in the middle of the page, it suggests the “method” signature and the “function” signature from the previous page are different, however they are identical as given.

167TYPO

3rd paragraph from the bottom, if we are creating “dead?” then we would want to cal “alive?” and negate the result, not call “dead?” (which we are creating).

168TYPO

The paragraph below the definition of the “discount()” function refers to a “discountedPrice()” function which should refer to “discount()”.

169TYPO

On line 4, “discountedPrice” should be “discount”.

187TYPO

First paragraph of “In Scala” section, “Scala’s” should be “Scala”.

188TYPO

The first paragraph should end with “it” instead of “here”.

81TYPO

The lambda_bar_and_grille.clj code sample should use the doseq macro instead of for to print the greetings. This is explained in the paragraph above the example.

86ERROR

there is no “for comprehension” here, only an ordinary for loop

Categories: