By Developers, For Developers

Historical errata for Programming Erlang

PDF PgPaper PgTypeDescriptionFixed onComments
39TYPO

What the text refers as “brackets” should read “parentheses”

2007-03-06
43SUGGEST

I suggest you show lists:foreach/2 before describing list comprehensions — they are a much more well-behaved form of iterating over the elements of a list

(Joe says: I don’t mention funs at all until the next chapter this is deliberate. Too much reorganisation involved and I don’t see the benefit.)

2007-03-02
46ERROR

I would strongly urge you to NOT show ==/2 at all — unless you really, really have to. I know that this goes against what the typical C programmer might be familiar with, but please under all circumstances avoid it to compare integers.
Use =:=/2 instead which has much more sane semantics.

2007-03-02
52TYPO

“Expresson” —> “Expression”

2007-03-02
54SUGGEST

In the beginning of Section 2.10, I think the most natural example you can show before the one with odds_and_evens/1, is the filter example of page 52, which is (space) efficient using an accumulator instead of the [H|filter()] construct. (Joe says: fixed in a way. Added a sentense about space efficiency in section 2.10)

2007-03-02
48ERROR

There is no is_tuple/2 guard.

2007-03-02
46ERROR

In mathematics, there is no operator. This is FORTRAN.
Instead of A**2 use A^2 in LaTeX instead.

2007-03-02
55SUGGEST

In Chapter 2 somewhere you should add a table showing all mathematical functions & operators.

2007-03-02
218SUGGEST

In R11B-3, several Erlang processes are allowed do do gen_tcp:accept/1 on the same listen socket. This will simplify making a parallel server, as you can have a pool of pre-spawned processes, all waiting in gen_tcp:accept/1.

2007-03-02
6SUGGEST

I think there is need for a short introduction of Erlang before the Getting Started.
Might also be good to have this on the backcover of the printed book

(Joe says: will discuss in introduction (not yet written))

2007-03-09
8ERROR

In chapter 1.1 bullet 5 it says:
5. Compile and run the programs you create in the shell.
This is wrong, you don’t create programs in the shell.
Should rather be something like:
5. Compile and run programs from the shell.

2007-03-03
9TYPO

Bullet 2 contains a bad reference
Bullet 4 contains a bad reference
Could you find something better than “programming parallell computers”? Mention multi core processors, SMP systems?
parallell computers sounds abstract and might not automatically point to the current situation with multi core processors where programming Erlang is much better than almost any other language.
Last in stage 2.5 there is a bad reference

2007-03-03
10SUGGEST

Erlang provides an ideal
environment for experimenting with networked applications.
Erlang is not only ideal for experimenting but also for IMPLEMENTING the real networked applications.

2007-03-02
10SUGGEST

Erlang (BEAM) emulator version 5.5.2 [source] … [kernel-poll:false]

Perhaps the line should be skipped including [source] and onwards because it can be misleading (so many different alternatives that we don’t want to explain)

2007-03-02
12TYPO

Bullet 1. (This file contains is release 11
version 3).
The “is” is redundant should be removed.

2007-03-02
18TYPO

“is we know that X+Y=10 and X-Y=2, then X will be 6 and Y will be 2 in both equations.” should read “if we know that X+Y=10 and X-Y=2, then X will be 6 and Y will be 4 in both equations.”

2007-03-02
18TYPO

End of first paragraph under “Pattern Matching” “the result again the pattern Lhs” should be “the result against the pattern Lhs”

2007-03-02
18TYPO

Second paragraph under “Pattern Matching”: “Now a variable, such X” should read “Now a variable, such as X”.

2007-03-02
23TYPO

The first paragraph of “Creating Tuples” reads, "Tuples are created and destroyed automatically when we declare them
we don

2007-03-02
22TYPO

2nd par: “Suppose you want to write program” should be “Suppose you want to write a program”

2007-03-02
29TYPO

In the last line on the page, “..beam” should be “.beam”.

2007-03-03
17TYPO

In this sentence, “When Erlang sees a statement such as X = 1234. in binds the
variable X to the value 1234.” the ‘in’ should be ‘it’.

2007-03-03
75TYPO

Last paragraph of page, first line of paragraph. Currently reads “…build a windows executable one any machine…” and should read “…builds a windows executable on any machine…”

2007-03-03
121TYPO

"Here are the results I obtained on the computer I

2007-03-03
124TYPO

Footnote has typo “manula” at:

2. io:format understands an extrememly large number of formatting options, the full set can be found in the io manula pages

2007-03-04
18TYPO

In th Pattern Matching code you have:
2> Y = 10
10.
3> X = 6.
6.

It should be:
2> Y = 10.
10
3> X = 6.
6

2007-03-04
20TYPO

Last paragraph before 1.7 Floating point numbers

you have:
we canimmediately infer

instead of:
we can immediately infer

2007-03-04
32ERROR

In C code there is "area(area(struct Shape* s) … is that area duplicate correct?

2007-03-04
39TYPO

"Now Let

2007-03-04
44ERROR

Variable L is never used and Buy is undefined:

total(L) -> lists:sum([shop:cost(A) * B || {A, B} <- Buy]).

should it be like:

total(L) -> lists:sum([shop:cost(A) * B || {A, B} <- L]).

2007-03-04
18TYPO

In the “Pattern Matching” paragraph the second line of the erlang shell is “Y = 10” and should be “Y = 10.” with the full stop.

2007-03-04
48TYPO

“Examples or OR-guards” should be “… of OR-guards”

2007-03-04
19SUGGEST

I think the example should be easier to read if the author in the text refers to them as the number indicated by the Erlang shell instead of counting the real numbers since the examples themselves are not provided with line-by-line numbers on the left side.

2007-03-09
13TYPO

“Elang” instead of “Erlang” in the first line.

2007-03-04
45TYPO

The top of the page says:
“[X || Quantifier1, Quantifier2, …]
X is an arbitrary expression, and each qualifier is either a generator or
a filter. ”

I’m guessing that Quantifier should be changed to Qualifier here.

2007-03-04
23TYPO

First sentence after “P = {10, 45}”.

Since the tuple itself is just contains a couple of integers we have to remember what its being used for.

The “is” is superfluous and shouldn’t it be “it’s”?

2007-03-04
31TYPO

Third full paragraph on the page: “This is just Width * Height ie 10 * 5 = 20.” “20” should be “50” and possibly “Height” should be “Ht” since that’s what it’s called on the rest of the page.

2007-03-04
33TYPO

Second bullet point in the list, “instances of cirlces need not be need not be located”, has an extra “need not be”.

2007-03-04
70TYPO

Red is twice in following text: “We decide to allocate 5 bits for the red channel, 6 bits for the green channel, and 5 bits for the red channel.”

2007-03-04
39TYPO

Expression 3 in the example at the top, “IsFruit = MakeTest(L).”, L is unbound and I think it should be “IsFruit = MakeTest(Fruit).”

2007-03-04
23SUGGEST

The last example (“>5”) uses a list which hasn’t been introduced.

2007-03-04
25SUGGEST

Shouldn’t you (at least in a footnote) mention Unification when explaining all the stuff about the pattern matching operator?

2007-03-04
24SUGGEST

The first sentence reads a little weird. I think this is a little more easier to read: “We said earlier that what looks like an assignment statement isn’t really an assignment statement at all. Instead, we stated that ‘=’ is a pattern matching operator.”

2007-03-04
45ERROR

The binding given for T (on the example list L) is wrong. The first element should be 6 as T is the tail of the list, in the text T is given as binding to the whole list.

2007-03-04
50TYPO

“Expr1 andaslo Expr2” should be andalso.

2007-03-04
30SUGGEST

The last paragraph: “‘area’ is made up from two clauses, the clauses are separated by a semicolon, and the final clause is terminated by dot-whitespace.” I think that the first part of the sentence before the first comma should be a single sentence, with the second part being another sentence. Also, I think that the first part should say: “‘area’ is made up of two clauses.”

2007-03-04
50TYPO

“is_atom(L) orelse (is_list(L) andaslo length(L) > 2)” should be andalso.

2007-03-04
31SUGGEST

A minor point: In the paragraph, “In this case …”, it says that in the prior example, order of the clauses does not matter. But, while starting to read “In general”, I got a little confused for a second, mainly because there was no “exception” word. I think it should say: “In general, though, clause order does matter …”

2007-03-04
33TYPO

Second bullet item: “Erlang is not an object oriented language, this means …” I think that this reads better: “Since Erlang is not an object-oriented language, data structures that create …”.

2007-03-04
48TYPO

In Figure 2.1, the indefinite articles are incorrect for many entries (e.g., “X is an list”).

2007-03-04
48ERROR

Examples of AND-guards: if “is_tuple(T, 6)” is correct then Figure 2.1 is wrong, because it shows is_tuple(X) where X is an atom.

2007-03-04
50ERROR

“The second guard means…OR the absolute value”, not “AND the absolute value”. Might want to reword so grouping is unambiguous. Suggestion: “The second guard means that either (X is an integer and is greater than Y) or the absolute value of Y is less than 23.”

2007-03-04
56TYPO

First bullet: “…are written with any special syntax” should perhaps be “…are written WITHOUT any special syntax”.

2007-03-04
57TYPO

First paragraph of 3.1: “For example, it’s impossible, to turn…” Remove the second comma.

2007-03-04
58ERROR

Last bullet, starting with “none()”: “This is used for a function that never returns has type (…) -> none()” needs to be fixed. Does it never return, or does it have type (…) -> none(), or are those the same things?

2007-03-04
92TYPO

In “Expr1 andaslo Expr2” should be andalso.

2007-03-04
39SUGGEST

“Evaluating Mult(3) returns fun(X) -> X * 3, ie the body of the inner fun with Times substituted with 3.”

It looks like in the place of “ie”, it should be “which is”. Or maybe this will give it a different meaning?

2007-03-04
61TYPO

3.3, first paragraph: “The Swedish Telecoms company Ericsson” (Where Erlang was developed)…" (A) “Where” should be lower-case. (B) Perhaps “Telecoms” should be “telecom”?

2007-03-04
61TYPO

3.3 second paragraph: “Handling errors…very different to handling errors…” should be “…very different FROM handling errors…”

2007-03-04
40SUGGEST

At the top: “As we have seen, using higher order functions we can create …” I think this is missing a word … “As we have seen, when using higher order functions, we can create …”

2007-03-04
62TYPO

Item 3.: “…is tying to fix…” should be “…is trying to fix…”

2007-03-04
47TYPO

On the top … “since the explanation would be many times tonger then the program,”

2007-03-04
15TYPO

Text in the grey box, first paragraph: “might have have forgotten” (duplicate “have”)

2007-03-04
51TYPO

A minor point: In the example where Person is set to a new record, I believe “Van Winkel” is really spelled “Van Winkle”. :)

2007-03-04
53TYPO

In the fourth paragraph, “In general, lists should always be build by appending elements … ”

I think it should be “built”.

2007-03-04
55TYPO

“The next chapter, covers all the remaining details of sequential Erlang.” The comma is extraneous.

2007-03-04
20ERROR

In the shell example at the bottom, Y = 10 doesn’t have a period at the end.

2007-03-04
24TYPO

Context: Well it turns out that pattern matching is fundamental to Erlang and that it

2007-03-04
25TYPO

"Once we

2007-03-04
29TYPO

“(called funs)” should probably read “(called *fun*s)”

"Then finally we

2007-03-04
28ERROR

The text implies that strings created by the “….” syntax are ASCII encoded this is only kind of true - a strings e.g. "H

2007-03-04
63TYPO

“can try an catch” should read “can try and catch”

2007-03-04
49TYPO

In Figure 2.3 tail is listed as lt(X)

2007-03-04
42TYPO

In the example at the bottom the calculations are wrong. Using the costs defined in shop.erl on page 34, L1 should be [20,8.20,27,21] and lists:sum(L1) should be 123.

2007-03-04
45TYPO

In the paragraph starting “Now we split T into two lists”, the criteria “that are less than Pivot” should read “that are less than or equal to Pivot”.

2007-03-04
46TYPO

Second paragraph, “where the sum of the sides is less than N” should read “where the sum of the sides is less than or equal to N”

2007-03-04
47TYPO

In the explanation of the AND-guard, if " X > Y" is spelled out “X is greater than Y” then “Y < 6” should be spelled out with “less than”.

2007-03-04
30TYPO

I don’t think annotions is a word. It’s not in my dictionary, anyway.

2007-03-04
50TYPO

First paragraph under “Short-Circuit Boolean Expressions”, “are boolean expression” should read “are boolean expressions”.

2007-03-04
33SUGGEST

The not-object-oriented paragraph makes it sound like being not OO is a benefit, which will be contrary to most people’s background, and does not support it. If that concept is discussed elsewhere it might be good to put a pointer to that here.

2007-03-04
70TYPO

The first example

M = <<X:3, Y:5, Z:11>>

gives a badarg because it isn’t divisible by 8.

2007-03-04
37TYPO

Might be nice to point out that funs will be powerful stuff. Right now it leaves you wondering “and how is this different from what we just did in the module section?” if you don’t know why first-class functions are important.

2007-03-04
84TYPO

In the gray box, paragraph 1: “It’s also a good idea to name rename your functions to make it clear that they return a boolean.”

Which one is correct?

2007-03-04
84TYPO

"So if we make sure all our functions which can only
return one of two atomic atomic value return booleans then
we

2007-03-04
83TYPO

In “Boolean Expressions”, the first item: “not B1 - Local not”. Looks like it should be “Logical” instead.

2007-03-04
97ERROR

A minor point: In 4.3, in the last paragraph, it says that hello.erl will print out “:hello world.”. But the code on the next page instead prints out “Hello world”.

2007-03-04
98TYPO

On the bottom, the sentence below “-s init stop”, it read “… evaluates the function it:stop()”. It looks that it should be init

2007-03-04
111TYPO

Below the receive example, in the next sentence starting with “This code …”, it says “… otherwise it wait for a message matching …” I think it should be “waits”.

2007-03-06
55TYPO

In the last sentence: “something with is very useful”. “with” should be “which”.

2007-03-04
31TYPO

In “Extending the Program” in the first sentence after the code there are two successive “doesn’t”.

2007-03-04
42TYPO

Extra closing paren: “but this is jumping too far ahead.)”

2007-03-04
96TYPO

in “then the code loader with search for a file” maybe “with” should be “will”

2007-03-06
97TYPO

“couiple” instead of “couple”

2007-03-04
68TYPO

In the text “The binary <<”cat“>> is shorthand for <<9,97,116>>”, the first integer should be 99, not 9.

2007-03-04
34SUGGEST

> Start your favorite text editor and enter the following
> into a file called shop.erl.

This to me is almost always the hardest entry point for anyone into a language. Start your text editor where? From the same directory as Cean? If you do that it doesn’t compile because the Cean start script immediately moves to the bin directory (at least under windows):

> cd erlang/erts*/windows/bin
> start werl.exe

In order for it to compile under the shell I’ve got to place the file in Erlang’s bin directory. Not exactly the place where you want to be storing your src and beam files.

(Joe says: will be addressed in windows appendix)

2007-03-25
26SUGGEST

The introduction to lists is a bit confusing.

The text talks about “Accessing the head of a list is a very ef ficient operation, so virtually all
list processing functions start by extracting the head of a list, doing
something to the head of the list, and then processing the tail of the
list.”

So you naturally assume that when you get to the next item called “Syntax” it will be talking about extracting items from a list. How to do a CAR/CDR.

What Syntax is really talking about is adding items to a list. Which doesn’t seem to fit the flow of the text.

2007-03-09
73TYPO

Near the end of the page, in “To pack the memory we just wrote the expression <<Red:5, Green:6, Blue:6>>.” that should be “Blue:5”.

2007-03-04
75TYPO

The first paragraph on the page after the list of specifiers begins “I’ve you found…”. It should read “If you’ve found…”

2007-03-04
75TYPO

Last paragraph: “…you can cut a MPEG file…” should read “…you can cut an MPEG file…”.

2007-03-04
76TYPO

In “We use dthe information”, “dthe” should be “the”.

2007-03-06
76TYPO

Bullet number 2: “consequative” should be “consecutive”.

2007-03-04
76TYPO

“Consecutive” is misspelled “consequative” in more than one place on this page. Perhaps on other pages as well?

2007-03-04
32SUGGEST

There should be some description on where to put modules such as math4.erl once it is downloaded so that c(math4). works without an error.

2007-03-09
77SUGGEST

At the bottom of the page, you use the syntax “2#11111111111” for a binary number. That syntax isn’t introduced until page 92. Perhaps there could be a brief note after the use on page 77 that explains that “2#” means base two?

2007-03-06
82TYPO

In the first paragraph of “Attributes”, “There two types…” should be “There are two types…”

2007-03-04
88TYPO

In the first paragraph after the code at the top of the page, square/2 should be square/1.

2007-03-05
29TYPO

The text:

“Compiled modules have the extension ..beam”

has two periods before beam.

2007-03-04
39TYPO

At the top of the page, the code fragment at prompt 3 is

3> IsFruit = MakeTest(L).

It should be

3> IsFruit = MakeTest(Fruit).

as L is not bound at this point, and Fruit was bound on the previous page

2007-03-05
49SUGGEST

Figure 2.2

Two different forms of equals are introduced. Perhaps add a note explaining the differences between them.

2007-03-05
56TYPO

Start of Chapter 3, definition of BIF does not make sense.

I think it should be “but are NOT written”.

2007-03-05
18TYPO

lines 5, 6
we know that X+Y=10 and X-Y=2, then X will be 6 and Y will be 2 in both equations. should be
we know that X+Y=10 and X-Y=2, then X will be 6 and Y will be 4 in both equations.

2007-03-05
101SUGGEST

Rather than using the “~n” format specifier, why not simply use “\
”? (This is a general comment for anywhere format specifiers are used.) The advantage of “\
” is that it’s already familiar—one less weird thing for people to balk at—and “\
” works just fine.

2007-03-09
56TYPO

The Miscellaneous topics bullet has an extraneous “topics”, it should probably read “This deals with a small number of topics”.

2007-03-05
58TYPO

The language in the bullet point for the none() type doesn’t flow well. Perhaps leave off “has type (…) -> none()” or break it into a separate sentence.

2007-03-05
58TYPO

In point 2 of the TypeExpression definition, should {X1, X2, …, Xn} be [X1, X2, …, Xn] since it’s a list?

2007-03-05
44TYPO

In paragraph “Have we said the final word on map? …” there’s a section reference missing (sect.pmapsect.pmap) and there’s a closing parenthesis to much.

2007-03-05
60TYPO

First paragraph, second sentence should read “Is FileName an atom”.

2007-03-05
49SUGGEST

How about sorting the entries in table 2.1 by priority?

2007-03-09
75TYPO

decode_header(<<2#111… )

no explaination or reference provided for defining integers in another base. In this case base 2.

2007-03-05
52TYPO

Aren’t you mixing the use of “,” and “;” in the “OR-guards” paragraph? Shouldn’t it be “AG1; AG2; … ; AGn” (note the semicolon before AGn) both in the code and the text? Using commas in the text is in this context a bit confusing.

2007-03-05
57SUGGEST

Maybe add a reminder that functions with different arity are entirely different functions. It took me a while to remember when starting at lib_misc.erl

2007-03-09
63TYPO

In the last paragraph before the last code sample, final sentence should read “we can try and catch” (or maybe “try to catch”).

2007-03-06
68TYPO

In the first sentence after the numbered list, “d(dog)” should be “g(dog)”.

(Joe says: actually, h(dog) :)

2007-03-05
70TYPO

“real-world code than uses the bit syntax.”
should be:
“real-world code that uses the bit syntax.”

2007-03-05
47TYPO

This means " when…

extra space between quotes and the word when.

2007-03-05
53TYPO

(built) by appending elements to the start …

I think it should be prepending elements to the start

2007-03-05
53TYPO

Um, how exactly do we do this magic reverse operation? It sounds like there’s a built-in efficient way to do it but then we’re not told how.

2007-03-06
55TYPO

Not sure I like the comma in “The bit-syntax, in particular is…”

2007-03-05
63TYPO

Is file name an atom, …

2007-03-06
106TYPO

2nd line from the top

makfiles

2007-03-08
106TYPO

In the paragraph starting with the number 2. spelling error declaired -> declared

2007-03-06
106TYPO

In the paragraph starting with the number 1. ‘Is ou’ should read ‘If you’

2007-03-06
108SUGGEST

The example in subsection 4.9 shows typing help() twice. One instance may be remove.

2007-03-06
73TYPO

“We use dthe information” should be “We use the information”

2007-03-05
76TYPO

“To write an write” should probably be “To write”

2007-03-05
70TYPO

“The shop does not sell:socks”

Should probably omit the : or put a space after it

2007-03-05
113TYPO

In paragraph 3, in the fourth sentence: “To send a reply
back, the client has to include an address that the sever can reply to.”

Sever should be “server”

2007-03-06
122TYPO

Subsection 5.7 (1st paragraph): ‘One the other had’ should be ‘On the other hand’

2007-03-06
77TYPO

You use 2#11111111111:11 here, and just 2#11111111111 on the next page. I’m also not sure what _D:1 means.

2007-03-11
133TYPO

Subsection 6.4 first line: ‘at the thre concepts’ s/thre/three/

2007-03-06
80TYPO

“Lines to match the IP datagram in a single pattern-matching expression.” Is that supposed to be a caption? It’s not a complete sentence. Also, “can be isolated (Lines to ).” doesn’t make sense either.

2007-03-06
85TYPO

Extra end: “The value of a begin … end end block”

2007-03-05
80TYPO

I think the xml tags, e.g. ‘#

2007-03-06
88TYPO

“Note that if some symbol X occurs K
times in B then only the first K occurs of X in A will be removed.”

Maybe rewrite as “Note that if some symbol X occurs only K times in B then only the first K occurences of X in A will be removed.”

2007-03-05
150SUGGEST

3rd possibility of distributing code is via the code server
(erl_prim_loader).

2007-03-09
103TYPO

Missing period after “Hello world had no arguments”

2007-03-06
96TYPO

“In the next chapter we’ll start looking at concurrent programs”, but you don’t cover concurrency until chapter 5.

2007-03-06
81TYPO

On the first line, function should be “functions”.

2007-03-06
115TYPO

You say “finally, the shell prints out {rectangle, 6, 10}” but it actually printed out {triangle, 2, 4, 5}. Also I think “by defining it as Pid1 ! Pid2 ! … ! M we send…” should use a different word than defining. Maybe, “by writing Pid1 ! …”

2007-03-06
88TYPO

In the description of -endif, “ifdef of endif” should be “ifdef or ifndef”.

2007-03-06
33TYPO

In the C area function,
area(struct Shape* s) {
if( s->kind = Rectangle){
should be
area(struct Shape* s) {
if( s->kind == Rectangle){

2007-03-05
128TYPO

In section 6.2, first paragraph: “We can wrote a function … ”

2007-03-06
54TYPO

When creating instance of person record should have
lastName = “Van Winkle”,
instead of
lastname = “Van Winkle”

2007-03-05
130TYPO

In the subsection “System Processes”: “When a process receives an exit signal, it too will die *unless it is
special kind of processes* called a system process.”

2007-03-06
137TYPO

The first paragraph in Section 6.6: “Suppose we have a large set of parallel processes that are involved in
come computation, and something goes wrong.”

2007-03-06
138TYPO

In the “Joe Asks … ” box: “One you understand …”

2007-03-06
145TYPO

In the bullet “Socket-based distribution”: "

2007-03-06
145TYPO

The first paragraph after the bullet points: “Writing a distributed Erlang program is easy all we have to do …”. After “easy”, it should end with a period.

2007-03-06
151TYPO

The second item on the top: “Choose a port or range of ports to be used for distributed Erlang itself, make sure these ports are open)”

2007-03-06
151TYPO

The first paragraph of section 7.2: “A complete virtual machine with its own address space and own set of processes.” This is an incomplete sentence.

2007-03-06
1SUGGEST

The example code should be of a more liberal license. Much of it is generally useful and having it under a suspicious “Copyrights apply… blah blah” license does the Erlang community a disservice, since this will surely become the definitive printed language reference for some time.

(Dave says: all code released in the United States has copyright applied to it automatically. The trick is to then allow its use by license (that’s how the GPL works, for example). What rights would you like to see included?

2007-03-05
121TYPO

I assume your laptop should have 512 MiB of memory and not kB, unless you’re talking about processor cache?

2007-03-06
9TYPO

top: Grammar: should be “Now that you’re comfortable with Erlang…”

2007-03-06
10TYPO

“telecoms applications” should be “telecom applications”. Similarly for “non-telecoms applications”

2007-03-06
11TYPO

“system dependant” should be “system dependent”

2007-03-05
12TYPO

My source tarball is called otp_src_R11B-3.tar.gz, not otp_src_R11-B3.tar.gz.

2007-03-05
13TYPO

“operating systemsand” should be “operating systems and”

2007-03-05
14TYPO

You should write “is not an observer sport” not “a observer sport”. Even better: “Programming is not a spectator sport.”

2007-03-05
15SUGGEST

Box: You haven’t mentioned what atoms are yet, so you should at least say e.g. “We’ll discuss what atoms are below.”

2007-03-09
15TYPO

A lot of the time I won

2007-03-05
18SUGGEST

It would be nice to mention that LHS means “left-hand side” and RHS means “right-hand side”, for the less math-literate.

2007-03-05
19TYPO

Say “belaboring”, not “laboring” the point. Or at least that’s how I say it. Also, it should be “arbitrarily complex” not “arbitrary complex”.

2007-03-05
19SUGGEST

If you’re going to mention tuples and lists at all (which is
probably not a great idea here) you should at least say that they represent compound data structures (i.e. with multiple components).

2007-03-10
20TYPO

Better grammar: "We must ask ourselves what an error is, and how an error makes itself known.

2007-03-05
20SUGGEST

The discussion of how single-assignment variables make debugging easier is reasonably persuasive, but I think the average programmer will be more concerned by how it’s possible to even write programs like that at all. Obviously, the rest of the book deals with this, but some reassurance that it is in fact possible (as long as you change the way you think appropriately) would be a good thing here.

2007-03-05
18TYPO

When I went to school my math teacher said

2007-03-05
21SUGGEST

The expression “(12 + 5)/3.” is misleading; the first time I read it I thought that the “3.” was a floating-point number. Instead, this relies on the fact that division promotes integer arguments to floats. This should be clarified.

2007-03-09
21SUGGEST

“If you’re used to enumerated types… then you will know about atoms” is a bit vague. Better to say “then you have already used atoms whether you realize it or not”.

2007-03-08
22SUGGEST

You mention that Erlang is a functional programming language. I haven’t seen this mentioned before. A brief discussion of this should probably go in the Introduction (which isn’t in the book yet).

(Joe says" this will be in the introduction)

2007-03-09
23SUGGEST

Note that tuples don’t have named fields, unlike structs in C.

The Person tuple should probably have the second to fifth lines indented an extra space to show the structure better.

Don’t say that tuples are destroyed automatically when we declare them! Say that the system manages the memory and destroys them when they are no longer being used. You might mention “garbage collection” here. You might also say “Much like in Java, but unlike in C, we don’t have to worry about memory allocation.”

2007-03-06
24TYPO

“Well it turns out” ==> “Well, it turns out”

“Command two” should be “Command 2”.

“at both sides of the equals sign” ==> “on both sides of the equal sign”

2007-03-05
25SUGGEST

“match out the first name of the person” sounds weird; I’d just say “match the first name of the person”.

Also, make sure you mention that “_” can match different things; it isn’t a variable as such.

Bottom: It might be nice to mention that the evaluation rule in Erlang evaluates element of a list before constructing the list.

2007-03-05
26SUGGEST

Top: We don’t have to “chop off” the head of the list to have the tail of the list. The tail is simply everything except for the head.

Also, the statement “the tail of a list is always a list” is technically true, but it’s misleading since you can have improper lists where the tail isn’t a list. Footnote?

2007-03-09
27SUGGEST

The $ is basically a unary prefix operator converting character atoms to numbers. Maybe this should be mentioned.

(Joe says: It’s Not actually a unary operator-it’s syntax)

2007-03-05
26ERROR

Under the subheading “Syntax:” you say,

“If L is a list then [X|L] is also a list, with head X and tail L.”

The use of [X|L] is unfortunate since if you try something like:

L = [1, 2, 3, 4].
[X|L] = L.

It won’t match. You should problably write something like.
“If L is a list then [H|T] is also a list, with head H and tail T.”

2007-03-05
48SUGGEST

The beautiful little perms/1 program does have a flaw in that it returns duplicates if the input list contains duplicates. If you’re not going to explain the program, perhaps you should at least mention this.

perms(L) -> lists:usort(perms1(L)).
perms1([]) -> [[]];
perms1(L) -> [[H|T] || H <- L, T <- perms1(L — [H])].

(Joe says: I’d rather not explain this)

2007-03-09
42OK

Trying to enter the definition of for:

Erlang (BEAM) emulator version 5.5.2 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.2 (abort with ^G)
1> for(Max,Max,F) -> [F (Max)];
1> for(I,Max,F) -> [F (I)|for(I+1,Max,F)].

1: syntax error before: ‘->’
1>

(Joe says: Not an error - this is what must be in the file. you can’t type this into the shell.)

2007-03-05
54SUGGEST

The intro to “Case and if statements” says that pattern matching is sometimes inconvenient. But case and if statements are based on pattern matching every bit as much as pattern matching in the function head. It should really say that defining separate function clauses for everything is inconvenient.

2007-03-05
123TYPO

“Sometime a receive statement might…” May be what was intended but if so it sounds a little awkward.

2007-03-06
124TYPO

misspelling of timeout as timout in the infinity paragraph

2007-03-06
127TYPO

misspelling in first paragraph: accoriding

2007-03-06
129SUGGEST

I like to see the problems at the end of this chapter. It’d be nice to see some problems or excercises in earlier chapters too.

2007-04-27
1SUGGEST

Maybe it is interesting as an anecdote to point in the introduction to Intel’s Teraflops Research Chip. This chip contains 80 cores and is claimed to be very energy efficient. So, another reason for choosing Erlang would be that you can take full advantage of such a chip in the future which would mean energy savings and less cooling needed in data centers…also 2 hot topics these days.

Some links about this chip:
www.eetasia.com/ART_8800453831_1034362_db7dce9c200702.HTM
www.intel.com/research/platform/terascale/teraflops.htm

(Joe says: will be address in introduction chapter (not yet written))

2007-03-09
156TYPO

The last bullet point on the page: “nil is the last argumnet in the connect call.”

2007-03-08
162TYPO

The second paragraph: "…but MSDs are very useful for viualising what

2007-03-06
163TYPO

“The function connect/5 simple creates a parallel process by
spawning handler/5.”

I think “simple” should be “simply”.

2007-03-06
165TYPO

In the third paragraph, which is after the first code example: “When a connection message arrives (which will occur in the disconnected state) the client sends a login message to the sever and waits for the reply in wait_login_response/2.”

2007-03-06
167TYPO

After the code example, the first sentence: “The sever loop is simple.”.

2007-03-06
92TYPO

In the first numbered item on the page (“2.”), the text starting “(for bases greater…” does not close the parentheses properly. As a suggestion, make that text a new sentence without the parenthesis: “For bases greater…”

2007-03-05
23TYPO

In the second paragraph:
Since the tuple itself is just contains…

Should be:
Since the tuple itself just contains…

2007-03-06
179TYPO

“The connected process has a special signifance: all message to the external program must … ”

“message” should be “messages”

2007-03-06
95SUGGEST

Section 4.1 on stopping the shell.

what about
1> q().

2007-03-06
102TYPO

Two places on this page, there are dollar signs (command line prompts) before the first Unix command, but not before the second one. For example (don’t know if the formatting will be screwed up here):

$ chmod u+x hello.sh
./hello.sh

should be

$ chmod u+x hello.sh
$ ./hello.sh

2007-03-06
102TYPO

In the sction “Run as an Escript” in the paragraph starting “On a Unix system…”, “We” should be uncapitalized.

2007-03-06
23TYPO

In the paragraph “Creating Tuples”:
5> [true, Q, 23, Costs].

But lists haven’t been introduced yet, so it should be:
5> {true, Q, 23, Costs}.

2007-03-06
103TYPO

In the first paragraph on the page, there is a period (full stop) missing after “Hello world had no arguments”

2007-03-06
191TYPO

The last paragraph before Erl Interface is described: “There are however, a number of libraries included in the Erlang distribution which simplify the job of interfaceing Erlang …”

2007-03-06
111TYPO

The first code example in “1.9 Tweaking the Environment” starts with the line “help().” twice. Only one is necessary.

2007-03-06
112TYPO

“functiions” should be “functions”

2007-03-06
56TYPO

“In general lists should always be built by appending elements to the start of an existing list [. . .]”.

The correct term here is “prepending”, not appending, since we are adding elements to the front of the list.

2007-03-05
72TYPO

In the explanation of list_bo_binary BIF, “Here IoList is a list, who elements” should read “Here IoList is a list, whose elements”

2007-03-05
20SUGGEST

Minor point: I’d consider changing the word “objects” in the sentence “because the shell objects like crazy and says:” to “complains” or something similar. Only because seeing “shell objects” together makes me think of some OOP construct and then I’m looking for the verb in the sentence… I had to read the sentence twice to figure it out.

2007-03-06
119SUGGEST

The processes:max() function prints the value of

erlang:system_info(process_limit).

Perhaps add a remark that some of these processes are reserved for system use, and so only some lesser number can be started in this test.

2007-03-09
56TYPO

The elements in Result are in the opposite order to the elements in the
origonal list,
——

should read “the original list”

2007-03-06
39TYPO

“But nothing could be further from the true”. Should be “truth”.

2007-03-06
39TYPO

Minor point: If you’re going to use the Queen’s English with “learnt” instead of “learned”, then “eyecolor” (pg. 23) should be “eyecolour”. 8^)

2007-03-08
41TYPO

“brackets” is used instead of “parentheses” throughout this page.

2007-03-08
59TYPO

Last bullet point (“Miscellaneous topics”). One “topics” to much in the sentence.

2007-03-06
61TYPO

In the “TypeExpression” second item (“2.”). “the list {X1,X2,…,Xn}” should that use “[]” instead of “{}”?

2007-03-06
63SUGGEST

I find the talk about the Erlang Type Notatio rather incomprehensible. At first I didn’t even understand that this is just for documentation and not part of the language. I guess it should be clearly explained what it’s used for.

(Joe says: this will be moved into a new chapter)

2007-03-15
64TYPO

so we

2007-03-06
63TYPO

3.3 Error handling, Exception, the paragraph starts with “We don’t try”. “as no possible repair is possible” does not sound right.

2007-03-06
66OK

I find the overuse use of the phrase “crash” in section 3.3 sounds peculiar and, to me, was unhelpful. As a motto it’s fine but otherwise I would suggest using exception terminology earlier.

(Joe says: My programs crash - I don’t want to alienate people
by using a too strict language at a point in the text where
it’s not necessary. I’ll be much more precise in the
error handling chapters. This is after all, only an introduction.)

2007-03-09
85ERROR

Booleans: There are no booleans in Erlang only the atoms true and false.
——

The very next section goes on to talk about boolean expressions and how “not true” is false. If ‘true’ and ‘false’ are just atoms then surely ‘not true’ should have as much meaning as ‘not ham’?

2007-03-06
131TYPO

Section 6.2: (A) The title should be “An on_exit Handler”, not “A on_exit Handler”. (B) In the first paragraph, the second sentence should be “We can write…”, not “We can wrote…”

2007-03-06
43SUGGEST

I went ahead and created a lists.erl file and defined sum and map. When I tried to compile the module, I get the error below. I realize the problem now, but you might point out to the reader not to try to redefine “system” modules and what “sticky” is.

3> c(lists).

=ERROR REPORT 5-Mar-2007::19:09:10 ===
Can’t load module that resides in sticky dir
{error,sticky_directory}

(Joe says: dded a new sidebar called
I like this draws attention to this but doesn’t break the flow)

2007-03-06
39SUGGEST

It might be worth introducing “=:=” in the text as I think this is the first time we’ve come across it.

2007-03-09
167TYPO

2nd line, the io:format argument “off we co …~p”

2007-03-06
170TYPO

2nd last paragraph of subsection 8.5: “creates four windows all of wich connect to”

2007-03-06
182TYPO

Description of example1_driver.c: “and calls the rotuines in example1.c”

2007-03-06
131TYPO

“that creates a link to the the process”

2007-03-06
134TYPO

capitalized Else isn’t consistent (of course it is pseudocode)

2007-03-06
140TYPO

“non /normal/” should probably be “/non-normal/” or at least “non-/normal/”

2007-03-06
142TYPO

I don’t think race condition requires a hyphen.

2007-03-06
143TYPO

but I think the adjective in “single-processor systems” does require a hyphen.

2007-03-06
1SUGGEST

I see the erl_crash.dump file mentioned in some makefiles, as clean target. It would be nice to know how to use them for debugging.

2007-03-09
12SUGGEST

Building Erlang from Source

There is an Erlang port in the FreeBSD ports collection.

Just do the usual make install dance and the port will automatically fetch the distfiles, check, extract, patch, configure, build and install it.
Example (the distfiles are already in ports/distfiles):

[root@hokage /usr]# cd ports/lang/erlang
[root@hokage /usr/ports/lang/erlang]# make install
=> Extracting for erlang-r11b3_3,1 => MD5 Checksum OK for erlang/otp_src_R11B-3.tar.gz. => SHA256 Checksum OK for erlang/otp_src_R11B-3.tar.gz. => MD5 Checksum OK for erlang/otp_doc_man_R11B-3.tar.gz. => SHA256 Checksum OK for erlang/otp_doc_man_R11B-3.tar.gz. => MD5 Checksum OK for erlang/otp_doc_html_R11B-3.tar.gz. => SHA256 Checksum OK for erlang/otp_doc_html_R11B-3.tar.gz. => erlang-r11b3_3,1 depends on file: /usr/local/bin/perl5.8.8 - found
=> Patching for erlang-r11b3_3,1 => erlang-r11b3_3,1 depends on file: /usr/local/bin/perl5.8.8 - found
=> Applying FreeBSD patches for erlang-r11b3_3,1 Hmm... Looks like a unified diff to me... The text leading up to this was: -------------------------- |--- configure.orig Fri Dec 7 16:13:39 2001 |+++ configure Fri Dec 7 16:19:33 2001 -------------------------- Patching file configure using Plan A... Hunk #1 succeeded at 1224 (offset 143 lines). done => erlang-r11b3_3,1 depends on file: /usr/local/diablo-jdk1.5.0/bin/java - found
=> erlang-r11b3_3,1 depends on executable in : gmake - found => erlang-r11b3_3,1 depends on file: /usr/local/bin/perl5.8.8 - found
=> erlang-r11b3_3,1 depends on shared library: iodbc.3 - found => Configuring for erlang-r11b3_3,1
creating cache ./config.cache
Disabeling caching
Removing cache file ./config.cache
checking host system type… i386-unknown-freebsd6.1
checking for GNU make… yes (gmake)
checking for a BSD compatible install… /usr/bin/install -c -o root -g wheel
checking whether ln -s works… yes
checking for ranlib… ranlib
updating cache /dev/null
creating ./config.status
creating Makefile
configuring in lib
running /bin/sh /usr/ports/lang/erlang/work/otp_src_R11B-3/lib/configure —enable-threads —enable-hipe —prefix=/usr/local —cache-file=/dev/null —srcdir=/usr/ports/lang/erlang/work/otp_src_R11B-3/lib
creating ./config.status

etc.

2007-03-06
20SUGGEST

I expected some mention of concurrency, mutation, locking, etc. here - even just a pointer to a longer discussion later in the book.

(Joe: will be included in new chapter or appendix)

2007-03-10
21SUGGEST

In the section on FP perhaps mention how to do integer division?

2007-03-09
18TYPO

“In Erlang variables, variables are just like they are in math.” - remove first “variables”

2007-03-06
21ERROR

I’m not too happy with equating atoms and C enums or #defines - C programmers very frequently depend on the numerical properties of the enum symbols. You should make it clear that atoms don’t have a numerical value.

2007-03-06
54ERROR

birthday(X#person{age=N}) ->
is syntactically invalid.
birthday(#person{age=N} = X) ->
would work.

2007-03-06
105SUGGEST

Since erlc understands .yrl files, there is no need to have a separate makefile rule for them.

2007-03-11
105TYPO

The parser definition files have the extension .yrl, not .yecc

2007-03-06
116TYPO

“The client and server in a client-server architecture are separated processes” - should be “separate”

2007-03-06
24SUGGEST

"These bindings are made

2007-03-09
131TYPO

In the 1st paragraph of 6.2, “We can wrote a function […]” should read “We can write a function […]”

2007-03-06
102SUGGEST

The described ways to run a program rely on the fact that a module has some function that either has 0 args, or accepts args as a list of literal strings. Frequently one wants to be able to execute an arbitrary Erlang function from OS command line. I suggest mentioning the -eval argument that is very handy for quick scripting:

erl -eval ‘io:format(“Memory: ~p~n”, [erlang:memory(total)]).’ -noshell -s init stop

—Serge

2007-03-09
11TYPO

“I’ll only show the banner (…) this information is only useful” is not grammatically correct.

2007-03-06
29OK

“Let’s see how in the next chapter….” should have only 3 dots

(Dave says: actually, 4 is correct: three for the ellipsis and one for the end of sentence)

2007-03-06
217TYPO

This is the meaning of the {packet, N} argument in the gen_tcp:connect
and gen_tcp:_listen functions.

Should be gen_tcp:listen

2007-03-16
222ERROR

In the 11.2 “Control issues” section the opening sentence says that sockets can be opened in one of two modes (active / passive), yet the following paragraphs talk about three modes {active, true | false | once}.

Additionally, the sentence “If the socket was opened in passive mode then the controlling
process is only sent one message each time it calls the routine
gen_tcp:recv.” is inaccurate. In passive mode the controlling process doesn’t get one message - it uses the gen_tcp:recv call to fetch N bytes from the socket descriptor.

2007-03-08
230SUGGEST

It may be worth noting that if hosts running UDP listeners are in different network subnets, the UDP broadcasts likely won’t reach them, as by default routers drop such UDP broadcast packets.

2007-03-06
48SUGGEST

“The infix operator X—Y is a copy of the list X where any element of X which also occurs in Y have been removed.”

that sounded to me like “[1,1,1,2]—[1]” should result in “[2]” while it actually results in “[1,1,2]”

2007-03-08
1SUGGEST

The code tar contains no hello.beam and hello.sh exposes Joe’s work directory path.

(Joe says: ello.beam is created when you run make
add note about the absolute path)

2007-03-09
81TYPO

At bottom of page, “are not know in advance” should be “are not known in advance”.

2007-03-06
31TYPO

First line on page: “.erl Modules must be…”
There should be a full stop after .erl, since it ends the sentence it belongs to.

2007-03-08
32TYPO

Line above “Extending the Program”: “Width*Ht ie 10*5 = 50.”
should be “Width*Ht, i.e., 10*5 = 50”, otherwise the “ie”
looks like some kind of operator.

2007-03-08
32SUGGEST

Last par.: “In this case, the order of the clauses doesn’t matter, the program means the same thing no matter how the clauses are ordered.”
A newbie probably asks “why is that?” here. You could make it clearer by pointing out that the clauses, as written, are mutually exclusive - no single term can match more than one.
Oh, and substitute a semicolon for the comma after “matter”!

2007-03-09
96ERROR

Figure 3.2 “Term comparisons” is missing the “>” “greater than” operator.

2007-03-08
33SUGGEST

Second bullet point: “We do not say what will happen if none
of the patterns match, we merely fail with a badmatch error.
This is deliberate.”
The use of “we” here is confusing. Rephrase as “The function
does not say what to do if none of the patterns match the
actual arguments. This is deliberate. If it should happen,
the function call will fail with a badmatch error.”

2007-03-09
33TYPO

Second bullet point: actually, it won’t be a “badmatch” error, but a “function_clause” error. Perhaps better to just say that there will be a runtime error (no emphasis on runtime).

2007-03-08
38TYPO

In the section where Double is created and assigned, the line containing “4> Double(4)” is missing a period at the end of the statement.

2007-03-08
35SUGGEST

Last par.: “In line 1 we compile …”
This paragraph ought to be moved to page 32, before the paragraph “So what happened here” but after the example (and be rewritten to match the “math4” example).
In addition, you should add a few words about the syntax “math4:area(…)” for calling functions in modules.

2007-03-10
36SUGGEST

The grey box with the “Tip” talks about writing export declarations - but you still haven’t described those at this point in the book! A good place to do so would be on page 35, just after the code for the “shop” module, explaining briefly that the function cost/1 must be declared as exported in order to be used outside the module. You should also explain the -module(…) declaration, at that point or perhaps even earlier.
Furthermore, in the grey box, don’t say “The compiler option …”, but “The special declaration …”, and make sure there is a period after the closing parenthesis!

2007-03-09
36SUGGEST

In fact, the grey box with the tip about “-compile(export_all).” comes much too early in the book, and would be better in chapter 4, “Compiling and Running your Program”.

2007-03-10
36SUGGEST

Second par.: “…and the system printed out an error message”.
This would be a good place to briefly explain that “function_clause” in an error message means that a function call failed because no clause matched the arguments.

2007-03-10
37TYPO

Last par.: “…it removes the head from the list,…”
It’s best to avoid wordings that sound like you are modifying the data structure. Rephrase as “…it picks out the head and the tail of the list,…”

2007-03-08
39TYPO

Par. 5, “…, so far the code…”
This should be the start of a new sentence, or at least the comma should be replaced by a semicolon.

2007-03-08
39TYPO

Par. 5, “they breath fire” should be “they breathe fire”.

2007-03-08
41TYPO

Par. 1, “And use it…”
This is not a new sentence, and should begin with “and” in lower-case.

2007-03-08
33TYPO

In the equivalent c-code for the function matching example:

"
area(struct Shape* s) {
if( s->kind = Rectangle){
int width, ht;
width = s -> shapeData.rectangleData.width;
ht = s -> shapeData.rectangleData.ht;
} else if (s->kind == Circle){ …
"

First, in your first “if” check, you’re assigning the value Rectangle to s->kind rather than testing the value, and secondly, this really would be written as a switch. There’s no sense making C look uglier than it has to.

2007-03-08
41SUGGEST

Par. 4, “The code inside the brackets”.
Please make it clear that the parentheses (not “brackets”!) are there for pedagogical reasons, to mark the “body” of the fun, and are not strictly necessary.

(Joe says: there are nearby examples without the
additional parentheses - so this should be clear
adding an additional comment would be even more confusing)

2007-03-08
42TYPO

Grey box, par. 1, “In practise” should be “in practice”.
Also, last bullet point: “functions with return funs” should be “functions that return funs”.

2007-03-08
43SUGGEST

Section 2.4: avoid giving the impression that the reader should try to define his own lists.erl module and compile it. In particular, move the footnote (about omitting the commands for compiling the module) to some earlier example where it actually applies. Make it clear that you are showing the definitions of the functions that already exist in the standard library “lists” module.

2007-03-10
44SUGGEST

Sec. 5, “Now that we’ve defined”. Rephrase as “Now that we know about”, to avoid giving the impression that the reader should create his own versions of these functions.

2007-03-09
44TYPO

Last par.: “-import(lists, (…)).” should be “-import(lists, […]).” with angular brackets instead of the inner parentheses.

2007-03-08
45SUGGEST

Bullet point: You ought already to have described -export declarations previously in the book (soon after -module declarations), so you should only describe -import here. Anyway, “-export((…)).” should be “-export([…]).” with angular brackets instead of the inner parentheses.

2007-03-08
71TYPO

First sentence “d(dog)”. You either mean “g(dog)” or “h(dog)”.

2007-03-08
75OK

Are there any examples on the bit synatx following somewhere in the book? I don’t think it’s really understandable as is.

(Joe says: there are already many examples of bit syntax)

2007-03-08
78SUGGEST

Maybe you should try to explain (at least) the first example. I mean, there are some functions used that are unknown to the reader and it’s also not entirely clear how the bit syntax works (e.g. what up with the “#”).

2007-03-09
79TYPO

“To write an write my Erlang program I first defined four macros.”

2007-03-08
20ERROR

the second entry in the example:

2> Y = 10

is missing a period at the end.

2007-03-08
77OK

In the “get_word” function you’re using the comma. And I think this is the first time this is used and unfortunately not explained.

(Joe says: these are defined earlier)

2007-03-08
53TYPO

“…so we often see programs which manipulated tuples…”

Should be manipulate tuples (without the d) so that tenses agree.

2007-03-08
53TYPO

A concrete example of a record would be nice. Just typing the given -record(person, …) into erl gives a badmatch error, and it doesn’t work in a file either (as far as I can tell).

2007-03-08
112OK

Section 5.2, bottom of the page, Paragraph started with “Note Pid !”: s/Pid! !/Pid1 !/ . -Brian Zhou

(Dave says: I believe it is correct as it stands)

2007-03-08
199TYPO

In the subsection Reading ID3 Tags, first paragraph, “MP3 files do not themselves contain information about the content of the file, so, for example, in an MP3 file contains music …”

It sounds like it should be “in an MP3 file that contains music”

2007-03-08
202TYPO

Second paragraph from bottom: “windows machine it will write carriage-return line-feed ASCII (13, 10)” I think the “w” should be capitalized.

2007-03-08
204TYPO

The last paragraph before the bottom example: “(ie it only output the characters embedded in the lists and not the list brackets themselves).”

2007-03-08
122TYPO

Section 5.7, first paragraph, 3rd line
s/One the other hand/On the other hand/

2007-03-08
213TYPO

First paragraph under the sample: “{packet,0} means that the TCP data is is ‘unframed’”

2007-03-08
131TYPO

Section 6.2, 2nd sentence —- “We can wrote …”
Wrong tense. It should be “We can write …”

2007-03-08
215TYPO

Fourth paragraph from the top: “Most packet sniffers include software which can decode and analyze the data in the packets and present the data in a meaningfull manner.”

2007-03-08
189TYPO

Last paragraph: “acts as aport interface”

2007-03-08
206TYPO

First paragraph: overwriting the origonal content

2007-03-08
221TYPO

Note 1, 2nd line: gen_tcp_connect should be gen_tcp:connect

2007-03-08
100TYPO

“The next sections show how to compile and run a couiple of programs…”

couiple should read couple.

2007-03-08
96TYPO

“In the next chapter we’ll start looking at concurrent programs”. It seems that the chapter about compiling and running programs has been inserted before the chapter about concurrent programming.

2007-03-08
111TYPO

Duplicated command:
1> help().
2> help().

2007-03-08
100ERROR

On Windows, the environment variables HOMEDRIVE and HOMEPATH point out where to look for the .erlang file, not HOME.

Erlang actually uses the following command

init:get_argument(home)

to find out where Erlang will look for the .erlang file.

2007-03-08
103SUGGEST

There is also an -eval option. If you also export fac/1 from the fac1 module, the following will work:

erl -noshell -eval ‘io:format(“~p\
”, [fac1:fac(25)]), c:q()’

2007-03-09
102ERROR

Relatively minor, but I think

$ chmod u+x hello.erl
./hello
Hello world
$

should probably read
$ chmod u+x hello.erl
$ ./hello.erl
Hello world
$

2007-03-08
60TYPO

Repeated ‘and’

two things, types and and function specifications.

2007-03-08
21TYPO

Include file in C is named “glob.hrl” instead of “glob.h” at the bottom of the page.

2007-03-08
32TYPO

last para: repetition of ‘the’: pattern matched against the the calling arguments

2007-03-08
88TYPO

“A B add (ie appends) …”. That should be add*s*

2007-03-08
95SUGGEST

So what’s the difference between == and =:=? I mean how should I interpret the difference between equal and identical. You hit that it has something to do with floats but it’s not actually explained.

(Joe says: it’s explained under terms, earlier)

2007-03-09
49TYPO

In Figure 2.1, argument type is “number” or “integer” but in the main text (first par of section 2.6), it is referenced as “integer” or “mixed”. So there’s a mismatch between “number” and “mixed”.

2007-03-08
123TYPO

“Sometime a receive statment might…”

Statment should be statement, and Sometime should probably be sometimes.

2007-03-08
0SUGGEST

In the Code section there is a duplicate/1 function that uses lists:member/2. I think this code may be re-written to avoid this call:

duplicates2(X) -> find_duplicates2(sort(X), []).

find_duplicates2([], L) -> L;
find_duplicates2([H,H|T], [H|L]) -> find_duplicates2(T, L);
find_duplicates2([H,H|T], L) -> find_duplicates2(T, [H|L]);
find_duplicates2([_|T], L) -> find_duplicates2(T, L).

All the best,
Philip

(PS: Sorry about entering page number 0 - I saw this on the “Code” link on the website so I don’t know where it is in the book.)

2007-03-08
53SUGGEST

In the section 2.8, first paragraph means essentially the same as the third paragraph. Maybe this redondancy could be avoided.

“When we program with tuples, we can run into a problem when the number of elements in a tuple becomes large. It becomes difficult to remember which element in the tuple means what. Records provide a method for associating a name with a articular element in a tuple, which solves this problem.”

=

“As the number of elements in a tuple becomes greater it becomes more and more difficult to keep track of the meanings of the individual elements in the tuple. When the number of elements in the tuple is large, or if we wish to name the elements in the tuple for documentation purposes, then we can use records instead of tuples.”

2007-03-09
54SUGGEST

It is unclear to me why we need to write X two times in the pattern matching clause of the function.
birthday(X#person{age=N} = X) -> X#person{age=N+1}.

In fact, i’m asking why the first X should be there. Why not write:
birthday(#person{age=N} = X) -> X#person{age=N+1}.

I guess this has to do with syntax. It might be interesting to clarify that.

Another thing, I was not able to run the example. I tried writing the record definition in the shell or in a module but without success. It looks like the export clause in the module should be different from what is used for exporting functions.

(Joe says: it was a bug)

2007-03-09
69SUGGEST

In discussion of the Erlang exception handling, I’d suggest covering the try-catch mechanism too. The original catch expression is ambiguous in some cases. I remember that from a paper written by Richard Carlsson.

(Joe says: Try-catch is in the pipeline - it will not be forgotten :-)

2007-03-15
61TYPO

In the list of type notations, “tuple() is an tuple.”

2007-03-08
51SUGGEST

in my erlang shell (5.5.2) ‘record’ raises a badmatch error. If I use ‘rd’ the examples work.

2007-03-09
26OK

Under the subheading “Syntax:”,

“If T is a list then [H|T] is also a list, with head H and tail T.”

That should probably be “If L is a list the [H|T] …” since [H|T] = T won’t match.

(Joe says: the original is correct)

2007-03-08
109TYPO

Under 1.
The pdf says “Is ou instead have spaces there…” when it should probably say “If you instead have spaces there…”

2007-03-08
1SUGGEST

What is OTP? I’m familiar with Online Transaction Processing, but I do not believe that is the use here. Perhaps at least a mention of what OTP stands for.

(Joe says: will discuss in introduction (not yet written))

2007-03-09
9SUGGEST

Bullet item 3 mentions make and Makefiles which are very familiar to C/C programmers in Unix. Do you want to mention other build tools such as ant which are more familiar to Java programmers?

(Joe says: there are many build tools I won’t mention them all
only make)

2007-03-09
9SUGGEST

Bullet 4 mentions the library collection named OTP. I’m only familiar with this acronym standing for Online Transaction Processing. What does OTP stand for?

(Joe says: will be discussed in the introduction)

2007-03-09
9SUGGEST

When I first read the last paragraph on page 8 and the first paragraph on page 9, I thought, “Have I mixed up my pages? Something is missing.” The transition from “…a working knowledge of the language.” (p.8) to “Now that you’re comfortable with Erlang….” (p. 9) seems harsh.

2007-03-09
183TYPO

At the top of the page, should be “output” not “oputput”

2007-03-08
15SUGGEST

The first paragraph mentions the term ‘cluster’; however, you do not define this term.

2007-03-09
15SUGGEST

In paragraph 1, you mention ssh. Most Unix programmers will be familiar with this shell; however, most Windows programmers will not.

2007-03-09
16TYPO

“…variables start with upper-case letters).” I thought that the closing period went inside the parentheses when the text inside was a complete paragraph. (It’s been a long time since I consulted a style guide.)

2007-03-08
17SUGGEST

“…single assignment variables can only be given a value once.” I was unclear if this statement indicated a global scope or if binding occurred locally. For example, can I bind the variable X to one value in one function but to another value in another function?

2007-03-09
144TYPO

Third paragraph, s/are some are some/are some/

2007-03-08
144TYPO

Last line on the page, s/have a have a/have a/

2007-03-08
17OK

Section “Variables that Don’t Vary.” This section distinguishes between binding and assignment. For programmers not familiar with Prolog, do we want to explain the difference between these two terms “up front” since we explain that variables are “single assignment variables” but are “bound” and not assigned?

2007-03-10
145TYPO

Last line in paragraph starts with “Distributed Erlang applications run …”, s/a open network/an open network/

2007-03-08
145TYPO

Last line in paragraph started with “We are all used to”, s/Even thought/Even though/

2007-03-08
151TYPO

BIF description for disconnect_node/1, tense problem
s/Forcibly disconnected/Forcibly disconnects/

2007-03-08
11SUGGEST

Although this test may work on Unix systems, it does not work on Windows (unless the reader has changed the PATH variable). Windows programmers (on XP) invoke Start > Control Panel > Add or Remove Programs. When the applet opens, search for “Erlang OTP R11B” (depending on installed versions).

)Joe says: added comment and reference
to section that I’ll write about windows)

2007-03-09
14ERROR

Invoking the command erl in a Windows cmd window only works if the reader has installed Erlang and changed the PATH environment variable to refer to the program. Assuming the reader installed the program in the standard way, the reader must invoke Start > All Programs > Erlang OTP to run these commands.

)Joe says: added comment and reference
to section that I’ll write about windows)

2007-03-09
14SUGGEST

The section labelled “1” does a great job describing how things work on Unix. What about describing how things work on Windows?

)Joe says: added comment and reference
to section that I’ll write about windows)

2007-03-09
15ERROR

Box. Although this procedure may work under Unix, the Erlang window under Windows does not seem to respond to Ctrl-C (other than to reprint the command number). (I tried simply pressing Ctrl-C after first opening the Erlang window.)

2007-03-09
15ERROR

Sidebar. In Windows, one types Ctrl-Break to get the “BREAK” message.

2007-03-09
21SUGGEST

“…different non-numerical atomic values.” I find it confusing to define atoms in terms of atomic values. (My experience as that the phrase “atomic” is used in the context of database transactions or concurrent updates.) Perhaps by “atomic” you mean “a object whose value is itself” (although I’m not certain if that phrase accurately communicates what you want to say).

2007-03-09
22SUGGEST

“…atoms are global in scope….” When I read that, I understood it to mean that all modules share a single, global name space; i. e., X defined once precludes all subsequent uses of X. I believe atoms are global in some scope: a module or a function. If we do not want to get into the details of scopes, we may want to refer to a future discussion. Otherwise, we might want to mention scopes.

2007-03-09
23TYPO

“…you might want to create a tuple{”joe“, 1.82}”

Missing a period.

2007-03-08
23SUGGEST

Context: …a tuple {“joe”, 1.82}. On page 22, we mentioned atoms and using single quotes to create atoms containing “unusual” characters. On page 23, we then suddenly use double quotes. When I first read this phrase, I thought joe was intended to be an atom. If it is an atom, I suggest using single quotes (or nothing); otherwise, I suggest mentioning double-quoted strings.

2007-03-09
23TYPO

Context: “struct point…P” I believe the statement in C requires a semicolon (but its been a long time since I’ve written C).

2007-03-08
23SUGGEST

“…and stores it in the variable P.” This statement sounds like an assignment in other languages. Do we want to communicate this idea to the reader?

2007-03-09
140TYPO

“Sometimes programming with links is tricky, because links are symmetic.”

symmetic should be symmetric.

2007-03-08
182TYPO

“The first two bytes, encode the packet length, this is followed by the result 77 (again one byte long).”

Should read:

“The first two bytes encode the packet length. These are followed by the result 77 (again one byte long).”

2007-03-08
25SUGGEST

The text uses the phrase ‘“in parallel.”’ Because of the double quotes, I was unclear if this phrase actually describes the details or if we might need a reference to a later description.

2007-03-09
25SUGGEST

The sixth paragraph uses the phrase “same shape.” I do not believe we have mentioned the word shape before. Do we need to provide an explanation of this term?

2007-03-09
26SUGGEST

Section 1.10 describes lists; however, it fails to mention the empty list. Do we need to mention this special list?

2007-03-09
76TYPO

At the bottom of the page: “To be really sure we look for three consequtive headers.”

2007-03-09
28SUGGEST

The second paragraph of section 1.12 mentions the word “terms.” I believe this instance is the first mention of this term. Do we need to define this word before using it?

2007-03-09
29SUGGEST

The code example in the middle of the page uses the expression “f().” The next to the last paragraph on the page describes the forget function. When I first read the code text, I wondered if I had missed or forgotten a previous description of the function f(). Might putting the description of f() before the code block make the code more understandable?

2007-03-09
76TYPO

There are two typos of the word consequtive. At the bottom of the page, point 2 in the list and the next to last sentence of the page.

2007-03-09
77TYPO

“find_sync tries to find three consequtive MPEG header frames.”

2007-03-09
39SUGGEST

First paragraph of “Functions Which Have Funs as Their Arguments” states “The module lists exports several functions…” and then shows an example of using lists:map(). Make it clear that lists:map() is not defined yet and will be built as part of the test. It looks like it’s part of the standard library and I spent several minutes figuring out what I was doing wrong. ;)

2007-03-10
30TYPO

“You’ll see how the ideas on pattern matching, that we learnt about in the first chapter, are used when we define functions.”

2007-03-09
30TYPO

First paragraph. I do not believe that the two commas in the last sentence of the first paragraph are needed.

2007-03-09
30TYPO

“…with the final program and no explanation….” I believe the “with” better expresses the idea than “and.”

2007-03-09
31SUGGEST

“In lines 1 to 4…in lines 5 to 14….” I think that using the shell input numbers is clearer than the actual line numbers.

2007-03-09
32SUGGEST

“…have moved ‘inside’ the modules…” Since the text has already talked about binding, I believe it is clearer to continue using this terminology. When I first read the term “moved ‘inside,’” I wondered if some kind of copying was occurring.

2007-03-09
33SUGGEST

I found describing area as having “several different entry points” confusing. The phrase “entry points” reminded me of Windows DLLs in which callers decide which entry point to call. In this situation, it seems as though the entry point is the first clause of area and the function has a set of branches taken based on the matched clause.

2007-03-09
33SUGGEST

“enum ShapeType…” might be preferable to “enum ShapeSort.” When I first read this name, I wondered “Are we going to sort the shapes?”

2007-03-09
33TYPO

“if( s->kind == Rectangle){” seems to be missing a space between ‘)’ and ‘{’.

2007-03-09
33TYPO

The expressions “s -> shapeData…” should be “s->shapeData…” to be consistent with other formatting.

2007-03-09
33TYPO

The code fragment “(s->kind == Circle){” is missing a space between ‘)’ and ‘{’.

2007-03-09
34SUGGEST

In the last bullet item, the text says that object-oriented languages put data and their functions in the same place. Proponents of object-oriented programs might argue this “requirement” is a strength. Might a sidebar explaining the advantages of putting these items in separate locations be worthwhile?

(Joe says: his is a long and complex argument - I can’t do justise to this
in a sidebar - this needs an entire book)

2007-03-09
34SUGGEST

The phrase “…data structures that create and manipulate instances of circles….” might be better expressed as “data structures that represent and functions that create and manipulate instances of circles….”

2007-03-09
34SUGGEST

The author briefly describes how people organize object-oriented code (“…data structures that create…located in the same place”). Might a sidebar describing how to organize code in Erlang be appropriate?

2007-03-09
35SUGGEST

The text says “Each clause contains a pattern…” Earlier, the text described that a clause consists of a head and a body. Might the text be clearer using a phrase like “The head of each clause contains a pattern…”?

2007-03-09
35SUGGEST

The third paragraph uses the phrase “…pattern which is just an atom.” Perhaps it is my “Prolog showing,” but I understood the head to contain two atoms cost and, for example, apples. Perhaps the meaning would be clearer if the text mentioned both the function name and the atom?

2007-03-10
36TYPO

The list “…[{oranges,4},{newspaper,1},….” might be more consistent with other entered lists with whitespace. For example, “…[{oranges, 4}, {newspaper, 1},….”

2007-03-09
43SUGGEST

Tip box. Although the approach mentioned (write a bit and then test a bit) works especially in a shell environment, I wonder if a mention of any unit testing frameworks - or lack thereof - might be appropriate at this time.

2007-03-09
38TYPO

“…actually did two different things, firstly it looked….” I believe this text should be two different sentences: “…actually did two different things. First, it looked….”

2007-03-09
38SUGGEST

The text asks the reader to enter the text “Double = fun(X) -> 2 * X end.” Might entering the text “Double = Z.” help to reinforce the ideas of binding discussed earlier?

2007-03-10
39SUGGEST

“Among other things this means that funs can be used as the arguments to functions….” Is this characteristic a characteristic of functional languages or any language that treats functions as first class objects (Scheme, Python, and so on)?

(Dave says: probably a diversion here…)

2007-03-09
39TYPO

I believe the phrase “…programming languages, they breathe fire….” should be “…programming languages: they breathe a fire….” (or perhaps a dash).

2007-03-09
40SUGGEST

I believe it may be worthwhile to add a sidebar comparing funs returning funs with closures.

(Dave says: this will probably disrupt the flow)

2007-03-09
0SUGGEST

I definitely think a chapter on the available tools for working with Erlang ( like all of the beautiful emacs stuff that is included in the distro ) would be good.

Emacs, Eclipse and those kinds of things. ( Debugging, Monitoring, Profiling, etc ).

(Joe: will be included in new chapter or appendix)

2007-04-25
31SUGGEST

The name “math4” for the module is not very suggestive. I recognize that “math” is taken. Maybe a name like “geometry” would be better.

2007-03-10
32TYPO

The sentence: “This makes
writing and extending programs very easy, we just add more patterns.” is grammatically incorrect (comma splice). Change the comma to a semicolon.

2007-03-09
33TYPO

The sentence “We do not say what will happen if none of the patterns match, we merely fail with a runtime error.” is grammatically incorrect (comma splice). Replace the comma with a semicolon. I’m guessing there will be a lot more of these, so I won’t submit any more errata of this form.

2007-03-09
34SUGGEST

In the sentence “Since Erlang is not an Object Oriented language, …” there is no need to capitalize “Object Oriented”, though you might want to hyphenate it (“object-oriented”). More significantly, although the example makes a good point, it overlooks the fact that to add extra clauses to the area function you need to rewrite and recompile the module, whereas in Java you just define a new class and compile it (but the old code stands as is). This is a classic tradeoff between an OO approach and a functional approach. I’m not sure if this needs to be mentioned, but don’t convey the impression that the Erlang approach is inherently superior in all ways; it’s just much lighter-weight.

2007-03-10
36TYPO

The phrase “provide the interfaces to the exported
functions remain the same” should be “provided the interfaces to the exported functions remain the same.” Also, you might mention that the -compile lines come at the top of the file, right under the module lines (do they have to?), and that lines starting with have special meanings to the compiler.

2007-03-09
37SUGGEST

In the explanation of “shop1:total([{milk,3}])”, you say that T matches the empty list. This is true, but why it’s true may not be evident to programmers who haven’t studied functional languages.

2007-03-10
37SUGGEST

At the bottom, make sure you mention that “(do something with the variables in Head)” is pseudocode.

2007-03-10
39SUGGEST

The statement “funs can return funs” suggests that only anonymous functions can return funs. You should say something like “funs or ordinary functions can return funs”.

2007-03-10
39SUGGEST

The word “learnt” is not idiomatic American english. We write it “learned”.

2007-03-09
39SUGGEST

For the Even example, is it necessary to use bitwise and? Surely Erlang has a modulus function.

2007-03-11
42TYPO

“Writing functions with return funs” should be “Writing functions which return funs”.

2007-03-09
42SUGGEST

The description of the “for” function at the bottom of the page is nice but somewhat misleading. In imperative languages, “for” works by side-effect and doesn’t return anything. Your version is an enhanced “for” control structure, since it returns a value. Footnote?

2007-03-10
43TYPO

“at same time making them a lot clearer” should be “at the same time making them a lot clearer”.

2007-03-09
44TYPO

"Here

2007-03-09
44TYPO

"Later, we

2007-03-09
46SUGGEST

After the code fragment “[{A,B} || {A,B} <- Buy].” you state “This is almost what we want but not quite.” That’s silly; it’s just a copy of the list. Just drop this sentence. Then in the line "we

2007-03-09
54SUGGEST

The statement “X#person{age=K} makes a copy of X replacing the old value of the field named age in X with the value K.” could be misinterpreted as referring to the left-hand side of the -> operator (i.e. the pattern match). This needs to be clarified.

2007-03-11
56SUGGEST

The statement “If you ever see code like this:
List [H]
It should set alarm bells off in your brain” is correct, but readers will wonder why you used the operator in the quicksort function. You should clarify this.

2007-03-10
41SUGGEST

“We don’t need any control structures.” Is this actually correct or is more accurate to state “We don’t need additional control structures.” In addition, I’m wondering if this statement is provable. I believe, for example, that it was proved mathematically that a language did not need a go-to statement. If this statement is empirical, we may want to qualify it to avoid the broader import.

2007-03-10
43SUGGEST

“…at the same time making them a lot clearer.”“” Although I agree that higher order structures are more lead to dramatically more powerful programs, I’ve also found that these are sometimes more difficult to understand at execution time and are sometimes more difficult for readers less familiar with these constructs. Do you want to address this issue?

2007-03-10
48TYPO

“The function pyth(N) generates…” should be “The function pythag(N) generates…” to be consistent with the code block in the middle of the page.

2007-03-09
50TYPO

“…(ie something like….” should be “…(i. e., something like….”.

2007-03-09
50SUGGEST

On pages 50 - 53, the text refers to “guard predicates”, “guard term comparisons” and “guard built in functions.” When I read these pages, I wondered if these particular expressions were only valid in guards. However, on page 53, the text states “…a guard can be used as an expression…” How can the text clarify whether the predicates and expressions used for guards are unique to guard clauses or are general expressions in the language?

2007-03-11
53TYPO

“Finally, a guard can be used as an expression, it will….” I believe this fragment should be two sentences: “Finally, a guard can be used as an expression. It will….”

2007-03-09
52ERROR

Figure 2.4 describes the function “element(X, N)” When I attempted to invoke this function in the shell, the shell responded with error messages. When I tried executing “element(1, {1, 2, 3, 4})”, the shell responded as I expected.

2007-03-10
224TYPO

Last sentence: “This returns the IP address and Port of the other end of the connection, so the server can who iniciated the connection.”

2007-03-09
226TYPO

Second paragraph in section 11.5: “UDP is a so-called connection-less protocol, which means that the client does not have to establish a connection to the sever

2007-03-10
226TYPO

Second paragraph in section 11.5: “This means that UDP is well suited for applicatations where large numbers of clients send small packets to a server.”

2007-03-10
229TYPO

Last sentence before example: “The code for a remote proceedure call now looks like this:”

2007-03-10
233TYPO

Last sentence: "If you look at the real code, you

2007-03-10
87SUGGEST

I am still confused by the meaning of the Boolean sections.

First it states that there are no booleans. Then it explains how the atoms ‘true’ and ‘false’ are interpreted as logical values, how they interact in boolean expressions, and how things evaluate to booleans.

If the point is that there in no distinct type called ‘boolean’ then I think that it would help to say “There is no distinct boolean type in Erlang instead the atoms ‘true’ and ‘false’ are given a special interpretation.”

If it’s not down to type then I just don’t understand…

2007-03-10
138TYPO

At the bottom of the page: Don’t you mean “edemo1:start(false,normal).” instead of {die,normal}. Or is “exit(normal)” the same as just finishing the function normally?

2007-03-10
140SUGGEST

“This program is identical to edemo1 with one small change to the function c/2 to make it call exit/2.”

Well, I wouldn’t say that c/2 is nearly identical to the old one. It’s a completely different function!

2007-03-10
40SUGGEST

Section 2.3 defines “arity”, but at the bottom of section 2.4 the “terminology” paragraph redefines it.

2007-03-11
18TYPO

“If X occurs in many differnt functions then all the values of X are differnt.” - shouldn’t this be 2 times different instead of differnt?

2007-03-10
54ERROR

The code fragments on this page can neither be entered into the Erlang shell nor compiled from an external file.

When I tried entering the record definition, the shell responded with an error message.

When I entered the 3 code blocks in an external file, I encountered several errors. The phrase ‘X#person’ appeared to be illegal. Removing them, the compiler then complained about X being unused. Replacing X#person with #person allowed the code to compile.

After compiling the record definition and the function definition, I tried to bind Person to a new record. The shell complained about the symbol #person being undefined. Even after adding the module qualifier record_eg (record_eg:#person, record_eg:person, record_eg#person), the shell complained about syntax errors and about record person being undefined.

(I’m just barely familiar with Erlang. It could well be user error.)

2007-03-10
55TYPO

I believe that “…case is evaluated as follows: Firstly….” should be “…case is evaluated as follows: firstly….”

2007-03-10
57SUGGEST

I do not understand the intent of the footnote “8. lists:reverse is recognized by the compiler and replace by efficient code to reverse the list.”

2007-03-10
58SUGGEST

If the reader is entering the suggested code fragments herself, he code fragment “{reverse(Odds), reverse(Events)}.” fails to compile. To compile it, the reader must include the fragment “-import(lists).” or change the reference to “lists:reverse.” (Although the author mentioned earlier that he would no longer include the “standard ‘prologue,’” I do not remember if this included the import statement.)

2007-03-11
58SUGGEST

The last paragraph states “The next chapter covers all the remaining details…”; however, the next chapter is named “Advanced Sequential Programming.” When I read a chapter title containing the word “advanced,” I assume that its not necessary; however, the statement about the remaining details tells me it is necessary.

How can the text better communicate the relationship between chapters 2 and 3?

2007-03-16
0SUGGEST

Two suggestions:
First, I would like some info about available tools: What are good editors on Linux, Windows and Mac OSX? What do people use? How about profilers, debuggers and the like?
Are there existing config files for emacs, Eclipse or other editors, at least enough to get paranthesis/bracket matching and perhaps syntax highlighting?

Second, I would like at least a brief description of style issues (as Erlang has been used in industry for years, I assume some sort of common patterns have evolved?) and how to map a few thousand lines of code to modules, files and folders so that the code is reasonably manageable.
(I find 1000-line Java files quite tolerable with an IDE that supports class- and method browsing. I suspect that a 1000-line Erlang file would be rather painful. Especially if there are no tools beyond vi and Notepad.)

(Joe: will be included in new chapter or appendix)

2007-03-10
34TYPO

with
enum ShapeType { Rectangle, Circle };
probably should include type square unless you want to show how easy it is to make simple C errors

2007-03-10
40ERROR

getting from Z/1 to Double/1 should have been
Double = Z.
rather than
3> Z.
#Fun<erl_eval.6.10732646>
4> Double(4).
8

2007-03-10
40TYPO

“badarity” is defined twice in the second-last and third-last paragraphs.

2007-03-10
50SUGGEST

the section heading “crosswords” should be “anagrams”

2007-03-11
53TYPO

in the patterns to which the guards apply, or, they are result of applying
one of the guard built in functions in Figure 2.4, on the next page to …

requires a comma after “on the next page”

2007-03-10
54TYPO

is “X =/= Y X is not equal to Y”
not identical?

2007-03-10
73TYPO

“Suppose we want to want to represent a 16-bit RGB color.” should be “Suppose we want to represent a 16-bit RGB color.”

2007-03-10
124TYPO

“I can also hear my disk chattering away. This is a sure sight that the system is paging…” should be “sure sign that the system…”

2007-03-10
81TYPO

"apply

2007-03-10
148TYPO

“The final step, can be problematic.” - extraneous comma.

2007-03-10
150TYPO

Gandalf is spelled with two As.

2007-03-10
151TYPO

home.net is a cybersquatter. Suggest example.com from RFC 2606, so we don’t give them unintended hits from cut and paste.

2007-03-10
142TYPO

In the explanation of “exit(Why)”: … then the current process will broadcast a exit signal, which argument Why to all processes to which it is currently linked.

Shouldn’t that be “with” instead of “which”?

2007-03-10
92TYPO

“a decimal point, a fractional POINT, and an optional” should read “a decimal point, a fractional PART, and an optional”?

2007-03-10
152ERROR

(gandalf@falcon.fugal.net)2>
=ERROR REPORT 10-Mar-2007::08:54:40 ===

Connection attempt from disallowed node ‘bilbo@sauron.fugal.net’

I followed the instructions very carefully but the node is disallowed. Same cookie, no firewall, same LAN. Is there some security-related step missing? Erlang 5.5 on Debian and 5.5.2 on OS X.

(Joe says: Very difficult to say what’s wrong. I Googled
this error message and it happens sometimes. Something is
wrong but I don’t know what. The instructions In the book
\t have been tested on my machine and work, and they
should work on other machines. Sound

2007-04-13
36SUGGEST

“The notation Name/N means a function called Name with N arguments.”

Maybe it’s too early in the book but you should mention something about “arity”

2007-03-10
188TYPO

First bullet paragraph on the page,
s/single bytes/single byte/
s/sighnedness/signedness/

2007-03-10
187TYPO

Explanation of (Line 30) in paragraph starting with “The {packet,2} option”
s/{PicC,{data,[2,45,32]}}/{PicC,{command,[2,45,32]}}/

2007-03-11
45SUGGEST

Under the “Common Errors” sidebar, it starts with “Some guys have mistakenly…” That sounds a bit rough. I’d probably change it to “Some people have mistakenly…” Not all readers are going to be men, or even “guys”.

2007-03-11
71SUGGEST

It would probably help to have an example for the section on the throw() BIF to help distinguish it from exit(). The difference is a bit subtle. I was reading fast through it and had to go back and read it a couple of times before I fully understood why I might want to use one and not the other. Perhaps an example and a recommendation would be best.

2007-03-16
69SUGGEST

In the discussions of working with the exception from

V = (catch shop:cost(socks)).

There are no line numbers next to the shell output, but the text references line numbers. Maybe this a beta book thing, but if it’s not, please add the line numbers as it’s hard to follow.

2007-03-11
88TYPO

In the gray box “Force Binary Functions to Return Booleans”, the last paragraph that starts “the answer is…” should be capitalized.

2007-03-10
89SUGGEST

Under character set, it might be nice to address Unicode. Since most modern programming languages are starting to use Unicode internally now, the lack of this in Erlang, while not necessarily problemmatic, is at least conspicuous.

2007-04-12
140TYPO

“In all case B traps the error”
Should be cases, no?

2007-03-10
94TYPO

In the description of $ syntax, the final sentence reads “Thus $\
is 10$\\∧c is 3 etc.”

There needs to be some punctuation between the “10” and the “\\^c” and the “etc.”

2007-03-11
94SUGGEST

In the sections describing integers and floats, the examples are all given on a single line with only a small bit of whitespace between them. At least in the PDF version, this makes it very hard for my eyes to determine where one number stops and another starts. I’d suggest either putting each of the examples on a separate line, or putting some sort of punctuation between them (probably a comma).

2007-03-11
97TYPO

The section on term comparisons has a paragraph that admonishes: "You should also be really very careful about using == (especially if you

2007-03-24
123SUGGEST

Section 5.5, How Long Does it Take to Create a Process

This section starts off saying that the reader may be worried about the performance of sending hundreds or thousands of messages between processes. Yup, that’s a logical question. But the section then goes on to show you how quickly you can created processes. That’s another interesting issue, but it’s not the one the section set up in the reader’s mind.

Perhaps do a full section on performance and cover both message sending/receiving performance, as well as process-creation performance.

2007-03-11
75TYPO

Suppose we want to want to

2007-03-11
58TYPO

Last paragraph of 2.11: whenever you want to reverse a list you should call lists:reverse any nothing else.

Should be “and”.

2007-03-11
84TYPO

So, to build a dynamic a dynamic call to a

2007-03-11
150TYPO

Second paragraph of 7.1: The reference seems to be missing. Maybe it’s because you spelled “tolerent” instead of “tolerAnt”?

2007-03-16
215SUGGEST

The footnote tells me:
“1. This is only true for HTTP/1.0, for more modern versions of HTTP a different strategy
is used. ”
Cool. Why not use a more modern version? Google will surely handle the “more modern version”… And it would be useful!

(Joe says: because it makes the program more complicated, and this section is about programming sockets and not HTTP)

2007-03-11
90TYPO

In we a remote module, we could refer to square/1 as follows:
- huh

2007-03-11
99TYPO

mentioned, but I

2007-03-11
102TYPO

sec.code.loadingsec.code.loading.
and
The two most common functions which we use manipulate the
(requires a “to” between use manipulate

2007-03-11
84SUGGEST

Why don’t you simply write

1> apply(erlang, atom_to_list, [hello]).
“hello”

instead of

1> F = list_to_atom(“atom_to_list”).
atom_to_list
2> apply(erlang, F, [hello]).
“hello”

?

2007-03-11
101TYPO

Typo in next to last para in section 4.1

“q() is an shell alias for the command init:stop().”

2007-03-12
103SUGGEST

On page 102 you define add_patha and add_pathz but on the next page you use add_patha and add_path without a “z”. Maybe you could mention that add_path and add_pathz do the same job if it is the case.

2007-03-14
106SUGGEST

Exemple is:
$ chmod u+x hello.erl

But in the text below you say:
(on a Unix system give the command chmod a+x File)

This is not wrong but you might want to write it “u+x” instead.

2007-03-12
115TYPO

First sentence of section 4.9:
“The Erlang shell has a number of build-in commands,…”

Built-in would be better I think. However I am not a native english speaker.

2007-03-12
118TYPO

At the beginning of section 5.1:
“All we we have to do is add the following primitives:”

2007-03-12
119TYPO

At the bottom of the page:
“the message sending primitive ! returns themessage itself.”

There should be a whitespace.

2007-03-12
126TYPO

“Note: some of these of these are reserved, so your program cannot actually use this number.”

2007-03-12
54SUGGEST

birthday(#person{age=N} = X) ->
X#person{age=N+1}.

Is the corrected code, but this is still too dense for me at this point, and I couldn’t figure out how a pattern could have an ‘=’, I rewrote it for myself to make it more clear, I’m still unsure how ‘X’ is the whole pattern match in #person{age=N} = X, I guess the right side evaluates first as a pattern, and then the result against that goes to the next pattern

birthday(X) ->
#person{age=N} = X,
X#person{age=N+5}.

(Joe: written 2.5 pages on this !!!! - thanks for
pointing out that it was incomprehensible,
in retrospect I agree :-))

2007-03-23
26ERROR

Second paragraph under section “Syntax” reads “We can add more than one element to the beginning of X by writing
[E1,E2,..,E2|X]”

Shouldn’t that be something like “[E1,E2,..,En|X]”?

2007-03-12
228TYPO

In Section 11.3:
“This returns the IP address and Port of the other end of the connection, so the server can [something missing here] who initiated the connection.”

2007-03-12
215TYPO

maybe your web server will be bet-
ter than than the best.

2007-03-12
115TYPO

End of page: “By defining it as Pid! ! Pid2 !…”. Should be
“Pid1” (the earlier erratum did not explicitly mention this).

2007-03-12
26TYPO

occurances —> occurrences

last paragraph before 1.10

2007-03-12
34TYPO

first bullet point
clause. -> clauses.

second bullet point
does handle -> does not handle

2007-03-13
39TYPO

"When we

2007-03-14
45SUGGEST

In the gray box in the previous page you just said to rename the module name to avoid name clashing with the standard modules and in this page you present a module named “lists.erl” which obviously is gonna clash. Maybe something like “mylists.erl” is better

2007-03-14
51SUGGEST

A minor problem: "All the possible arithmetic expressions are shown in Figure 2.1. Each arithmetic operation has either one or two arguments

2007-03-14
61SUGGEST

The bulleted list at the top of the page says “list(T) is an alias for [T].” Because we’ve used T in so many places to identify the tail of the list, I was initially confused as to its use in this bullet.

2007-03-14
61SUGGEST

The bullet item for none() states “Strictly it’s not a type…” I believe this fragment needs a comma: “Strictly, it’s not a type…”

2007-03-14
61SUGGEST

In the middle of page 61, the text contains the line “@type newType() = TypeExpression.” When I first read this line, I thought it was introducing new syntax for the language. It was only after reading the note in the middle of page 62 that I realized this line was not valid Erlang.

2007-03-16
62SUGGEST

Item 5 states “…an instance of a predefined type is a type expression.” Because of my background in object-oriented terms, I was confused by an instance being described as a type. After continuing, I understood the phrase; however, “object purists,” perhaps like myself, might find this description confusing.

(Dave says: each area has its own jargon)

2007-03-16
62SUGGEST

I, too, found the explanation of types confusing. Perhaps, instead of presenting the abstract notation first, presenting a concrete example and then “dissecting” it would be clearer.

(Dave says: this will be clearing in the next major beta)

2007-03-15
65TYPO

The last sentence of the first paragraph after the list states: “The error is detected and the system….”. I believe this needs a comma like “The error is detected, and the system….” In addition, the next sentence states: “Failing this it tries to…” Again, I believe this phrase should have a comma: “Failing this, it tries to….”

2007-03-14
66SUGGEST

The phrase “…system raises an exception—this is the technical term for….” might be better as “…system raises an exception—the technical term for….”

2007-03-13
67SUGGEST

The last sentence before the new section starts with “If evaluating (catch Expr)…” When I read the sentence, I expected more detail.

2007-03-16
69SUGGEST

Earlier (page 65), in the justification for Erlang’s approach to exception handling, the text lamented having 30% overhead in code devoted to defensively handling arguments to functions.

When I read this code, I wondered, “How does this code differ from defensive programming in other languages?” If the example is to illustrate a point, I think it is important to note that (even in a footnote). If this code is typical Erlang programming style, then a better explanation of defensive programming on page 65 is in order.

(Dave says: have a look at the upcoming exceptions chapter)

2007-03-16
71SUGGEST

The text states “…was caught and corrected in g.” Perhaps “…was caught and handled in g.” might better communicate what happened. (Perhaps I’m being pedantic but I found it difficult to agree that returning 10 was “correct.”)

(Joe says: I’m going to totally remove this)

2007-03-13
72SUGGEST

The text uses the phrase “…message sent over a network etc and…” I was unclear what other things the “etc” might refer to in this paragraph.

2007-03-14
73TYPO

The phrase “ie” should be “i. e.”

2007-03-13
73SUGGEST

The next to the last paragraph states “…the shell will print the binary as a string, otherwise it will be printed as…” I believe a semi-colon is more appropriate with otherwise: “…the shell will print the binary as a string; otherwise, it will be printed as….”

2007-03-13
75SUGGEST

The fourth paragraph states “Then we’ll dive into the details of bit syntax expressions, and finally we’ll look at….” I believe the ideas might be more clearly suggested by two sentences: “Then we’ll dive into the details of bit syntax expressions. Finally, we’ll look at….”

2007-03-13
76SUGGEST

The text states: “…must be evenly divisible by 8.” Although the math is simple, I wondered if Erlang provided some way to pad a binary so that its total size was divisible by 8.

(Joe says: No, This is not possible)

2007-03-13
143TYPO

spawn_link(Fun) -> Pid
This exactly like spawn(Fun) but in a addition a link between the parent and child processes is created.

This IS ex…
and
but in addition…

2007-03-13
144TYPO

some computation, and something goes wrong. How can we identify

a comma or the “and”

and

non-normal exit reason, then all th…

no comma
(heavy duty technical errors here)

2007-03-13
16TYPO

The first sentence on the page says “…integer in a certain word size,” I believe the trailing comma should be a period.

2007-03-13
20SUGGEST

The first sentence in the new section states “…a bound variable is merely represented….” I’m unclear if the word “merely” is needed.

2007-03-13
21SUGGEST

The first sentence of the second paragraph states “In Erlang variable values….” I believe it needs a comma: “In Erlang, variable values….”

2007-03-13
21SUGGEST

In the fourth paragraph, the text states “So once we know which variable is incorrect then we can immediately….” It might be more understandable to read: So once we know which variable is incorrect, we can immediately…."

2007-03-13
21TYPO

The text states: “…how it’s possible to program without variables,” I believe this trailing comma should be a period.

2007-03-13
21SUGGEST

The last paragraph on the page states: “Don’t get confused here in line one the…” I believe its clearer to break this line into two sentences: “Don’t get confused here. In line 1 the….” (I used the digit for consistency with other line references.)

2007-03-13
22SUGGEST

The C code fragment reads:
if( ret == RET_SUCCESS ) {

Since the text elides part of the code, it might be better written on a single line:
if( ret == RET_SUCCESS ) { … }

2007-03-13
22SUGGEST

The last line on the page states: “…there are no macro definitions and….” Although the text is contrasting Erlang with other languages, a footnote referring reader to macros might clarify the distinction between macros and “macro definitions.”

2007-03-14
24SUGGEST

The text states: “If you use a variable in building a new tuple then the new tuple….” It might read better with a comma: “If you use a variable in building a new tuple, then the new tuple….”

2007-03-13
25TYPO

The text states: “In command 2 X is bound…” I believe it should read “In command 2, X is bound….”

2007-03-13
25SUGGEST

The third paragraph from the end of the page states: “…must both have the same number of elements.” I believe it might be clearer to state: “…must both have the same number of elements and corresponding elements on both sides must bind to the same value.”

2007-03-13
25SUGGEST

The last paragraph describes the behavior of Erlang when matching fails. It might be valuable, at least for readers familiar with Prolog, to contrast that Erlang considers non-matching an error instead of failing and back-tracking.

2007-03-13
27TYPO

The footnote reads: “In a pattern this syntax unpacks the CAR and CDR in an expression it constructs a CONS cell.” It might be more understandable to read: “In a pattern, this syntax unpacks the CAR and CDR. In an expression, it constructs a CONS cell.”

2007-03-13
205TYPO

Paragraph starting with “The main entry point”, 7th line in the paragraph,
s/trim the trim the/trim the/

2007-03-13
31SUGGEST

The text of the second paragraph states: “…we’ll return to the shopping list that we introduced in the last chapter and we’ll write some code…” It might read better with a comma like “…we’ll return to the shopping list that we introduced in the last chapter, and we’ll write some code….”

2007-03-14
31SUGGEST

The last paragraph of the opening section states: “…create your own control abstractions. Then finally we’ll talk about….” It might be better split into two sentences: “…create your own control abstractions. Finally, we’ll talk about….”

2007-03-14
33SUGGEST

The first paragraph states “…the body consists of a sequence of expressions, which are evaluated….” In previous places, the text has emphasized that Erlang is a functional language in which everything returns a value. Perhaps a footnote could indicate what is the result of evaluating a sequence of expressions?

2007-03-16
34SUGGEST

The first paragraph states: “…clause order does matter, and when a function is entered the clauses….” This sentence might read better as two sentences: “…clause order does matter. When a function is entered, the clauses….”

2007-03-14
40SUGGEST

All the functions described in the text calculate their result using a single expression. Can a fun evaluate multiple clauses?

2007-03-21
52SUGGEST

The next to the last paragraph states “…or the atom true.” I found myself asking two questions: “What would be the purpose of including true as part of a guard (since it is always true)?” and “What results if a guard includes the atom false?” I think a footnote to address those two questions might be useful.

2007-03-16
54OK

The first paragraph states “OR-guards are just AND-guards separated by semicolons.” Is the phrase “AND-guards” accurate? (I understood AND-guards to be guards separated by commas.) In addition, if the phrase “AND-guards” is inaccurate, the example “AG1; AG2; …; AGn” should probably be changed to “G1; G2; …; Gn”.

2007-03-21
53TYPO

The last sentence on the page reads “…head of the list L…” I believe the trailing ellipsis should be a period.

2007-03-14
53SUGGEST

The last paragraph in the OR-guards section states “The first guard means…” On this page, the last paragraph states “Line 1 means…” I find identifying the guards as first and second instead of referring to line numbers to be clearer.

2007-03-16
54SUGGEST

The first sentence of the Short-Circuit Boolean Expressions states “…only evaluated if necessary.” On reading this statement after reading about AND- and OR-guards, I wondered, “What is the default order for evaluating guards? Is it indeterminate? Are all guards ordered (even after the boolean value is determined)? What heuristics should a programmer employ to determine when to use a short-circuit expression versus other guards?”

I would find a “tip box” very helpful in answering these questions, but something I could skip if necessary.

2007-03-23
55SUGGEST

The third paragraph of the Records section states that record declarations can only be used in modules and not in the shell. The fifth paragraph states “Warning: -record is not a shell command…” These two references so close together seem redundant. Could the text either combine them into a single paragraph or remove one.

2007-03-14
56SUGGEST

The last paragraph describes how Erlang evaluates a case statement. On page 57, the next to the last paragraph describes an if statement and states “At least one of the guards…must evaluate to true otherwise…”

What happens if no patterns in a case statement match?

2007-03-14
57TYPO

The next to the last paragraph has the text: “…evaluated as follows: Firstly Guard1 is evaluated, if this….” I believe this sentence is clearer if written like: “…evaluated as follows: first, Guard1 is evaluated. If this….”

2007-03-14
57TYPO

The next to the last paragraph states: “If Guard1 does not succeed Guard2… is evaluated until a match is found”. I believe it is clearer if written: “If Guard1 does not succeed, Guard2 is evaluated, and so on, until a guard succeeds.”

2007-03-14
58TYPO

The third paragraph from the bottom has the text: ‘…build them in “natural” order, ie by appending elements to….’ I believe “ie” should be “i. e.,”

2007-03-14
58SUGGEST

The last sentence of the next to the last paragraph states: “If you look in the source code for the module lists you’ll find a definition of reverse, but the compiler ignores this definition and uses an internal version which is much more efficient that the version defined in Erlang.”

I’m confused by this sentence. I believe the text might be better written: “If you look in the source code for the module lists, you’ll find a definition of reverse. However, this definition is simply used for illustration. The compiler, when it encounters this definition, ignores it in favor of the much more efficient internal version defined in the OTP standard library.” (I believe the last terms are correct.)

2007-03-14
93TYPO

“In line 1 we pattern match the term {tag1, A, B} and line 3 we call f with”…

There should be an “in” before “line 3 we”.

2007-03-14
101ERROR

Control+C on Windows immediately terminates the shell rather than displaying a menu.

2007-03-24
217TYPO

There are some issues with the second last paragraph. “This is message is…” should probably read “This value is..”. Also, I’m a Erlang newbie, but isn’t the data fragment added to the head of the list rather than “appended”?

2007-03-14
222TYPO

The comment for line six says “The we encode…”

2007-03-16
64SUGGEST

You mention that spec and type are only found in documentation files, and are not part of the Erlang language. This should have been introduced earlier when you introduced the @type syntax. Furthermore, the justification/rationale for it not being part of the language (if any) should have been presented.

2007-03-15
64TYPO

Bullet point 3: “Type — A a type expression” has one too many a’s.

2007-03-15
65TYPO

“we represent by a name by a descriptive variable name” is messed up.

2007-03-15
76SUGGEST

At the top of page 76, explain where the number <<23,180>> comes from. Sure, it’s pretty obvious, but not everyone will get it.

2007-03-25
77TYPO

The sentence “This section has three examples from real life all the code here is cut-and-paste from real world programs.” is a run-on sentence.

2007-03-16
78TYPO

“Our our assumption was incorrect” is is incorrect.

2007-03-15
81SUGGEST

If you’re going to introduce macros on this page, you at least have to mention what the ?DWORD syntax means.

2007-03-18
82SUGGEST

Don’t assume that people know what IPv4 is, or even what IP is.

2007-03-24
83TYPO

“each Erlang process has a local area of the destructive storage” is ungrammatical. “of destructive storage” is probably what you mean.

2007-03-15
85TYPO

“Note that only exported function can be called from
outside a module.” should be “exported functions”.

2007-03-15
87OK

You talk about beam code on this page. Has beam code been mentioned before?

(Joe: yes - page 33 B1.6)

2007-03-24
88TYPO

In the box: “which return true or false” should be “which returns true or false”.

2007-03-15
90SUGGEST

What do you mean by a “conventional include file”? It’s not clear what include files buy you (if anything) that modules don’t.

2007-03-24
57SUGGEST

When I read the title of the section, “Building Lists in the Wrong Order,” I thought this section would describe some “natural” programming tendency to avoid.

In my first three readings, I was confused. The text kept telling me to build lists naturally and, if necessary, reverse them later. Because I would tend to do this anyway (perhaps my Lisp and Prolog familiarity), I kept wondering, “What am I missing?”

Finally, after my fourth reading, I understood it was telling me not to “fear” building a list “backward.” Simply build it efficiently backwards and reverse it at the end.

How could the section title change to avoid giving the impression that the “natural” approach is wrong?

2007-03-23
65TYPO

The last sentence on the page states “Open File which is string according to…” I believe it should read “Open File which is a string according to…” Another alternative, similar to the next API description might be “Open File (a string) according to…”

2007-03-15
34ERROR

Your C code should look like this, so it matches the Erlang version:

enum ShapeType { Rectangle, Circle, Square };
struct Shape {
enum ShapeType kind;
union {
struct { int width, height; } rectangleData;
struct { int radius; } circleData;
struct { int side;} squareData;
} shapeData;
};

double area(struct Shape* s) {
if( s->kind Rectangle ) { int width, ht; width = s->shapeData.rectangleData.width; ht = s->shapeData.rectangleData.height; return width * ht; } else if ( s->kind Circle ) {

Note the addition of a return type for the area() function, and the
addition of the return statement for the Rectangle area
calculation. Note also the consistent use of “height” for the
rectangleData member name.

2007-03-16
35SUGGEST

For the Java code, why not use “height” or “ht” for the
rectangle, rather than “length”, just to remain consistent with the
Erlang code?

2007-03-16
37TYPO

Apples and oranges cost 2 and 5 units, not 2 and 3 units.

2007-03-16
37TYPO

Footnote 6: change “claused” to “clause”

2007-03-16
138TYPO

The last sentence in the second-to-last paragraph reads: " (Note: process
<0.43.0> is process B, as it is process B that dies.)"

I really don’t understand what this is trying to communicate in any case, but isn’t the PID wrong (should be <0.44.0> instead of <0.43.0>)? There isn’t a <0.43.0> mentioned anywhere.

2007-03-16
139SUGGEST

The example in the middle of the page where process C is killed notes that the reason is changed from “kill” to “killed”. Indeed, the pseudo-code for the error handling presented a few pages earlier support this. No mention is made on page 139 as to why this is significant, however. Immediate questions that come to mind are:
1. Why does it work that way?
2. Should I care? Is it significant to an application programmer?

2007-04-13
140TYPO

Under “Exiting Another Process” the last sentence of the third paragraph reads " This is as a
safety measure to avoid accidently killing more of the system that you
had intended."

This should say “than you had indended.”

2007-03-15
161TYPO

Chapter 8, first paragraph: “So far we have see all the parts but not how to put the parts together.” This should read “So far we have seen…”

2007-03-16
121TYPO

Here are the results I obtained on the computer I

2007-03-16
126TYPO

Typo in footnote

2. io:format understands an extrememly large number of formatting options, the full set can be found in the io manula pages.

2007-03-16
162TYPO

Under “The Group Controller” it says “If a message is send the controller it broadcasts the message to all members in the group.” Replace “send” with “sent to”.

2007-03-16
163TYPO

"It

2007-03-16
163TYPO

Lots of grammar issues in this paragraph:

“The message sequence diagram, show the messages that result from a user typing an line into the io widget message entry region. This results in a message to the chat controller ©, followed by a message to one of the middle men (M1) this goes via M2 to the group controller (G).”

2007-03-16
164TYPO

“deign” -> “design”

2007-03-16
58TYPO

Just before 2.12: “uses a internal version” should be “uses an internal version” and “much more efficient that” should be “much more efficient than”

2007-03-16
59SUGGEST

The text starting from “Now we can write Erlang modules” doesn’t fit well with the text that precedes it. It sort of jumps out and surprises you. I suggest making it a separate section, just to set it off from the preceding topic.

2007-03-24
128TYPO

Spelling mistake in the last paragraph: “caclulation”

2007-03-15
215TYPO

In step 3, it currently reads: “This is message is one of the data fragments…” That should be “This message is…”

2007-03-16
215TYPO

In step 3, it currently reads: “The third argument in this tuple is a binary, this is because we opened the socket in binary mode.”

There are two distinct sentences there. Thus: “…tuple is a binary. This is because…”

2007-03-16
66SUGGEST

The first sentence of the last paragraph states: “The main reason why we don’t check for errors has to do with concurrency.” The remaining system talks about the separation of concerns in an Erlang system between “workers” and “supervisors.”

I do not understand how this separation of concerns (a good architectural and design principle) affects concurrency and how concurrency affects the way we handle errors.

2007-03-16
71TYPO

The third paragraph of the section “The throw() BIF” states: “…within some function F then the result of evaluating….” I believe this reads better with a comma like “…within some function F, then the result of evaluating….”

2007-03-16
72TYPO

The first sentence on the page states: “…in our earlier example, we might write”. I believe it needs a trailing colon: “…in our earlier example, we might write:”

2007-03-16
72SUGGEST

The code block at the top of the page defines total/1 and implements error handling by printing message, skipping the erroneous value and continuing processing.

How typical is this idiom in Erlang programming (since it seems very different from conventional wisdom today)?

2007-03-23
216SUGGEST

This actually spans from the last paragraph of 216 to the first paragraph of 218, ignoring the sidebar on page 217. This paragraph starts “1. We called connect(Host, Port, [binary. {packet,0}]) to connect to the…”

Basically, the paragraph describes the binary option again. This was already described twice before when the example was first presented. At this point, I’m really curious not about “binary” but about what other options are possible for this field. All the repetition starts to beg the question after a while (and is redundant).

2007-04-13
76TYPO

I believe that the last sentence of the next to the last paragraph, “If an item is omitted then a default value….” might be better written as “If an item is omitted, then a default value….”

2007-03-16
77SUGGEST

The text mentions the “endianness” of the machine. Does this mean that binaries written to the file system or to the network are suitable for moving to different processor architectures?

2007-03-24
77TYPO

The first sentence describing Unit states: “…Size x Unit bits long, this value must be….” I believe this fragment should be two sentences: “…Size x Unit bits long. This value must be….”

2007-03-16
77SUGGEST

The description of the unit specifier states: “…this value must be…a multiple of 8.” On my second reading, I found myself wondering: “What does ‘this value’ refer to? Must the Unit value by a multiple of 8? The total size of the binary be a multiple of 8? (Mentioned on page 76) Or must each segment be a multiple of 8?”

2007-03-24
78SUGGEST

The second sentence of the third paragraph states: “We use the information we find there….” It might read better written as “We use the information found at that position…”

2007-03-16
78SUGGEST

The fourth paragraph states: “…we first assume that we are correctly positioned at the start of an MPEG header then we try to compute….” I believe this might be better written as two sentences: “…we first assume that we are correctly positioned at the start of an MPEG header. We then try to compute….”

2007-03-15
79TYPO

The last paragraph states: “To catch any errors we wrap the call….” This might be better written with a comma: “To catch any errors, we wrap the call….”

2007-03-15
219ERROR

The discussion on “framing” says “TCP socket data is just an undifferentiated stream of bytes. During transmission this data can be broken into arbitrary sized fragments so
we need to know how much data represents a single request. Deciding how to break the input stream of data into logical packets is called framing.”

This is a really inaccurate description. “Framing” in a networking sense has nothing to do with anything at the application layer. Further, the socket API has nothing to do with how TCP data is actually represented on the wire. There is NOT a 1-to-1 correspondence between TCP sends or receives at the API with the packets that actually go out on the wire. The TCP stack is free to coalesce or fragment data that passes through the API before and after it interacts with the wire. The only guarantee that TCP and the sockets API make is that data will be received in order.

The next paragraph then says, “In the Erlang case we use a very simple form of framing and say that every logical data packet will be preceded by a N (1, 2 or 4) byte length count. This is the meaning of the {packet, N} argument in the gen_tcp:connect and gen_tcp:listen functions. Note that the arguments to packet used by the client and the server must agree. If the server was opened with
{packet,2} and the client with {packet,4} options, then nothing would work.”

It took me a while to understand that you were now talking about something very Erlang-specific — the transmission of Erlang terms over the network using an Erlang wire format — and that all this talk of “framing” now had to do with this Erlang-specific wire format. As a person who is well-schooled in the sockets API, this leap in context was not at all apparent. In fact, it was terribly confusing.

2007-03-25
80TYPO

The second paragraph on the page states: “…2 bits into B 2 bits into C etc.” I believe a comma is missing: “…2 bits into B, 2 bits into C etc.”

2007-03-15
81SUGGEST

The code block in the middle of the page uses macros to reduce the semantic gap for Windows programmers. Might the example be clearer by showing stepwise refinement leading to the macros? (I believe someone experimenting with the language for the first time would be more likely to not use macros immediately.)

2007-03-23
219ERROR

As a long-time datacomm networking guy, I object to the use of the word “packet” on pages 219 - 220 to refer to an application-level concept. At least for me, packets are the things on the wire. Perhaps, I’m being overly pedantic. I realize that there are too few words here to describe the concepts uniquely. I would normally propose “message” but that conflicts with Erlang’s language-level message sending/receiving terminology. Maybe “application message,” “protocol message,” “socket message,” or “request/response.”

2007-03-25
81TYPO

The last paragraph states: “Characteristics is a 16-bit word…” I it should read" Characteristics is a 32-bit word…" based on earlier definitions.

2007-03-15
82TYPO

The first paragraph states: “The code <> converted Characteristics which was an integer, into….” I believe it is missing a comma: “The code > converted Characteristics, which was an integer, into….”

2007-03-15
82SUGGEST

The third paragraph states: “Using these macros made unpacking the data in COFF format, well I can’t really use the word easy, bit at least it was possible and the code was reasonably understandable.” I believe it is more understandable written as: “Using these macros made unpacking the data in COFF format—well I can’t really use the word easy—but at least it was possible, and the code was reasonably understandable.”

2007-03-23
84TYPO

The first sentence states: “apply is used is circumstances….” I believe it should read: “apply is used in circumstances….”

2007-03-15
84TYPO

The last part of the first sentence reads: “…when the arguments to the function are not known in advance, but are computed dynamically.” I believe it reads better without the comma: “…when the arguments to the function are not known in advance but are computed dynamically.”

2007-03-15
85SUGGEST

The third paragraph states: “Calling abc:a(..) will result….” UML “aficionados” seeing a function call will ellipses assume it can take any arguments. Perhaps writing “Calling abc:a(5) will result…” will clarify the text.

2007-03-15
86SUGGEST

The text mentions a number of pre-defined module attributes, but it does not mention -record(…) which appears to have the same syntax. Is -record(…) not a module attribute?

2007-03-24
86SUGGEST

Page 85 states that -vsn is a pre-defined attribute. However, the shell output in the middle of the page seems to indicate that vsn is an user-defined attribute. Adding further to my confusion, the output on the printed page contained the term “{version, ”4.4.1“}” left-justified so I thought it was the version and wondered where the 4.4.1 had come from. Finally, when I executed this example in my local Erlang shell, I realized the {version, “4.4.1”} described the compiler (because the “pretty-printing” indented it under the compile term.)

2007-03-24
224OK

In section 11.2, “Control Issues”, what about non-blocking transmission of data? That is, how can I prevent a message send from blocking if the remote peer isn’t accepting data fast enough?

(Joe: This is not a book about
networking but about
Erlang. At some point I have to cut off the detail.
Digging deeper at the end of the chapter has some
\t reference that might be helpful)

2007-03-27
86SUGGEST

The text and code block describing how to automate extracting (beginning with “If we want to automate….”) the module attributes is better if it occurs after the next three paragraphs describing the shell interaction.

2007-03-24
87SUGGEST

The text states: “attrs:module_info(attributes) returns….” What other arguments does this function recognize?

2007-04-12
87SUGGEST

I found it difficult at this point in the text to understand how to use block expressions. Perhaps this topic is better introduced earlier in the book—perhaps via a sidebar or footnote.

2007-03-18
224SUGGEST

In section 11.2, “Control Issues,” it isn’t clear what setting {active, true/false/once} does for a gen_tcp:listen. Does that put the listening socket into a non-blocking mode? Or are listens always blocking? Does it simply set an option that is ignored by the listening socket but then inherited by every connected socket accepted from the listening socket?

There are multiple valid models to use here, but it isn’t clear from the description which one Erlang has chosen, or even if multiple models are supported by the Erlang API.

(Joe: This is not a book about
networking but about
Erlang. At some point I have to cut off the detail.
Digging deeper at the end of the chapter has some
\t reference that might be helpful)

2007-03-27
88SUGGEST

Since many popular languages today (for example, C, C, C#, Python, Ruby, Java, Perl) use short-circuit evaluation, I believe you need to discuss Erlang semantics of undefined evaluation order whenever you mention boolean expressions (and guards?) to keep reminding readers that the language may be different from the reader’s expectations.

2007-03-24
90OK

Earlier, the text discusses defining functions using simple expressions, for example, fun 2 * X end. Now, the text uses fun to refer to a compiled function.

Since some languages, like python, have very different performance characteristics when using these two different function references, do you want to mention any performance differences between these two uses?

(Joe: There are no perfomance issues here. Compiled funs
\t have the same performace characteristic no matter how they are referred to.
In general I don’t mention perfomance apart from where it
is important - like
the ets and dets chapter)

2007-03-24
91SUGGEST

The text states: “Variables occurring in macro definition match complete forms…” What is a complete form?

2007-03-24
91ERROR

The text states: “Thus it is not possible to use macros like the following:”

Actually, I entered these macros into a module and the call to foo/1 compiled and executed. I did need to change the definition of foo/l to the following:

foo(A) ->
?start a ?stop.

After compiling, executing foo(abc) in the shell produced the result {a}.

2007-03-24
92SUGGEST

The code block near the bottom of the page states: “…io:format(”TRACE ~p:~w ~p~n“…)” Although the text previously mentioned io:format(…), it has not explained the placeholders ~p, ~w and ~n. Perhaps we need to explain these symbols in a footnote with a future reference.

2007-03-24
92SUGGEST

The code block near the end of the page states “-define(TRACE (x), void).” Is void a built-in Erlang symbol? Does it mean “no-op”? Or is it simply an atom?

2007-03-24
92SUGGEST

The shell interaction at the bottom of the pages begins with compiling a module: “c(m1, {d, debug}).” I assume that the term following the module is a compiler option that defines the atom debug to the compiler. Is this understanding correct?

2007-03-24
94SUGGEST

Earlier, the text described the notation Var |-> Value to mean that Var is bound to (unified with) Value. In the description of put(Key, Value), it uses this same notation to describe the result of put/2. Is this an accurate description, or is it more accurate to say that Key is mapped to Value?

2007-03-24
95TYPO

The last paragraph states: “As you can see, variable in the process dictionary….” I believe the text should state: “As you can see, variables in the process dictionary….”

2007-03-15
95TYPO

The last sentence on the page states: “If you use the process dictionary then your code will no-longer be side-effect free…” I believe this reads better written as: “If you use the process dictionary, your code will no longer be side-effect free…”

2007-03-15
96SUGGEST

The last sentence of the first paragraph states: “For this reason the process dictionary should be used sparingly.” Might it be beneficial at this point to discuss the limited conditions in which using the process dictionary might have benefit?

2007-03-24
96OK

Figure 3.1 specifies escape sequences for entering octal character codes. Does Erlang, like C/C/C#, provide for escape sequences using hexadecimal codes?

(Joe: no - the text says “all possible ..” and this text is correct
you can’t represent hex in a string only octal)

2007-03-24
96SUGGEST

The last line of Figure 3.1 states that \\C is an escape sequence whose meaning is the ASCII code for C where is an integer code. I found this explanation confusing. Is C the integer ASCII code, for example “\\97” for the character “a”. (This does not appear to work in the shell.) Does this mean that if I supply a character, it will replace it with the (integer) ASCII value? Is it referring to a control character?

2007-03-25
96TYPO

The first sentence states: “…discussed in sect.non.dest.assignment.sect.non.dest.assignment…” This reference, I believe is a backward reference. Shouldn’t it resolve itself like other existing references?

2007-03-15
96SUGGEST

The description of orelse states: “This first evaluates Expr1 if Expr1 evaluates to true then Expr2 is not evaluated. If Expr1 evaluates to false then Expr2 is evaluated.” This description might read better as “This first evaluates Expr1. If Expr1 evaluates to true, Expr2 is not evaluated. If Expr1 evaluates to false, Expr2 is evaluated.” A similar comment applies to the explanation of andalso.

2007-03-15
97TYPO

I believe the phrase “…(A or B, and, A and B)….” is has an extra comma after the “and.” It should read “…(A or B, and A and B)….” (Tough call.)

2007-03-16
97TYPO

The second bullet describing conversions states: “…the arguments are use ”as-is" ie without conversion." I believe “use” should be “used.” In addition, I think the sentence might be better written as: “…the arguments are used ”as-is“; that is, without conversion.”

2007-03-15
47TYPO

Last paragraph in the grey box: "Once I

2007-03-16
99SUGGEST

The next to the last paragraph changes perspective. It first uses we then I. Although the tone is informal, might it be clearer in this paragraph if we use a single perspective?

2007-03-16
99SUGGEST

The next to the last paragraph states: “Now we’re actually through with sequential Erlang, there are a few small topics….” I believe this sentence is better split into two: “Now we’re through with sequential Erlang. There are a few small topics….”

2007-03-16
99SUGGEST

The last sentence states: “In the next chapter we’ll look at how to compile….” Might this be improved with a comma: “In the next chapter, we’ll look at how to compile….”

2007-03-16
224SUGGEST

Section 11.2, “Control Issues”: I looked through the rest of the chapter and there are several important TCP concepts that are missing or only touched on briefly:

1. Name lookup.

2. Address handling.

3. Non-blocking sends.

4. Half-close, which is imporant in some protocols.

5. Out-of-band (urgent data), which is critical in some protocols.

6. Socket options in general.

(Joe: This is not a book about
networking but about
Erlang. At some point I have to cut off the detail.
Digging deeper at the end of the chapter has some
\t reference that might be helpful)

2007-03-27
226SUGGEST

In section 11.3, “Where Did That Connection Come From?”, what representation does the returned address have? Is the returned address a string, an large undifferentiated integer, a tuple, or a binary? These would all be possible representations, some better than others in terms of usefulness.

2007-03-25
230SUGGEST

Section titled “Additional Notes on UDP”. There are a couple suspicious statements and possible errors in this section.

On the issue of UDP flow control, while a receiver cannot block a sender from sending, it can allow the UDP stack to drop the error rather than trying to receive it. In fact, after a point this is better than pulling UDP datagrams out of the UDP stack and queing them. If the receiver is really being overrun, it’s better to start dropping packets than to fill up all of process memory with queued packets and then die (whether you’re an Erlang process or an OS process). Thus, the idea of {active, once} and {active, false} UDP sockets actually makes a lot of sense.

Second, while it is possible for a UDP packet to arrive twice, it’s extremely rare in today’s networks. You might note some possible reasons for this in order to help readers accept that this is true. The basic issue is that because UDP is connectionless, there is no way for a receiver to distinguish between two identical datagrams sent by the sender versus a duplicate copy created accidentially in the network because of a hardware or software bug. Thus, the receiver must deliver all received, uncorrupted UDP datagrams to the application. If the application needs guarantees about ordering, removal of duplicates, etc., then the application programmer must create mechanisms to enforce those attributes on top of the raw UDP protocol.

(Joe: This is not a book about
networking but about
Erlang. At some point I have to cut off the detail.
Digging deeper at the end of the chapter has some
\t reference that might be helpful)

2007-03-27
55SUGGEST

I think the guards sections is a bit too brief. After reading it I was left with a number of unanswered questions:

1) Why do guards have their own syntax? Couldn’t they just be boolean expressions?

2) From the description of “andalso”/“orelse”, I assume “and” and “or” do not use short circuit evaluation but this is not explicitly stated.

3) Why use “;” and “,” when you could presumably use bracketed expressions with “andalso” and “orelse” to achieve the same effect?

4) “Finally, a guard can be used as an expression. It will always evaluate to one of the atoms true or false.”. Not sure what this means.

2007-03-23
130TYPO

Bottom of page 129, top of page 130:
“Such a processeS is called a registered process.”

2007-03-15
130TYPO

In the description of register BIF (top of the page):
“The registration fails if Name has already been used to register a processeS.”

2007-03-15
130ERROR

In the example, a message should be printed on stdout.

3> area ! {rectangle, 4, 5}.
{rectangle,4,5}

should be

3> area ! {rectangle, 4, 5}.
Area of rectangle is 20
{rectangle,4,5}

2007-03-15
235TYPO

‘.. anlayse it … ’ (in the got_request function) should be ‘.. analyse it …’

2007-03-16
131SUGGEST

Wouldn’t it be a good idea to place the following paragraph earlier in the book as io:format is used often before page 131 ?

"io:format(String, [Args]) prints the the variables in [Args] in the Erlang shell according to the formating information in String. The formatting codes are preceeded by a (~) symbol. ~p is short for

2007-03-24
132TYPO

“by” doubled.

“A tail-recursive function can be compiled so that the last function call in a sequence of statements can be replaced by by a simple jump to the start of the function being called.”

2007-03-16
135TYPO

I think a dot should end the sentence before the next section begins. Maybe it’s just a matter of style.

“The exit handler is in itself a very useful building block for constructing more advanced abstractions:”

2007-03-16
136TYPO

Paragraph just before section 6.3.

“evoked” should be “invoked”.

“The function that is evoked when the function dies can, of course, perform any computation it likes, it can ignore the error, log the error, or restart the application.”

2007-03-16
141OK

When I try the example, the message does not change to “killed” as written in the code. I don’t understand what is the meaning of that kill thing, even in the pseudo-code on page 138. Maybe i am just wrong.

Instead of
“Process a received {’EXIT’,<0.56.0>,killed} <— changed to killed

I have

38> edemo1:start(false, {die, kill}).
Process a received {’EXIT’,<0.115.0>,kill}
process b (<0.115.0>) is dead
process c (<0.116.0>) is dead
ok

(Joe: Cannot reproduce. I just re-tested this. I get exactly
the expected result. I see your output starts 37> …
the 36 commands you did before this might have influenced the result.
trying giving this command as the first thing you do in a new shell.)

2007-03-25
144TYPO

“Set up a monitor. Item is a Pid or a regisetered name of a process.”

2007-03-16
146TYPO

"To wind up this chapter we

2007-03-16
1SUGGEST

(not sure about the page number…) I would like it if there was a chapter on debugging an Erlang system, i.e. how to use the debugger tool (and maybe invisio also). The ability to debug a flawed program is essential for any programmer and introducing the tools to do this in Erlang would be a nice addition I think.

2007-04-25
185TYPO

‘the data send from’ should be ‘the data sent from’

2007-03-16
195TYPO

I don’t understand the command:

‘3> example1_lid:st ’

is it a typo?

2007-03-16
101ERROR

Control-C kills Erlang run from a command prompt in a command window. In the Erlang window created by Start > All Programs > Erlang OTP …>, Control-C has no effect. Control-Break produces the “BREAK” banner.

2007-03-24
101SUGGEST

The text states: “When you start programming in Erlang you’ll probably…” It might read better with a comma: “When you start programming in Erlang, you’ll probably…”

2007-03-16
101SUGGEST

The text says “The Erlang run-time system makes use of a code auto-loading mechanism.” Although the term “auto-loading mechanism” may be understood by current Erlang programmers, other programmers may be more familiar with the idea of a “search path.” Perhaps the text might be improved by stating: “The Erlang run-time system makes used of a search path to support auto-loading of requested code.”

2007-03-24
101TYPO

The last sentence states: “…is actually programmed in Erlang and we’ll talk more….” I think it may read better with a comma: “…is actually programmed in Erlang, and we’ll talk more….”

2007-03-16
102SUGGEST

The first paragraph describes how Erlang tries to find the object code file for a missing module by searching all directories in the current load path. As I read this, I wondered, “Does this search stop at the first matching file, or does it find all matches? If it finds all matches, which match does it choose?”

2007-03-16
102TYPO

The text states: ‘Code loading is performed “on-demand”.’ I believe the period and closing quotation mark are transposed: ‘Code loading is performed “on-demand.”’

2007-03-16
102SUGGEST

The text states: “…in a module which has not been loaded then an exception occurs….” This might read better replacing the “then” with a comma: “…in a module which has not been loaded, an exception occurs….”

2007-03-16
102SUGGEST

The text describes the two most common functions to manipulate the load path. As I read the description, I wondered, “What advice would you give a learner/beginner on deciding between these two functions?”

2007-03-24
102SUGGEST

Ah, the Windows “home” directory. Although the home directory is well-known in Unix, Windows has many personalities. (And it varies by Windows version!). Many programs respect the Unix HOME variable set in the Windows environment. Other programs seem to use HOMEDRIVE + HOMEPATH.

I don’t know if you want to discuss these vagaries in a sidebar at this point, or if you want footnote a future reference to init:get_argument/1 so that a poor Windows user knows where to put the .erlang file.

2007-03-24
102SUGGEST

The text describes starting Erlang with a command line to supply additional search path directories. This works if one invokes Erlang from a command prompt; however, if invoking Erlang using the Windows shortcuts, you must edit the properties of the short cut to supply new options.

The requisite magic under Windows is “Start > All Programs > Erlang OTP …” Now right-click the Erlang menu item and select Properties. On the Shortcut tab the Properties dialog, edit the Target field to include the new search directories. However, to avoid destroying the original shortcut, you may want to copy the original link at first.

“Curiouser and curiouser,” said Alice.

2007-03-24
205TYPO

‘Tagging program often appear’ should read ‘Tagging programs often appear’

2007-03-16
103SUGGEST

The “Tip” near the bottom of the page describes how to discover what Erlang thinks is its home directory.

Can I do anything to affect that decision? (I prefer not to put these kinds of files in my Windows “home” directory if I can avoid it.)

2007-03-24
103TYPO

The text states: “Alternatively you can run your program directly…” It might read better with a comma: “Alternatively, you can run your program directly…”

2007-03-16
158SUGGEST

Some more info on how cookies work would be nice. Are they sent across the network in the clear, or are the cookies encrypted first? Are they used to encrypt all communications?

2007-03-26
158TYPO

“This file is automatically created the first time Erlang is run on your machine it contains a random string.” doesn’t flow very well.

2007-03-16
104ERROR

The code at the bottom of the page may execute correctly under Unix, but it fails on Windows unless the user has set the PATH variable to include the directories containing the Erlang binaries.

An alternative to setting the PATH variable on Windows is to invoke the commands using a fully qualified path:
“C:\\Program Files\\erl5.5.3\\bin\\erlc.exe” hello.erl
“C:\\Program Files\\erl5.5.3\\bin\\erl.exe” -noshell -s hello start -s init stop

(And, yes, for this path, you need the quotation marks.)

2007-03-25
105SUGGEST

The text says: “…has three component parts:” Might it be better to say: “…has three options:”?

2007-03-24
105SUGGEST

The text states that the two -s options cause Erlang to run the functions hello:start/0 and init:stop/0. When I read this description, I wondered: “Can I supply more than two -s options? Does it execute all the functions in the order supplied on the command line?”

2007-03-24
211TYPO

’ to include file,hrl which contains’ should read ’ to include file.hrl which contains’

2007-03-16
105SUGGEST

The text states: “To run the shell script we chmod the file…” This step is necessary for Unices (and cywin). In a Windows environment, one creates a batch file (.bat), the #! trick does not work (although it is ignored), and one must use the full pathname to the binaries if the path is not set.

For example, my batch script is:
#!/bin/sh
“C:\\Program Files\\erl5.5.3\\bin\\erl.exe” -noshell -s hello start -s init stop

2007-03-24
106TYPO

The text in the sidebar states: “When you’re developing code it’s a bit of a pain….” It might read better with a comma: “When you’re developing code, it’s a bit of a pain….”

2007-03-16
107SUGGEST

The code for module fac1.erl in the middle of the page mentions a function named main/1. To avoid confusing us poor C/C/C#/Java programmers, you might want to clarify that this name is simply used for familiarity (by us!) and could be anything.

2007-03-19
108SUGGEST

The text states: “I’m not going to explain makefiles in general.” You may want to reference another book or a hyperlink which provides readers unfamiliar with makefiles at all to gain some information.

2007-03-24
108SUGGEST

Although another reviewer mentions that you do not need the target for .yrl files, if you decide to include it, you may want to add a comment about it since the text has not mentioned these types of files yet.

2007-03-24
108OK

The Makefile.template file might be suitable for Unix; however, it failed to execute using nmake (the incarnation of make provided by Microsoft for the Windows world). It first failed because the module line “…” did not have a trailing \\. It then failed on the compile line.

You may need to provide two different Makefile templates: one for Unix and one for Windows (sigh… so much for standards adherence).

(Joe: No instread I’ll show you how to setup MSYS and MinGW that understand
GNU Makefiles)

2007-03-24
109SUGGEST

Line (1) describes a special target. The text later says that “…some modules need special treatment (for example the module special1 in the template file), so there is a separate rule to handle this.”

Although make gurus will understand that a module only needs one target describing how to build it, make novices may not so a comment before the target in the makefile template might be worthwhile.

2007-03-24
110OK

The second and third paragraphs give a quick, gentle introduction to makefiles. I think it is beneficial to move this description before the details of the makefile template. This positioning will help “makefile newbies” more effectively “grok” the use and purpose of a makefile.

(Joe: elsewhere I usually start with the example and then explain
\t it - this seems ok here as well)

2007-03-24
109ERROR

The subdirs target has two references to dir1. I believe the first reference should be dir1 and the second reference should be dir2.

2007-03-18
111SUGGEST

If a reader has been entering commands in the Erlang shell while following the book, the advanced editing commands described here would have been very useful to have been described earlier when introducing the shell.

2007-03-19
111SUGGEST

The last bullet point describes how to kill the Erlang monitoring process. Although I might be able to find this process on Unix, I’m not even certain what process I would be looking for in Windows.

2007-03-24
113SUGGEST

The word “spelt” is a chiefly British spelling. I’m not certain how you plan to handle British versus American spelling (“spelled”).

2007-03-16
114SUGGEST

Another common problem I have encountered as a “newbie” Erlang programmer: I put periods between function clauses instead of semi-colons resulting in a duplicate function error.

Although it’s simple to fix, it takes getting used to.

2007-03-24
115SUGGEST

The text describes a number of useful commands for the shell. If one is familiar with an interpreted environment, one easily “groks” that these functions return Erlang terms which can be operated upon by other Erlang functions (such as filtering the history list to only review the history item(s) you are interested in). However, if one is only familiar with (most) compiled environments (C/C/C#/Java), it may be unclear how to utilize the information returned by these (and other) “introspective” functions.

A sidebar describing that the results are just Erlang terms (and not simply a “printout”) might help developers understand how to better use these commands.

2007-03-24
119TYPO

The text in the middle of the page states: “In line 3 we sent a message….” The text should state: “In line 6 we sent a message….”

2007-03-18
119TYPO

The next to the last sentence on the page states: “…primitive ! returns themessage itself.” It should read “…primitive ! returns the message itself.”

2007-03-16
121TYPO

The text states: “…the message is usually called a client and the process which….” I believe it reads better with a comma: “…the message is usually called a client, and the process which….”

2007-03-16
122TYPO

The text states: “…from the server it will mis-interpret this message….” I believe mis-interpret is not hyphenated. In addition, I believe it reads better with a comma: “…from the server, it will misinterpret this message….”

2007-03-16
34TYPO

First bullet point reads “The function area is made up of several dif ferent clause.” It should be “clauses”.

2007-03-16
25TYPO

Slight typo, this:

and so the shell prints out {point, X, Y}.

Should read:

and so the shell prints out {point, 10, 45}.

That is, the shell prints out 10,45 not X,Y.

2007-03-16
39TYPO

extra trailing ) in first paragraph of section 2.3

2007-03-16
138ERROR

The pseudo code for EXIT handling is wrong.
When not trapping exits all non-normal exits lead to death. Processes that trap exits die if ExitReason==kill.

if ExitReason normal then continue; else if ExitReason kill then
broadcast the exit signal “killed” to
all processes in my link set
then die;
else
if process_flag trap_exit == false then
die;
else
add the message {’EXIT’, Pid, ExitReason}
to my mailbox
end
end

2007-03-25
138SUGGEST

Add a lines or two about the special exit reason ‘kill’, and why it is changed to ‘killed’ when propagated. ‘kill’ is untrappable (even when trapping exits), but the propagated signal must be trappable; otherwise, supervision wouldn’t work.

2007-03-25
153ERROR

“doris $ erl -name gandalf -cookie abc
(gandalf@doris.myerl.example.com) 1> kvs:start().”

This is actually wrong. It should be -setcookie abc
The reason why it works for you may be that you have a
$HOME/.erlang.cookie file that happens to be the same on both computers. The flag -cookie is obsolete and has no effect, according to the manual (why is it allowed then?)

2007-03-18
153SUGGEST

“When we have two nodes on the same machine we use “short” names (as indicated by the -sname flag), but when they are on different machines we use -name."

Actually, -sname works fine even across machines, as long as they are on the same subnet. Using -sname across machines is also the preferred (only?) option if there is no DNS service.

2007-03-26
154SUGGEST

Re. how to get the same version of the code running on all nodes, there is a very nifty shell command for doing this: nl(Module) will load Module on all connected nodes (make sure they’re connected first, through use of ping/1, for example)

2007-03-26
155SUGGEST

“All the nodes in a distributed Erlang system must have been started with the same magic cookie.”

This is not entirely correct. It is possible to use erlang:setcookie(Node,Cookie) to configure each individual connection. If NodeA has cookie “cA” and NodeB has cookie “cB”, then NodeA must call erlang:set_cookie(NodeB,“cB”), and NodeB calls erlang:set_cookie(NodeA,“cA”). Then, they can connect, even though they have different cookies.

2007-03-26
64SUGGEST

On the try … catch syntax:

“try Func of
Pattern1 -> Expressions1;
Pattern2 -> Expressions2;

catch”

Rather than just Func (which of course works), the construct actually allows a sequence of expressions, as evident in the yecc grammar:

try_expr -> ‘try’ exprs ‘of’ cr_clauses try_catch :
\tbuild_try(line(‘$1’),‘$2’,‘$4’,‘$5’).
try_expr -> ‘try’ exprs try_catch :
\tbuild_try(line(‘$1’),‘$2’,[],‘$3’).

The Erlang Reference Manual doesn’t mention this, and it’s (unsurprisingly) not widely used.

2007-03-23
67OK

You could perhaps specifically mention the fact that, using try … catch, we can pattern-match exactly those errors that we want to catch at each level. This is not possible with old-style catch, which catches everything. With try, we can catch a specific throw(), for example, and let default error handling handle the errors. This is a very useful feature.

2007-03-21
104SUGGEST

This point can be driven home with a special Warning sign. Since _Var is a normal variable, very subtle bugs can be caused by forgetting this and using it as a “don’t care” pattern. In a complicated pattern match, it can be difficult to spot that e.g. _Int is repeated when it shouldn’t have been, causing the pattern match to fail.

2007-03-24
160SUGGEST

While I’m a big supporter of using funs in spawn commands, I think you should mention spawn[_link](Node,M,F,A). There are good reasons to use it in the distributed case, e.g. when the different nodes aren’t necessarily running the same version of a particular module. spawn(Node,Fun) can break in certain situations where spawn(Node,M,F,A) will work fine.

2007-03-26
224TYPO

“One of the most well-know and possibly the best is wireshark”

Should be “well-known”.

2007-03-18
36ERROR

In the Rectangle class, change

final double length;

to

final double ht;

to match the rest of the code.

2007-03-18
249TYPO

“When we’ve finished with a table we can dispose of it with dets:close(TableId) or ets:destroy(TableId).”

It should be “ets:delete(TableId)”

2007-03-18
227TYPO

There

2007-03-25
230SUGGEST

with respect to Dave Roberts I don’t think you can
duplicate even a small part of Stevens on TCP in a
book on erlang, if the correspondence with the commonly
document C equivalents is clear that should be enough.
If more pages are available please use them on OTP.

(Joe: This is not a book about
networking but about
Erlang. At some point I have to cut off the detail.
Digging deeper at the end of the chapter has some
\t reference that might be helpful)

2007-03-27
70SUGGEST

Could you describe how to interpret the stack trace output? And maybe the best way to use the stack trace output as part of debugging?

It would be very helpful for Erlang newbies like myself. Thank you.

2007-03-23
77SUGGEST

You should explain why BIFs do impossible things. The book says: BIFs are functions which are built into Erlang. They usually do things
that are impossible to program in Erlang.

I assume the reason is because of side effects.

2007-03-23
252TYPO

In 14.4 “public
Create a public table. Any process which knows the table
identifier can read and write write this table.” - duplicated “write”.

2007-03-18
254TYPO

“To write our iterator we need a massive world list.” - “world” should be “word”.

2007-03-19
13SUGGEST

Installing on Mac OS X - two points:
1) I haven’t found installing MacPorts scary - there is a proper package-based step by step installer.
2) MacPorts build from source, taking dependencies into account. If the reader doesn’t already know this, he/she will be given the impression, by the way you put “Building Erlang from Source” in the next section, that MacPorts are binary.

2007-03-23
168TYPO

"In this chapter *we

2007-03-18
169TYPO

The refernce to the figure (10.1 I guess) isn’t correct.

2007-03-21
170TYPO

The first sentence of “10.1” doesn’t make much sense:

1. The reference to 10.2 should probably be in parens. It can’t be part of a sentence like that.
2. “resulting” should be “result”

2007-03-26
34SUGGEST

Please give a sidebar covering the use of pwd() and cd() (including the fact that forward slashes are always used, even on Windows). Hiding the information in an appendix is a bad idea. Footnote 3 says "If you have downloaded the code you

2007-03-23
16SUGGEST

The lines:

"Warning

2007-03-23
22TYPO

In the line

“To understand why this is true we must ask ourselves what an error is, and how an error makes itself known?”

the ? at the end should be a period.

2007-03-18
22SUGGEST

In the line:

"If I

2007-03-21
24SUGGEST

The lines:

"So, for example, if you want to represent someone

2007-03-21
28SUGGEST

In the discussion of lists, it might be worth pointing out that [H|T] is still a valid value even if T is not a list. You say that in this case [H|T] is “improperly formed” which makes it sound like an error, which it isn’t. I like the term “improper list”.

2007-03-21
252TYPO

“Name is an atom. [Otp] is a list options, taken from the following:”
Otp should be Opt.

2007-03-18
253TYPO

in the gray box: “Anybody know know the name of the blackboard can read the
blackboard, but only the owner can write on the blackboard.” should be “Anybody who knows the name …”

2007-03-19
253TYPO

“Note: An Ets tables which has been opened in public mode can
be written and read by any process that knows the table name.
In this case it the user must ensure that reads and writes to the
table are performed in a consistent manner. ” - ‘tables’ should be ‘table’ and remove ‘it’.

2007-03-18
253TYPO

“Note: opening a Ets table with zero otions is the same as opening it with
the options [set,protected,{keypos,1}].” - otions should be options.

2007-03-18
262TYPO

“Finally, Ets and Dets tables were origonally designed to be used to
implement Mnesia.” - origonally should be originally.

2007-03-18
262TYPO

" We havn

2007-03-18
24TYPO

“Atoms can also be quoted. Using the quoted form we can create atoms that start with an uppercase letters…” - delete “an” before “uppercase letters”.

2007-03-18
16SUGGEST

It is good that you point out, on this page, that the shell has powerful features, and refer the reader to a later chapter. It would be even better if you gave the information that’s immediately of value right here: that you can bring back previously entered lines for editing using up-arrow or Ctrl-P.

2007-03-21
29SUGGEST

You write “Sometimes we want to know which integer represents a particular character” to explain why we might write [$S,$u,$r,$p,$r,$i,$s,$e] instead of [83,117,114,112,114,105,115,101] (or “Surprise”). That seems strange - do you mean “You don’t have to know the integer representation of a particular character; you can use $a to represent the character ‘a’, etc.”?

2007-03-23
61TYPO

Erland should be Erlang in the first sentance.

2007-03-18
63SUGGEST

You introduce the acronym BIF on paragraph 2 without ever explaining what a BIF is or what BIF stands for. On page 53 you use the term built in function but you don’t introduce the acronym BIF until page 77.

2007-03-23
64TYPO

The code following the after keyword is used to for cleaning up after Func.

Shold Be:

The code following the after keyword is used for cleaning up after Func.

2007-03-18
75TYPO

namedoc@type@author should probably have commas inserted between the tags.

2007-03-18
75TYPO

Remove the duplicate a’s in:

The module edoc exports a a large number of functions

2007-03-18
75TYPO

Change “contained” to “containing” in the last paragraph.

2007-03-18
31TYPO

“so we now we can step up” I think the first we is not necessary :)

2007-03-18
254TYPO

“Make a iterator” should read “Make an iterator”

2007-03-19
252TYPO

“Ets tables are c reated by” should read “Ets tables are created by”

2007-03-18
67TYPO

Just above section 3.5, change “loose a lot of precision” to “lose a lot of precision”.

2007-03-18
67OK

Given that this chapter is about exceptions, in section 3.5, wouldn’t it be better if the example in this section caught an exception and used erlang:error to print a more meaningful error message?

(Joe: erlang:error does not print an error it raises an exception)

2007-03-23
69TYPO

In section 3.7, first sentence, change “ideom” to “idiom”.

2007-03-18
69TYPO

In the last sentence on the page, there’s an extraneous double quote just before the word “instead.”

2007-03-18
71TYPO

In “a way of talking about Erlang soure” change “soure” to “source.”

2007-03-23
74SUGGEST

Do not say “Five BIFs” but “The following” or something like that. There are more, for example binary_to_list, that should be mentioned here.

2007-03-23
78OK

“You’ll find a full list of all BIFs in the erlang manual page in your Erlang distribution or online at … www.erlang.org/manual/erlang.html.”

The target of the URL does not exist

(Joe: this will be corrected)

2007-04-17
100TYPO

Examples of integers: 32#wow gives an illegal integer error.

36#wow gives the value listed in the next line.

2007-03-18
230SUGGEST

The code for start_parallel_server spawns a fun to do the listening, while the sequential version does not.

My understanding is that you are trying to show how to handle the parallel processing of a request. I think the initial spawn confuses the issue, since the spawn in par_connect(..) causes the parallel processing to take place. [Unless I have misunderstood something ..]

2007-03-25
225TYPO

2. We wrote the code…
When all the fragment[s] have arrived and the socket is closed
we reverse the list and concatenate all the fragments.

2007-03-19
53SUGGEST

“All the guard predicates are shown in Figure 2.2, on the following page and the guard term comparisons are shown in Figure 2.3, on the next page.” — this way seems the figures are in two separate page but they are on the same. So I guess “are shown in Figure 2.3, on the same page.” is more correct

2007-03-24
42TYPO

10> needs a period at the end.

2007-03-18
42SUGGEST

After 14> (the code block), the two paragraphs basically say the same thing, i.e. programming this way leads to short, easy to understand programs.

2007-03-18
42TYPO

“Programs that use operations like map and filter will lead to programs which are short and easy to understand.” and a few lines after “Using list-at-a-time operations makes our programs small and easy to understand;”. Maybe you want to eliminate one of those, it’s a repetition …

2007-03-18
14TYPO

Getting Started, 1.6 “Variables”, pp 14 of 24, from PDF excerpt

“we know that X+Y=10 and X-Y=2, then X will be 6 and Y will be 2 in both equations.”

be 4 in both equations.

2007-03-18
14TYPO

Getting Started, 1.6 Variables, pp14 of 24, PDF Excerpt.

“Lhs = Rhs really means: evaluate Rhs then match the result again the pattern Lhs.”

result against the pattern Lhs.

2007-03-23
14TYPO

Getting Started, 1.6 Variables, pp14 of 24, PDF excerpt.

“Now a variable, such X, is a very simple form of pattern.”

such as X

2007-03-23
40SUGGEST

The sentence “They have
nothing to do with each apart from a co-incidental use of the same
name.” should probably read “They have
nothing to do with each other apart from a co-incidental use of the same
name.”

2007-03-21
135TYPO

The word process (which is split with the previous page) is misspelled as “processe”.

2007-03-23
41SUGGEST

“5> Hypot= fun(X, Y) -> math:sqrt(X*X + Y*Y) end.” doesn’t follow the convention that the other pattern matching statements seem to use… “Hypot=” should probably read “Hypot =” (with a space before the equal sign) to match your other examples.

2007-03-21
42ERROR

“10> Even = fun(X) -> (X rem 2) =:= 0 end” is missing the dot after the word “end.”

2007-03-21
57TYPO

Last line: “If non …”. I think it’s none, not non.

2007-03-23
61TYPO

Last sentence: “that wil make your life easier.” it should be “will”.

2007-03-23
80TYPO

The example shows that “Mem = <<Red:5, Green:6, Blue:5>>.” produces <<23,180>> but the text states that the shell prints the result as <<23,189>>.

2007-03-23
81TYPO

In the sentence “Size must be an an expression which evaluates to an integer” change “an an” to “an”.

2007-03-23
165ERROR

In the server code configuration file the service is called ‘nameService’ while in the rest of the example it is called ‘nameServer’.

2007-03-19
53ERROR

In the sentence at the top of page says “Guards can be used …, or they can be used at any place in the language where an expression is allowed.” This is NOT true for OR-guards forms, they can only be used in proper guards. The short circuit boolean are equivalent in this case and can be used everywhere.

2007-03-24
53SUGGEST

Should you mention the old forms of the guard predicates, those without is_? While they shouldn’t be used people might run into them in old code. Not worth more than a short comment or footnote though.

2007-03-23
200TYPO

In the sentence “A socket provide a stream of bytes between two applications how these applications interpret these bytes is up to the application.” shouldn’t there be a comma between “applications how”?

2007-03-19
6SUGGEST

(This is not specific to this page, but is general to the whole book — I put it here because it’s the first page in the PDF that allows you to report errata.)

There are many sentences in the book in which you use the word “which” when you should really use the word “that.” See the Chicago Manual of Style for an explanation:

www.chicagomanualofstyle.org/CMS_FAQ/Whichvs.That/Whichvs.That01.html

I suppose the copy editor will fix these, but in my experience it’s better to get them right yourself rather than relying on copy editors to do it for you.

(Joe: I’m Englishman - but you’re right.
The publisher says it should be US spelling
and usage - and we’re working at it.
I learn’t in school that 95% of the
time “that” should be replaced by “which”.
Somewhere along the line these problems
will be fixed either by my or later
with the help of the copy editor. Right
now I’m concentrating on the technical bugs)

2007-03-23
33ERROR

This bit:

“”“In the Java code an instance of a circle is created by code in the Circle class, but in Erlang circles can be created anywhere in the code.”“”

Doesn’t really make any sense to me. I can say “new Circle(4.0d)” anywhere. You could argue that it’s possible to have functions that extend circle/square/rectangle anywhere, and that would make a little more sense, but with Erlang’s type system, those seem more like the equivalent of static methods on a utility class than extensions of the type. (If this was Haskell, I think your point would be made by the ability to make pre-existing types instances of a type class.)

2007-03-21
190TYPO

In the second dot point you refer to the “byte sequence [1, N]” and you say “the 1 means call the function sum” but this dot point is talking about the twice function.

The third dot point has you encoding “sum” as [2,N,M} instead of [2,N,M].

2007-03-19
195TYPO

Where do example1_lid and ifconfig come from in the MODS line of the Makefile?

2007-03-26
222SUGGEST

On 13.1 Using TCP, you show a simple http client example. Wouldn’t it be nice to tell readers that there is a more sophisticated http client implmentation already in the library? (e.g. http:request(“”).

2007-03-24
143ERROR

The way I read the pseudocode description of receipt of exit signals, it looks like system processes do not receive messages corresponding to normal exits of linked processes. I’m pretty sure that’s wrong.

(Joe: I’ve added more explanation)

2007-03-25
188TYPO

signifance

2007-03-20
124SUGGEST

The last paragraph seems disjoint to the page. I think it should be moved to section 7.1 since it seems a bit more appropriate there.

2007-03-24
125TYPO

Are there supposed to be line numbers in the statement “(lines to )”?

2007-03-24
127TYPO

Should have a space between } and Pid in {Pid, Reply}Pid.

2007-03-20
135SUGGEST

It might be a good idea to mention that Name is an atom. Otherwise someone (like me) may try to use a string.

2007-03-23
197TYPO

Typo: “effect” should be “affect” in “Any fatal error in the linked-in driver will crash the Erlang system itself and effect all processes in the system.”

2007-03-20
137SUGGEST

I really think that tail recursion should be introduced much earlier. It is an important concept to know about from teh get go.

2007-04-13
34TYPO

Footnote 2: “Epressions” should “Expressions”

2007-03-21
95TYPO

First line: “Epressions” should be “Expressions”?

2007-03-23
57TYPO

“If non of the patterns match then an exception is raised.” should be “If none of the patterns match then an exception is raised.”

2007-03-23
140TYPO

Drop “too” in the following sentance in Paragraph 2:

If a process linked to a system process exits for some reason, the system process is not automatically terminated too.

2007-03-23
140TYPO

Drop the comma in the following sentance in the 4th paragraph:

The exit handler is a process that evaluates a particular function, when some other process crashes

2007-03-20
95TYPO

The sentence toward the end of the page: “In we wish to call a function ….”, should read “If we wish ….”.

2007-03-20
95TYPO

At bottom of page the example code:

double(L) -> lists:map(fun x1:square/1, L).

with explanation:

fun x1:square/1 means the function lists/1 in the module x1.

The explanation should read:

fun x1:square/1 means the function square/1 in the module x1.

2007-03-23
53OK

In the discussion about lists: “this is very inefficient and only acceptable if the list is very short, and if this is not done in a loop.”

This is worth clarifying, since it will throw those new to FP. A list is a value composed of two values, one for the head element and one of the list that is the tail. Adding an element to the end of the list means that you’re changing every tail value that makes up the nested structure of the list!

(Joe says:this is too much detail at this point in the book)

2007-03-21
154TYPO

Distributed Erlang

2007-03-20
154TYPO

a minor one :) it should be “U” in the text below

"Socket-based distribution

2007-03-20
158TYPO

“Before we do this we start two terminal windows on the on the two different machines.”

2007-03-23
78SUGGEST

This bit syntax stuff seems to come out of nowhere. You need to provide a far better up-front explanation of exactly why anyone would care about it, why it’s in the language, why it’s useful, etc. It reminds me of C/C bit fields, a feature typically used only by programmers dealing directly with hardware or OS kernel structures.

2007-03-24
1SUGGEST

I think it’d be good to highlight how to find and share code libraries for and in Erlang.

The book includes great coverage of Erlang-proper, but I’m coming from the land of .Net, Java, and Python, and it’s pretty discouraging to think I might need to write the millionth HTTP library.

Is there something like Ruby’s rubyforge or Python’s Cheese Shop? If not, there should be, and this book would be a great chance to introduce it.

I suspect you will sell a lot of this book, but my concern over libraries tempers my interest in the language.

(Joe: Read about CEAN page 1.2 (this (we hope) will be like
CPAN or CTAN) also there will be a resources appendix)

2007-03-23
170TYPO

In description of the Chat Server (S), “The group server is a single process” should be “The chat server is a single process”

2007-03-26
12TYPO

“On a windows system” should read “On a Windows system”. (section 1.2 below first code example).

2007-03-23
28TYPO

"Most of the library function assume that lists are properly formed and won

2007-03-21
229ERROR

The code listing for the function seq_loop/1 in the Sequential Server ends the initial line for the function declaration with “,” instead of “->”

2007-03-24
20SUGGEST

Variables X and Y are being reused in expression 2. By this point, the reader has not been informed that he can forget the bindings with f(), and it was suggested on p10 that the reader enter the examples exactly as they appear in the text.

2007-03-23
117TYPO

glurk:oops(1,23).
The indentation of the error message is not correct.

2007-03-24
120TYPO

“All these commands are define”. Should be “defined”.

2007-03-24
72SUGGEST

One should not confuse deep character lists as recognized by io_lib:deep_char_list() with I/O lists (which can contain binaries). iolist() is explained in erlang(3).

2007-04-17
75TYPO

“or even, @spec file:open(string(), mode())”. Should be “[mode()]”.

2007-03-24
261TYPO

“binary(FileName)”, “integer(Index)”. These guards are deprecated. Use “is_binary” and “is_integer” instead.

2007-03-24
261SUGGEST

“ok = dets:insert(”. Perhaps test if lookup() or insert() returns an error tuple.

2007-03-24
260OK

“ok = dets:insert(”, “ok = dets:close(”. “exit(eEtsOpen)” should perhaps be something else.

2007-03-25
260SUGGEST

dets_file() -> this_dir() “/filenames.dets”.
could be
dets_file() -> filename:join(this_dir(), “filenames.dets”).

2007-03-24
157TYPO

…“open two terminal windows and start two Erlang systems:”
Should be “…systems.” (a dot).

2007-03-24
158TYPO

“As we can we can see the program works…”

2007-03-24
158TYPO

“…the client is running in one node and the server running in a different node.”. The phrase “on a node” has been used more often in the text.

2007-03-24
158TYPO

End of page:
“but when they are on different machines we use -
name.”.
Badly placed newline.

2007-03-24
160TYPO

End of page:
“…BIF will be send {nodeup, Node} and {nodedown, Node} messages…”.
Should be “sent”.

2007-03-24
161TYPO

“Returns true if the local node is alive; and can be part of a distributed system. Otherwise, it returns false”
Superfluous “;”, missing “.” (dot).

“In addition send can be used to send messages to a registered process…”
The first “send” should have some other font.

2007-03-24
162TYPO

“Two modules is the standard distribution cover most needs.”
Should be “in the”.

2007-03-24
93SUGGEST

The sidebar at the top of the page uses an example of traffic lights for a boolean expression. Traffic lights are not a good example here, as they generally are tri-state devices (green, yellow/amber, red), at least in some parts of the world. Please choose another example.

2007-03-24
51ERROR

“lists:seq(N)” should be “lists:seq(1,N)”

2007-03-24
101TYPO

short-cut expression has been explained in Page 55 “Guards”.

2007-03-25
82TYPO

Last paragraph, second sentence “Each frame has it’s own” should be “Each frame has its own”.

2007-03-25
164ERROR

In the code below “cd;” should be replaced by “cd /;”

So to destroy your system all you

2007-03-25
85TYPO

Second paragraph from the end starts off “Not only is this code beautiful. It is also highly efficient.” I don’t think this is a congruent usage.

2007-03-26
189TYPO

Figure Figure 11.1

2007-03-26
208TYPO

2 typos.

“ID3 tags were invented by a progrmamer called Eric Kemp to store meta-data desribing the content of an audio file.”

2007-03-25
210TYPO

Typo in the sentence below: “find all the by…”.
Moreover in the code listed on page 209, the function lib_misc:find is not used. It is rather lib_find:files.

“The first thing we do is find all the by calling lib_misc:find(Dir, ”*.mp3“, true)”

2007-03-25
212TYPO

“compete” should be written “complete”.

There is no such complete list in section 12.3. Moreover that text is written in section 12.3. Not too useful to make a reference to section 12.3 when in section 12.3.

"You

2007-03-25
215TYPO

Bottom of the page.

“To find out about a file F we call file:read_file_info(F) this returns {ok, Info} if F is a valid file or diectory entry”

2007-03-25
215SUGGEST

"To find out about the individual files in the directory listing we

2007-03-25
82ERROR

“Specifies the endianess of the machine” is a bit misleading - it’s the endianness of the format. As you know, one might well use /big to communicate between two little-endian machines. Printing {<<16#12345678:32/big>>, <<16#12345678:32/little>>, <<16#12345678:32/native>>, <<16#12345678:32>>} in the shell might be a useful illustration.

2007-03-25
84SUGGEST

In unpack_header() you use the old catch syntax, having told the reader not to use it in the previous chapter

2007-03-25
52SUGGEST

The table of arithmetic operations might perhaps be one good place to introduce the 16#deadbeef notation for non-decimal integer literals - I would guess 99% of non-Erlang speakers will be expecting to use 0xdeadbeef instead. Or it can go somewhere else, but should go somewhere reasonably early on.

2007-03-25
62SUGGEST

I found chapter 3 to be somewhat less satisfying than the surrounding chapters. It’s a lot of detail early on (the sequencing of material in your previous Erlang book was superb pedagogy, this seems more random) and people can get a long way through Erlang programming without having to grapple with this stuff. You also vaguely allude to the debate about whether to return {ok, Val} and pattern match or whether to return Val and throw an exception, but without giving any clear guidance. The main impression one is left with IMHO is that Erlang is complicated because of all this and it’s hard to know what to do.

(Dave says: we hear you—it’s changing)

2007-03-25
70SUGGEST

Showing how to generate a stacktrace is useful for semi-experts; the bigger problem for newcomers to Erlang is not being terrified of the little blighters in the first place. Even the very first error messages on page 18 are pretty intimidating and opaque until you know how to read them. Maybe a bit of early hand-holding on at least not being freaked by these would probably go a long way, and then once arities, export syntax etc is understood, going into more detail in reading error reportrs and backtraces might be useful.

For embedded systems, mentioning SASL at least in passing might be useful, for more detailed error reports.

(Joe: in new appendix - sasl has been described now)

2007-04-17
71SUGGEST

Other than a single instance on p.68, this is the first time comments have been introduced. Given how the first two chapters are very good for people who haven’t even fired up the shell before, this is rather late to be learning this basic information.

Chapter 4 (like chapter 3) also has an air of “eat your greens before you’re allowed desert” about it - the dedicated will plough through it, but it’s not inherently about the exciting stuff that draws on to Erlang in the first place. In both cases, is there any way in which an abbreviated “this is the stuff you REALLY have to know before we go on” chapter can go here, and move the more reference-type material later on? Otherwise people might just put the book down before they get to the really juicy bits.

2007-03-25
95ERROR

“In Erlang all syntactic constructions are technically expressions.” No they’re not, otherwise you could do everything in the shell that you can in a .erl file, as per the recent thread on erlang-questions. There are also declarations, such as function definitions.

2007-03-25
104TYPO

In the sentence in point 1, you spell the first instance of “open” in lowercase but the second instance is capitalized. The second instance should also be lowercase “open”.

2007-03-25
21SUGGEST

“Why Does Single Assignment Make My Programs Better?” - I’m afraid the example of changing pi, whilst amusing (can’t insert hyperlinks, google for “should the value of pi change”) isn’t really that convincing to, say, C progrmmers who would always use a macro for that. However, if you can talk more about side-effect-freeness and how this allows scaling up with multiple processor cores (passing messages can reduce to simple pointer passes within the VM) and better modularity/unit testing, you’re hitting far more buzzwords-du-jour. I don’t know if enabling simpler soft-real-time garbage collection is worth mentioning too - Java has RT extensions now too, so posssibly not.

(Joe says: will be addressed in a new introduction)

2007-03-26
105TYPO

Last sentence should start “On a windows system” or “On a Windows system”.

2007-03-25
115TYPO

Second paragraph from the end that starts “I’m not a fan of clutter…” should terminate with a period after “… not relevant to my application.”, then start a new sentence with “This results …”.

2007-03-25
116TYPO

“Erlang can sometime be …” should change to “Erlang can sometimes be …”.

2007-03-25
116TYPO

All of the bullet points at the bottom of the page end in a period except the first one.

2007-03-25
118TYPO

First paragraph under My Makefile, third sentence should change from “…deal with most common…” to “..deal with the most common…”.

2007-03-25
119TYPO

All of the numbered bullet points in the middle of the page end in a period except the last one (“I type c 2 which…”).

2007-03-25
120TYPO

First paragraph under section 6.9 reads “… built-in commands, You can…”. The comma should be a period.

2007-03-25
120TYPO

“…just create a module called user_defaults” - should be “user_default”.

2007-03-25
56ERROR

On p. 56, it says that “A >= –1.0 andalso math:sqrt(A+1) > B” is an example of guards.

However, it isn’t a legal guard expression. When it is used in an if statement, the compiler thinks it is an illegal guard expression since it uses an external function(math:sqrt).

It would be nice if you explicitly marked that external functions can’t be used in an guard expression.

2007-03-25
124SUGGEST

The text states: “Having received a message the process prints….” I believe it might be better with a comma: “Having received a message, the process prints….”

2007-03-25
124TYPO

The next to the last paragraph states: “…prints out the Width and Ht.” I believe it should state: “…prints out the area.”

2007-03-25
125TYPO

The first line of the page says, “If we send the process a message….” I believe it should say, “If we send a process a message….”

2007-03-25
125SUGGEST

The last sentence in the first paragraph states: “This is performed by the last part in the receive statement.” Might “part” be better described as “clause”?

2007-03-25
125TYPO

The second paragraph states: “When the client wants the server to do something it sends a message….” I believe it reads better with a comma: “When the client wants the server to do something, it sends a message….”

2007-03-25
125SUGGEST

The text states: “In the previous program, all that was needed was to send a message to a process, then receive and print that message.” Perhaps it reads better as: “In the previous program, all that was needed was to send a message to a process which received and printed that message.”

2007-03-25
125TYPO

The text states: “Now what we want to do is…p” It may read better with a comma: “Now, what we want to do is….”

2007-03-25
125SUGGEST

The text states: “The trouble is we do not know who to send the reply to.” I believe it reads better as: “The trouble is, we do not know to whom to send the reply.”

2007-03-25
125SUGGEST

The text states: “…the client has to include an address that the server can reply to.” I believe it reads better as: “…the client has to include an address to which the server can reply.”

2007-03-25
125TYPO

The text states: “So the sender must include a reply address This can be done….” I believe it is missing a period: “So the sender must include a reply address. This can be done….”

2007-03-25
125SUGGEST

The text states: “Then we have to change the code that receives the message from” I believe it might read better like: “In order to respond to the message, we have to change the code that receives the message from”.

2007-03-25
126SUGGEST

The text states: “…sends the message is usually called….” It might read better as: “…sends the initial message is usually called….” or “…sends the initial request is usually called….”

2007-03-25
127SUGGEST

The text states: “…we send a message to the server, and then wait for a reply, but we do not wait for a reply from the server, we just wait for any message.” It might read better like “…we send a message to the server and wait for a reply. But we do not wait for a reply from the server; we wait for any message.”

2007-03-25
127SUGGEST

The text states: “So if some other process sends the client….” It might read better without the “so,”: “If some other process sends the client….”

2007-03-25
127SUGGEST

The text states: “…while it is waiting for a reply from the server it will misinterpret….” It might read better with a comma: “…while it is waiting for a reply from the server, it will misinterpret….”

2007-03-25
127TYPO

The text states: “…so in the pattern { Pid, Reply} Pid is bound and….” I believe it needs a comma: “…so in the pattern { Pid, Reply }, Pid is bound and….”

2007-03-25
127TYPO

The text states: “…where the first element is Pid. all other messages….” I believe it should read: “…where the first element is Pid. All other messages….”

2007-03-25
127TYPO

The text states: “…other messages will be queued (receive provides what is called….” I believe it requires a period: “…other messages will be queued. (receive provides what is called….”

2007-03-25
129SUGGEST

The text reads: “To run this we call the functions….” It might read better with a comma: “To run this, we call the functions….”

2007-03-25
129SUGGEST

The text reads: “send does not send a message….” It might read better like: “send does not actually send a message….”

2007-03-25
129SUGGEST

The text states: “When you send a message to the process the message is put into….” It might be better with a comma: “When you send a message to the process, the message is put into….”

2007-03-25
129SUGGEST

The text states: “If the match succeeds the message is removed….” It might read better with a comma: “If the match succeeds, the message is removed….”

2007-03-25
130TYPO

The text states: “…in the mailbox match, then the processes is suspended….” I believe it should state: “…in the mailbox match, then the process is suspended….”

2007-03-25
130SUGGEST

Throughout sections 7.1 to 7.4, we refer generically to messages and to clients and servers. At a number of points, I was confused as to which message was sent by which process. It might be better to use the terms request and reply or request message and reply messages.

2007-03-25
132TYPO

The first full paragraph states: “Sometime a receive statement….” It should read: “Sometimes a receive statement….”

2007-03-25
132TYPO

The text states: “…for a number of reasons, there might be….” I believe it should read: “…for a number of reasons. For example, there might be….”

2007-03-25
132SUGGEST

The text states: “To avoid this problem we can add a timeout….” I believe it reads better with a comma: “To avoid this problem, we can add a timeout….”

2007-03-25
132SUGGEST

When I first read the description of receive with a timeout, I was confused about “when the clock started.” I believe it states when the system begins evaluating the receive statement; however, in particular when I was trying to understand receive within a loop, I kept wondering if the timer reset at every message.

My lack of understanding may reflect my C / C / Java understanding of timers.

2007-04-13
133TYPO

The text states: “Without the timeout clause flush_buffer would suspend forever….” I believe it reads better with a comma: “Without the timeout clause, flush_buffer would suspend forever….”

2007-03-25
133TYPO

The text states: “…the first message in the mailbox, and if there is…” I believe it reads better as two sentences: “…the first message in the mailbox. If there is….”

2007-03-25
133TYPO

The text states: “If there is a message matching { alarm, X } then this will be….” I believe it reads better with a comma: “If there is a message matching { alarm, X }, this will be….”

2007-03-25
133SUGGEST

The text states: “…then this will be returned immediately….” It might read better like: “…then this message will be returned immediately….”

2007-03-25
133TYPO

The text states: “…this will be returned immediately, remember the….” I believe it reads better as two sentences: “…this will be returned immediately. Remember the….”

2007-03-25
133TYPO

My previous suggestion stated “Remember the after section….” I believe I forgot a comma after the word, “Remember.”

2007-03-25
125SUGGEST

The section introduces client-server architectures. For developers used to Web programming, the term “client-server” conjures images of a PC / browser and a server node. It might be useful, to describe client-server more generally and to emphasize that the roles and client and server can change depending on the services being requested.

2007-04-13
132SUGGEST

In section 7.6, the text describes the operation of receive with a timeout. Section 7.4 contains a step-by-step description of how receive works.

To better explain how the timeout and message pattern matching work, it might be clearer if the text either describes how to modify the previous step-by-step description or to include a revised table.

2007-04-13
134TYPO

The next to the last paragraph states: “…which want to communicate with this processes.” I believe it should read: “…which want to communicate with this process.”

2007-03-25
135TYPO

The text on the first line states: “cesse is called a registered process.” It should read “cess is called a registered process.”

2007-03-25
135SUGGEST

The text states: “Once the name has been registered we can send it….” I believe it is better with a comma: “Once the name has been registered, we can send it….”

2007-03-25
136OK

The footnote states: “…the full set can be found in the io manual pages.” Although Unix developers will understand how to find this information, Windows developers will not. Windows developers need to open the installed Erlang documentation and select the “stdlib” link on the left-hand frame.

(Joe: described on page 126 getting help)

2007-03-27
138TYPO

The text states: “Next we’ll look at error recovery, and see how….” I believe it reads better without the comma: “Next we’ll look at error recovery and see how….”

2007-03-25
140TYPO

Fourth paragraph, second sentence should be changed from “…shows how to use these mechanism…” to “these mechanisms” or “this mechanism”.

2007-03-25
141TYPO

Extra word “as” in “…send it a message as like this:”

2007-03-25
140TYPO

The text states: “…the exit signal will cause it too to exit.” I believe it reads better with commas: “…the exit signal will cause it, too, to exit.”

2007-03-26
139SUGGEST

When I first read the description of an error signal and saw the form in the diagram on page 139, I thought an error signal was a message. I did not understand that an exit signal is NOT a message until several readings of the text (and some experimentation on my own).

I believe that this chapter contains the first mention of a signal. Perhaps the text needs to introduce that concept before talking about linking processes?

2007-04-03
140SUGGEST

The text states: “In part (b), B dies, and in © an exit signal is sent to A.”

I understand that A receives an exit signal whether or not it is a system process. If A is a system process, it converts that signal into an exit message. Is this understanding correct?

2007-04-13
140TYPO

The text states: “…that evaluates a particular function, when some other process crashes.” I believe it reads better without the comma: “…that evaluates a particular function when some other process crashes.”

2007-03-26
266TYPO

The code listing uses filelib:is_file(File) while the explanation references filelib:exist(File).

2007-03-26
266TYPO

Paragraph starting with “In this code”, 5th line
s/there can’t by/there can’t be/

2007-03-26
261SUGGEST

Suggest to explain get_next_word() function a little bit, especially the meaning of the third parameter. My understanding is: L is the character list accumulated so far, with characters reversed.

2007-03-26
140TYPO

The text of the last paragraph begins: “When a process exits we might want to perform….” I believe it reads better with a comma: “When a process exits, we might want to perform….”

2007-03-26
141SUGGEST

The text of the first paragraph states: “Finally, when the process dies an exit signal….” I was unclear which process was referred to at first; I had to read the section a second time and examine the function code. Second, I believe the fragment reads better with a comma: “Finally, when the process dies, an exit signal….”

2007-03-26
141TYPO

The last paragraph of the section states: “…perform any computation it likes, it can ignore the error, ….” I believe it reads better with a colon: “…perform any computation it likes: it can ignore the error, ….”

2007-03-26
141SUGGEST

The last sentence of the first section states: “The choice is up to the user.” I believe “user” should be “developer,” “programmer,” or “system.”

2007-03-26
142OK

The first sentence on the page reads: “…machine—in distributed Erlang (next chapter) we’ll see that….” I believe it reads better as two sentences: “…machine! In distributed Erlang, described in the next chapter, we’ll see that….”

2007-03-26
142TYPO

The text on exit signals states: “…divide a number by zero the exit reason….” I believe it reads better with a comma: “…divide a number by zero, the exit reason….”

2007-03-26
142SUGGEST

The text on system processes states: “…from a process Pid then the exit signal….” I believe it reads better with a comma: “…from a process Pid, the exit signal….”

2007-03-26
142SUGGEST

The text of the last paragraph states: “…it receives an exit signal ExitReason from….” Since the preceding text has used the atom Why, it might be clearer to replace ‘ExitReason’ with ‘Why.’

2007-03-26
144TYPO

The last full sentence on the page reads: “Now we’ll run the program and generating different exit signals in C and observe the effect in B.” I think it reads better as: “Now we’ll run the program generating different exit signals in C and observing the effect in B.”

2007-03-26
144SUGGEST

The last sentence on the page reads: “As we run the program it might be helpful….” I believe it reads better with a comma: “As we run the program, it might be helpful….”

2007-03-26
145SUGGEST

The first paragraph states: ‘…the “before” part shows the processes…." I was initially uncertain where to find the “before” part in the diagram. Perhaps it is clearer if it reads: ’…the “before” part (at the top of each diagram) shows the processes…." Similarly change the “after” part to mention the bottom of the diagram.

2007-03-26
145SUGGEST

The second paragraph states: “…that cannot trap exits:” I was unclear if it cannot or if it simply does not. (I think of “cannot” as implying some kind of authorization or outside agency instead of a programming choice.)

2007-03-27
145SUGGEST

The text states: “As it exits, B then broadcasts the unmodified exit signal….” It might read better like: “As it exits, B broadcasts the unmodified exit signal….” In addition, “broadcast” might be better as “re-broadcast.”

2007-03-26
145SUGGEST

The text states: “A (which is trapping exits) receives….” It might read better with parenthetical commas, “A, which is trapping exits, receives….”

2007-03-26
146OK

The text printed in response to command three begins with the line “Error in process….” Because the rest of the output text is generated by the code, I was at first unclear how this line was generated.

Perhaps the text needs to remind the reader that an error results in printing the error message.

2007-04-13
147SUGGEST

The text states: “…when a run-time failure occurs a run-time failure….” I believe it is better as two sentences: “…when a run-time failure occurs. A run-time failure….”

2007-03-26
147TYPO

The text states: “…is something like devision by zero, or calling a BIF with an argument of an incorrect type, or….” I think it reads better without the first “or” as follows: “…is something like division by zero, calling a BIF with an argument of an incorrect type, or….”

2007-03-26
147SUGGEST

The text states: “…a run-time failure is something like…completing evaluation of the function it was spawned with.” I am unclear how completing evaluation of a function is a run-time failure.

2007-03-26
147TYPO

The text states: “The process that sends the exit signal does not die, but resumes execution….” I believe it reads better without the comma: “The process that sends the exit signal does not die but resumes execution….”

2007-03-26
76SUGGEST

More information on the dialyzer would be nice.

(Joe says: there’ll be notes in the Resources chapter)

2007-03-26
87ERROR

You mention on page 72 that we should not use the case(catch foo(…)) syntax and should instead use try foo(…). Should this code be updated to reflect the newer convention?

2007-03-26
87SUGGEST

Could you dry up the find_sync code, please?

Maybe something of the form
find_sync(Bin, N) -> calls find_sync(Bin, N, 1).
find_sync(Bin, N, Count) -> Does is_header with recursion
find_sync(Bin, 3) -> the one that stops the recursion.

(Joe: I prefer my verison)

2007-03-26
41TYPO

I think paragraph 3 should read “badarity means that Erlang couldn’t find a function with the given name …” (currently it says “Erlang could find …”).

2007-03-26
147SUGGEST

The text describes “kill signals” and “killed signals.” Although the difference seems obvious, the text has not previously mentioned “killed signals.” A footnote describing a “killed signal” might clarify the difference.

2007-03-26
147TYPO

The text states: “…intended to kill rogue processes, and should not….” I believe it reads better as two sentences: “…intended to kill rogue processes. It should not….”

2007-03-26
147SUGGEST

The text states: “…and should not normally be used without careful thought.” A double negative is difficult to understand. To make it easier, the text might italicize “not” and “without.” An alternative, although it does not have the same emphasis is: “…and should always be used with careful thought.”

2007-03-26
147SUGGEST

The first line of edemo2:c/2 states: “process_flag( trap_exit, true )”. I’m unclear when a function needs to invoke process_flag and when not. Perhaps a box earlier describing not only the syntax of process_flag, but a description of why (or why not) to use the function.

(Joe: this was described is the section marked “System Processes”
\tpg 148 of B1.7)

2007-03-26
149SUGGEST

The text states: “Links are symmetric.” Designing in a symmetric environment is far more difficult than an asymmetric environment because of the complexity of the symmetric links.

A box describing how to design a set of processes in this environment would help the reader to understand how to handle this additional complexity.

2007-04-13
149SUGGEST

The text states: “…then a noproc exit signal is sent….” I understood the exit signal to be a special signal. Based on this statement, I understand that different “kinds” of exit signals exist. Is this correct?

In addition, I expected this condition to raise an error instead of sending an exit signal. Finally, the text describes sending the signal to the “calling process.” I’m not certain what process this phrase refers to. Is it the process that invokes link( Pid ).

2007-03-26
150SUGGEST

The second paragraph in the text box states: “…need to monitor processes, and know why things….” I believe it reads better as" “…need to monitor processes, and to know why things….”

2007-03-26
150SUGGEST

The fourth paragraph of the text box states: “Using this we can start….” During my first reading, I was unclear what “this” referred to. I believe the text is better written as: “Using this technique, we can start….”

2007-03-26
150SUGGEST

The last paragraph in the text box states: “…get yourself access to two computers then you’re well on your way….” I believe it reads better with a comma: “…get yourself access to two computers, then you’re well on your way….”

2007-03-26
150SUGGEST

The first paragraph of the “Monitors” section states: “If A dies then B will be sent….” I believe it reads more clearly with a comma: “If A dies, then B will be sent….”

2007-03-26
150SUGGEST

The second paragraph of the “Monitors” section states: “If process A monitors process B, then if B dies then A will be….” I believe it might read more clearly written as: “If process A monitors process B and if B dies, then A will be….”

2007-03-26
150SUGGEST

I found the last sentence in the “Monitors” section confusing. The section briefly describes monitors and then says details will be provided in a different section. The next section then describes a “Keep-Alive Monitor.”

Do these sections use monitors in two different ways? I wondered if the monitors described in this section was a technical use particular to Erlang. In addition, I wondered if the use of the term “keep-alive monitor” was a more generally recognized use.

2007-03-26
151SUGGEST

The first paragraph states: “To wind up this chapter we’ll make a keep-alive monitor.” I believe this sentence reads better with a comma: “To wind up this chapter, we’ll make a keep-alive monitor.”

2007-03-26
151SUGGEST

The text refers to a “global process.” I do not recall any previous use of this term. What does it mean?

2007-03-26
151SUGGEST

The text states: “…in on_exit and keep_alive—I wonder if….” I believe it reads better as two sentences: “…in on_exit and keep_alive. I wonder if….”

2007-03-26
151SUGGEST

The text states: “…two bits of code (this bit) and the….” I’m unclear what is meant by “this bit.”

2007-03-26
152SUGGEST

The text states: “…Erlang primitives spawn, spawn_link, register etc you must….” I believe it reads better with a comma: “…Erlang primitives spawn, spawn_link, register, etc., you must….”

2007-03-26
152SUGGEST

The text states: “…which you can use to build applications and these libraries have been….” I believe it is better as two sentences: “…which you can use to build applications. These libraries have been…”

2007-03-26
152SUGGEST

The text of the next to the last paragraph states: “…to build systems that can recover from faults and build reliable software systems.” I’m uncertain what this phrase means. Might it be better phrased as: “…to build reliable software systems that can recover from faults.”

2007-03-26
88SUGGEST

Since you haven’t yet discussed file operations, would you insert a snippet of code showing the use of find_sync in the shell? Just enough to open an mp3 and load it into find_sync along with a reference to the file handling section would be great.

2007-03-26
46ERROR

The link to mylists.erl comes up as a 404:
media.pragprog.com/titles/jaerlang/code/mylists.erl

2007-03-26
157SUGGEST

on Windows when localhost refers to hostname contains dash (in my case, ZSG-45TFJ1S), rcp:call(gandalf@localhost,…) fails. Need to use rpc:call(‘gandalf@ZSG-45TFJ1S’,…), better footnote. Thanks.

2007-03-26
59TYPO

Second para on top of the page. “include” should be “included”.

"For example, suppose we want to keep manipulate a

2007-03-26
59TYPO

Second para on top of page.

To keep or to manipulate, that is the question ;)

"For example, suppose we want to keep manipulate a

2007-03-26
59TYPO

“To do this in the shell we have to read the record definitions into the shell before we can define a recod.”

2007-03-26
59TYPO

“if” should be “of”.

“In line 4 we modified an existing record. The syntax X#todo{status=done} means create a copy of the X (which must be of type tag) changing the field value status to done. Remember this is a copy if the original record, the original record is not changed.”

IMHO, I would write it like this: “… means create a copy of X (which must be of type todo) …”. The type of the record in the example is “todo” and not the generic type “tag” used in the formal syntax.

2007-03-26
50TYPO

Footnote 11 should end with “… good programming practice”." not “… practise.”

2007-03-26
60TYPO

"Records are just tuples. Now let

2007-03-26
67TYPO

At the bottom of the page.

“ExceptionType is an atom (one of throw, exit or error) which corresponds to the how exception was generated.”

2007-03-26
260TYPO

"All the code is in lib_trigrams we

2007-03-26
260TYPO

“This function appies the fun F to every trigram in the English language.”

The word appies should be applies (note the “l”).

2007-03-26
227SUGGEST

I would avoid telling TCP is commonly known (typo below) as TCP/IP as it is the entire protocol suite (the stack) that is known as TCP/IP.

"In this chapter we

2007-03-26
231TYPO

In item 1 of list, the bracket is not closed at the end.

“(ie the argument Data in the message {tcp,Socket,Data} is of type binary.”

2007-03-26
55TYPO

In the second paragraph of section 2.8: … ‘separated by a semicolon(,)’ It says semicolon, but prints a comma.

2007-03-26
55TYPO

Toward the bottom of the page: “In addition, guards cannot be user-defined boolean expressions, since
we wish to guarantee that are side-effect free and terminate.”

Should be …“that they are side-effect free”

2007-03-26
56TYPO

“Thes second line” should read “The second line”

2007-03-26
56TYPO

"Note: The atom true can used as a

2007-03-26
56SUGGEST

The introduction of short-circuit expressions is a bit sudden and confusing for someone new to Erlang. Is this meant to contrast that the guard separators (; and ,) are not short-circuit?

2007-04-12
60TYPO

“S and N are bound” should read “S and W are bound”

2007-03-26
262SUGGEST

“Counting #trigrams=3357707 time/trigram=0.528715
Ordered Set size=19.0200 time/trigram=2.85540
Set size=19.0193 time/trigram=1.48031
Dict size=15.4341 time/trigram=9.95878”

The stuff on the first line after the “#” has been colored green, probably by the code style doing some autocoloring stuff. I don’t think it should be green, since it’s output data and not code data.

2007-03-27
267ERROR

in the definition for filename2index, there appears to be a race condition between the lookup of free and the insertions of the FileName values. Does erlang magically handle this, or is the race condition being ignored deliberately?

2007-03-28
106TYPO

The word “modifying” is misspelled in the title of section 6.2.

2007-03-27
106TYPO

Change “it’s” to “its” in the last sentence of the first paragraph in section 6.2.

2007-03-27
115TYPO

footnote instead of “yecc (yet nanother compiler compiler)” it should be “yacc (yet another compiler compiler)”

2007-03-27
11TYPO

There

2007-03-27
22OK

“value of Pi (horrors):” => “value of Pi (horror):”

2007-03-27
23OK

i think should be for float:
7> R = 5.0.

2007-03-27
44OK

“say fruit;” => should be “say Fruit;”

(Joe: Not a typo fruit here is an noun
\t Fruit is a variable in my program)

2007-03-27
142TYPO

The second word “function” should be “process”.

“The function that is invoked when the function dies can, of course, perform any computation it likes: it can ignore the error, log the error, or restart the application. The choice is up to the programmer.”

2007-03-28
16SUGGEST

The paragraph starting with "Warning

2007-04-11
53TYPO

youself => yourself

2007-03-27
143SUGGEST

In section 7.4 when you define system process, you write:
“When a process receives an exit signal, it too will die unless it is special kind of process called a system process.”

I am a little bit confused by that because, as far as I understand the matter, when a process receives a normal exit signal it won’t die (system process or not). The pseudo-code confirms it. But the sentence above let me think a process will always die when receiving an exit signal.

Maybe it would be a good idea to clarify the phrase. Or perhaps it is just me :)

2007-04-11
56TYPO

when exaluating => when evaluating

2007-03-27
59ERROR

records.hrl not found on media… link

2007-03-27
59TYPO

“X#todo{status=done}” => should be X1#…

2007-03-27
60TYPO

“On the left have side” => should be “On the left hand side”

2007-03-27
148SUGGEST

I have difficulties to understand the behavior of processes receiving kill signals.

Both execution below are bases on your code and looks the same in the book.

In line 33, process B does not trap and process C dies with exit(kill). The exit signal sent from C to B is kill and is changed to killed when travelling from B to A. Right ?
In line 34, process B traps and process C dies with the same exit(kill). The exit signal sent from C to B should still be kill. But you wrote in pseudo-code that a process receiving the kill signal should die. So B should even if it is trapping errors. The behavior is different from what I thought… I am confused.

33> edemo1:start(false, {die,kill}).
Process a received {’EXIT’,<0.148.0>,killed}
process b (<0.148.0>) is dead
process c (<0.149.0>) is dead
ok
34> edemo1:start(true, {die,kill}).
Process b received {’EXIT’,<0.153.0>,kill}
process b (<0.152.0>) is alive
process c (<0.153.0>) is dead
ok

If I change the C function to specifically send the signal to B when it dies (exit(Reason) becomes exit(B, Reason)), then the B process dies even if it traps errors !
The line 36 is exactly the same as line 34 above but this time process B dies.

36> edemo1:start(true, {die,kill}).
Process a received {’EXIT’,<0.161.0>,killed}
process b (<0.161.0>) is dead
process c (<0.162.0>) is dead
ok

My conclusion is that sending an explicit signal with exit(Pid, Reason) is different from sending an implicit exit signal to linked processes after dying which is done with exit(Reason). IMHO I don’t think the text permits me to understand fully what is happening. Am I missing something ?

(Joe: You are right. exit(Pid, kill) and exit(kill)
behave differently - the code is correct
\t but the explanation needs changing a bit.
\t I’m thinking of a better wording)

2007-04-11
35SUGGEST

After using the c() function for compilation for the first time, you should point out that this function in fact compiles a module. It’s obvious from context, but you should still state it.

2007-03-27
42SUGGEST

The line “You could have called it hedgehog/2 and the meaning of the program would be the same.” should be changed to read
“You could have called it hedgehog/2 and the meaning of the program would be the same, assuming that sum/1 called hedgehog/2 instead of sum/2.”

2007-03-27
48SUGGEST

The line “Applying any function to the elements of an empty list (there are none!) just produces an empty list.” should read “Mapping any function over the elements of an empty list (there are none!) just produces an empty list.” Mapping a function is, of course, quite different from applying a function.

2007-03-27
56SUGGEST

In the line “Calls to the Bifs in Figure 2.3, on page 58 and the guard predicates in Figure 2.2, on the next page”, you haven’t mentioned yet what a BIF is.

2007-03-28
56SUGGEST

Re the line “Here are some examples of guards using short-circuit boolean expressions:”; you’ve given a forward reference to short-circuit boolean expressions, but it would be best to at least briefly describe what they are.

2007-04-12
56SUGGEST

You mention guard predicates in the numbered list at the top of the page. It would be good to explain what a predicate is (this term is, I would guess, unknown to the majority of programmers).

2007-03-31
58SUGGEST

The warning about -record not being a shell command should come after you have introduced -record in the first place.

2007-03-28
59SUGGEST

It’s not clear if records can be imported and exported from modules, or if the include mechanism is the only way to get them from an external source. This should be spelled out somewhere (here you might just put a forward reference).

2007-03-28
59TYPO

The line “The syntax X#todo{status=done} means create a copy of the X (which must be of type tag)” should be “The syntax X#todo{status=done} means create a copy of the X (which must be of type todo)”.

2007-03-27
60SUGGEST

The lines:

To match a record of a particular type we might write:

do_something(X) when is_record(X, todo) ->

are quite confusing. Specifically, do_something(X) looks like a function call, not a pattern match. I don’t think this is what you intended.

2007-03-27
62OK

After introducing the if statement it would be nice if you redefined filter using if instead of case. This would illustrate why the language has if in the first place (i.e. to make common expressions more concise).

2007-03-27
62SUGGEST

In the first clause of the definition of some_function: obviously you’re using a sequence expression here (multiple statements with a period at the end of each statement). I don’t think this has been introduced yet, so it might be confusing.

2007-03-27
64SUGGEST

The line:

The next two chapters look briefly at error handling and the Erlang type notation.

isn’t correct; the material on the type notation has been moved to Appendix A.

2007-03-27
65TYPO

“seem” => “seen”

2007-03-27
65TYPO

“did” => “dig”

2007-03-27
56SUGGEST

IMHO “Calls to the Bifs” Bifs, the acronyme should be declared here first if already referenced and not on page 74

2007-03-28
232TYPO

"3. After we have accepted a conection it

2007-03-27
236TYPO

Bottom of page. Actually, in the code, we sleep for 1 second.

“We spawn a server (and sleep for 5 seconds to give it a chance to start).”

2007-03-27
242TYPO

“Thus the smallest header block can be represented in the binary <<0>>,”

2007-03-27
81SUGGEST

“knowledge of A to M” is somehow ambiguous

2007-03-27
77TYPO

“In most language*S* this involves some messy low level involving bit shifting and masking.”

2007-03-27
80OK

Instead of leaving all the details uncovered, why don’t you present everything because you use them below in function decode_header. I mean bits EEEEFFGH IIJJKLMM.

“AAAAAAAAAAA the sync word (11 bits, all ones)
BB 2 bits is the MPEG Audio version ID
CC 2 bits is the layer description
D 1 bit a protection bit
and so on…”

(Joe: This is a book about Erlang not MP3)

2007-03-27
82ERROR

“Now decode_header is written to crash (by calling exit/1)
if its argument is not at the start of a header.”

As far as I understand the code of function decode_header, it does not “crash” if it is not at the beginning of a header but it rather returns the atom “error”. Which is a value like another one. The function exists only if the calculated length is below some threshold (21).
That’s fine because find_sync knows what to do when the atom “error” is returned.

2007-03-27
83TYPO

Towards the top of the page, the following phrase is missing an object to the phrase: “In most language this involves some messy low level involving bit shifting and masking”

2007-03-27
86TYPO

“expression?.” The “.” after the “?” is superfluous

2007-03-28
86TYPO

precidence => precedence (IMHO)

2007-03-28
87TYPO

“and and” => one “and” enough

2007-03-28
231ERROR

In the alternate definition of receive_data (where you use concat_binary() ) shouldn’t it be concat_binary([SoFar,Bin]) so that the new packet gets appended? Otherwise I guess you’ll get the data the wrong way round as you don’t do a reverse() in the other branch.

2007-03-28
89SUGGEST

“User-defined attributes can be extracted” => Why only “user-defined” is can see the predefined as well i.e. -export, -import, …

2007-03-31
93TYPO

“function function” => external function

2007-03-28
93TYPO

“In we wish” => “If we wish”

2007-03-28
98TYPO

“Precidence” => “Precedence”

2007-03-28
99TYPO

“Opertors” => “Operators”

2007-03-28
100TYPO

“diction” => dictionary

2007-03-28
108TYPO

“you home directory” => “your home directory”

2007-03-28
258TYPO

Comment line above get_next_word(…),
s/reverseed/reversed/

2007-03-28
249TYPO

12.8: gen_tpc -> gen_tcp

2007-03-28
57TYPO

be consistent with Mr. Van Winkle’s last name. There is an instance of ‘Winkel’

2007-03-28
59SUGGEST

In: "It should set alarm bells off in your brain

2007-03-28
64TYPO

“Pattern1, Pattern2 … until match is found.”

Perhaps ‘until a match is found’?

2007-03-28
64TYPO

“which corresponds to the how exception was generated”

should be

“which corresponds to how the exception was generated”

2007-03-28
120SUGGEST

“JCL” => this acronyme should be explained in a footnote

2007-03-31
127TYPO

“reply address This” => missing a point “.”

2007-03-28
144TYPO

“handing” => handling

2007-03-28
209TYPO

In section “Reading the entire file into a binary”, the example uses io:read_file but the text below mentions io:read. I think it should be io:read_file too.

2007-03-28
148TYPO

“alway kill” => always kill

2007-03-28
150TYPO

“to the the process” => to the process

2007-03-28
151SUGGEST

“then if B dies then” => better “and if B dies then”

2007-03-31
158TYPO

“The client ran on the first node” => “The server ran on the first node”

2007-03-28
254TYPO

Second para of section 13.3
double “and” in phrase.

"When you choose between a set and and ordered set you should think about what you want to do with the table after it has been constructed

2007-03-28
164TYPO

“communicated” => communicate

2007-03-28
165TYPO

“of the following form:” => “in the following form:”
(IMHO)

2007-03-28
151OK

“To make something fault-tolerant you need at least two computers.” Is this really true? If thought strict a two node system (on one physical host) should be enough, except fault-tolerant is meant in the sense of some hardware redundance.

(Joe: You need at least two computers for fault tolerence
If a machine with two nodes crashes, both nodes die. You can’t
do fault-tolerence only in software)

2007-03-28
153SUGGEST

Please, do show the solution to the race condition problem here. I’m very interested in knowing how to avoid race conditions in Erlang.

(joe: this is a huge topic - this would detract from the text here)

2007-04-13
161TYPO

Typo in “Access to a node of set of nodes”

2007-03-28
265TYPO

"We *havn

2007-03-28
191SUGGEST

“the external C program and the Erlang” => better “the external C program and Erlang”

2007-03-31
197TYPO

“the the more” => one “the” superfluous

2007-03-31
201TYPO

“How you can you” => “How can you”

2007-03-31
201SUGGEST

“which simplify the job” => “which simplifies the job”

2007-03-31
67SUGGEST

When introducing the try/catch statement, you should mention its similarity to the case statement, perhaps with a line like “the try/catch statement is like a case statement on steroids”. Basically, the try/catch statement is a case statement with catch and after blocks at the end.

2007-03-31
70SUGGEST

The output of try_test:demo2 is pretty obscure. I’d like to see some discussion of this, especially with the backtrace.

2007-04-13
71SUGGEST

When you describe code that doesn’t have a “common case” you should be clear what you mean. IOW you might say that a lot of code that can throw an exception will only do so under very unusual circumstances; we say that this code has a “common case”. In contrast, some code can often throw an exception, and in this case…

Joe: Disagree. That’s why common case is quoted. My
PhD thesis discusses this in detail (section on intentional
programming) - a long discussion here would detract from the text
and confuse people)

2007-04-12
204SUGGEST

“when in comes” => “when comes in”

2007-03-31
204TYPO

“number different ways.” => “number of different ways.”

2007-03-31
73SUGGEST

I don’t believe that tail recursion has been mentioned explicitly up to this point in the book, so a forward reference would be appropriate when mentioning that tail recursive calls are missing from a stack backtrace.

2007-04-12
73SUGGEST

When describing the effect of tail calls on stack backtraces, don’t conflate tail calls with tail recursion; not all tail calls are tail recursive.

(Joe: tail calls are tail recursive in Erlang - they must be
otherwise infinite loops in processes won’t work)

2007-04-12
207TYPO

"just isn

2007-03-31
212TYPO

“in Ags there” => “in Args there”

2007-03-31
214TYPO

“write simple function” => “write a simple function”

2007-03-31
215TYPO

(“www.erlang.org”)) => closing parenthesis to much

2007-03-31
218TYPO

“elemts” => “elements”

2007-03-31
230TYPO

“messages” => “message”

2007-03-31
232TYPO

“conection” => “connection”

2007-03-31
235SUGGEST

“enable reception” => IMHO “reenable reception”

2007-03-31
235TYPO

“that that” => “that”

2007-03-31
237TYPO

“Then client is then sent” => “Then the client gets sent”

2007-03-31
237TYPO

In this context “of” is not a keyword, therefore not bold.

2007-03-31
239TYPO

“we can we can see” => “we can see”

2007-03-31
239TYPO

“make make” => “make”

2007-03-31
240ERROR

“wait_for_ref(Socket, Ref);” why there is a “;”

2007-03-31
241TYPO

“brodcasts” => “broadcasts”

2007-03-31
241TYPO

“chose” => “choose”

2007-03-31
243SUGGEST

“to the server.” => i think it should be “to the client.”

2007-03-31
253TYPO

“and and” => “and”

2007-03-31
254SUGGEST

“list options” => IMHO “options list”

2007-03-31
255TYPO

“a Ets table” => “an Ets table”

2007-03-31
256TYPO

“fun to type” => “fun of type”

2007-03-31
271TYPO

“or example).”=> “for example).”

2007-03-31
51SUGGEST 2007-03-31
52SUGGEST

Could you explain the difference between a boolean expression and a predicate?

2007-04-11
54OK

Why is the priority of bnot 2 instead of 1? Is bnot X * Y the same as bnot (X * Y) or (bnot X) * Y ?

(Joe: Because 1 is reserved for : and #.
It has to be higher than (: #) and lower than the
arithmetic operations.

Why: think of it like -
> –3+10.
7\t
> bnot 3+10.
6
> bnot (3+10) .
–14
> (bnot 3)+10.

So bnot X * Y means ((bnot X) * Y))

If in doubt use parenthesis)

2007-04-13
55SUGGEST

The use of “sequence” here is very confusing. Better text might be:

“A guard sequence is either a single guard or a series of guards, separated by semicolons (;).”

“A guard is a series of guard expressions, separated by commas (,).”

2007-03-31
55TYPO

“The set of valid guard expression” should be “expressions” (plural)

2007-03-31
56SUGGEST

The last paragraph talks about a detail of using guards with if statements, but we haven’t been introduced to them yet. Perhaps this section should be moved to a later point in the book.

2007-04-12
56TYPO

cross reference to section 4.4, incorrect spelling of “precedence”

2007-03-31
58SUGGEST

Perhaps you should describe the rr() shell function next to the warning about -record() not being a shell command

2007-04-12
58ERROR

Are record keys variables or atoms? Are they spelled with initial upper or lower case?

2007-03-31
59ERROR

“The syntax #todo{Key1=Val1, …, KeyN=ValN} is used to create a new record of type todo.” The upper-case Keys are inconsistent with the preceding examples and with the next sentence which says they are all atoms.

2007-03-31
52ERROR

This version of quicksort is not stable - it does not preserve the relative order of elements that compare equal. (This might not matter in Erlang - I don’t know if you can have semantically equal values that are structurally different.) To fix this make the comparison in the Smaller list < and in the Bigger list >=.

2007-03-31
13TYPO

The source tar files are named otp_src_RXXY-Z.tar.gz, not otp_src_RXXYZ.tar.gz as the text indicates (the difference being the dash). Maybe not important, but it’s always nice to avoid confusion in the early stages :-)

2007-03-31
197TYPO

“2> example1:sum(45, 32).
60” ==> “2> example1:sum(45, 32).
77”

2007-03-31
93SUGGEST

The sidebar seems wrongly placed. Shouldn’t it be in the Boolean section. While reading it I was trying to see how it was related to block expressions. The confusion did not last long though.

2007-03-31
158SUGGEST

What do you do when the rpc call fails? What are some of the debugging tools you can use if you get a {badrpc,nodedown} (like I do)?

(joe: Not added Then I’d have to explain flush which would
probably confuse matters)

2007-05-04
214TYPO

There’s an extra closing parenthesis at the end of the first line of the shell example,

(“www.erlang.org”)),

should be

(“www.erlang.org”),

2007-04-01
40TYPO

In 2.3 first para last sentence “They have nothing to do with each apart from a co-incidental use of the same name.” the word “other” is missing after “each”.

2007-04-01
33TYPO

“After line 7 the variable bindings in the shell are {Width 7→ 10, Height 7→ 5, R 7→ 2.4}.” - “Height” should be “Ht” to match the shell session listing.

2007-04-01
271TYPO

“Type declarations are NOT Erlang code and cannot by typed into the shell.” - “by” should be “be”.

2007-04-01
259SUGGEST

For this example it would probably be better to use the module sets instead of dict as this better describes what you are doing. I doubt it will make any significant difference in the measured times though.

2007-04-13
270SUGGEST

The module erlang is VERY big and contains a very varied collection of functions. I wonder if it is worth including its man page. I think including gen_udp would be better.

(Joe: won’t be included - change of plans)

2007-04-13
218TYPO

Opening curly braces missing in result returned by lib_misc:ls(“.”). The text has

1> lib_misc:ls(“.”).
[{“Makefile”,regular,1244}},
{“README”,regular,1583}},

but the actual output is

[{“Makefile”,{regular,1244}},
{“README”,{regular,1583}},

2007-04-01
219ERROR

It states in sec 11.4 that “There is no function to copy a file”, yet there’s a function file:copy(Src,Dest) that does exactly that. It’s documented and appears to work fine in R11B-2 (which I’m running on my OSX laptop).

2007-04-01
220TYPO

At the end of the third line on the page, ‘etc,’ should be ‘etc.,’.

2007-04-01
220TYPO

The first sentence of sec 11.8 refers to ‘file:file_info’, but it’s ‘file:read_file_info’ that’s actually used in this example.

2007-04-01
240TYPO

You might want to spell it iTunes, not Itunes.

2007-04-01
243TYPO

‘Itunes’ should be ‘iTunes’. Also, ‘Xmms’ should probably be ‘XMMS’.

2007-04-13
224ERROR

The receive_data/2 function in the example uses concat_binary/1, but this is deprecated according to the erlang(3) man page. It should probably use list_to_binary/1.

2007-04-02
56SUGGEST

I tried to put the definition of the -record(person, … in a file. I was able to compile but not to use the record directly in the shell. Suggest discussing here how records are designated outside of the module they are defined.

2007-04-12
232SUGGEST

It might be useful to include a footnote explaining how to stop the sequential server in the shell, in case someone actually starts it up. (…assuming there’s a way to do that.)

2007-04-13
13SUGGEST

MacPorts current installs R11B-2, which is two releases behind. If you have any hints for installing erlang under MacOS X from source (without MacPorts), I think it would be useful to people who want to be able to run the latest version.

2007-04-12
110SUGGEST

This page is not very clear that running the application using “erl -noshell” requires the program to first be compiled. Yes, it mentions the beam file, and yes, the first example shows compilation and running from within erl. But nowhere does it explicitly state that you have to compile the program first for “erl -noshell”. It might be a good idea, in fact, to show how to compile the program from the same command line where you run “erl -noshell”, rather than implying compilation requirements by showing such compilation in erl as part of the first example.

2007-04-02
110SUGGEST

Given that escript is now included in the latest versions of Erlang, is the warning about it not being there really necessary? If you intend to keep the warning, you should specify exactly which version escript appeared in, so that those who installed that version or later needn’t worry about it.

2007-04-12
111SUGGEST

I disagree with the sidebar about exporting functions. Instead of the advice given, I’d recommend using export_all during development as well but also recommend writing and maintaining a commented-out export statement that correctly declares the desired exports. This is because if you think you’re going to return to your code later to decide on the real exports, there’s a large chance that “later” will never arrive, the export_all will remain in your production code, and another user or application will come to depend on exports you never intended to have. At least with the commented-out export statement, you can run a simple script over your code before release to eliminate export_all and uncomment the real exports.

2007-04-12
113TYPO

Just before the section “A Makefile Template,” “you” should be “your” in the phrase “build you own makefiles.”

2007-04-02
68ERROR

When is the after clause run? immediately after FuncOrExpressionSequence or after the relavant ExpressionsN or ExExpressionsN clause?

2007-04-10
79SUGGEST

based-number syntax bas not been described yet, so the 16#12345678 should be left in decimal.

2007-04-12
95ERROR

Control flow in macros - “inside a macro definition” - you do not show how to use -undef(), ifdef(), etc. inside a definition and it would be surprising if that worked!

(Joe: added note to say macros must be properly nested)

2007-04-13
102SUGGEST

The \\XYZ notation is confusing - there’s no hint that XYZ is supposed to mean three octal digits. \\NNN or \\777 would be better.

2007-04-12
102SUGGEST

I think it would be clearer to say that \\C for non-special C is the same as unescaped C - like other languages.

2007-04-12
111ERROR

The escript URL is broken.

2007-04-17
112SUGGEST

The box about export_all looks like it belongs on page 89.

2007-04-17
113TYPO

The output of the first fac program (no brackets) is inconsistent with the format string (brackets)

2007-04-02
116SUGGEST

The documentation for crash dumps is at: …/doc/doc-5.5.4/erts-5.5.4/doc/html/crash_dump.html

And there seems to be a viewer application: …/doc/doc-5.5.4/lib/observer-0.9.7.3/doc/html/crashdump.html

both on www.erlang.org

2007-04-05
124ERROR

The description of receive implies that the waiting is sequential - that a later pattern can’t match if the process is waiting for a match on an earlier pattern. I’d suggest “This code waits for a message. If it matches a guarded pattern then the corresponding expressions are evaluated. If none of the patterns matches then the process continues to wait for another message which does match.”

2007-04-02
249ERROR

…“Ets and Dets tables look as if they were implemented in Erlang, but
in fact they are implemented in the underlying run-time system”…
The text implies that both Dets and Ets tables are implemented in the underlying runtime system. Actyally only Ets tables are implemented within the emulator, Dets is “just” an ordinary module (although quite complicated).

2007-04-02
141SUGGEST

The code for on_exit/2 uses the variable named Pid. On my first reading, I was unclear whose process id this variable represented. Is it the monitoring process? The monitored process? When I saw how it was used in the example on page 142, I better understood the code.

In general, we use the term Pid as a variable containing a process id in the chapters on error handling and concurrent programming. I believe the source code would be clearer if the variable names distinguished the roles of the different processes.

2007-04-13
141SUGGEST

The pseudo-code at the top of the page seems to indicate that normal exits are broadcast to every Erlang process in a link set. Is this true?

2007-04-13
144SUGGEST

The text of the first paragraph states: ‘Note that the exit signal kill is changed to killed, why is this? exit(Pid, kill) generates an “unstoppable exit” A process cannot handle an exit kill signal and must die.’

This text might be clearer as: ‘Note that the exit signal kill is changed to killed. Why is this? exit(Pid, kill) generates an “unstoppable exit.” No process can trap an exit kill signal. It must die.’

2007-04-11
146SUGGEST

The text of the second paragraph on the page states: “First suppose B is a normal process.” I understood that all process were normal processes. Perhaps it is better to read: “First, suppose B is not a system process.” (I understand that negatives are tough in English.)

2007-04-13
17SUGGEST

On page 17, you advise the user to hit C-c and a to abort the node ‘when things go really wrong’. Why not advise C-g k s c instead? It’s far neater (you mean I can have multiple shells!? on remote machines?!), it doesn’t require killing any processes you may have started up, it doesn’t require killing a node, and it works for the most likely newbie errors.

2007-04-11
22SUGGEST

Your Pi example sucks. Sorry. You follow it up very well, but maybe
you can have a comparison of broken Erlang and otherlanguage code, to show how single
assignment aids readability. (I’ve already seen this example mocked publically, once.)

2007-04-11
25SUGGEST

On page 25 about atoms, how about ‘an example with spaces’?

2007-04-11
29SUGGEST

In page 29 ‘Defining Lists’, you might give an example of an improper list ([1|2]), if only to brush it off, and recommend that the Lisp hackers in the audience use a tuple in place of non-tree cons.

(Joe: I don’t even want to show people how to do bad things -
they might start doing this)

2007-04-11
33SUGGEST

In page 33, you refer to ‘case statements’ and ‘if statements’, even as you explain
elsewhere that they are expressions. Why not just call them expressions up-front?

2007-04-11
48TYPO

subscript 9 on page 48 talks about omitting a c(mylists) that you don’t have.

2007-04-10
103SUGGEST

On pages 103 and 104, ‘Underscore Variables’, you explain what happens without explaining why — and the error you give does make people wonder about the why — please consider inserting this explanation: hxxp://www.erlang.org/pipermail/erlang-questions/2007-February/025146.html

(Joe: disagee - interesting though this is it’s a bit off topic)

2007-04-12
113TYPO

On page 113, ‘Programs With Command Line Arguments’, you have `erl -noshell -l -s fac1 main 25`, which just hangs after calling fac1:main(25), with the -l having no significance.

(Joe: the -l is incorrect. The program doesn’t hang when I run it
if it prints out the factorial it should then stop
this is what init:stop() does)

2007-04-02
114ERROR

On page 114, ‘A Makefile Template’, you say: ‘if you just type “make” then “make all” is assumed’. Make does not assume ‘all’ as a default target — it rather assumes the first defined target as the default target.

2007-04-05
143SUGGEST

The text of the System Processes paragraph states: “When a process receives an exit signal, it too will die….”

I understand that a normal exit sends an exit signal but any linked processes do not die. If I understand correctly, the text might be better written as: “When a process receives an exit signal for any reason other than a normal exit, it too will die….”

2007-04-11
147TYPO

The text of the third paragraph states: “B ignores this, as receiving a normal signal” I believe it needs a period (full-stop): “B ignores this, as receiving a normal signal.”

2007-04-11
147SUGGEST

The third paragraph states: “B ignores this, as receiving a normal signal” The text has previous mentioned exit signals and kill signals but has not mentioned normal signals.

What is a normal signal? Does the text need a sidebar explaining more details of Erlang signals? I thought they were similar to events, but later descriptions make me wonder if this analogy is correct?

2007-04-11
148TYPO

The second paragraph states: “…by explicitly evaluating exit(Why) or when a run-time failure occurs or simply by completing evaluation of the function it was spawned with.” I believe this text reads better with commas: “…by explicitly evaluating exit(Why), when a run-time failure occurs, or when evaluation of the spawned function completes.”

2007-04-11
148TYPO

The text of the second paragraph states: “…something like division by zero, or calling a BIF….” I believe it reads better without the comma and with a parallel ‘by’: “…something like division by zero or by calling a BIF….”

2007-04-11
148SUGGEST

The text states: “…a process Pid can explicitly send an exit signal X to….” I’m confused by this use of the term “exit signal.” In my experience (not with Erlang), a signal is raised by some process and then sent to other processes to indicate some event of interest.

In this situation, the event “signal” seems more like a command than an signal.

2007-04-11
148SUGGEST

The text states: “Pid2 will receive a {’EXIT’, Pid1, Arg} message (if it is trapping exits), exactly as if the originating process had died.”

I find this behavior confusing. If Pid2 is not trapping exits, if Pid1 is linked to Pid2, and if Pid1 invokes exit(Pid2, Arg), Pid2 will exit and will send an exit signal to all its linked process. If Pid1 is trapping exits, it will receive the message {’EXIT’, Pid2, Arg}. However, it Pid2 is trapping exits, it converts the original message into {’EXIT’, Pid1, Arg}; however, Pid1 has not died!

How is Pid2 to interpret the message {’EXIT’, Pid1, Arg}? (I am learning Erlang as I go along. I recognize that I have lots of learning to do and may misunderstand how Erlang behaves or how its behavior supports its design goals.)

2007-04-11
148TYPO

The text of the third paragraph states: “…send an exit signal X to a process Pid2 by evaluating exit(Pid2, X).” Later, the text states: “Pid2 will receive a {’EXIT’, Pid2, Arg} message….” I believe all arguments need to be “X” or all arguments need to be “Arg.”

2007-04-05
148TYPO

The text in the fourth paragraph states: “When a process receives a kill signal it dies and….” I believe it reads better with a comma: “When a process receives a kill signal, it dies and….”

2007-04-13
148TYPO

The third sentence of the fourth paragraph states: “This is as a safety measure….” I believe this reads better as: “This behavior is a safety measure….”

2007-04-05
149TYPO

The description of spawn_link/1 states: “…like spawn(Fun) but in addition a link….” I believe it reads better with commas: “…like spawn(Fun), but in addition, a link….”

2007-04-05
149SUGGEST

The description of spawn_link/1 describes two actions occurring. Although you discuss race conditions later, I found myself wondering what happens to the link if the spawn call fails? Are these two actions somehow “atomic” or can one fail and the other “succeed”?

2007-04-13
150SUGGEST

The specification of process_flag is “process_flag(trap_exit, true).”

On reading this specification, I wondered, what if the second argument is false?

2007-04-13
151SUGGEST

The sidebar about fault-tolerant systems seems misplaced. This entire chapter discusses error-handling on a single Erlang node, but the sidebar focuses on distributed systems.

Perhaps it would be clearer if the box indicates that future chapters will discuss distributed nodes.

Another alternative would be to move the text of this sidebar to the beginning of the chapter as part of the introduction to error handling (again including a future reference to distributed programming).

2007-04-13
151TYPO

The first paragraph on the pages states: “The is illustrated in Figure….” I believe it reads better like: “This behavior is illustrated in Figure….”

2007-04-02
152SUGGEST

The text of keep_alive/2 contains the fun: “fun( _ ) -> …”

I believe all previous funs either had no argument or had named arguments. I’m unclear why this fun expects a single anonymous argument.

(joe: changed to named variable)

2007-04-13
155SUGGEST

The text states: “…for programming applications which run on a set of tightly coupled computers.” When I first read this text, I wondered what “tightly coupled” meant. Although I believe it is related to “tightly coupled objects” or “tightly coupled modules,” I was unclear what this phrase means in this context.

2007-04-13
155TYPO

The text of the next-to-the-last paragraph states: “We are all used to writing sequential programming but writing distributed….” I believe it reads better as two sentences: “We are all used to writing sequential programming. Writing distributed….”

2007-04-13
155TYPO

The text states: “In this chapter we’ll look at….” I believe it reads better with a comma: “In this chapter, we’ll look at….”

2007-04-13
155SUGGEST

The second sentence of the last paragraph states: “To do this we’ll only need to learn two things to make our first distributed program.” I believe it reads better as: “To do this, we’ll only need to learn two things.” Another alternative might be: “To make our first distributed program, we’ll only need to learn two things.”

2007-04-13
155SUGGEST

The last sentence states: “We’ll learn how to start an Erlang node, and how to….” I believe it reads better like: “We’ll learn how to start an Erlang node, and we’ll learn how to….”

2007-04-13
156SUGGEST

The text of bullet item 1 states: “…so this presents no new challenges).” I believe it reads better as: “…so this process presents no new challenges.)”

2007-04-13
156SUGGEST

The text states: “…in different domains, then we can run into problems with connectivity and we have to….” I believe this reads better as: “…in different domains, we can run into problems with connectivity, and we have to….”

2007-04-13
156TYPO

The next-to-the-last sentence states: “…but get started with….” I believe it is missing the word “to”: “…but to get started with….”

2007-04-05
158SUGGEST

The text describing Stage 2 describes how to perform the work in a Unix environment. Although with suitable set up, these steps work in a Windows environment, I’m unclear how one would use the Windows erlang shell (werl.exe) to perform the same steps.

2007-04-13
158SUGGEST

The shell commands about two-thirds down the page references the rpc module. When I first read the commands, I wondered if this rpc was the function that we wrote recently. I eventually realized that it referenced a module that the text had not previously mentioned. Does the text need to indicate that the rpc module is a standard library module?

2007-04-13
159SUGGEST

The text of the second paragraph states: “…the client is running on one node and the server….” I believe it reads better with a comma: “…the client is running on one node, and the server….”

2007-04-13
160SUGGEST

The text in bullet item 4 states: “In our case the same version module code….” I believe it reads better with a comma: “In our case, the same version module code….”

2007-04-13
160SUGGEST

The text mentions the phrase: “version module code.” When I read this phrase, I wondered, “What does this phrase mean?”

2007-04-13
160SUGGEST

Footnote 4 states: “And the same version of Erlang.”

When I read this footnote, I wondered: “What happens if they differ?” Perhaps the text could include a forward reference for the “curious.”

2007-04-13
161SUGGEST

The text uses the term “cluster.”

When I read this term, I was unclear if this was an Erlang cluster or a general cluster.

2007-04-13
161SUGGEST

The text states: “…do not permit incoming connections and we will have to….” I believe it reads better as two sentences: “…do not permit incoming connections. We will have to….”

2007-04-13
161SUGGEST

The text states: “…for distributed Erlang you will have to….” I believe it reads better with a comma: “…for distributed Erlang, you will have to….”

2007-04-13
118TYPO

In item 2 in the numbered list, change "you

2007-04-03
121TYPO

Change “user_defaults” to “user_default”.

2007-04-03
124SUGGEST

The next to the last paragraph ends with “the value of Pid ! Msg is defined to be Msg.” The last paragraph then begins with “Pid ! M is defined to be M”. This is redundant; one of them should be eliminated or reworded.

(Joe: No harm in repetition - good if you missed it the first time
\t bangs the point home.)

2007-04-12
252TYPO

“This is true for all data structures except binaries” i think should have been “This is true for all data structures except large binaries”. (Small binaries are kept on the heap)

2007-04-03
260TYPO

"Since
there can

2007-04-03
261SUGGEST

The statement "It

2007-04-03
56ERROR

“Warning: -record is not a shell command. Record declarations can only
be used in Erlang source code modules and not in the shell” should maybe be changed to something like "Warning: record is not a shell command. Although records can be used in the shell, they are declared using a slightly different syntax than in a source code module." or something like it (rd(Name, {Field, …}).).

2007-04-12
126TYPO

In the middle of the page, change “Putting all of this togther we get” to “Putting all of this together we get” (“together” is misspelled).

2007-04-05
126OK

I’m not sure that RPC is really what your example on this page shows. The term “remote procedure call” refers specifically to a round-trip call/response operation made to a remote system, where the call from the programming language perspective is made to look just like a local (normal) procedure call. In other words, RPC is more of a programming language concept than it is a distributed computing concept. Unfortunately, the term is often misused to refer to any networked call-and-wait-for-response operation, regardless of the language being used. Erlang doesn’t even have procedures! So, instead of RPC, I suggest that you refer to this as a “synchronous request/reply operation.”

(Joe: This usage of the word RPC is deeply ingrained into Erlang
we’ve been using the word this way for 20 years - the wikipedia says
<<Remote procedure call (RPC) is a technology that allows a computer
program to cause a subroutine or procedure to execute
in another address space>> which is what we do. A process is
another address space)

2007-04-13
130TYPO

Near the top of the page, change “These names which more accurately describe
what the server does” to “These names more accurately describe
what the server does” (delete “which”).

2007-04-05
0SUGGEST

Some mention or a section of a chapter on how to maintain state or get around maintaining state will help a lot for those of us coming from a more imperative background. Thanks!

(Joe: State is maintained in variables, or ets tables or
process dictionaries. here are numerous examples throughout the book)

2007-05-22
131SUGGEST

In the numbered list that describes how receive() operates, it might be worth describing what the concurrency effects are for the mailbox. Is the mailbox a global resource under the covers, shared by all Erlang processes within a given UNIX process for example? If so, why is it not a significant source of contention? It might help to provide some details along these lines on how mailboxes are implemented.

(Joe: section 6.2 says "Each process in Erlang has an associated
mailbox … the answer is in the text)

2007-04-11
67SUGGEST

When talking about “Improving Error Messages”, I suggest showing the use of erlang:error/2 to fill in the arguments to the topmost function in the stack backtrace (i e erlang:error({squareRootNegativeArgument, X},[X])).

(Joe: Disagree. A marginal improvement, at the expense of
having to explain erlang:error/2)

2007-04-12
76SUGGEST

Dialyzer does not use the type annotations in the source (yet, at least), I think the text and contect implies diffrently (or is it only my interpretation that’s wrong?)

(Joe: I havn’t said what the dialyser does with annotations)

2007-04-12
109SUGGEST

“followed by a newline (~n in Erlang)” suggests that ~n is a general way of writing the newline character (like \
in i.e. C). This is not true, it’s a feature of the io/io_lib functions. Compare io:format(“~p~n”,[“X~nY”]) to io:format(“~p~n”,[“X\
Y”]). I suggest “(~n in the io:format function)” or something like it.

2007-04-12
25SUGGEST

You write : ‘But remember: erlang is a functional language…’. Maybe I have overlooked something but I do not remember this as a prominent statement already made.
Should it read : But becaus erlang is a functional language …’

2007-04-11
138TYPO

Change "

2007-04-05
161TYPO

The first sentence of the last paragraph states: “Access to a node of a set….” I believe it reads better as: “Access to one node of a set….”

2007-04-13
161SUGGEST

The text states “…have their cookie changed to the same value by….” Can a node have multiple cookies?

2007-04-13
161SUGGEST

The text states: “All the nodes in a distributed Erlang system must have been started with the same magic cookie….” Does a single “shared” cookie define an Erlang cluster?

(joe: Not added Then I’d have to explain flush which would
probably confuse matters)

2007-05-04
162OK

The text of the note states: “…this form of spawn is more robust than….” I’ve also had some experience in which the value returned by self() differs depending on whether it is invoked in a fun() in spawn/1 or invoked in spawn/3.

(Joe: No - the nodes might have the same cookie but never every know about
\teach other - example a cluster in Sweden would not know about one in
\tFrance. This is talked about in the section on code loading)

2007-04-13
162SUGGEST

The text describing monitor_node/1 states: “…if Node joins or leaves the system.” On reading this sentence, I wondered, “What is the system? Is it a set of connected Erlang nodes? A single Erlang node?”

2007-04-13
162SUGGEST

The text describing node/1 states: “If the local node is dead…” I was unclear how one invokes this function if the local node is dead.

2007-04-13
163TYPO

The text states: “In addition sendcan be used….” I believe it reads better as: “In addition, send can….”

2007-04-13
163SUGGEST

The text states: “…to a registered process in a distributed Erlang nodes.” I believe it reads better like: “…to a registered process in a distributed set of Erlang nodes.”

2007-04-13
163SUGGEST

The text has previously spoken of the register/2 BIF; however, it made no mention of registration in the context of an Erlang cluster. Does this syntax mean that a registered name is local to a Node?

2007-04-13
163SUGGEST

The text of the last paragraph states: “…the program must be copied and compiled before starting….”

I believe the text has discussed both compiling within the shell and the erlc compiler. Does this phrase mean that the .beam file must on both systems?

2007-04-13
164SUGGEST

The text states: “…maintaining global locks in a….”

I do not believe that the text has mentioned “global locks” before.

2007-04-13
165TYPO

The text states: “…Erlang nodes to communicated they must….” I believe “communicated” should be “communicate.” In addition, I believe it reads better with a comma: “…Erlang nodes to communicate, they must….”

2007-04-05
165TYPO

The shell text for bullet 1 states the cookie begins with “AFRTY12….” The command in bullet 2 uses the cookie “FRTY12….” (missing an A).

2007-04-05
165TYPO

The text states: “In case you’re wondering cookies are never sent….” I believe this text reads better with a comma: “In case you’re wondering, cookies are never sent….”

2007-04-05
165SUGGEST

The text of the last paragraph states: “…not used to encrypt the data traffic between nodes.”

Is traffic between Erlang nodes encrypted by default? I do not believe that the text has not mentioned this behavior previously.

2007-04-13
166TYPO

The text of the first paragraph states: “…where everybody cannot be trusted.” I believe it reads better as “…where everyone can be trusted.” or “…where nobody can be trusted.”

2007-04-13
18SUGGEST

(Note that variable names
start with uppercase letters.)

Do you think this is important enough to state boldly - not just include it as a note? After I had read the Atom section where the syntax of an Atom is described… I realised that variable names and Uppercase is not just a convention - at least that is my current mental model!

Of course, this suggestion might seem dumb to me in a few more pages :-)

2007-04-11
26SUGGEST

Is this the first example in the book of an Erlang programming “idiom” or somesuch. Not a language requirement but a style of use that is highly recommended…

Tuples.
"To make it easier to remember what a tuple is being used for it

2007-04-11
30SUGGEST

I am working through the exercises and Erlang is fun AND powerful. To encourage readers to actually evaluate bindings in the shell, just in case they aren’t, even after the earlier encouragement, perhaps augmenting the following text:
This succeeds with bindings Buy1

2007-04-11
30TYPO

Try 115 instead of 83
7> I = $s.
115

[I-32,117,114,112,114,105,115,101].
“Surprise”

2007-04-05
32TYPO

The type style of the following Note: does not follow all previous instances. More importantly these 2 items:

>>tell

2007-04-05
31TYPO

Is the comma, , correct?

If you

2007-04-05
31SUGGEST

Do the new words Term and Query need to be introduced in this section?

If you

2007-04-11
36ERROR

The Windows tip has errors: The file must be placed in the ‘bin’ subdirectory of the erlang installation, otherwise it will not be called.

Being placed there, another problem arises : It gives this output:
—————————-

Erlang (BEAM) emulator version 5.5.2 [async-threads:0]

d:/download
Now in:“d:/download”

=ERROR REPORT 5-Apr-2007::09:26:03 ===
file:path_eval([“.”,“H:\\\\”],“.erlang”): error on line 1: 1: syntax error before:
‘[’
Eshell V5.5.2 (abort with ^G)


(Joe: cannot reproduce - works fine for me
exactly as I desribed. In your path_eval example
the syntax error appears to be in the .erlang file
you might have some stuff after the “Now in …” statement
check the content of your .erlang file)

2007-04-11
40SUGGEST

in the shop1 examples it would be nice to see a table with the evaluations listed one after the other. Its hard to follow the argument in prose alone.

(Joe: I disagree. this would get very verbose - a table AND
the text. There is alread two paras of explanation after
each line. Adding a table would make it even more wordy
and distract from the code.)

2007-04-12
111TYPO

“$ chmod u+x hello.erl” => “$ chmod u+x hello”.

2007-04-05
115SUGGEST

The ERTS users guide in the standard documentation describes the erlang crash dump. The crash dump viewer tool is described in the observer application users guide.

2007-04-05
47TYPO

for(Max, Max, F) ?? Name ‘Max’ used 2 times.. Why does this work ?

2007-04-05
120SUGGEST

The text more or less implies that only windows has the HTML pages. I suggest “The documentation is also downloadable as a set of HTML files. On windows the HTML documentation is installed by default and accessible through the start menu.”

2007-04-05
51SUGGEST

Now we make a new list by copying every element of the original list:
2> [{A,B} || {A,B} <- Buy].
[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]
———-
Maybe mention that {A,B} is a tupe which matches the elements in Buy by its structure. These are tuples too. I am an Erlang Newbie so it took me a while to figure this out.

2007-04-05
134TYPO

“The function timer:start(Time, Fun)” => “The function stimer:start(Time, Fun)” (stimer is the module name used in the rest of the text)

2007-04-05
158TYPO

Stage 2 : The notation gandalf@localhost does not necessarily work. Under Windows it may be rquired to use the Hostname like so :
——-
(bilbo@A96200CH)6> rpc:call(gandalf@A96200CH,kvs,store, [weather,fine]).
——-

2007-04-13
93TYPO

Perhaps:
the last expression in the sequence. This is computed using
instead of:
the last expression in the sequence this is computed using

2007-04-05
143SUGGEST

The pseudo code for the exit signals does not seem correct.
I believe this to be a better description:

if ExitReason kill then broadcast the exit signal "killed" to all processes in my link set then die else if process_flag trap_exit true then
add the message {’EXIT’, Pid, ExitReason} to my
mailbox
else
if ExitReason == normal then
continue;
else
broadcast the exit signal ExitReason to
all processes in my link set
then die
end
end
end

i.e. ‘kill’ cannot be caught and is therefore translated before beeing resent to other linked processes, while ‘normal’ is ignored by processes not trapping exit, the trapping processes still get it (which is good, as they wont to know that a process died, even normally).

2007-04-11
47SUGGEST

This is the first page that has bugged me. It sets the reader up for a related but different error. The page starts with a Box titled Common Errors then proceeds to the execution of an uncompiled module.

Download lib_misc.erl appears on page 42 but there has been no instruction to compile it - or encouragement to make the mistake warned about in Common Errors.

The notice that the reader now has to remember to compile modules comes on the next page, page 48 - as a footnote:
9. from now on, I

2007-04-11
48TYPO

the issues around subscript 9 need to be addressed on the previous page or deferred to this page (by including the compile command on both pages). Either way, include the compile command for one last time and tell the reader, as a warning, or as a footnote that you are doing so.

9. from now on, I

2007-04-10
78TYPO

The URL for the Erlang documentation appears to have changed. Should probably be: www.erlang.org/doc/doc-5.5.4/doc/

2007-04-12
48SUGGEST

Perhaps the circles numbered 1 and 2 at the bottom of the page should be 3 and 4 to avoid confusion with the 1 and 2 at the top of the page. It would be good if the explanation for 2 was on the same page.

The code in mylists.erl marks these clauses as 1, 2, 3, 4 but in a different order.

Also, if I knew more I might understand why the [] case is handled second at the top of the page but first at the bottom.

2007-04-11
52SUGGEST

How about adding this command after 2> lib_misc:qsort(L). to actually create the bindings described in the text?
3> [Pivot|T] = L.
[23,6,2,9,27,400,78,45,61,82,14]

Then the 2 commands currently numbered 27 and 28 will work and they can be renumbered.

4> Smaller = [X || X <- T, X =< Pivot].
[6,2,9,14]
5> Bigger = [X || X <- T, X > Pivot].
[27,400,78,45,61,82]

2007-04-10
57SUGGEST

Figure 2.2: Guard predicates
Perhaps the heading of the first column should be changed from Operator to Predicate to match the referring text on the previous page and the caption.

2007-04-12
59TYPO

>>Creating and Updating Records
Change Updating to Modifying in line with the text “In line 4 we modified an existing record.”

>> Now we

2007-04-10
60TYPO

This is not a sentence.
>>Matches that X is a record of type todo.

Perhaps you could write something like:
This function does something if the evaluation of the guard predicate succeeds. (to use the terminology of the previous section on guards)

2007-04-10
62SUGGEST

The … have been in use for a few pages now. Why the need to explain it now?
>> (where … just means

2007-04-13
62SUGGEST

I found the section “Building Lists in Natural Order” a bit awkward.

The second last paragraph seems to be a repeat of the second paragraph.
The code pattern does not show what seems to be a simple concept.

The basic idea I have picked up is fairly simple:
1 Add elements Head first
2 Taking the elements of an InputList Head first and adding them to an OutputList Head first results in the OutputList having the reverse order of the InputList
3 If the order matters then use lists:reverse/1 - it is wierdly optimised.
4 Avoid going against these recommendations.

Therefore Building Lists in Natural Order means
Head first
Head in Head out reverses the order. If that matters then use lists:reverse/1 it is optimised.

Is that what you intended?

2007-04-12
64TYPO

“changing the second clause of odds_and_evens” should be
changing the second clause of odds_and_evens_acc /3

2007-04-10
64TYPO

Remove the two?
>> The next two chapter looks briefly at error handling.

2007-04-10
66TYPO

let

2007-04-10
67TYPO

until a match is found
<< until match is found

2007-04-10
40SUGGEST

(This is a general comment - page number is an example or where the fun..end syntax is shown).

It would be useful to have a summary somewhere of the Erlang punctuation rules - ie. how to use “,” (comma), “.” (period), “;” (semi-colon) & “end” - sometimes you should use “;” (semi-colon) to combine expressions (ie. in a receive block, between definitions of functions with the same arity), sometimes you should use a , (comma), and sometimes expressions have an explicit “end” (eg fun..end/receive..end) however in this case you dont need the piece of punctuation just before the “end”.

I am sure that there is a simple rule for these which I am missing however this doesn’t seem to be described anywhere - can you please add a sidebar to explain.

2007-04-13
193ERROR

example1_driver.c:

- uses read_cmd()/write_cmd() without declaring a prototype for either: not ANSI C.

- it would be clearer to use switch (fn) { … } rather than cascading if () { … } statements.

2007-04-29
166TYPO

The text of the last paragraph in the first section states: “In these circumstances we will use a restricted….” I believe it reads better with a comma: “In these circumstances, we will use a restricted….”

2007-04-13
166TYPO

The text describing the start_server/0 function states: “…on the local host the behavior of the server is….” I believe this text is missing a period (full-stop): “…on the local host. The behavior of the server is….”

2007-04-13
166TYPO

The description of start_server/1 states: “…on the local host the behavior of the server is….” I believe this text, too, is missing a period (full-stop): “…on the local host. The behavior of the server is….”

2007-04-13
166SUGGEST

The second paragraph describing start_server/1 states: “In both cases the server configuration file….” I believe it reads better with a comma: “In both cases, the server configuration file….”

2007-04-13
166TYPO

The last sentence describing start_server/1 states: “Start listening to port number NNNN” I believe this sentence is missing a period (full-stop): “Start listening on port number NNNN.”

2007-04-13
167SUGGEST

The describing the service S states: “If the service is started then a process is created….” I believe it reads better with a comma: “If the service is started, then a process is created….”

2007-04-13
167SUGGEST

The text describing connect/5 describes how a client connects to a server process using a socket. As I read the description, I wondered: “Is the password sent from the client to the server as clear text?”

(Joe: no)

2007-04-13
167TYPO

The text describing connect/5 states: “…{ok, Pid} will be returned, where will be the Pid of a proxy process….” I believe the text is missing a word: “…{ok, Pid} will be returned, where Pid will be the Pid of a proxy process….”

2007-04-10
167TYPO

The first paragraph on page 167 states: “…two processes are spawned, one on the client-side, the other on the server-side.” I believe this text reads better as follows: “…two processes are spawned: one on the client-side and the other on the server-side.”

2007-04-13
167TYPO

The last sentence of the first paragraph states: “…handle conversion of Erlang messages to TCP packet data and trapping exits from the controlling processes and socket closured.” I believe this reads better as: “…handle conversion of Erlang messages to TCP packet data, trapping exits from the controlling processes, and socket closure.”

In addition, I’m unclear if “controlling” should be “controlled.”

2007-04-13
167SUGGEST

The third paragraph of the section named “The Server Code” states: “When a connection is created, by the client calling:” I believe this paragraph reads better without the comma: “When a connection is created by the client calling:”

2007-04-13
167SUGGEST

The text of the last paragraph states: “…At this stage you should stare….” I believe it reads better with a comma: “…At this stage, you should stare….”

2007-04-13
168SUGGEST

The second bullet point describing mod_name_server states: “…closes for any reason then a message….” I believe it reads better with a comma: “…closes for any reason, then a message….”

2007-04-13
168SUGGEST

The text of the second bullet point describing mod_name_server states: “…form {chan_closed, MM} will be received.” I believe the text is clearer as: “…form {chan_closed, MM} will be received by the server.”

2007-04-13
168SUGGEST

The text of the third bullet describing mod_name_server states: “…send a message X to the client it does so by….” I believe it reads better with a comma: “…send a message X to the client, it does so by….”

2007-04-13
168SUGGEST

The text of the fourth bullet point describing mod_name_server states: “…explicitly close the connection it can do so by….” I believe it reads better with a comma: “…explicitly close the connection, it can do so by….”

2007-04-13
168SUGGEST

The text of the next to the last paragraph states: “To test this we will first….” When I read this text, I was unclear to what the word “this” referred. I thought it might be better written as “this call”, “this function”, “these functions”, or “this code”.

2007-04-13
169SUGGEST

The text of the last paragraph states: “Note that in this case it is the owner….” I believe it reads better with a comma: “Note that in this case, it is the owner….”

2007-04-13
170SUGGEST

The text of the second paragraph states: “Instead, we’ll invent our own protocols.” When I first read this text, I wondered if the code as presented would encapsulate those protocol details so that it would be a fairly easy “exercise for the reader” to replace the implementation with an implementation that actually uses the IRC protocol.

If this approach is used, I believe it would be worthwhile to state that plan here.

2007-04-13
170SUGGEST

The text of the third paragraph states: “The reason for this is….”

To what does the word “this” refer?

2007-04-13
170SUGGEST

The text in the third paragraph states: “…to introduce you to one concept at a time, and show what can be achieved with the language alone and minimal use of libraries.” I believe it reads better as: “…to introduce you to one concept at a time and to show what can be achieved with the language alone with minimal use of available libraries.”

2007-04-13
170SUGGEST

The text of the last paragraph states: “Each component is simple but they fit together….” I believe it reads better with a comma: “Each component is simple, but they fit together….”

2007-04-13
171SUGGEST

The text of the paragraph describing the user interface widget states: “The user interface is a GUI widget where the user can send and display received messages.” I believe it reads better as: “The user interface is a GUI widget used to send messages and to display received messages.”

2007-04-13
173SUGGEST

The text of the third paragraph states: “…—this helps me think what’s going on, I’m not usually a fan….” I believe it reads better with a period (full-stop) : “…—this technique helps me think about what’s going on. I’m not usually a fan….”

2007-04-13
173SUGGEST

The text of the third paragraph states: “…a program like the chat system I often cover….” I believe it reads better with a comma: “…a program like the chat system, I ofter cover….”

2007-04-13
174SUGGEST

The text of the paragraph describing the io widget states: “…the io widget can be programmed to parse….” When I read this text, I was confused because the paragraph beginning on page 173 states: “When the user types anything in the entry section of the widget…and Parse is the result of parsing the input string….”

When I read the phrase, “can be programmed,” I think it is possible; however, the earlier paragraph seemed to indicate that parsing “was a done deal.” When I read the actual source code on page 175, I understood how both statements could be true; however, I was unclear during my initial reading.

2007-04-13
173SUGGEST

The text of the last paragraph states: “When the user types anything in the entry section of the widget a message of the form….” I believe it reads better with a comma: “When the user types anything in the entry section of the widget, a message of the form….”

2007-04-13
175SUGGEST

The source code for chat client uses the variable name “Nick.”

When I read it, I wondered, “Who is Nick?” It took me a moment or two to realize that “Nick” was short for “Nickname”.

The text might avoid confusing the reader by writing out “Nickname” for the variable name.

2007-04-13
175SUGGEST

The source code for handler calls the function disconnected/3. When I first read this source code having just read “Finally, it waits for a connection event in disconnected/2,” I thought disconnected/3 modeled a finite state machine. However, when I read the source code fro disconnected/3, I realized it was not directly implementing a state machine.

Might the source code use a different name than “disconnected” to better communicate the use of this function?
(Joe: your first thought was correct - it is a state machine)

2007-04-13
175TYPO

The last bullet point states: “Finally it waits for a connection event in disconnected/2”.

I believe this sentence needs a period (full-stop), and I believe the name of the function should be disconnected/3. In addition, I believe it reads better with a comma: “Finally, it waits for a connection event in disconnected/3.”

2007-04-13
176OK

Earlier in the book, we mentioned race conditions. The text of the first paragraph and the source code for handler seem to allow for a race condition. (The text states that the message arrives “eventually.” If the calling process is interrupted during the start_connector/3 message, might the connected message be sent before disconnected/3 is invoked.)

When I first read the code, I wondered, “What happens if the connected message is sent before disconnected/3 has been invoked?” I eventually realized that the message would simply be deposited in the message queue; however, it may be worthwhile to remind the reader of this behavior, perhaps in a footnote, to avoid these questions.

2007-04-13
176SUGGEST

The implementation of start_connector/3 calculates self() and then uses that temporary value in the fun.

In my own experimenting with Erlang and with fun, I discovered different behavior invoking self() inside a spawned fun (it returns the Pid of the spawned process) and invoking it outside the fun (or calling spawn_link/3 passing self() as an argument).

If I had not discovered this behavior, I would wonder, “Why assign the value of self() to a temporary variable?” I might even, as I did, re-write the code replace S in the fun with self().

I believe it would be useful to readers to discuss this behavior of Erlang / this implementation choice in a footnoe or a sidebar.

2007-04-13
176OK

When I first read the source code for try_to_connect/4, I was confused by the variable name Parent. I wondered, “Parent to what?” Although I eventually realized that it was the parent to the spawned and linked process, I believe that a name describing its use in the chat program instead of a name describing its structural relationship to the spawned process might clarify the code.

(Joe: parent is always used consistently to be the name of the process
which created a process)

2007-04-13
176OK

The last three arguments to the function try_to_connect/4 are Host, Port and Pwd. Although these names describe what the variables represent, I was unclear if they described the use of the variables within the function. In addition, I found it difficult to mentally distinguish between the host of the calling process and the host of the called process.

The function may read more clearly by using names like ToHost, OnPort, and WithPassword (assuming I understood their use in the function—I’ve been known to misunderstand code).

(Joe: disagree - too long variable names make program difficult to read
there can only be one hostname in involved here - the host you are
connecting to)

2007-04-13
176OK

The implementation of try_to_connect/4 is an infinite loop. In most languages, coding with an infinite loop like this is quite a “no no” (at least for production code).

Might the text avoid a reader questioning this implementation by describing why this infinite loop is “okay” in Erlang in the paragraph describing try_to_connect/3 or in a sidebar / footnote?

(Joe: described in the concurrency chapter, under tail recursion)

2007-04-13
176SUGGEST

The next-to-last paragraph on the page states: “…the client sends a login message to the server….”

When I first read the text, I looked “forward” to the source code for wait_login_response/2 for the “login message.” When it was not in that source code, I realized that it actually occurred in the implementation of disconnected/3.

Might it be clearer if the text referred to the the implementation of disconnected/3 on the previous page?

2007-04-13
176SUGGEST

The text of the last paragraph states: “…it should receive an acknowledgment message….”

Will all expected readers understand that the atom ‘ack’ is often used as shorthand for acknowledgment?

2007-04-13
176SUGGEST

The implementation of wait_login_response/2 will wait forever for an acknowledgment message.

Might the text avoid the reader questioning its correctness if it had an after clause to avoid waiting forever?

(Joe: yes it will wait forever - I want to keep the code simple -
who knows they might reply - if the socket closes the process will
die anyway, because it’s linked)

2007-04-13
176TYPO

The text of the last paragraph states: “If all goes well, it should receive…”

I was unclear to what “it” referred.

2007-04-13
176SUGGEST

The last paragraph states: “If all goes well, it should receive an acknowledgment message, (0in our case this is the only possibility since the password was correct) and calls active/2.” I believe this paragraph is clearer as several sentences: “If all goes well, this function should receive an acknowledgment message. (In our case, this is the only possibility since the password was correct.) After receiving the acknowledgment message, this function calls active/2.”

2007-04-13
177SUGGEST

Several source code fragments use the variable name “MM.” When I initially read it in this fragment, I wondered, “What does this name really stand for?” Eventually, I remembered that it refers to “middle man.” Might the name “Proxy” or “MiddleManProxy” better communicate its purpose to readers not familiar with this technique?

2007-04-13
176SUGGEST

The source code for active/2 sends the message ‘$close’ to MM. Although using a $ in atom name is legal Erlang syntax, I was unclear if names with a leading ‘$’ meant something special.

2007-04-13
177SUGGEST

The first paragraph on the page states: “…from the widget to the group (and vice versa)…” When I first read this text, I wondered, “Which process does this refer to? Does ‘group to widget’ make sense?”

After re-reading the source code, I realized that it does make sense; however, I believe the text is clearer if it make the “reverse messages” explicit: “active/2 sends messages from the widget to the group, sends messages from the group to the widget, and monitors the connection with the group.”

2007-04-13
115SUGGEST

Great stuff so far. I’d love a section that described some of the day to day practicalities of developing in erlang, eg. unit-testing, team development practices and, particularly, deployment of an erlang application. Most of the examples seem to recommend deploying modules into the same location as the built in erlang libraries. This may not be achievable for an application (eg. a web server) that is going to be deployed to a machine you don’t own or has to coexist with other applications. Any tips about getting an app. into production would be really useful!

2007-04-11
143SUGGEST

Hmmm… It seems my earlier comment and pseudo code about the exit signal handling was not correct:
The pseudo code I wrote earlier only holds if the exit signal is sent via exit(Pid,Reason) to the process. If the process gets the exit signal via a link (and that, I believe is the issue in this chapter), the following is what happens:

if process_flag trap_exit true then add the message {'EXIT', Pid, ExitReason} to my mailbox else if ExitReason normal then
continue;
else
if ExitReason == kill then
broadcast the exit signal “killed” to all processes in my link set
then die
else
broadcast the exit signal ExitReason to all processes in my link set
then die
end
end
end

- The kill signal is only “non maskable” if sent as exit(Pid,kill), not when arriving via a link (that’s deliberate in the code and has been like that since OTP R1, don’t ask me why, maybe ask Mike :-))
Another special case is exit(self(), normal) which kills a process that’s trapping exits… Also BC with OTP R1…

In the context of this chapter, however, the pseudo code in this message should be correct… I hope…

Sorry for the incorrect suggestion earlier, hope I got it right this time!

2007-04-11
158SUGGEST

“1. Start Erlang with the -name parameter” This is not needed if the machines are in the same domain and resolv.conf is configured correctly. -name could be introduced when the machines are on different networks instead.

2007-04-13
161SUGGEST

The statement “If the local node is dead, nonode@nohost is returned.” may be confusing, how about “If the local node is not distributed, nonode@nohost is returned.” instead?

2007-04-13
35OK

compiling geometry.erl using CEAN full download on windows gives me an error…I’ve checked to make sure I’m pointed at the right directory…

=ERROR REPORT 11-Apr-2007::15:51:18 ===
Error in process <0.46.0> with exit value: {undef,[{compile,file,[geometry,[repo
rt_errors,report_warnings]]},{c,c,2},{erl_eval,do_apply,5},{shell,exprs,6},{shel
l,eval_loop,3}]}

exited: {undef,[{compile,file,[geometry,[report_errors,report_warnings]]},
{c,c,2},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]}

(Joe: This is a CEAN bug - not a bug in the book
use the erlang distribution from
www.erlang.org)

2007-04-12
142TYPO

Last paragraph begins “Because an Erlang system consists of large number of parallel processes…” should read “Because an Erlang system consists of a large number of parallel processes…” or “Because an Erlang system consists of large numbers of parallel processes…”.

2007-04-12
41OK

The shell command that’s stated in paragraph 3 doesn’t work.

6> shop1:total(Buy).
123

All I receive from typing that command into the shell is:

1: variable ‘Buy’ is unbound

(Joe: have you typed all the lines?
\tYou can’t just type line 6
1> Buy = …
is where it was defined on the previous page.
See note in section 1.5 where it tells you to type all the
lines)

2007-04-12
42OK

The code listing for sum should contain the export line too, as without is the discussion later about the naming of sum/2 will be confusing.

(Joe: footnote 4 page 39. Func/N means the function Func with N
arguments whether exported or not)

2007-04-12
170TYPO

“So, for example, there is a complete self-contained client-sever architecture and a form of error recovery based on explicit manipulation of links.”

The word “server” is misspelt.

2007-04-13
98TYPO

“we can write a binary digit as 2#00101010”

We’re writing a number, using multiple binary digits. It should say something like “we can write a number in binary as 2#00101010 or a number in hexadecimal as 16#af6bfa23”.

2007-04-13
105TYPO

“Makefile” is capitalized inconsistently. On p. 105, I see “Makefiles” and “makefiles” (each in the middle of a sentence). It seems that most of the uses are lower case (except in section headings), so you might want to make them all lower case. See also pp. 114, 119, and 196.

2007-04-13
353ERROR

The “Should I Care About Multicore CPUs?” box states that Sun has a 32 core Niagara machine on the market today. However isn’t the UltraSPARC T1 a 6 or 8 core CPU with 4 threads per core? That would make the high-end have 32 threads, represented as 32 CPUs under Solaris, but really it only has 8 cores.

2007-04-15
279TYPO

“OPT” should be “OTP” in the second sentence of the chapter (…because OTP is far more general…)

2007-04-15
282TYPO

Misspelling of “original” in comment for loop/3: “loop with the origonal state”

2007-04-15
302TYPO

Last two lines:
Var = …
qlc:q(Val)

‘Val’ should be ‘Var’

2007-04-15
307TYPO

Shouldn’t the availability test “NOranges > Nwant”
be stated as “NOranges >= Nwant”

Comment Opps - not enough oranges
Should be “Oops”

2007-04-15
279TYPO

In the footnote: “Ericsson has released OPT …”

2007-04-16
308TYPO

The word “transitions” should be “transactions” in the next to last line of the page.

2007-04-15
291TYPO

Amount misspelt as ‘Ammount’

2007-04-15
292TYPO

‘Opts controlls the’ should be ‘Opts controls the’

2007-04-15
292TYPO

‘The call gen_ser ver(Name, Mod, InitArgs, Opts) starts’ should read ‘The call gen_server:start_link(Name, Mod, InitArgs, Opts) starts’

2007-04-15
289TYPO

The second function in the list of functions in step 2, I think, should be “stop()”.

2007-04-15
295TYPO

‘system per fomr ms a software’ should read ‘system performs a software’

2007-04-15
340TYPO

“Let’s lanuch our company” should be “launch”.

2007-04-15
344SUGGEST

The start/2 function really can be reduced to just
start(_Type, StartArgs) ->
sellaprime_supervisor:start_link(StartArgs).
since the case statement only returns any value anyway.

2007-04-17
309TYPO

In the note on the top “You can’t possible call it amnesia …”

2007-04-15
345TYPO

“applictaion” should be “application”.

2007-04-15
348TYPO

“error_loggersupervisor” should be “error_logger, supervisor”.

2007-04-15
314TYPO

‘nodes crashes, the table’ should read ‘nodes crash, the table’

2007-04-15
317TYPO

‘These are operation which’ should read ‘These are operations which’

2007-04-15
336TYPO

‘compute_area({rectonge, X, Y})’ should read ‘compute_area({rectange, X, Y})’

2007-04-15
336TYPO

just dawned on me that the previous error I posted (rectongle) is probably intentional… doh!

2007-04-15
338TYPO

first worker in the supervision definition should be ‘[area_server]’ not ‘[prime_server]’. same problem exhibited on the next page too.

2007-04-15
340TYPO

‘Who want to buy’ should read ‘Who wants to buy’

2007-04-15
361TYPO

url doesn’t exist: erlang.org/multicore

2007-04-17
365TYPO

‘Waring: The word map, ’ should read ‘Warning: The word map, ’

2007-04-15
370TYPO

code contains a function ‘possibly_stop()’ but the text refers to ‘should_i_stop()’.

2007-04-15
281TYPO

“… the same time it contain the interfacing…”

contain should be contains.

2007-04-15
31TYPO

The first paragraph of section “1.11 Strings” states: “Strings are enclosed in single quotation marks (”)" but clearly the quote mark in the parentheses is a double quote and the section goes on to state: “Note: In some programming languages strings can be quoted with either single or double quotes. In Erlang you must use double quotes. ”

2007-04-15
130TYPO

Typo “If non of the patterns match,”…

non should be none

2007-04-15
132TYPO

“Having received a message, the process prints out the area of the rec-trangle.”

A rectRangle sounds fascinating but I think you mean rectangle.

2007-04-15
290ERROR

In the body of handle_call in gen_server_template.mini, “Reply” is unbound. Is this intentional? It is just a template, after all, but the other callback routines don’t have unbound variables.

(Joe: Yes It’s Intentional, if you don’t edit this
you’ll get a compiler error, which will remind you to change it)

2007-04-15
327TYPO

“every” should be “ever” in "…nobody can every remember all the arguments to the logger

2007-04-15
355TYPO

“effected” should be “affected” in “all processes reading the table will be effected”

2007-04-16
279TYPO

I think COBRA is supposed to be CORBA

2007-04-15
283TYPO

seveer should be server (2nd paragraph)

2007-04-15
180TYPO

“The user interface is a GUI widget which is used to send messages”.

“to” is missing.

2007-04-15
151SUGGEST

To avoid any ambiguity, I would rewrite
“… When a process receives a kill signal, it dies and
broadcasts killed signals to the processes in its link set. This is used by the supervisor process in OTP to kill rogue processes. This is a safety measure to avoid accidently killing more of the system than you had intended.”

as

“… This is used by the supervisor process in OTP to kill rogue processes. When a process receives a kill signal, it dies and broadcasts killed signals to the processes in its link set. This is a safety measure to avoid accidently killing more of the system than you had intended.”

Second phrase becomes the first one. Because the second “this” refers to the kill->killed behavior.

BTW, nice rewriting of the signal stuff. It’s crystal clear now :)

(Joe: Thanks Ludovic. Replacing the pseudo code with
a table made things much clearer. Also adding the
three idioms which actually cover virtually all code
you’ll every see. I was very good to get all the
errata which basically said “we don’t grock this stuff”
I’m delighted that the rewrite seems to have done the trick)

2007-04-15
339TYPO

In the text immediately following the init/1 data structure, “stragegy” should be “strategy” and “talked about … early” should be “talked about … earlier”.

2007-04-15
340TYPO

In the text about [Mod1] you make reference to “gen_sever”. You also missed a closing parenthesis at the end of that paragraph.

2007-04-15
343ERROR

The sentence at the bottom of the page implies that the report displayed by rb:show(3) is a fan alarm. Did you mean for this example to show the results of rb:show(2) and rb:show(1) instead of (3)?

2007-04-15
344TYPO

sellaprime.app contains {modules, […, selaprime_supervisor,…]} and {registered, […, sellaprine_super]}.

2007-04-15
346TYPO

Second paragraph, “When we build complex systens”. The second sentence sounds clunky starting with “So” too, better to join the two sentences with a comma or rephrase the second one “This allow us to start and stop…”

2007-04-15
26ERROR

Atoms can contain dots too. This isn’t mentioned in the erlang reference manual either.

2007-04-16
59SUGGEST

You need to explain what a “reference” is somewhere.

2007-04-17
279TYPO

“because OPT is far more general that you might think”, the “OPT” should be “OTP”.

2007-04-15
279TYPO

"OTP contains a number of powerful tools

2007-04-15
283TYPO

Second para. “the” should be added in the phrase.

“When the handler function fails the client which sent the message which caused the failure is sent a message which causes it to crash.”

2007-04-15
284TYPO

first sentence.

“If we send the server a swap code message then it will change the callback module to the new module contianed in the message.”

2007-04-15
321TYPO

“to to” -> “to”

2007-04-15
283TYPO

State1 should be NewState.

“But if the handler function succeeded then it loops with the
new value of State1 provided by the handler function.”

2007-04-15
284ERROR

The module new_name_server still imports functions from the module named server1. Should be server3.
Maybe it’s worth mentioning somewhere that the import of name_server should change when we use server2 instead of server1 and server3 instead of server2.

2007-04-17
279TYPO

‘because OPT is far more’ should be ‘because OTP is far more’

2007-04-15
19SUGGEST

The numbers in the prompt are not sequential. They should be 1>, 2>, 3>, … instead, they are 1>, 2>, 5>, 6>

2007-04-15
22TYPO

Near the bottom of the page in the sentence beginning, "I

2007-04-15
290SUGGEST

This is the first page where the -behaviour(…) declaration is used, and it’s never formally defined. Some mention of what it really does, how the machine handles it, something technical (other than a comparison to J2EE containers) would be nice.

2007-04-15
356SUGGEST

BIG THANKS for the new release of the book. 5 new chapters - WOW.
Great work Joe, and the team! Just wanted you to know that even if my feedback seems nit-picking I recognise how much work must go into such an endeavour and it is great tha you have opened the book up early. I hope we are all benefiting from the approach.

(Joe: Thank’s Ross for those kind words.
This has been an amazing experience.
Simple comments like “I don’t understand this”
have lead to 3 page rewrites (like the stuff on
records and error handling) - I have never had
feedback like this before and I’m certain it
improves the quality of the book - direct contact
with the readers)

2007-04-15
356TYPO

next concert of the The Strolling Bones.
<<next concert of the The Strolling Bones concert.

2007-04-15
337TYPO

“…one_for_oneorall_for_one.”
Not sure if it’s an issue with my PDF viewer (OSX Preview) or what, but there appear to be no spaces between one_for_one, or, and all_for_one. Just a bit of an aesthetic issue, probably.

2007-04-15
361TYPO

missing to:
If this parameter is omitted it defaults to the number of physical processors in the SMP machine.
<< If this parameter is omitted it defaults the number of physical processors in the SMP machine.

2007-04-15
299TYPO

Spelling:
gen_server
<< We haven

2007-04-16
358TYPO

“… dictionary will not be effect the process…”
the “be” is a typo. Should read “will not effect…”.

2007-04-15
12TYPO

“How to run and optimize you program” should say “How to run and optimize your program”

2007-04-15
287ERROR

Is it necessary to have the pattern {become, G} in the receive statement of my_fac_server:loop ?

2007-04-17
293TYPO

“reply” should be written with a capital R.

“Normally we return {reply, Reply, NewState}. When this happens, reply goes back to the client, where it becomes the return value of gen_server:call. NewState is the next state of the server.”

2007-04-15
295TYPO

In the code change section:
“This topic is described in detail in the section on Release handling in the OTP design principles documentaion

2007-04-15
300SUGGEST

In the footnote:
“Structured Query Language, which is used to query relational databases.”

FYI, SQL is not an abbreviation. It is just a three letters word. It comes from SEQUEL and was renamed. But it is a popular belief that it stands for Structured Query Language.
Source: Jim Melton’s SQL:1999 book

2007-04-15
302ERROR

IMHO, qlc is “one of the modules” instead of “one of the functions”. And q is one of the functions.

In fact, qlc stands for

2007-04-15
303TYPO

“shops” should be written “shop” in singular form in the from clause of the SQL query

SQL equivalent
SELECT shop.item FROM shops
WHERE shop.quantity < 250;

2007-04-15
304TYPO

there should be commas in the select list
SELECT shop.item, shop.quantity, cost.name, cost.price

SQL equivalent
SELECT shop.item shop.quantity cost.name cost.price
FROM shop, cost
WHERE shop.item = cost.name
AND cost.price < 2
AND shop.quantity < 250

2007-04-15
307TYPO

Arity of function insert is missing.

“Note: mnesia:insert/ and mnesia:delete/1 should only be called inside a fun which is processed by mnesia:transaction/1.”

2007-04-15
306SUGGEST

In the example code you use the function “write” to insert tuples in the DB, but in the text (section 15.3) you refer to function “insert”. Both functions exist ?

In particular, you say at the beginning of section 15.3:
“When we added and removed data from the database, we wrote the code something like this.:”
But in fact insert was not used in the examples.

2007-04-15
365TYPO

“Acc is an accumulator. Whose initial value is Acc0.”

This shouldn’t be two sentences. “Acc is an accumulator whose initial value is Acc0.”

2007-04-15
365TYPO

“…each value of Xin L.”

Another one where (at least for me) the space between your font for variables and the font for normal text is getting eaten. As long as the print copy looks OK this doesn’t matter, but it looks a bit ugly in PDF.

2007-04-15
236SUGGEST

In the phrase ‘terminates a standard internet protocol’ I’d prefer a word other than ‘terminates’ maybe ‘supports’ as this suggests the software could filter or translate between protocols as well as just sit at the very end of a protocol.

2007-04-16
238SUGGEST

‘we use a very simple convention and say that every logical request or response will be preceded by a N (1, 2 or 3) byte length count.’ This sentence is a bit confusing. Maybe it could be something like ‘we use the very simple convention that every logical request or response will be preceded by an N (1, 2 or 3) byte length count.’

2007-04-16
238SUGGEST

‘using term_to_binary and its inverse to encode and decode the data.’ might be clearer as ‘using term_to_binary to encode and its inverse to decode the data.’

2007-04-16
240TYPO

‘This does not effect’ should be ‘This does not affect’.

2007-04-16
240SUGGEST

‘computes a reply, sends a reply’ could be ‘computes a reply, sends the reply’ if we are sending ‘the’ reply we have just computed rather than ‘a’ reply which might not be the one we have just computed.

2007-04-16
240SUGGEST

There are two sentences starting ‘To test this’ where I found ‘this’ to be unclear. Maybe the the first could be ‘To test it’ where ‘it’ means the server and the second could be something like ‘For this test’ or ‘As a test’. I wasn’t sure whether the second ‘this’ meant the client, the server or a combination of the two.

2007-04-16
240TYPO

‘move the the client window’ should be ‘move the client window’

2007-04-16
240TYPO

My typo: I meant ‘move to the client window’

2007-04-16
56SUGGEST

Would be nice to have the explanation of perms somewhere. Maybe you can come back to it in a later chapter or something. I am not really fond of these kind of cliff hangers…

(Joe: there must be some mysteries left)

2007-04-27
241SUGGEST

When I read the restated start_nano_server I was wondering what happened to the gen_tcp:close that was in the original code. Maybe it’s OK to drop this without comment, but it made me go back and re-read the original.

(Dave says: the first version could only handle one incoming call at a time. This version supports multiple concurrent calls)

2007-04-17
242SUGGEST

I think ‘The crucial difference is the additional spawn’ should be ‘The crucial difference is the addition of spawn’, since ‘additional’ suggests there was one there already and we are just adding another, whereas there were actually none there originally.

2007-04-16
242SUGGEST

‘look at the placement of the additional spawn statements’ can be ‘look at the placement of the spawn statements’ since we are looking at the placement of all the spawn statements not a subset of them.

2007-04-16
244TYPO

‘We can only write a non-blocking server’ should be ‘We should only write a non-blocking server’

2007-04-16
244SUGGEST

‘The code in the server loop calls gen_tcp:recv every time it wants to receive data. If it never calls recv then the client will block until the server has called recv.’ could be expressed more concisely as ‘The server loop calls gen_tcp:recv every time it wants to receive data. The client will block until the server has called recv.’

2007-04-16
245SUGGEST

I was confused by the sentence which starts ‘Unfortunately if we use passive mode’. Maybe this could be rewritten somehow.

2007-04-25
247SUGGEST

‘We spawn a server (and sleep for two seconds to give it a chance to start). We then send it a message containing the binary <<’123’>>.’ might be reworded to get rid of the brackets: ‘We spawn a server, sleep for two seconds to give it a chance to start, then send it a message containing the binary <<’123’>>.’

2007-04-16
247TYPO

‘When this message arrives at the server, the server tried … crashes.’ There is a confusion of tenses between ‘arrives’, ‘tried’ and ‘crashes’ which doesn’t seem right.

2007-04-16
252SUGGEST

‘Here we need two ports, one which is used to send the broadcast the other to listen for answers.’ might be simpler as ‘Here we need two ports, one to send the broadcast and the other to listen for answers.’

2007-04-16
252TYPO

‘the the folks’ should be ‘the folks’.

2007-04-16
53TYPO

In the second paragraph after the doubling the number of items to buy example, first sentence, ‘original’ is misspelled.

2007-04-16
54TYPO

Discussion at end of page (referring to the Quicksort example) does not match the code presented. Specifically, the Smaller list consists of [X || X <T, X =< Pivot], when the presented code has the list being constructed via [X || X < T, X < Pivot] (i.e., not =<, just <). The same applies to the Bigger list presented on the start of page 55.

2007-04-16
312TYPO

top of the page, RAM tables.
database should be written as a single word.

“These are very fast. The data in them is transient so it will be lost if the machine crashes or when you stop the data base.”

2007-04-16
74TYPO

Near the top of the page, “… we lose a lot precision …” should read, “… we lose a lot of precision …”.

2007-04-16
313TYPO

Under “Common Combinations of Table Attributes” it says: "In all the following, we

2007-04-16
323TYPO

At the bottom of the page: “event_handler:add(Name, Fun)”. But the code shows this function name as “add_handler”.

2007-04-16
176TYPO

Remove the word “what” from the sentence "Here

2007-04-16
177TYPO

Just after mod_name_server.erl in the bulleted list, in the phrase “it will appear in mod_name_server as a messages of the form” the word “messages” should instead be the singular “message”.

2007-04-16
177TYPO

In the last bullet item on the page, replace “be” with “by”: “If the server wishes to explicitly close the connection, it can do so by evaluating MM ! close”

2007-04-16
178TYPO

In the final sentence on the page, “The configuation file specifies which applications are permitted on this machine, and which port is to be used to communicate with these applications,” the word “configuration” is misspelled.

2007-04-16
300SUGGEST

‘look a lot like both SQL and like list comprehensions’ might read better as ‘look a lot like both SQL and list comprehensions’.

2007-04-16
301TYPO

‘I want to you follow’ should be ‘I want you to follow’.

2007-04-16
303SUGGEST

It would be nice to have the SQL code using consistent capitalisation and field referencing. So we see ‘Item’ in the first example and ‘shop.item’ in the second which seems to do the same thing.

2007-04-16
306TYPO

Stray full stop in ‘something like this.:’

As a point of style I would prefer the words ‘as follows’ which often precede examples to be dropped. These words rarely tell us anything the colon doesn’t. I like your simple direct wording better

(Joe: as regards style I’m waiting for the proof reader for the final
word)

2007-04-16
284SUGGEST

Why call ‘new_name_server:all_names().’ here ? Shouldn’t this read ‘server3:all_names().’. That seems me to be th point of the exercise

(Joe: server3 does not export all_names().
new_name_server exports all_names(). The code is
correct. The point of the exercise was to change the callback
module on-the-fly and this is what happened)

2007-04-17
307TYPO

‘This code is written is a pretty stupid way’ should be ‘This code is written in a pretty stupid way’

2007-04-16
310TYPO

‘Java Programmer’ should be ‘Java programmer’

2007-04-16
312TYPO

I think ‘mnesia:_create_table’ should be ‘mnesia:create_table’

2007-04-16
313TYPO

‘instances of this record..’ has an extra full stop and ‘on page 262’ is missing one.

2007-04-16
314TYPO

‘When the crashed node come back on-line’ should be ‘When the crashed node comes back on-line’

2007-04-16
315SUGGEST

‘In the previous session, we exit’ would be better as just ‘Then we exit’ or maybe ‘We exit’ since the preceding sentences seem to be talking about the same session as the one we now want to refer to.

2007-04-16
315TYPO

‘the the initial display’ should be ‘the initial display’

2007-04-16
317TYPO

‘Dirty operation are used’ should be ‘Dirty operations are used’

2007-04-16
356TYPO

At the end of the page: “But it but it”

2007-04-16
34SUGGEST

is it possible to include some writing about parameterized modules?
Keep up the great work!

rjkerkhoff@gmail.com

(Joe: We decided not to mention parameterized modules.
They still have “unofficial” status)

2007-04-16
356TYPO

“These is no cheap and easy fix here.” these should be there

2007-04-16
287TYPO

In the “Erlang on PlanetLab” box: “Once I’d got this layer running it was an easy job to send messages to the empty severs telling them to become real servers.”

The word “servers” is spelled incorrectly the first time.

2007-04-16
309SUGGEST

Could you add a note somewhere (maybe in the box) that says how “mnesia” is pronounced?

(Joe: like amnesia without the a)

2007-04-17
376SUGGEST

The description below is confusing. The description on p 374 seems clearer. Perhaps:
Note: spec and type will only be found embedded in comments.
example @spec fac(int()) -> int().

<< Note: spec and type will only be found in documentation files, this is
not part of the Erlang language, so you

2007-04-17
186TYPO

Second line on the page: the word “happened” is misspelled.

2007-04-17
59TYPO

“In guards, which are side-effect free, there is no difference between (and and andalso) or between (or and orelse).”

This is not true. One of the reason for allowing orelse and andalso in guards is illustrated by this example:

6> f(X), X = 0, (X 0) or (1/X > 2). ** exited: {badarith,[{erl_eval,eval_op,3}, {erl_eval,expr,5}, {erl_eval,expr,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** 7> f(X), X = 0, (X 0) orelse (1/X > 2).
true

2007-04-17
338TYPO

Not shure if the module name mentioned by the other poster should not be [sellaprime_supervisor]

2007-04-17
94TYPO

footnote, comple probably should be compile?

2007-04-17
16TYPO

In the erl example on line 2 should be:
>1 % I’m going to enter some expressions in the shell..

Note: I added the ‘>1’ and the ‘to’.

2007-04-17
314TYPO

a ] is missing at the end of the expression.

mnesia:create_table(shop,[Attrs,{disc_copies,[node()]})

2007-04-19
363TYPO

“The results are show in Figure 17.1” should be “The results are shown in Figure 17.1”.

2007-04-19
59TYPO

[Correction of my last comment]

A more complex example is needed to see why short-circuit Boolean guards are sometimes necessary:
1> f(X), X = 0, if (X > 1), ((X 0) or (1/X > 2)) -> a; true -> b end. b 2> f(X), X = 0, if (X > -1), ((X 0) orelse (1/X > 2))> a; true -> b end.
a

(Joe: This example is too complex - this is an extremely
rare form of guard. Adding more text would make this section
unecessarily complicated and in an area that is not
\t really important. Guards such as your example
are exceedingly rare and the text is correct as it stands.)

2007-05-04
189TYPO

Second sentence in the Group Manager section: the word “is” is missing from the sentence “The most important part of this is the dispatcher.”

2007-04-19
386TYPO

down on page you write ‘This is done in lib_chan_auth:check_resopnse’ . Besid eth typo the name of the fuction should read :is_response_correct

2007-04-19
206TYPO

In the phrase “preceeded by a two byte header” the word “preceded” is misspelled.

2007-04-19
207SUGGEST

In discussing the interfacing to the C code, you should also note that the example you give is extremely trivial, and provide a deeper discussion of the details of exchanging data between Erlang and C. You mention the fact that Erlang and C have different ideas of integer sizes, but that’s just the tip of the iceberg, isn’t it? You should at least mention the fact that you’ll talk more about complex data and interfacing at the end of the chapter.

2007-04-25
208SUGGEST

It would be helpful if you could briefly describe an example of using {fd, In, Out} with open_port. No need to show code, but just a sentence of two describing how it would be used would be helpful.

2007-04-25
369TYPO

Just a little typo: “One we have built an inverted index” instead of “Once we have built an inverted index”

2007-04-19
279TYPO

The word “about” is doubled in the phrase “The writer of the callback does not have to worry about about things like fault-tolerance” toward the bottom of the page.

2007-04-20
3SUGGEST

I am currently reading the e-print of the book on Erlang by Joe Armstrong. Almost fnished a first round through the book.

Sofar I like the tone of the book: personal, pleasant; in all good stuff, with good examples.

I started working on the code examples right from the start. Somewhere in one of the chapters, still in the sequential part of the book when error handling is reported, the text says something like “if you followed along with the code examples, you probably have seen error messages”. Spot on, but I would suggest that certain sidebars from chapter 5, especially the one on the export statement, should be moved a little bit to the front of the book, as they provide essental clues to some of the arity errors.

(Joe: Difficult to know where to place it
the early pages are somewhat crowded with sidebars.
I’ve actually mentioned export_all quite a few times
and arities - I don’t want to have too many ’cos
it gets to be nagging)

2007-04-25
237SUGGEST

In your function receive_data/2 on pg.237 in the PDF the function concat_binary/1 is used. This function is deprecated and should be replaced with list_to_binary/1.

2007-04-25
283SUGGEST

You show code swapping by defining a different module then explicitly swapping to it in the server. Perhaps you should mention what would happen if you just modified and reloaded the currently used module.

(Joe: described in the appending on dynamic code
upgrade - “only confuse the reader with one thing at a time”)

2007-04-25
302SUGGEST

You should probably mention that the include_lib in mensia_tests.erl
-include_lib(“stdlib/include/qlc.hrl”).
is necessary for the qlc:q/1 function to work as it is not completely normal function call. You might need a small section on parse transforms as well.

2007-04-25
356TYPO

In the 4th paragraph there is a sentence starting “These is no cheap and easy fix here.” It should be “There is no …”.

2007-04-25
61TYPO

Warning: -record is not a shell command (use -rr in the shell, see the
description that comes later in this section).

The shell command is just ‘rr’ and not ‘-rr’.

2007-04-25
22TYPO

This is a nitpick, but the inconsistency bothered me a bit.

7> Y=X.

The previous lines all had spaces around the equals sign (i.e. Y = X.)

2007-04-25
268SUGGEST

You introduce aNewStyleInNames in this chapter as compared to_the_usual_one, you also mix them in the same program. Using underscores in names like_this is generally considered to be more readable. You should be consistent throughout the book.

2007-04-29
339TYPO

In the Worker specification tuple you call the first field ‘Tag’ while in the description which follows you use ‘Id’.

2007-04-25
347TYPO

In the paragraph on stopping an application you say to call application:_stop(sellaprime), it should be application:stop(…).

2007-04-25
280TYPO

More of a question really. Do you need more discussion about when to use generic servers and when to completely roll your own?

(joe: Not added Then I’d have to explain flush which would
probably confuse matters)

2007-05-04
267SUGGEST

Should you say more about the value of actually doing tests and measuring to determine the best algorithm to use. While it is obvious it could certainly be stressed as a good programming practice. A small box?

2007-04-25
271SUGGEST

From the text it is unclear which set won as there are two of them. Perhaps just say Ets set to make it clear. It is not really necessary as you give the results.

2007-04-25
15SUGGEST

It might be useful to mention that users may have to cean:install(compiler), depending on their installation. Not knowing this, I ran into the initial examples in the book and was immediately frustrated by being unable to compile the beams (CEAN seems to be a great resource/idea, but this gotcha seems inadequately documented).

2007-04-25
200TYPO

The phrase “all message from the external program are sent to the connected processes” should instead say “messages”.

2007-04-25
199TYPO

“Stare at the message sequence diagram in Figure 9.2, on page 181 make sure you understand in and check you can identify all the messages in the program code.”

Should probably read: “Stare at the message sequence diagram in Figure 9.2, on page 181. *Make sure you understandit* and check that you can identify all the messages in the program code.”

2007-04-25
27TYPO

“Which creates a tuple and binds it to the variable P.” is not a complete sentence.

2007-04-25
393SUGGEST

I think B.1 Fetch MingW and B.2 Fetch MSYS has nothing whatsoever to do with using Erlang on Windows. I think these steps are just for those who don’t really like Windows and would like a UNIX like environment everwhere.

For someone who knows and likes Windows it is perfectly enough to download the Erlang version for Windows (prebuilt binary) and start programming. Emacs is still very useful because of the Erlang mode, but there are alternatives which also support Erlang.

You would need MingW etc. if you need to do some C-programming on Windows (if you don’t have the Microsoft C/C compiler etc.) but that is not what this book is about.

2007-04-25
273TYPO

Change “a” to “an” in “survive a entire system crash”

2007-04-25
429SUGGEST

I think the F.1 and F.2 chapters are pretty useless. With no describing text, what use are they.
Apart from the questionable usefulness the information is also WRONG since it lists modules which are not part of the public interface. Fore example dets_v9 is by no means a module with public functions. There are lots of other modules which also only are helper modules to other modules. For example: dets is a module with a public API, it uses dets_v8 and dets_v9 and possibly other modules for its implementation but these modules are not part of the public interface. So, the list of mudules and functions , if to be published like this must be generated from the correct source , which is the dsitributed documentation. It MUST NOT BE GENERATED FROM THE ACTUAL MODULES.

2007-04-26
424SUGGEST

I think the chapter about tracing is weak and that’s a pity since that is one of the real strenghts of Erlang (compared with other languages).
The tracing is always available (no need to compile in a special way).
Basic Tracing can easily be activated without need for programming.
Especially the call trace (on function calls and returns) is really useful as an alternative to the debugger.
Tracing can and is used for troubleshooting in live commercial systems.
Other applications in the OTP distribution which offer frontends to the trace facilities are ttb (trace tool builder) in the observer application. And the inviso application (under development) but already part of the distribution.

The trace output can be directed to the Erlang shell, to a file, to a TCP-socket or to a ram-buffer.

Togheter with call trace there are so called match-specifications where conditional tracing patterns can be created. For example trace on function foo(Arg) only if called with Arg=1. This is a very valuable feature for limiting the output which can be huge depending on trace pattern.

There is also something called sequential tracing (forlopp) where the trace can follow the message chain between processes from a chosen start-point.

2007-04-27
381TYPO

how mapreduce words => how mapreduce works

2007-04-25
373TYPO

Left off the full-stop at the very end of the page.

2007-04-25
374ERROR

Read pedantically, your “SMP” footnote suggests that one single-core CPU could be an SMP system. I would rephrase it as “An SMP (Symmetric Multiprocessing) machine has two or more identical CPU cores which are connected to a single shared memory. These CPUs may be on a single multi-core chip or spread across several chips, or a combination of both.”

2007-04-25
14TYPO

“build you own behaviors,” should be “build your own behaviors,”

2007-04-25
14TYPO

“We need errors logs” should probably be “We need error logs”

2007-04-25
14TYPO

“about shared_memory” should probably be “about shared memory”

2007-04-25
14TYPO

“full text search engine written.” should probably be “full text search engine written in Erlang.” or perhaps “full text search engine.”

2007-04-25
164TYPO

“Ideom 3” should be “Idiom 3”.

2007-04-25
398TYPO

“at mmany sites”. Should be “many”

2007-04-25
420ERROR

Footnote 1: einval is short for “Erlang Input Value”.

This is wrong. einval is a POSIX error code that stands for “invalid value”.

2007-04-25
428SUGGEST

You can link directly to the description of purge_module/1 by using an anchor:

www.erlang.org/doc/man/erlang.html#purge_module/1

2007-04-25
394SUGGEST

Why not putting the step about installing Erlang as step B.1, and point out more clearly that the other steps are optional.

2007-04-25
16TYPO

Acknowledgements, 4th paragraph: Spelling: Rickard Green (a “c” is missing before the “k”).

2007-04-25
258TYPO

“and {K1,K2,K3,K4,K5,K5,K7,K8} for IPv6” => second K5 should be K6

2007-04-25
381TYPO

line 19 is missing the word “look” - “contents might like this”.

2007-04-25
38SUGGEST

In the chapter “2.10 Lists”, it is said that we can “add more than one element” to the beginning of a list with the syntax:
> NewList = [E1, E2, E3, …, En | Tail].

But the same syntax can be used to “extract multiples elements” from the head of a list (in a pattern matching context with the = operator), that’s why I suggest adding another example to the paragraph named “Extracting elements from a list”, something like:

> [Buy3, Buy4, Buy5 | ThingsToBuy4] = ThingsToBuy3.
(where 3 elements, named Buy3, Buy4 and Buy5, are extracted from the head of the list ThingsToBuy3)

or:
> [Buy1, Buy2 | ThingsToBuy2] = ThingsToBuy1.
(which would replace the two examples seen on the lines 4> and 5>)

Another example can be seen in the book “Getting started with Erlang”, chapter “2.5 Lists”:
> [E1, E2 | R] = [1, 2, 3, 4, 5, 6, 7].

2007-04-25
338TYPO

error_msg should be written using another font because it is the name of a function.

"I

2007-04-25
344TYPO

Top of the page.

“To isolate a partiular error we can use commands”

2007-04-25
345TYPO

Top of the page. handler_event should be handle_event.

“The interesting routine is handler_event(Event, State).”

2007-04-25
345SUGGEST

What is the purpose of “xyz” ? I can’t see where it is explained. It looks like a dummy atom but what’s the semantic of the atom ?

gen_event:swap_handler(alarm_handler,
{alarm_handler, swap},
{my_alarm_handler, xyz}).

2007-04-25
347TYPO

Bottom of the page.

“This is also written with the gen_server behavour.”

2007-04-25
373TYPO

practice.

“To see how this works in practise we need a script which automates our tests.”

2007-04-25
374ERROR

URL gives a 404 error.

http : // www.erlang.org / news.html

2007-04-25
426TYPO

As coded, the sleep() function sleeps for three seconds (3000ms), not two.

2007-04-25
425SUGGEST

The section on dynamic code loading would benefit from having a statement at the beginning as to how it actually works from a coding perspective. My understanding from the old book is that the full function reference filename:function() is the key. If in the example code for module a.erl the tail-recursive call to loop had been “a:loop(Tag)”, then recompiling module a.erl would result in code replacement. Perhaps add that to the end of your example?

A minor nit - show the startup as “Pid1 = a:start()” so the processes can be killed at the end of the example!

2007-04-25
393TYPO

URL to download mingw should be download.shtml instead of download.html. Error 404.

http: // www.mingw.org / download.shtml

2007-04-25
397SUGGEST

IMHO, the name of Mickael Remond should be spelled Micka

2007-04-25
398TYPO

“The Comprehensiove Erlang Archive Network. An attempt to merge all ongoing Erlang projects.”

2007-04-25
398TYPO

Depository. Or do you mean “repository” ?

“A large depositry of Erlang projects at sourceforge.”

2007-04-26
400TYPO

“a” is doubled.

“To make the appendix self-contained there is a a considerable amount of overlap with the material in Section 10.5, lib_chan, on page 187.”

2007-04-26
402TYPO

access should be written with a capital A

“Step 4 - access the server over the network”

2007-04-26
292SUGGEST

I’d like to see a list of supported behaviors and a reference to the documentation here at the beginning of Chapter 16, since some of these behaviors will be illustrated in Chapter 18. Perhaps you can then say which ones you’re using to build the sample OTP application in Chapter 18.

As a side question, the Road Map for this chapter talks about writing your own behavior. Is it actually possible to create your own behavior template, then use in some code as

-behavior(my_behavior_template)

(Joe: I don’t think so - you have to tinker with the compiler)

2007-04-27
27TYPO

“To have shatter” might have to be “to have to shatter” :) French speaking here so I’m hesitating.

"What on earth is going on here? Well, to explain it, I

2007-04-26
30TYPO

Doubled “you”.

In side note, "If you you use a conventional programming language like C or Java to program a multicore CPU then you will have to contend
with the problem of

2007-04-26
1SUGGEST

A very good book that could be easily turned into a very great book by adding two important parts: Yaws and XMerl - that will show a lot of programmers the way to everyday usage of Erlang for web apps (a huge market).

(Joe: I think yaws needs it’s own book.
For now there’s just a reference.
Read the next thrilling installment …)

2007-04-27
396SUGGEST

The first link is called the Main Erlang manual page and is pointing to …..doc/erlang.html. I think this is very strange since erlang.html contains descriptions of the built in functions, a specific module but nothing “main” about this. I think this link should point to the roor of the complete documentation for an Erlang OTP distribution which is www.erlang.org/doc/. There is no link like that mentioned elsewhere (at least I can’t find any)

2007-04-26
363TYPO

The following:
changed)

2007-04-26
364TYPO

Last sentence:
Now on the final chapter…
I don’t think you are referring to the final chapter, rather the next chapter.

2007-04-26
364SUGGEST

I still think that you are not stressing enough that, since most Erlang programs (except compilers) already
is structured as a number of coworking processes they can take advantage of multi-core technology without changes. And that is quite unique compared with other languages.

2007-05-04
365SUGGEST

you

2007-04-29
368SUGGEST

This is very dangerous. It is only safe if: …
I think you are exaggerating , it is only dangerous if
a process is dependent of doing more than one operation in a row (dependent operations) without the table beeing change by another process during that time. This could actually happe even before the SMP support.

2007-05-04
219OK

When I try to run the Makefile as listed in the book I get:

make: * No rule to make target `example1_lid.beam’, needed by `all’. Stop.

(Joe: should work. Is there a file called example1_lid.erl
in the same directory as the makefile?)

2007-04-26
39TYPO

About half way down the page, you have doubled “the” in “… $a is actually the the …”

2007-04-26
58TYPO

In the last paragraph, you have doubled “the” in “Mapping any function over the the …”

2007-04-26
61TYPO

About half way down the page, you have doubled “the” in “… right hand side of the the …”

2007-04-26
110TYPO

In the first paragraph, you have doubled “the” in “… prints the the variables …”

2007-04-27
129TYPO

In the third paragraph, you have doubled “the” in “… first target in the the file …”

2007-04-26
195TYPO

Right before section 11.3, you have doubled “the” in “… entered in the the entry box …”

2007-04-26
202TYPO

In the first paragraph, you have doubled “the” in “… will be sent to the the group controller …”

2007-04-26
369TYPO

In the first paragraph after the title “A Distributed Ticket Booking System”, you have doubled “the” in “… next concert of the The Strolling …”

2007-04-26
322TYPO

In the mnesia_tests.erl example at the bottom of the page, the word “circle” is misspelled as “cirle”.

2007-04-26
13TYPO

“Chapter 14,”… “A SHOUTcast server. This is a streaming media
sever, which can be used to stream MP3 data to using the SHOUTcast
protocol.”

“sever”
“to using”

2007-04-26
14TYPO

“on page 363Is is”

2007-04-26
23TYPO

“$ erl Erlang (BEAM) emulator version 5.5.1 [source] [async-threads:0] [hipe] Eshell V5.5.1 (abort with ^G)”

On page 20 you said you would never show this information again. And on page it was 5.5.2!

2007-04-27
35TYPO

“If we want to extract some values from a tuple we use the pattern matching operator = ,”

The last character should be a dot.

2007-04-26
55TYPO

The last paragraph before the section “Defining Your Own Control Abstractions”
reads, “So Mult is a generalization of Double instead of computing a value, it
returns a function, which when called will compute the required value.”

This should be split into two sentences, the second starting with
“Instead…”.

Also, in my opinion the text in the latter half of this paragraph does not
need to be italicized.

2007-04-27
307TYPO

“how they occurred. terminate(Reason, State)”

Should not be a dot.

2007-04-26
394TYPO

“B.4 Erlang Got to”

“Go to”

2007-04-26
325TYPO

Near the bottom of the page, under “Creating Tables” the word “successfully” is misspelled.

2007-04-27
326TYPO

In the first sentence under “Common Combinations of Table Attributes,” there are extra words: "In all the following, we

2007-04-27
327ERROR

Is the last example of creating an Mnesia table not redundant?

mnesia:create_table(shop, [Attrs, {ram_copies, [node(),someOtherNode()]}, {disc_copies, [node(),someOtherNode()]}])

Should that be disc_only_copies instead. since disc_copies already implies ram_copies? Maybe I’m missing something, in which case I suggest adding some more explanation.

2007-04-27
398TYPO

In the first paragraph after the C.3 heading, last sentence, you have, “The page has pointers to a later number …”. The word “later” probably should be “large”.

2007-04-27
274TYPO

“survive a entire system”

Should be “an”

2007-04-27
274TYPO

“A kind of journaling system is used to recover corrupt Dets tables caused by a system crash.”

I think this a misunderstanding. There is no journal associated with a Dets table. Repairing a dets file means that all of the file is scanned byte by byte. That is why repairing a large Dets table can take such a long time.

2007-04-27
11SUGGEST

The text reads “…large-scale industrial products. That has great libraries and an….” Although the period emphasizes the two ideas, a comma may read better “…large-scale industrial products, that has great libraries and an….”

2007-04-27
11TYPO

The text of the last paragraph contains “…Chapter Chapter 18,….” I believe only one “Chapter” is intended.

2007-04-27
277TYPO

“sending message between processes”

Should be “messages”.

2007-04-27
277TYPO

“the table can be deleted by calling ets:delete.”

On page 274 you wrote:
“When we ve finished with a table we can dispose of it with dets:close(TableId) or ets:delete(TableId).”

One could draw the conclusion that dets:close deletes the table, which it doesn’t (of course).

2007-05-01
13SUGGEST

The text states that “Functional programming forbids code with side-effects.”

I’m unclear the audience you’re addressing with this statement. “Purists” may agree, “novices” (long away from school) may not understand side-effects, and those somewhat familiar with functional programming may treat this as a “slam” against their favorite functional programming language (for example, Lisp).

How can the text state more effectively what Erlang does without provoking a meaningless war about what constitutes a functional programming language?

(Joe: This is not the place to have a long discussion of
\twhat FP means - this is a short introduction not
\ta long discussion.)

2007-04-27
13SUGGEST

The text of the third paragraph states: “…but no locks, and no synchronized methods and….” I believe it reads better without the first “and”: “…but no locks, no synchronized methods and…”

2007-04-27
13SUGGEST

The text of the fourth paragraph states: “…which run on a single processor, can run on a multicore processor or be mapped to a network of processors.” I believe it reads better like: “…which can run on a single processor, can run on a multicore processor, or can run on a network of processors.”

2007-04-27
13SUGGEST

When I read the bullet describing chapter 5, I wondered, “What is the difference between ‘Sequential Programming’ described earlier and ‘Advanced Sequential Programming’”? How might the text answer this question more effectively?

2007-04-27
13TYPO

The bullet describing chapter 7 states: “…we change gear.” I believe it should read “…we change gears.”

(Joe: ?? Not sure - I’ll see what the proof reader says)

2007-04-27
13SUGGEST

The bullet for Chapter 8 states: “…create a parallel process in Erlang?” I think it might read better as: “…create parallel processes in Erlang?”

I found this text confusing. I thought to myself, “Parallel processes always occur in numbers greater than 1.” I understand that most people will not think of processes spawned by the Erlang shell as parallel processes, but for someone with more experience with operating system processes, using the plural term may communicate the intent more clearly.

2007-04-27
14SUGGEST

The text at the top of the page states: “We time how fast we can create parallel processes.” I believe it might read better as a question: “How fast can we create parallel processes?”

The text describing Chapter 8 on the previous page consists of questions. Because of this preceding structure, I expected another question.

2007-04-27
14SUGGEST

The bullet for Chapter 11 states: “…our first non-trivial application and develop a mini IRC-like….” I believe it reads better with a colon: “…our first non-trivial application: a mini IRC-like….”

When I read the bullet describing Chapter 14 which mentioned the “second sizable application,” I wondered, “What was the first?” It took me a few moments scanning backwards to find that application. I believe the colon helps emphasize that the mini IRC-like application is the first significant application.

2007-04-27
395TYPO

The steps are named B.x not A.x

2007-04-27
14SUGGEST

The text of the bullet on Chapter 16 states: “Our behaviors allow us to…”

I found this phrase confusing. Did we intend to use “Behaviors” (similar to our use in the immediately preceding text)? Or did we intend a more abstract meaning: “Separating a problem into independent behaviors allows us to….”

2007-04-27
15TYPO

The bullet for Chapter 19 states “…on page 364Is is a short….” I believe this should read “…on page 364 is a short….”

(I believe this errata may be identical to #8161.)

2007-04-27
15SUGGEST

The text describing Chapter 19 asserts that Erlang is well-suited from programming multicore computers. At least in the Microsoft world, Microsoft attempts to hide the multicore nature of the processor (although this hiding often causes previously working multi-threaded code to break).

Do we want to address why Erlang is a more productive environment than vendor-provided frameworks here? Do we want to address it later?

(Dave says: I don’t think so)

2007-04-26
15SUGGEST

When I first encountered the name “mapreduce” in the table of contents, I read it as “ma preduce” It was only here in the description of Chapter 20 that I realized it was “map reduce.”

Might we include an underscore to separate these two words to prevent others from making the same mistake?

(Joe: it’s called mapreduce in the literature - no blanks or hyphens)

2007-04-27
15TYPO

The bullet for Appendix C states: “…on page 397Has a catalogue….” I believe it should read “…on page 397 has a catalog” (The space is required; the American spelling is optional.)

2007-04-29
15TYPO

The text describes Appendix A and Appendix C. Where is the description of Appendix B?

2007-04-29
15TYPO

The text lists the description of Appendix C before the description of Appendix A. I believe these two descriptions should be reversed.

2007-04-27
19SUGGEST

The text of bullet 2 states: “You’ll start learning the libraries.” I believe the text reads better as “You’ll start learning the libraries (called modules).”

The next sentence describes the five modules most used by the author. If one is coming from another language background, “modules” may means something completely different from libraries. Indicating this equivalence may prevent confusion in the reader.

2007-04-27
21SUGGEST

The fourth paragraph states: “If you see something that looks like this, Erlang….” I believe it may read better like: “If you see something like the output above, Erlang….”

When I first read this code, I wondered, “To what does ‘this’ refer?” Because the Erlang banner code is far away in the readers mind (two whole paragraphs! :), I think it is better to clarify what ‘this’ refers to.

2007-04-27
23SUGGEST

The text states: “…give the command cean:install(compiler) which….” This text might read better like: “…execute the command cean:install(compiler) to the Erlang shell. This command….”

Although I recognized the syntax for an Erlang function call, other readers might not and might wonder, “How can I execute this in the (Unix/DOS) shell?”

2007-04-27
25TYPO

The fourth paragraph states: “…(like -module. -export etc.)” I think a comma is better than the period: “…(like -module, -export, etc.)”

2007-04-27
396TYPO

these paths don’t look like windows !

(setq erlang-root-dir “/usr/local/lib/erlang” )
(setq exec-path (cons “/usr/local/lib/erlang/bin” exec-path))

2007-04-27
395ERROR

Do you really suggest to unpack emacs under Desktop ? This would be desastrous with roaming profiles.

2007-05-04
25TYPO

The fourth paragraph states: “…(like -module. -export etc.)” I think a comma is better than the period: “…(like -module, -export, etc.)”

2007-04-27
29SUGGEST

The second paragraph on the page states: “…global variables or private shared variables shared by different….” It might read better without the two “shared”: “…global variables or local variables shared by different….”

2007-04-27
28TYPO

The text states: “…a statement such as X = 1234. it binds the variable….” I found the period confusing. I first thought the text ended the sentence. Then I thought the text tried to use correct syntax by ending the statement with a period. In other places, the text uses the assignment expression without the terminating period.

2007-04-27
29SUGGEST

The last paragraph states: “…we say X = Rhs1, Erlang says….” I think it might read better like “…we say X = Some_Expression, Erlang says….”

When I first read Rhs1, I thought the text contained a typo; however, when I scanned the remainder of the paragraph, I realized it was not a typo. I believe ‘Some_Expression’ more effectively communicates the intent of the statement than ‘Rhs1’ (because it describes what was intended instead of its position in the expression).

2007-04-27
30TYPO

The next-to-last paragraph states: “Expressions five to seven above….” I believe this should be: “Expressions four to seven above….”

I assume that the term “expressions” refers to the input command lines in the code earlier on the page.

2007-04-27
66TYPO

A guard is a series of guard expressions, separated by commas (,).

2007-04-27
317SUGGEST

After section 17.1 where you describe mnesia database queries using comprehensions these are never referred to again. How do they interact with transactions and accessing the database through mnesia:read/write/delete?

2007-05-04
44SUGGEST

It is unclear to me were I need to put the file geometry.erl inorder for the compiler to find it.

Or more helpfully, how do I specifcy a directory path to allow the compiler to find this file?

(Joe: in the sidebar on the next page)

2007-04-27
218TYPO

The listing of the erlang module example1 has line numbers in it; while helpful no other listings do.

2007-04-27
222TYPO

In the description of the {env,Env} option there id the sentence “Env is a list of {VarName,Value} pairs where varName and …”. The second VarName starts with a lowercase ‘v’.

2007-04-27
238TYPO

There are line numbers in listing of module scavenge_urls.erl.

2007-04-27
52OK

The text says “The function sum(L) sums the elements of a list L. It makes use of an
auxilliary routine called sum/2 . . .”

but the code listed is:
sum(L) -> sum(L, 0).
sum([], N) -> N;
sum([H|T], N) -> sum(T, H+N).

There’s a link to lib_misc.erl, but that doesn’t seem to have sum/2 either, AFAICT.

(Joe: lib_misc does have a function sum/2 — look again :-)

2007-04-27
325TYPO

Disk tables should survives a crash

Should be “survive”

2007-04-27
326TYPO

"In all the following, we

2007-04-27
139TYPO

“made up of dozens, possible thousands…”

Should be possibly

2007-04-27
140TYPO

“Erlang has no locks no keys”

or keys, or and no keys perhaps?

2007-04-27
328ERROR

The second example on this page is supposed to initialize an Mnesia database on node joe, but the code specifies node(), not joe. This:

mnesia:create_schema([node()]).

should presumably be this:

mnesia:create_schema([joe]).

2007-04-27
369SUGGEST

I could not find any mention of the fact that the ets operations are in fact atomic. The text on page 369 seems to suggest that individual objects can be corrupted, which is not true. It is even possible to search a table or insert several objects at once atomically. What is not possible is to perform a sequence of ets operations as one atomic unit.

2007-05-04
297ERROR

In this section on the road to gen_server there are several places where the arity of the start function is incorrect.

it should be start/2 in each sample, but it switched back and forth between start/2 and start/3

-Scott Fleckenstein

2007-04-27
66SUGGEST

Add a reference to “6.9 A word about tail recursion” where you are talking about “space efficient”.

(Joe: Sorry I think this would confuse people)

2007-04-27
142SUGGEST

In item 4 you could mention (perhaps in a footnote) that the old contents of the mailbox (saved messages) not is matched again when the process is re-scheduled.

2007-04-29
73SUGGEST

In demo1() and demo2() you ought to use list comprahensions as you already has introduced the concept and claimed that they are easier to read.

2007-04-27
81SUGGEST

Claiming that (bit) syntax is a mechanism feels a little bit awkward. Invent a new less confusing term for the “bit syntax”. “Bit matching” feels more like a name of a mechanism than “bit syntax”.

2007-04-27
82SUGGEST

Explain why the the bits in the binary must be evenly divisible by 8.

2007-04-27
82SUGGEST

Change “value must be a variable” to “variable must be a bound variable”.

2007-04-27
83SUGGEST

Move the reference to appendix A from “Sign” to “End” where you make use of “@type” the first time.

2007-04-27
94TYPO

Change “comple” to “compile” in footnote 3.

2007-04-27
95SUGGEST

I missed “andalso” and “orelse” when I read the chapter “boolean expressions”. Perhaps you should integrate it with “short circuit boolean expressions”.

2007-04-27
96SUGGEST

Mention that is a comment convention. It enables automatic indentation in the Emacs mode.

2007-04-27
20SUGGEST

“Exit from it (type control-G, followed by the letter q, then hit enter or return).”

q().
is a nice way to leave the shell.

2007-04-27
98SUGGEST

Explain that ‘kernel’ in the include_lib example refers to an application and add a reference to chapter “16.7 The application”.

2007-04-27
100SUGGEST

Move “void;” to next line in the example in order to be more consistent in the code layout.

2007-04-27
101SUGGEST

You say “much more efficient way”. Do also add that it is less error code as the code (creation of the tuple) is less error prone.

2007-04-27
102SUGGEST

When you are talking about the “conventional syntax” you are mentioning that an integer may be arbitrary large as long as it fits in memory. But you should also mention this for “base k integers” as they have the same characteristics.

2007-04-27
104SUGGEST

Be more specific int the operator precedence table. State associativity for each operator. You should stress that “andalso” an “orelse” have different precedence than “and” and “or”.

2007-04-27
107SUGGEST

At this stage you have not yet introduced the concepts pid, portand reference. But still you mention them when defining the ordering of terms. Is this deliberately?

2007-05-04
107SUGGEST

You describe the difference between == and =:=, but I miss the corresponding discussion about /= and =/=.

2007-04-29
130TYPO

“All we have to do is add…” should be “All we have to do is to add…”.

2007-04-27
133SUGGEST

You have introduced the terms “request” and “response” but in your examples you are using “query” and “reply”. It feels a little bit inconsistent.

2007-04-27
134SUGGEST

You could send a message to the shell, e.g. “self() ! surprise” and use flush() in order to make the selective receive concept more obvious.

(joe: Not added Then I’d have to explain flush which would
probably confuse matters)

2007-05-04
140SUGGEST

Mention that large mailboxes gives a subsantial performance penalty when using priority_receive(). Footnote?

2007-04-27
140SUGGEST

You are passing fun’s to spawn in your examples. The syntax for this is quite nice and I think that you can continue to do so. BUT you should also mention that a severe drawback of spawning funs is that soft code upgrade does not work as expected. In production systems it is a BAD idea to spawn funs.

2007-04-29
148TYPO

“we can spawn process” should be “we can spawn processes”

2007-04-27
153SUGGEST

In your example you are using sleep() to synchronize your processes. Please, mention that this is a unsafe method that may lead to race condition problems.

2007-04-29
282TYPO

io:format("Module set lookup=~

Should be “Module sets”
&c

2007-04-27
283TYPO

“Well it was a walkover. Sets won by a large margin. On my machine sets took about half a microsecond per lookup”

What do you mean by “Sets”? Ets set or the module sets?

2007-04-27
154SUGGEST

In your example you are using process_info/1 to check whether a process is alive or not. Use is_process_alive/1 instead. As the code you have in your examples will serve as templates for new Erlang programmers I think that it is important that you think about the production code quality aspects of the examples as you are setting the code standards. (Avoid spawning funs is definitely a better example of what I mean than this harmless BIF.)

2007-04-27
285TYPO

“returns true if File exists, otherwise false.”

“true” is Courier, “false” is not.

2007-04-27
158SUGGEST

Do you mean what you write or is it just a white lie when you are claiming that 7.5 contains a COMPLETE set of primitives for…?

2007-04-27
181SUGGEST

Introduce MSD for short of message sequence diagram when you are mentioning the term for the first time since you are using MSD later in the text,

2007-04-27
198SUGGEST

You claim that ‘try … catch’ is better than ‘catch’ in one place in the docuement but in your example you are using ‘catch’. Be consistent!

2007-04-27
285SUGGEST

“The other trick I used here was the way in which I located the external Dets file….”

The code is on pages 283 and 290. This paragraph seems to be a bit misplaced.

2007-05-04
201ERROR

You claim that “In Erlang we do not allow this for reasons of safety.” This is not true as we allow drivers. (If you mean that we do not allow static linking you should say so.)

2007-04-27
286TYPO

“race condition in filename2index If two”

A dot is missing, or something.

2007-04-27
286TYPO

“there is no file name associated”

Should be “filename”

2007-04-27
213ERROR

Change “ic module” to “ic application” or simply drop the word “module” as the compiler consists of more modules that “ic”.

2007-04-27
261ERROR

ets and dets supports more than two types of operations. An example of this is ets:delete(Tab, Key).

2007-04-27
262ERROR

I do not think that the first element in a tuple stored in ets/dets USUALLY is the key Instead I think that is more common to store records or tagged tuples in ets/dets. In these cases the key is the second element.

2007-04-27
267SUGGEST

You are mixing naming styles of your functions. Mostly you are using the traditional Erlang style but sometimes your are using the Smalltalk style. Examples are scan_word_list and forEachTrigramInTheEnglishLanguage. Be consistent!

2007-04-27
279TYPO

In several places you have written OPT when you mean OTP.

2007-04-27
295SUGGEST

You should mention that this code change mechanism actually enables to switch versions of a module. It is not the same thing as you earlier code swapping example. You should again mention the drawback with funs in regard of code change.

2007-05-01
285SUGGEST

You could add an example with sys and proc_lib before continuing with the heavy duty gen_server in order to give a deeper understanding of the mechanisms.

2007-05-05
293ERROR

I think that it is more common that the server itself replies to the client later (after first returning noreply) than it delegates this to another process.

2007-05-05
295TYPO

“perfomrms” should be performs

2007-04-27
61SUGGEST

Perhaps there should be an example pointing out that the pattern part of a list expression acts like a filter. For example, [X || {X,_} <- [{1},{2,a}]] yields [2].

[R#r.a || R <- L] is not exactly the same thing as
[A || #r{a = A} <- L]. Just another example.

2007-04-27
300ERROR

Mnesia is NOT a database. Mnesia is a database management system (DBMS) managing the data(base). The heading is ok as it may refer to the data, even though I would prefer to use the term DBMS as it is probably what you mean. Database in “You probably need a database” and “is a complete database” should be changed to DBMS. It is probably a good idea to write DataBase Management System the first time you use the DBMS acronym.

2007-04-27
301SUGGEST

The module mnesia_tests is a bad example of a user defined module as it begins with the name of an already existing application. You even discuss this aspect later in the book. Be consistent!

2007-04-27
302TYPO

Change Var to Val in this example:

Var = [X || X <- mnesia:table(shop)],
qlc:(Val).

2007-04-27
306ERROR

“it tries to lock the table” is misleading as Mnesia sometimes locks single records and sometime locks entire tables. In the current context in your text Mnesia will just lock a single record. Change to “it tries to lock the record or the entire table depending of the context”.

2007-04-27
307SUGGEST

I would like to have some wording about the bad idea of catching calls to Mnesia functions. Calls to Mnesia should never be catched as the automatic transaction restart mechanism itself relies on catch.

2007-05-04
308TYPO

Change “transitions” to “transactions”

2007-04-29
309ERROR

Change “Database” to “DBMS”.

2007-04-27
312ERROR

Change “data base” to "DBMS.

2007-04-27
312TYPO

Capitalize mnesia.

2007-04-27
314ERROR

The wording “If the node crashes, the table will be saved on disk” is misleading as it may be interpreted as the data will be written to disk after the crash. Change to “If the node crashes, the table will be recovered from disk”.

2007-04-27
314ERROR

In the last example in 15.5 you have the same list of nodes as both ram_copies and disc_copies. This is an error as you cannot have a node a both ram_copies and disc_copies for the same table. Change

“[{ram_copies, [node(), someOtherNode()]}, {disc_copies, [node(), someOtherNode()]}]”

to

“[{ram_copies, [node(),someOtherNode()]}]”

and add yet another example with

“[{disc_copies, [node(), someOtherNode()]}]”.

2007-04-27
316ERROR

Change “powerful database” to “powerful DBMS”.

2007-04-27
357SUGGEST

In the end of 17.1 you should mention the concept of fragmented tables in Mnesia. They are an example of distributed hash tables that scales extreamly well.

(Joe: added sidebar in mnesia - this might need indexing?)

2007-05-04
348TYPO

Add a comma between error_logger and supervisor.

2007-04-27
344TYPO

Change “sellaprine_super” to “sellaprime_super”.

2007-04-27
375SUGGEST

Is there no real IO list type allowing binaries? You mention deep_string but that is not the same thing.

2007-05-04
66SUGGEST

“boolean” has been used throughout the text. Dictionaries seem to prefer “Boolean”.

(Joe: I checked one or two computer books - boolean seems
ok - I’ll let the proof reader decide)

2007-04-27
68ERROR

f(X) when X =:= 0 or (1/X > 2) ->

should be

f(X) when (X =:= 0) or (1/X > 2) ->

2007-04-27
68SUGGEST

One more “advanced” thing: when a guard expression fails, the guard fails, but not necessarily the guard seqeunce. There were bugs until not so very long ago, but now it has been settled: if some subexpression of a guard fails while evaluated, the guard fails. It used to be that if one of the operands of, for instance, or/2 failed, the or-expression was given the value ‘false’. It was very confusing, but actually used in some code. orelse and andalso can now be used instead to give the desired behaviour.

(joe: I don’t want to explain about bugs that were in the system
and which have been corrected. This would just be confusing)

2007-05-04
21TYPO

"you

2007-04-27
38SUGGEST

The third paragraph from the end states: “…the tail of a list is always a list.” I’m uncertain if this is an accurate statement.

A few paragraphs later (on the next page), the text mentions “improper lists” and how the library routines only work correctly on a proper list. I’m uncertain if the first statement is an introductory statement or if it needs a footnote stating the you will discuss improper lists in a few more paragraphs.

2007-04-29
141TYPO

In your description of John and Jane dying Jane dies in both examples, not, as I would expect, Jane to die in one and John in the other.

2007-04-29
163TYPO

There are line numbers on the listing at the top of the page.

2007-04-29
163TYPO

A thought just struck me concerning #8290, perhaps there should be line numbers here!

2007-04-29
16TYPO

You use hyphenation of words inconsistently. You should search on e.g.
“fault tolerant” vs “fault-tolerant”
“socket based” vs “socket-based”
“concurrency oriented” vs “concurrency-oriented”
Another inconsistency is “telecoms” vs “telecom”.

2007-04-29
13TYPO

“Chapter 6 … about the different way of running…”
should be “different ways”.

2007-04-29
21TYPO

You use the word “database” sometimes, and “data base” other times. Both are correct, but pick one. Also Mnesia really isn’t a database, but a database management system, or DBMS. Mnesia is the hammer - not the nail.

2007-04-29
35ERROR

Unquoted atoms cannot (officially) contain a period. It kindof works, but that is an unsupported modification for the purpose of the package system. The Erlang Reference Manual says nothing of periods in unquoted atoms.

2007-04-29
38TYPO

Footnote 7: “For reader familiar with Prolog”, should be “for readers”.

2007-04-29
167TYPO

“If you really want to known, read on” -> “want to know”

2007-04-29
22TYPO

At the beginning of “Binary Distributions”, you repeat “and” (Windows and and Linux)

2007-04-29
303TYPO

The code uses gen_server:start_link but the description talks about gen_server:start

2007-04-29
39TYPO

In 2.11 you say that double quotation mark but write a single quote in parenthesis. (Same with "Hello’ is just shorthand for…)

2007-04-29
140TYPO

Sentence should begin with a capital S.

“sue: Did you hear me?”

2007-04-29
139TYPO

What happens when you lose your
keys?

2007-04-29
141TYPO

" That

2007-04-29
36TYPO

In the last paragraph on the page, the attributes for a person should be written as “their name, height, foot size, and eye colour.”

2007-04-29
38TYPO

In footnote #9, the line should start with “For readers”.

2007-04-29
347TYPO

“set or clean” should probably be “set or clear.” I the first point of the list labeled “What happened here?”

2007-05-01
139TYPO

In the little play that exemplifies sending messages between processes on p.139 of the PDF you have:

“sue: Did you hear me?”

Sue should have a capital letter. Sorry that it’s such a pissy little erratum.

Oh yes. I’ve found another on the same page only a couple of paragraphs above:

“This is how it is with Erlang processes. Erlang processes have no shared memory. Each processes has its own memory.”

The third of these sentences might be “Each process has its own memory.”

2007-05-01
325TYPO

Disk Table

\t“disk tables should survives crash…”

should be

\t“disk tables should survive crashes …”

2007-05-02
14TYPO

Chapter 8, Concurrent Programming, […] How fast we can create parallel processes?

Should be: How fast can we create parallel processes?

2007-05-01
52SUGGEST

The text box states: “…in a function calls, data constructors and pattern.” I believe it should read: “…in function calls, data constructors and patterns.” Another option is to replace “patterns” with “pattern elements”. (I’m uncertain if commas separate patterns or pattern elements; i.e., {rectangle, Width, Height}.)

2007-05-01
315TYPO

demo(select_shop) ->
do(qlc:q([X || X <- mnesia:table(shop)]));

should not be terminated with a ‘;’

(Joe: There should be a semi colon - the function has
more clause to come — see the entire listing at
the end of the chapter)

2007-05-01
314TYPO

is this the only way to create a table? record_info() generates compile time errors. (need to confirm in the doc that this is the ONLY way) or provide options.

mnesia:create_table(config,[{disc_copies,[node()]},{attributes, record_info(fields,config)} ]),

2007-05-04
16TYPO

-It

2007-05-01
77TYPO

In the sentence "
try_test:generate_exception/1
was probably called by try_test:demo() (we can’t be sure about this because
try_test:demo() might have called some other function which made a tail
recursive call to try_test:generate_exception/1 in which case the stack
trace won’t have any record of the intermediate function)."

try_test:demo() should be try_test:demo3()

2007-05-02
0TYPO

when my laptop goes to sleep, I get warning messages. It might be interesting to mention:

=ERROR REPORT 1-May-2007::08:02:04 ===
Mnesia(nonode@nohost): WARNING Mnesia is overloaded: {dump_log,
time_threshold}

2007-05-04
315OK

Shouldn’t that be demo(shop) instead of demo(select_shop) at the top of the page?

(Joe: There is no function demo(shop) only demo(select_shop)
the code is correct)

2007-05-01
66SUGGEST

The second paragraph in section 3.7 describes the priority of operators. Although the text makes the order of evaluation clear for operators of different priorities, I was unclear what was the order of operations that have equal priorities. Is it left-to-right? Is it arbitrary or undefined (implementation dependent)?

2007-05-02
326TYPO

In the second sentence describing disk tables, “This disk log grows continuously and regular
intervals the information in the disk log…” there is a missing “at”: “…continuously and AT regular intervals…”

2007-05-02
132TYPO

In section 6.5,
^F or Left Arrow Forward Character
should be
^F or Right Arrow Forward Character

2007-05-02
79SUGGEST

What is a BIF ? … Introduce it at least please, it’s confusing …

2007-05-02
367ERROR

I would suggest replacing: “8 core (with 4 hyperthreads per core)” with “32 logical processors (8 cores with 4 hardware threads per core)” since hyperthreads are Intel technology/terminology.

2007-05-02
369TYPO

“We can create a shared dets table which several different process can write to”. “process” should be “processes”

2007-05-02
375ERROR

The default number of schedulers equals logical processors detected, not physical processors. (The Erlang/OTP documentation say “processor cores”, but this is wrong; I will fix the OTP documentation).

2007-05-02
375ERROR

SMP Erlang is enabled by default (i.e., an SMP virtual machine is built by default) since R11B-0 on all platforms that SMP Erlang has been thorougly tested on by OTP. Build of SMP Erlang on other platforms can be forced by passing —enable-smp-support to configure (note that not all platforms are smp supported yet, e.g. windows).

2007-05-02
375TYPO

R11-B0 should be R11B-0

2007-05-02
379TYPO

“dfferent” should be “different” in “Mapreduce can be implemented in lots of …”

2007-05-02
0ERROR

The following erratum written by me refers to the wrong version of the book. #8326, #8327, #8328, #8329, #8330, #8331. It should refer to version B1.13:2007-04-26, not B1.14:2007-04-27.

2007-05-02
190TYPO

Mentions lib_tcp_mm:connect/2 as the all important call, but I honestly don’t see that call anywhere.

2007-05-02
336TYPO

“5. Make a supervision tree and add the servers it.” Missing verb at the end?

2007-05-02
79SUGGEST

The last paragraph on the page uses the pronoun “we” throughout. As I read the paragraph, I was sometimes unclear on the person to whom the “we” referred. Sometimes, it seemed to refer to “we” as the programmer / designer / developer of a function. At other times, “we” seemed to refer to the client programmer of a function. (A client programmer is a programmer who uses code I have written.)

Perhaps distinguishing these two uses of the pronoun would make this role distinction clearer.

2007-05-04
13TYPO

in section 1.1 “Road Map”…the line:

In Chapter 7, Concurrency, on page 139 we change gear.

should read:
In Chapter 7, Concurrency, on page 139 we change gears.

2007-05-03
339TYPO

Missing “]” in the “@type Report” of “error_logger:error_report”.

2007-05-03
72SUGGEST

Perhaps there should be some example showing a case clause with a guard sequence, like case X of Y when G -> v end.

2007-05-04
13TYPO

In beginning of last paragraph of first page of Chapter 1 - Begin:

"In Section 20.3, Running SMP Erlang, on
page 376 we

2007-05-04
398TYPO

C.3 Link Collections: “… at the University of ERLANG …”. I think you mean the University of Uppsala ;)

2007-05-05
424TYPO

“All the commands without a module prefix (ii/1, iaa/1, etc.) are exported from the module (i). This is the debugger/interpreter interface modle.” modle -> module

2007-05-05
242TYPO

The text at the top of the page states: “…we call file:read_file_info(F) this returns {ok, Info}….” I believe this fragment is missing a period: “…we call file:read_file_info(F). This function returns {ok, Info}….”

2007-05-05
242SUGGEST

The first paragraph states: “…if F is a valid file or directory entry.” Although I believe Unix programmers will understand the phrase “directory entry,” I am unclear if Windows programmers will understand it.

(I vaguely recall the term, but my serious Unix programming was a long time ago in a galaxy far, far away.)

2007-05-05
242SUGGEST

The file_info record defines two different “fields”: access and mode. Access is defined to be one of four atoms whereas mode are the file permissions. I do not understand the difference between these two fields.

If I understand correctly, the mode is the value supplied to the chmod command, for example 0444 for a file readable by anyone. Since these modes correspond to read, write and execute for user, group and other, I was unclear how access differed from mode.

2007-05-05
91TYPO

The first sentence on the page reads: “…extension to pattern matching used extracting and….” I believe it is missing the word “in”: “…extension to pattern matching used in extracting and….”

2007-05-05
90SUGGEST

The second paragraph on page 90 states “Returns a binary constructed from….” I believe this sentence reads better as: “list_to_binary/1 returns a binary constructed from….”

On the previous page, the text introduces the function list_to_binary/1. The paragraph immediately after this introduction describes the Erlang Type Notation. This paragraph refers back to the function on the previous page. Although the paragraph describing Erlang Type Notation is parenthetical, I found the sentence as written somewhat unclear.

Two other alternatives would be to put the entire paragraph on Erlang Type Notation as a footnote or to put this paragraph after the description of the function but before the next function.

2007-05-05
53TYPO

When trying to compile the lib_misc module as given for the example showing the creation of the sum function I get the following error:

21> c(lib_misc).
./lib_misc.erl:98: can’t find include lib “kernel/include/file.hrl”
./lib_misc.erl:102: record file_info undefined
./lib_misc.erl:102: record file_info undefined
./lib_misc.erl:356: record file_info undefined

Erlang (ASYNC_THREADS) (BEAM) emulator version 5.5.2
Linux iris 2.6.20-15-generic #2 SMP
package: erlang-base (1:11.b.2-4ubuntu1)

(joe: How did you get your erlang. Is this from cean or apt-get
The package does not include the compiler - it might be nice to know how you
installed erlang)

Joe: this is an error in your installation of erlang - probably a
\t cean error. try: cean:install(compiler)
see note on page 24)

2007-05-05
107TYPO

In the Comments section, the function is named “my_funtion”. Should be “my_function”?

2007-05-05
107TYPO

In the Comments section, the function is named “my_funtion”. Should be “my_function”?

2007-05-05
61TYPO

I needed to add

-import(shop, [cost/1]).

to shop2.erl in order to get it to compile.

I think either it should be added, or you should mention that you should have the shop module compiled in the shell already.

Or perhaps this is intentional for the reader to try and solve?

-module(shop2).
-export([total/1]).
-import(lists, [map/2, sum/1]).
-import(shop, [cost/1]).

total(L) ->
sum(map(fun({What, N}) -> shop:cost(What) * N end, L)).

(Joe: shop2.erl is correct - your added line does nothing
you can compile shop2.erl as given it has no errors.
probably you got a run-time error when you ran shop2
because shop.erl was not compiled - if you do things in the
order presented in the book they should work)

2007-05-05
78TYPO

First paragraph, second sentence: “let’s take brief detour”

2007-05-19
107TYPO

“Double percent marks are recognize…” , replace recognize with recognized

2007-05-19
16TYPO

Second sentence in Begin Again. Reads “It it had a unfamiliar syntax…” “it” is repeated.

2007-05-19
42TYPO

The table with the pattern matching examples omits the comman separating the second pair of values in some cases. The shell examples below the table appear to have the correct syntax.

2007-05-19
190ERROR

I don’t think the rpc:multicall/2, that is used to demonstrate that people can run any code, exists.
(I just checked and it uses apply, does that even understand funs?)

2007-05-19
77DEFER

I’d like to see a list of short exercises for the reader to do at the end of each chapter or throughout the chapter (with possible solutions) so that the reader can really test their understanding of what was taught in that section.

102SUGGEST

The text describes the module attribute using the text: “-module(module)”. When I read the text describing this attribute, it referred to the name “module” a number of times.

Although I understood what the text was trying to say, I was initially confused. “Which atom ‘module’ does this reference mean?” In addition, I noticed that the other attributes used the syntax of unbound terms for its arguments, for example, import.

Might the text be clearer if we use a different atom, for example, ‘module_name’? As an alternative, what if we used the same convention as we used for the other attributes: ‘-module(Mod)’ or ‘-module(ModName)’? (with similar replacements in the explanation.)

2007-05-19
102SUGGEST

The description of the -import attribute describes its function.

Do any recommendations or conventions exist for when to use -import and when to simply use the fully qualified function name? Do these two methods have any difference in performance?

(Joe: no - and no diference in performance)

2007-05-19
103SUGGEST

The text describing the -vsn attribute describes its function and says that the Version argument can be any literal term.

Do any recommendations exist on how to most effectively use this attribute?

(Joe: anything you like)

2007-05-19
103SUGGEST

The text describes the syntax and functionality of user attributes.

Do any recommendations / best practices exist on how to use these attributes?

(Joe: No anything you like)

2007-05-19
105SUGGEST

The text of the first paragraph says that: “The module beam_lib contains a number of functions for analyzing a module without loading the code.”

Although this paragraph describes what occurs when one loads the .beam code instead of loading the module, I’m unclear, other than using the functions in beam_lib, what would be the reason for doing this.

(Joe: beam lib does not load the code, this might be dangerous if you
were running a newer version with the same name)

2007-05-19
107SUGGEST

The last section on this page (and the next) uses the term “escape convention.”

When I first read this term, I wondered, “What is an ‘escape convention’? How does it differ from an ‘escape sequence’ (my C/C background)? Why is it a ‘convention’ instead of a hard and fast syntax rule?”

From reading the text, I understood “escape convention” to be a synonym for “escape sequence.” Perhaps using “escape sequence” will avoid confusing us poor C/C/Java programmers.

2007-05-19
108SUGGEST

The table of escape sequences / escape conventions does not list an escape sequence for entering hexadecimal characters (\\xNN).

Is this lack an oversight, or does Erlang only support using octal characters?

(Joe: Hex in strings is not supported))

2007-05-19
109SUGGEST

The third paragraph on the page describes an expression sequence. Its effect seems to be the same as a block expression (described on page 105).

When I read this section, I wondered, "What is different between a ‘block expression’ and an ‘expression sequence’ (other than the different syntax)? When would you use one or the other?

2007-05-19
109SUGGEST

The section named “Function References” describes how to create a function reference.

For a C/C/Java/Python programmer (like me), I think of the name of a function as identical to a reference to the function. I understand that Erlang distinguishes between a function name and a reference. If my understanding is correct, it may be valuable to highlight that language difference to better communicate to programmers of those languages.

2007-05-19
109SUGGEST

The next to the last paragraph describes referring to a function in a remote module.

When I read this description, based on other text that talks about “loading a module,” I wondered, “When does this remote module get loaded? Is it loaded when the fun is encountered or only when it is evaluated?”

Although the difference may not be significant, a note might help avoid these questions and provide a deeper understanding for some readers.

2007-05-19
111SUGGEST

The second paragraph states: “…match complete forms in the….”

After reading the remainder of the section, I understood the phrase ‘complete forms’ to be equivalent to the C-preprocessors textual substitution mechanism.

If the Erlang community uses the term ‘complete form,’ might a note explaining its meaning be beneficial to readers with other language backgrounds? (Or did I misunderstand completely?)

2007-05-19
22OK

while it is possible to install erlang with the given directions, on a Mac, if you want HIPE… that’s a whole other story. I have not been able to install HIPE on my Mac for several days. (you example shells show HiPE running.)

(Joe says: I suggest you ask on the Erlang mailing list)

2007-05-19
42SUGGEST

I’m not sure if this is worth reporting, but reading the PDF in Adobe Reader on a 21" monitor in 1600x1200 with zoom at 100% the double quotes in the pattern matching table look exactly like single quotes. Trying to match [H|T] against ‘cat’ stumped me for a long time until I ended up cut and pasting to an IRC channel for help and found out it was really double quotes.

Maybe a different font would help.

2007-05-19
114SUGGEST

The text states “…represents the integer code for ASCII character….”

Earlier, the text mentioned that Erlang accepted any character in the Latin-1 encoding.

Does Erlang only support converting ASCII characters to integers or does it support any character in the Latin-1 encoding? If it supports the latter, what is the syntax for characters outside the ASCII range?

2007-05-19
115SUGGEST

The text states: “…all the Erlang operators in order of falling priority….”

I think it reads better using the term ‘descending’: “…all the Erlang operators in order of descending priority….”

2007-05-19
115SUGGEST

The text describing erase/1 states: “Return the value of the key or the….”

When I first read this fragment, I thought that the function returned Key (because of the phrase ‘the value of the key’ instead of ‘the value associated with (or mapped to) the key’. When I read the examples later on the page, I understood that it returned Value or undefined.

I believe this fragment reads better in value is set in the different font (like ‘Key’ in the previous sentence).

2007-05-19
153SUGGEST

The last paragraph states: “This sets a maximum time that a process will wait to receive a message.”

When I first read this sentence, I interpreted it to mean ‘receive any message’; however, I then wondered: “Any message at all or only a matching message”?

Although the Erlang community may consider a received message to be a message sent to a process and successfully matching a class in the receive…end statement, my C/C/Java/Python brain considers a message “received” when it enters the mailbox of the receiving process.

The first paragraph of the next page clearly states: “If no matching message…”

Perhaps including the word “matching” would make the last paragraph clearer: “This sets a maximum time that the process will wait to receive a matching message.” Another alternative would be a footnote emphasizing the special meaning used within the Erlang community for the word ‘receive.’

(Joe: I think the text is ok)

2007-05-19
435TYPO

Change “folling” to “following” in “To learn more about tracing you need to read three manual pages for
the folling modules:”

2007-05-19
154SUGGEST

The last paragraph states: “…implement a form of ‘priority receive.’”

When I read the code for priority_receive/0, I wondered, “What happens if {alarm, X} arrives while the function is executing the innermost receive…end loop?”

I understand if {alarm, X} is in the process message queue it is processed before any other message; however, I’m unclear what is the behavior of this code if the {alarm, X} message arrives after other messages.

(Joe: There might be a glitch here,
there have been discussions on the Erlang mailing list about this)

2007-05-19
64SUGGEST

I realize that the purpose of the exercise was to understand list comprehension, but I’d like to get rid of duplicate entries (where A and B are swapped). Two suggestions:

pythag(X) ->
[ {M*M - N*N, 2*M*N, M*M + N*N} ||
M <- lists:seq(1,X),
N <- lists:seq(1,X),
M > N,
2*M*(M+N) =< X
].

pythag(X) ->
[ {A, B, C} ||
A <- lists:seq(1,X),
B <- lists:seq(1,X),
C <- lists:seq(1,X),
A+B+C =< X,
A*A + B*B =:= C*C,
A < B
].

The first requires more math and doesn’t show list comprehension as well, so the second is probably preferable.

(Joe: I prefer the simpler example)

2007-05-19
15TYPO

“Mnesia is a integrated DBMS…”

‘a’ should be ‘an’

2007-05-19
151SUGGEST

The text of the first paragraph states: “…with an explicit module and function names and argument list….”

I believe it is clearer like: “…with an explicit module, function name, and argument list….”

2007-05-22
93SUGGEST

Last paragraph: "In case you

2007-05-19
32SUGGEST

I think it is clearer to change:
“has non-mutable state” -> “has no mutable state”
“having non-mutable state” -> “having no mutable state”

And it will be consistent with the sentence “In Erlang, there is no mutable state,…”.

2007-05-19
33TYPO

It would be better to change comma position:
“If this variable changed values many
times, and at many different points in your program then finding out
exactly which of these changes was incorrect can be extremely difficult.”
->
“If this variable changed values many
times and at many different points in your program, then finding out
exactly which of these changes was incorrect can be extremely difficult.”

2007-05-19
104TYPO

You refer to “{version, ”4.4.1“} in the text but in the example it’s ”4.4.3".

2007-05-19
34SUGGEST

I think it is better to change:
‘When you divide two integers the result is automatically
converted to a floating point number.’
->
‘When you divide two integers with “/”, the result is automatically
converted to a floating point number.’

2007-05-19
35OK

I think this sentence is wrong.
“In a C program the values of these constants are not interesting, only
the fact that they are all different and that they can be compared for
equality.”

Value constants defined with #define macro does matter.
Above sentence is true for enum constants defined without values.

I think it is not appropriate to write about #define’d contants here because C program’s #define’d constants are just text based macro, and they are replaced with values and constant name will disappear.

Instead, an example of enum constants should be shown.

(Joe: The book is about Erlang not C - I’d rather stick with my example
since use of defines (in C) seems much more common that use of enums.
Also I want the example to be clear to non C programmers)

2007-05-22
168TYPO

The text of footnote 2 states: “Using sleep for synchronize processes is unsafe.” I believe it should either read: “Using sleep to synchronize processes is unsafe” or “Using sleep for process synchronization is unsafe.”

2007-05-19
56SUGGEST

“here X rem 2 computes the remainder after X has been divided by 2 and
=:= is a test for equality.”

It worth to note the difference between == and =:=, the current wording is not enough for beginners to realize this.

2007-05-19
69ERROR

f(X) when (X =:= 0) or (1/X > 2)

This example does’t help to prevent divede by 0.0 as =:= operator doesn’t catch this. Here == would be a better choice.

2007-05-19
381TYPO

Now that we understand how mapreduce words we can go back to our

2007-05-19
140TYPO

Paragraph 5: “… uncessarily difficult” should be “… unnecessarily difficult”.

2007-05-19
142TYPO

Paragraph 5: “… because because …” should be “… because …”.

2007-05-19
142TYPO

Paragraph 5: “That’s is…” should be “That is…” or “is” should be removed.

2007-05-19
61OK

The simple list processing algorithm in shop2.erl does not seem to work on OS X. Following the instructions from the text results in the following error message:

=ERROR REPORT 9-May-2007::23:30:20 ===
Error in process <0.31.0> with exit value: {undef,[{shell_default,total,[[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]}

exited: {undef,[{shell_default,total,
[[{oranges,4},
{newspaper,1},
{apples,10},
{pears,6},
{milk,3}]]},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]}

(Joe: I think you missed out the module name
try
> shop2:total(L)
)

2007-05-19
32TYPO

I found some issues with the Getting Started extract. I have no idea if this corresponds to a recent beta, but I don’t see this in the errata, so here goes:

Character Sets Used In Strings

This passage is wildly confusing. A string can contain any Latin-1 character code, and then a string is just a list of integers in some encoding, implying that the encoding is irrelevant but possibly associated with the string, and then the string will be printed correctly if it happens that they’re Latin-1 codes. Some of the above simply isn’t true. (1) What if it’s UTF-8 and my terminal is set correctly for UTF-8? (2) Is the encoding attached to the string somehow, or do I need to carry a separate variable around for that?

I suspect you want to say “A string is a just a list of integers” and leave it at that until you can treat the issue of encodings with the requisite depth, but I know nothing about Erlang.

2007-05-19
27TYPO

> Note how we used atoms both to identify the field and (in the case of
eyecolour) to give the field a value.

Shouldn’t the parenthetical read “in the case of name and eyecolour”?

2007-05-19
90ERROR

Erl 5.5.4 returns the different result for the expression below.
1> {B1, B2} = split_binary(<<48,49,50,51,52,53,54,55,56,57>>,3).

the result in book: {<<48,49,50>>,<<51,52,53,54,55,56,57>>}
actual result: {<<“012”>>,<<“3456789”>>}

2007-05-19
91TYPO

The dot is missing after the expression:
1> size(<<1,2,3,4,5>>).

2007-05-19
93TYPO

The expression below is printed in three colors, should be in one color.
{<<16#12345678:32/big>>,<<16#12345678:32/little>>,
<<16#12345678:32/native>>,<<16#12345678:32>>}.

(Dave says: our syntax highlighting can get confused. Sorry)

2007-05-19
156TYPO

In the example source code, “Expresssions1” should be “Expressions1”. Also, “ExpressionTimout” should be “ExpressionTimeout”.

2007-05-19
339TYPO

The word “occurred” is misspelled as “occured” in the first two code samples on this page.

2007-05-19
154DEFER

I thought the section on Selective Recieve went a little fast.

Since message passing/recieving is such a large portion of the language perhaps another example program would have been good here.

157SUGGEST

In Section 8.7, it may be helpful to mention that a process will become unregistered if the process is no longer alive. I spawned a process with a built-in timer, confirmed that the process was alive and registered the process. When the timer expired, the process was no longer available and the registered name was removed from the list of registered processes.

2007-05-19
140TYPO

“What happens when you loose your
keys?” should be “What happens when you lose your
keys?” The word “lose” is also misspelled as “loose” on the top of page 141.

2007-05-19
404TYPO

Reads:
Once you

2007-05-19
1OK

I copied the pdf to Adobe Reader (version 3.05) for PalmOS, and the conversion program complains that the pdf is not a “tagged” pdf. The file is generated, but I notice that spaces are sometimes missing between words, giving an effectsomethinglike this. Would it possible to generate a “tagged” pdf file?

(Dave says: Adobe doesn’t support micro-spacing in tagged PDFs, so I’m afraid not)

2007-05-12
50TYPO

In the box at top, second line, “arguments in a function calls” should be “arguments in function calls” (get rid of “a”).

2007-05-19
203TYPO

The first paragraph says that the most important call to understand is lib_tcp_mm:connect/2. I think you mean lib_chan_mm:controller/2.

2007-05-19
206ERROR

The Chat Program is broken in a number of places. I have fixed them in my local copy of the code. Send me an email (cashion at gmail com) if you’d like a patch.

(Joe: have mailed - but no got no response)

2007-05-22
42SUGGEST

In the result column of the table on this page, you use both “success” and “succeed” interchangeably. Maybe settling on one of them would make it better?

2007-05-19
14TYPO

The Chapter 8 description says: “How fast we can create parallel processes?”, when it should be “How fast can we create parallel processes?”.

2007-05-19
23SUGGEST

Section: Installing on Mac OS X. The MacPorts version of Erlang is now at the same version as the current version, saying it is two releases behind isn’t accurate anymore.

2007-05-19
419SUGGEST

lib_md5 doesn’t come with erl5.5.3 Windows package. Not sure where to get it. Suggest a note to Windows users.

(Joe: in the code that accompanies the book, from the prag web site)

2007-05-19
338DEFER

Could you please mention OTP behaviors not covered by the “OTP Introduction” and “Making a System With OTP” chapters, and where to go for further information? gen_fsm is very useful in certain systems.

91TYPO

The code example for @spec size(Bin) needs to have a trailing period:

1> size(<<1,2,3,4,5>>).
5

2007-05-19
152TYPO

The actual output of “processes:max(20000).” does not contain a newline betewen the line “Process spawn time=3.50000 (9.20000) microseconds” and the line “ok”,
because there is no “~n” after “microseconds” in the source
code line:
io:format(“Process spawn time=~p (~p) microseconds”,
\t [U1, U2]).

You should fix either the source code or the output.

2007-05-19
153ERROR

When I execute below in otp_win32_R11B-4, “Too many processes” occurred.
$ erl +P 500000
1> processes:max(50000).
By trial and error, I find the real max value which does not cause an error is 49978.
I execute i(). and notice the count of the listed processes is 12, so that’s it.

Joe: I hadn’t done this on windows, the diffrence is marginal)

2007-05-19
205OK

I am trying to run the software on a Windows machine, hence I am not using the make command to run. The server runs fine, but the chat_client returns with error:
chat_client login unexpected:{’EXIT’,<0.41.0>,connectorFinished}
lib_chan_mm: protocol error:{login,“general”,“joe”}

The server apparently did authenticate the client as it states “off we go”, so I don’t understand the error. I have verified that both sides use the correct IP, port and pwd.

(Joe: not enough info to help - mail the erlang mailing list
if you can’t fix this yourself )

2007-05-19
304SUGGEST

Line 1 states that there are some subtle errors in the above examples and that towards the end of the chapter the will be hints as to why. I have read all ofd it, but I cannot find those hints. On the other hand I would like to use ALL of the code I find in the book as a base to work on, so I’d rather get some reusable code, not code with errors, after all it’s the Erlang Guru himself who’s writing this. The server examples here are nice and I like also the description of updating the code, so I might use this structure rather than the gen_server because no hint is given as to how to update ge_server code and the manual cited there does not clear up my doubts on how to do that. So can I or can I not use this nice code ?? =)

(Joe: Use the OTP gen_servers etc for your projects. If you
do use the code here think through any possible race conditions
that might occur. The code here is probably correct, but not
as well tested as the OTP code)

2007-05-19
303ERROR

is the statement really true : “Our process will remain a factorial server, until we send it a {become,
Something} message and tell it to do something else.” It seems to me that the factorial server, which is going to receive the become message we send, will just ignore it and keep waiting for more factorial calls?

2007-05-19
303ERROR

is the statement really true : “Our process will remain a factorial server, until we send it a {become,
Something} message and tell it to do something else.” It seems to me that the factorial server, which is going to receive the become message we send, will just ignore it and keep waiting for more factorial calls?

2007-05-19
150TYPO

In the first paragraph, two times you refer to the tuple as {Pid, Reply}, when in all the code examples it is {Pid, Response}.

2007-05-19
118TYPO

Note 6 seems to use “infer” for “imply”.

2007-05-19
152TYPO

In the processes code example comment, it says “see how long time this takes”. I imagine you meant “see how long this takes”, or “see how much time this takes”

2007-05-19
69SUGGEST

The Advanced paragraph could use a re-write. It implies that “or” and “and” have changed since the early days when they were not shortcut operators [“the boolean operators and/or were originally defined”]. In fact, they still evaluate their arguments, and orelse/andalso still serve a purpose.

2007-05-19
100OK

Intro paragraph to 5.4 is bloated. Perhaps something like:
“We have now covered all the major topics in sequential Erlang. We’ll go over the remaining odds and ends in this section:”

2007-05-19
66OK

In figure 3.1, Arithmetic Expressions, + and - are shown as priority 1, while * and / are shown as priority 2.
On page 65, it says that operations with priority 1 are evaluated first. So 1+2*3 should be 9, by these rules.
Of course, erlang gives the value 7 to 1+2*3.

(Joe: No. + and - have priority 3
you are confusing unary plus (+X) (pri 1)
with binary plus (A + B) (pri 3))

2007-05-19
126SUGGEST

Chap 6, “Programs With Command Line Arguments”, fac1.erl and the escript example seem gratuitously different, especially main(). The parsing of the command line is different, variable names changed for no reason, formatting is different etc. I thought the program should be the same, just a different setting.

2007-05-19
138TYPO

Chap 7: Under “People function as independent entities that communicate by sending messages.”,

replace “possible” with “possibly” here:

“An Erlang program is made up of dozens, possible thousands or
even hundreds of thousands of small processes.”

2007-05-19
138ERROR

Section 6.9 (Tweaking the Environment): It is stated that the [exported] functions of user_default.erl are available once the user_default.erl file has been compiled and placed in the load path, however, according to the ‘erl -man shell_default’ man page, it is necessary to include the line ‘code:load_abs(“$PATH/user_default”).’ to the .erlang file.

(Joe: If it’s in the load path then code:load_abs
is not necessary)

2007-05-19
172OK

In the results of running edemo2, output lines for “status(a, A)” are missing.

(Joe: There are no calls to status(a, A) it’s not missing - this
is deliberate)

2007-05-19
345TYPO

Under the text “To test this we start Erlang, generate an error message, and then look in the log file,” there’s an example whose formatting is very wrong:

$ erl -boot start_sasl -config elog2 1>
error_logger:error_msg(“This is an error\
”). =ERROR
REPORT 27-Mar-2007::11:53:08 === This is an error ok

It should instead appear like this:

$ erl -boot start_sasl -config elog2
1> error_logger:error_msg(“This is an error\
”).
=ERROR REPORT 27-Mar-2007::11:53:08 ===
This is an error
ok

2007-05-19
370TYPO

In the sidebar at the top of the page, the sentence fragment “a 32 core CPU might give us an equivalent or 128 threads to play with” contains “equivalent or” instead of “equivalent of.”

2007-05-19
401TYPO

’You

2007-05-19
401TYPO

‘faily’ => fairly

2007-05-19
512TYPO

In the index you “ni” instead of “in”:

Hello world program, 125
command line arguments, 128
ni Erlang shell, 125

should be:
in Erlang shell, 125

Nice book :)

2007-05-22
65OK

Compiling and running pythag/1 from lib_misc.erl fails.
—————————————————————————
Eshell V5.5.4 (abort with ^G)
1> c(lib_misc).
{ok,lib_misc}
2> pythag(6).

=ERROR REPORT 19-May-2007::02:06:29 ===
Error in process <0.31.0> with exit value: {undef,[{shell_default,pythag,[6]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]}

exited: {undef,[{shell_default,pythag,[6]},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]}
3>

Joe: Not an error. You missed out the module name. Try:
> lib_misc:pythag(6)
The book is correct)

2007-05-22
23ERROR

“This file contains release 11 version 4”
should read “This file contains version 11 release 4”
(it is the 4th maintenance release of version 11)

2007-05-22
55SUGGEST

I spent too long tracking down what turned out to be a syntax problem in going from what works in the shell, to what works in a file. I was trying to map a function, and thought this was the obvious thing (assume foo(X) is defined):

lists:map(foo, [1,2,3])

Instead, it took me a while to figure out the correct syntax:

lists:map(fun foo/1, [1,2,3])

An example near page 55 or so would probably have caught my eye. It is explained on page 109, but I hadn’t got that far, and missed it in my search of the book…

2007-05-22
105ERROR

extract:attribute/2 can only extract attributes from a module called “attrs’.
The sample contains a match: ”{ok, {attrs, [{attributes,L}]}}" but the ‘attrs’ atom is actually the module name. “{ok, {_, [{attributes,L}]}}” appears to work if you wish to extract attributes from other modules.

2007-05-22
364TYPO

the link to /doc/pdf/appmod.pdf should be /doc/pdf/appmon.pdf

2007-05-22
274ERROR

The name of the module is shout, not shoutcast.

2007-05-22
68SUGGEST

The phrasing of the sentence “The reason for restricting guard expression* to a subset of Erlang expression* is that we wish to guarantee that evaluating a guard expression is side-ef fect free.” is confusing, being hard to tell if the words where I have added asterisks are meant to be pluralized or not.

2007-05-22
161TYPO

Last paragraph of section 8.10 you have:
“if is is compiled” you need to remove one “is”.

2007-05-22
389SUGGEST

“and step back and think” => “step back and think”

2007-05-23
166OK

The effects of an exit signal don’t depend only on it’s value and the state of the receiving process as shown in the table. exit/1 and exit/2 behave differently: only exit(pid, kill) sends an untrappable exit signal. This is implied by a footnote and can be seen in subsection “Trapping Exit Signals (Advanced)”. It would be nice to rephrase the explanation above the table as to avoid the initial confusion that it produces.

Changing the table somewhat might be an option, but it might introduce too many variants and make it unwieldly. Making a difference between a “broadcasted exit signal” (sent by exit/1) and a “directed exit signal” (sent by exit/2) might be a valid alternative, though it introduces a differentiation that in a broader context might be unnecessary, and it probably uses a non-standard terminology.

(Joe: this version is the “clear rephrasing” - many people have
checked this and we think it is correct. The terminoly “bradcasted exit
signal” and “directed …” do not exist and would further confuse people)

2007-05-22
168TYPO

“dieing” should read “dying”

2007-05-22
178TYPO

Replace “co-ordinate” with “coordinate”.

2007-05-22
180TYPO

“Stage 4 - Test the name-server of two different machines”: replace “of” with “on”.

2007-05-22
180SUGGEST

Use either name-server or name server, but not both.

2007-05-22
66SUGGEST

I do know that it should be simple….. I guess I’m slow but I have a lot of trouble understanding perms… So yes, I know that it would take time to explain but at least giving some hints would be nice….

2007-05-23
185SUGGEST

Specify the protocol (TCP, UDP, …) for which ports (e.g. 4369) must be open.

2007-05-23
12TYPO

“There are loads of programming language, so why…”: replage “language” with “languages”.

2007-05-23
14TYPO

“We finish this chapter with the second sizable application. A SHOUTcast server”. A colon seems more appropiate than a full stop.

2007-05-23
15TYPO

“We talk about the techniques for ensuring that Erlang program will run …”. It should read “programs”.

2007-05-23
15TYPO

"

2007-05-23
16TYPO

"It

2007-05-23
20SUGGEST

It looks weird that the two footnotes are expansions of acronyms but one ends with a dot and the other doesn’t. I would opt to erase the dot.

2007-05-23
294SUGGEST

[Nitpick] Use in the same paragraph of two spellings of the same word: “behaviour” and “behavior”. Throughout the text, “behavior…” wins.

2007-05-23
28TYPO

“Shell , on page 133).”: Delete closing parenthesis.

2007-05-23
167TYPO

First paragraph of Idiom 3: the “and” in italics should contain spaces.

2007-05-23
168TYPO

On the first line, “from dying processes.” should be “from dying processes,”.

2007-05-23
168TYPO

On second line, “detected a processes failure” should either be “detected failed processes” or “detected process failures”.

2007-05-23
168TYPO

In footnote 1, the second closing parentheses should either be removed or changed to a period.

2007-05-23
173TYPO

In the definition of spawn_link/1, “This exactly” should be “This is exactly”.

2007-05-23
175TYPO

Remove the trailing single quote from the third paragraph.

2007-05-23
176TYPO

In the fourth paragraph of section 9.8, the sentence starting with “There a rather subtle” should be “There is a rather subtle”.

2007-05-23
181SUGGEST

The first paragraph, “We’ll start with the name server”, seems redundant. I think the same message and tone is conveyed without the paragraph. Although if you intended to say “We’ll start with the simple name server” then the paragraph would be fine.

2007-05-23
373TYPO

In the list, the sentence should read: “… one process at a time writes to the table and that all other processes read from the table …”.

2007-05-28
384TYPO

In the comment for collect_replies/2 at the bottom of the page, in the line of the comment that says, “When N processes have terminate return a dictionary,” the word “terminate” should be “terminated” instead.

2007-05-28
388ERROR

Step 2 describing the worker process says that lib_find:file is called to find the files in the directory that should be indexed, but the code shows that indexer_misc:files_in_dir(Dir) is called. No call to lib_find:file appears in the code.

2007-05-28
391SUGGEST

The book proper seems to end very abruptly! Shouldn’t there be a better conclusion or summary for this chapter than this?

2007-05-28
23DEFER

Because erlang is mainly for embedded developer interesting, mabe you could note some common size/memory footprints and in this context point out of a minimal erlang configuration (standalone “sae”)

366ERROR

There is a bug in the lib_primes.erl file. If the user attempts to generate or test a 1-digit prime, it fails with an error. For example:
lib_primes:make_prime(1).
or
lib_primes:is_prime(7).

- BillC

2007-05-28
366SUGGEST

The Bertrand’s postulate is used for deriving a “limit” when searching for primes. The postulate would guarantee that the algorithm will eventually stop (in theory) even without implanting the limit into the program. Why not use the postulate just as a comment? Nevertheless I suppose it is probably just a joke. It is not too useful to know that the algorithm will stop at most after N steps when we consider that N can be 500 digits long …

(Joe: I guess if multicores follow Moore’s law then N = 500
won’t be a problem :-)

2007-05-28
380OK

On gnu/linux systems, and possibly others, you can use $(seq 1 32) instead of explicitly enumerating 32 numbers in the runtests script. bash also supports a ‘let’ which can perform increments within a while loop.

2007-05-28
283TYPO

In the code listing for lib_trigrams.erl the function for_each_trigram_in_the_english_language is misspelled as for_each_trigram_is_the_english_language (is instead of in).

2007-05-28
285TYPO

There is an errant space inserted in the first sentence of the second paragraph:

“The insertion time per trigram was 2.9 microseconds in an ETS ordered set, 1.5 microseconds in an ETS set, and 9. 3 microseconds in an Erlang set.”

Note the space erroneously inserted in the middle of the number 9.3.

2007-05-28
287TYPO

The second paragraph of the page says:

“code:which(?MODULE) returns the directory where the object code for ?MODULE was located.”

However, doesn’t code:which(?MODULE) return the full filename for the modules code? Seems like the sentence should be rewritten to read:

“filename:dirname(code:which(?MODULE)) returns the directory where the object code for ?MODULE was located.”

2007-05-28
305ERROR

I don’t think there is such a call gen_server:stop(?MODULE). This also applies to the download link on page 307.
Although I have a limited understanding of this, it seems that one would have to implement stop() as a request to handle_call, that returns a {stop, …} response.

2007-05-28
310TYPO

“ Description: Handling all none call/cast messages”
none -> non

2007-05-28
310ERROR

gen_server:stop(Name, Reason) ?

On my installation of R11B-4, gen_server:module_info() reports the following exports, which do not include a stop function:

{exports,[{behaviour_info,1},
{start,3},
{start,4},
{start_link,3},
{start_link,4},
{abcast,2},
{abcast,3},
{multi_call,2},
{multi_call,3},
{multi_call,4},
{enter_loop,3},
{enter_loop,5},
{init_it,6},
{system_continue,3},
{system_terminate,4},
{system_code_change,4},
{print_event,3},
{format_status,2},
{module_info,0},
{module_info,1},
{cast,2},
{reply,2},
{enter_loop,4},
{call,2},
{call,…}]},

2007-05-28
57TYPO

In the first paragraph under the “Defining Your Own Control Abstractions”, in the second sentence, there should be a comma between “switch statements” and “for statements”.

2007-05-28
59TYPO

In the code at the bottom of the page, there’s a comment that says “Last Time I do this.” Why is time capitalized? I think it should be lower case.

2007-05-28
142TYPO

At the end of the page:
“These message may or may not be received and understood.”
Should be:
“These messages may or may not be received and understood.”

2007-05-28
168TYPO

At the top of the page:
“… and can take any action it wants when it has detected a processes failure.”
Should be:
“… and can take any action it wants when it has detected a process’ failure.”

2007-05-28
194TYPO

Second sentence:
“… how to spawn process, …”
Should be:
“… how to spawn processes, …”

2007-05-28
318OK

As per the note on p317, the tuples in the result can be in any order

2007-05-28
57TYPO

Last paragraph:
——-
How does the pattern matching in the for loop work? The first clause in for matches only when the first and second augments to for are the same.
——-
“augments” should be “arguments”.

2007-05-28
364357ERROR

The lib_primes.erl still doesn’t work properly for single digit primes. The statement:
make_prime(1) ->
lists:nth(random:uniform(5), [1,2,3,5,7]);
should be:
make_prime(1) ->
lists:nth(random:uniform(5), [2,3,5,7]);
because “1” is not a prime number. Also, if you execute the following function call:
lib_primes:is_prime(7).
you get an error. Something similar to the following should be added to is_prime:
is_prime(_, N, 0) ->
lists:member(N, [2,3,5,7]);
after the “is_prime(0, ,) -> true;” clause.

2007-08-07
366ERROR

I submitted bug report and fix #8605. However, even if the fixes in that submission are made, there is still another problem. The function make_prime(K) does not CONSISTENTLY return a prime number “K” digits long. For example, when I ran the following:
io:format(“~p”, [lists:map(fun(_X) -> lib_primes:make_prime(2) end, lists:seq(1,100))]).
I got output that included a 3-digit prime (101 - at the end of the listing). Here’s the output:
(emacs@bc)18> io:format(“~p”, [lists:map(fun(_X) -> lib_primes:make_prime(2) end, lists:seq(1,100))]).
Generating a 2 digit prime .
Generating a 2 digit prime ….
Generating a 2 digit prime .
Generating a 2 digit prime .
Generating a 2 digit prime .
Generating a 2 digit prime …
Generating a 2 digit prime ……
Generating a 2 digit prime …..
Generating a 2 digit prime ……
Generating a 2 digit prime ….
Generating a 2 digit prime ….
Generating a 2 digit prime .
Generating a 2 digit prime ……
Generating a 2 digit prime .
Generating a 2 digit prime …
Generating a 2 digit prime ….
Generating a 2 digit prime .
Generating a 2 digit prime …..
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime .
Generating a 2 digit prime ..
Generating a 2 digit prime ….
Generating a 2 digit prime ….
Generating a 2 digit prime ….
Generating a 2 digit prime ..
Generating a 2 digit prime .
Generating a 2 digit prime …..
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime …
Generating a 2 digit prime …..
Generating a 2 digit prime ….
Generating a 2 digit prime ….
Generating a 2 digit prime .
Generating a 2 digit prime ..
Generating a 2 digit prime ……..
Generating a 2 digit prime .
Generating a 2 digit prime .
Generating a 2 digit prime .
Generating a 2 digit prime …
Generating a 2 digit prime ..
Generating a 2 digit prime .
Generating a 2 digit prime ..
Generating a 2 digit prime …
Generating a 2 digit prime ……
Generating a 2 digit prime …..
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime …
Generating a 2 digit prime …..
Generating a 2 digit prime ….
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime ….
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime …
Generating a 2 digit prime .
Generating a 2 digit prime ..
Generating a 2 digit prime …..
Generating a 2 digit prime ..
Generating a 2 digit prime …
Generating a 2 digit prime ..
Generating a 2 digit prime …..
Generating a 2 digit prime .
Generating a 2 digit prime .
Generating a 2 digit prime …..
Generating a 2 digit prime .
Generating a 2 digit prime .
Generating a 2 digit prime …
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime ..
Generating a 2 digit prime ….
Generating a 2 digit prime .
Generating a 2 digit prime …
Generating a 2 digit prime …
Generating a 2 digit prime .
Generating a 2 digit prime ..
Generating a 2 digit prime ….
Generating a 2 digit prime ..
Generating a 2 digit prime …..
Generating a 2 digit prime …
Generating a 2 digit prime .
Generating a 2 digit prime …
Generating a 2 digit prime ..
Generating a 2 digit prime .
Generating a 2 digit prime .
Generating a 2 digit prime …
Generating a 2 digit prime ..
Generating a 2 digit prime …..
Generating a 2 digit prime ….
Generating a 2 digit prime …
Generating a 2 digit prime …
Generating a 2 digit prime ..
Generating a 2 digit prime .
Generating a 2 digit prime ..
[11,
97,
97,
37,
7,
23,
97,
97,
97,
17,
17,
31,
97,
5,
11,
59,
79,
37,
23,
89,
97,
71,
17,
83,
47,
19,
71,
79,
31,
89,
59,
29,
23,
83,
59,
19,
97,
5,
29,
89,
47,
31,
13,
11,
71,
37,
29,
7,
23,
47,
7,
67,
37,
17,
71,
53,
37,
11,
59,
17,
31,
73,
53,
47,
29,
83,
59,
23,
89,
53,
31,
89,
47,
7,
29,
43,
29,
11,
53,
37,
97,
47,
97,
89,
29,
11,
79,
23,
101,
61,
23,
23,
101,
97,
37,
53,
37,
7,
5,
31]ok

2007-08-08
391383TYPO

Change “slowing” to “slowly” in the sentence “Large, monolithic processors are slowing becoming dinosaurs, …”

Also, consider changing the sentence:
“The techniques we grew up with for writing programs are struggling in this new world.”
to:
“The techniques that we grew up with for writing programs are struggling in this new world.”

2007-08-07
4028TYPO

In “Extracting Elements from a List”
The erlang response line “{newspaper,1},{apples,10},{pears,6},{milk,3}]”
is missing a leading ‘[’

2007-08-07
21OK

You state on the last line that one can use your code as a starting point for one’s own programs, yet ALL source code states, that it is copyrighted and may NOT be used for anything, so what’s the deal ?? May I use it or not ?? I would love to use the code to begin my projects and obviously state, that the original source code came from you, but if I can’t then all the source code and hence the whole book is useless. I suggest you eliminate this contradiction between the book and the source code and (hopefully) state something like this: You may use the source code as long as you give credit to the author for the original source code [link to the book + webpage].
Or maybe you have something else in mind, but as of now I am very confused, the book says “white” and the code says “black”.

(Dave says: the source code says that it may not be used to create teaching or training material and the like. You can use it in projects)

2007-08-07
294285TYPO

At the beginning of the 4th paragraph:
“The power of OTP comes from that properties such as fault tolerance, …”

might be better if written as:

“The power of OTP comes from the fact that properties such as fault tolerance, …”

2007-08-07
305296TYPO

“We�ll ignore the other arguments to gen_server:start for now.”
should read (to match the code above):
" We�ll ignore the other arguments to gen_server:start_link for now."

2007-08-07
39DEFER

I’m new to this, but I note in the transition between the section on tuples and lists, no real explanation is given as to the difference between a tuple and a list. It seems from the examples on p.37 and p.38 that I could use a tuple to hold a sequence of atoms, or I could use a list. So when would I choose a tuple, and when would I choose a list. It might be worth a “sidebar” section on - “The difference between tuples and lists …”, or something.

Anyway just a suggestion from an erlang newbie.

43OK

You could introduce a final section entitled “Clearing existing bindings” for your short discussion about “f().”, rather than burying it in an unrelated section on pattern matching :)

2007-06-20
383374SUGGEST

The explanation for F2 at the bottom of the page is very confusing. For instance, when you say “It then calls”, what do you mean by “It”?

Also, the sentence “It then calls…” seems to explain what you just mentioned: “the reduce process will have merged all the values…”

Is that what you meant?

Thanks,
Seth

2007-08-07
423425TYPO

In an Erlang code comment near the bottom of the page, “ text erorr log” should of course be “ text error log”.

2007-08-07
295DEFER

In the code for server2.erl, the catch clause uses “:Why“. I didn’t understand what that meant at first. The concept of tags is introduced very loosely on page 80 (”internal errors…always have the tag error“). The code example on page 84 shows a catch that catches ”:_” and explains that the tag “throw” is the default, but in my opinion that is not emphasized enough.

I’d like to suggest that the term “tag” be more formally and clearly defined, and also that you quickly re-explain the “:” syntax on p. 295 near the code for server2.erl.

307OK

In Calls and Casts, you might want to parenthetically mention that “cast” is short for “broadcast”.

2008-07-01
0DEFER

This is not specific to any page, but I feel that more attention needs to be paid to Erlang’s string handling performance and techniques. The book mentions that binaries should be used as much as possible, and shows an example of parsing URL’s from a text file, but it does not go far enough.

Based on my reading on the Internet and my own explorations, Erlang string handling (lists of integers) is both very slow performance-wise and extremely inefficient memory-wise (at least 16 bytes per character on 64-bit systems). String handling is a big deal in these days of the Web, and I know of a Web server (Yaws) written in Erlang, so obviously some people think it is suited for these types of applications.

I looked at the source code for Yaws and it seems as though it is doing some clever things with string data to get good performance, but my lack of Erlang knowledge really hamstrings me and I’d like more guidance from the book.

I was hoping that Joe would add a section (or at least a few more paragraphs) to the book on string performance and how to maximize it. I hope the answer is not something like “don’t use Erlang for applications that do heavy string manipulation”!

83OK

In section 4.6, programming styles with try..catch is explained. Instead of calling the cases as explained in the book, i would have preferred something along the lines described below:

“Code Where Error Returns are Common”
Case where you have a generic way of handling errors

“Code Where Errors are Possible but Rare”
Case where you want to handle each error/exception differently

“Catching Every Possible Exception”
Case where you want to handle all exceptions raised by the system (excluding the ones internally raised by runtime)

2007-06-20
124DEFER

Maybe you like to link the pages 124 and 47. Both care about the .erlang file.

Kind regards,
Nils

5241TYPO

In the fourth para of the Box “Where Do I put Those Semicolons?”, there’s a stray “kn” between “in” and “function”.

2007-08-07
65DEFER

As someone with a Haskell background, I found the section about ‘list comprehension’ quite understandable. However I noted that my fellow colleagues (who also enjoy the book very much!) did not reallly understand it with the perms example alone. I explained it to them with a simpler example at first, which opened the door to understanding perms:

mychar([]) -> [[]];
mychars(L) -> [ X || X <- L ].

Thus, mychars(“abc”) results in [“a”, “b”, “c”]. A colleague did not understand this at first, thinking a ‘list comprehension’ [ X | Y ] always needs a form of recursion to ‘generate’ a list of elements…

Hope this helps,

I might have been a bit vague on the explanation, I can be reached at bkok@ebay.com

15TYPO

Under the Chapter 17 bullet point, shouldn’t “soft, real-time” be “soft real-time”? “soft” is modifying “real-time” I believe, not “response times”.

2007-08-07
243DEFER

The file_info record shown here is missing the minor_device, inode, uid, and gid fields.

72OK

The last sentence of the ‘Creating and Updating Records’ sentence reads “Remember this is a copy of the original record; the original record is not changed.”

This should probably be “the original record has not changed.”

2007-06-20
7261TYPO

In the ‘Extracting the Fields of a Record’ section a sentence fragment is repeated:

On the left side of the match operator (=), we write a record pattern with the unbound variables W and Txt. record pattern with the unbound variables W and Txt.

2007-08-07
250TYPO

When
binaries are pretty printed, all control characters are displayed in an escaped format. And the binary is truncated, which is >>>indicted<<< by the three dots (…>>) at the end of the printout.
—————
Should be “indicated”.

2007-08-07
8069TYPO

Second para:

erlang:error(Why)
This is used for denoting �crashing errors.� That is, something rather nasty has happened that callers are not really expected to handle. This is >>>on par with<<< internally generated errors.
——-
Probably meant “on a par with”.

2007-08-07
2614TYPO

Third paragraph: “make an secure shell (ssh) connection” should be “make a secure shell (ssh) connection”

2007-08-07
342TYPO

In the type description for error_logger:error_report(Report), square brackets do not match.

2008-07-01
75OK

Section 3.11: may need some insights about adding an element to a list (why it should be appended to the head, not to the tail).

2007-06-20
75OK

may need some insights about adding an element to a list (why it should be appended to the head, not to the tail).

(Joe says: no change planned)

2007-08-07
80OK

Expecting knowledge on java or ruby may not be fair. or mention that in preface?

(Dave says: I don’t believe it is critical to understanding the book)

2007-06-20
8574SUGGEST

: suddenly appears. Some description would be helpful.

2007-08-07
130OK

In the makefile template, it may be better to use variable ($MAKE) when referring to ‘make’ command (same about other commands and variables, too).

(Dave says: I agree, but the author would rather not change these)

2007-08-07
133DEFER

Section 6.6: so how can we identify the heartbeat process? What name does it have?

(Joe says: On some Unix system “ps -ax | grep heart” works)

2007-08-07
138OK

It would be helpful if sample crash dump is provided (as the reader is probably not aware of the way how to create it intentionally).

(Joe says: The crash dump is not meant to be read by users. It can
be sent to the maintainers to help them identify the reason
for a crash. I don’t know how to make it intentionally,.)

2007-08-07
205ERROR

The chat server/client code did not work as it was downloaded on Linux (and probably Mac OS X).
Here is my patch:
diff -x ‘.beam’ -x ’~’ code/socket_dist/chat_client.erl new_code/socket_dist/chat_client.erl
37a38
> io:format(“starging connector~n”),
47c48,49
< \t MM ! {login, Group, Nick},
—-
> \t io:format(“connected to server\
sending data\
”),
> \t MM ! {send, {login, Group, Nick}},
63c65
< \t{MM, ack} ->
—-
> \t{chan, MM, ack} ->
64a67,68
> \t{’EXIT’, _, connectorFinished} ->
> \t wait_login_response(Widget, MM);
75c79
< \t MM ! {relay, Nick, Str},
—-
> \t MM ! {send, {relay, Nick, Str}},
77c81
< \t {MM,{msg,From,Pid,Str}} ->
—-
> \t {chan, MM,{msg,From,Pid,Str}} ->
98a103
> \t io:format(“error: ~p~n”, _Why),
102a108
> \t io:format(“try_to_connect: ok: ~p~n”, [MM]),
diff -x ‘.beam’ -x ’~’ code/socket_dist/chat_group.erl new_code/socket_dist/chat_group.erl
18,19c18,19
< C ! ack,
< self() ! {C, {relay, Nick, “I’m starting the group”}},
—-
> C ! {send, ack},
> self() ! {chan, C, {relay, Nick, “I’m starting the group”}},
34,35c34,35
< \t{C, {relay, Nick, Str}} ->
< \t foreach(fun({Pid,_}) -> Pid ! {msg, Nick, C, Str} end, L),
—-
> \t{chan, C, {relay, Nick, Str}} ->
> \t foreach(fun({Pid,_}) -> Pid ! {send, {msg, Nick, C, Str}} end, L),
39,40c39,40
< \t C ! ack,
< \t self() ! {C, {relay, Nick, “I’m joining the group”}},
—-
> \t C ! {send, ack},
> \t self() ! {chan, C, {relay, Nick, “I’m joining the group”}},
42c42
< \t{close,C} ->
—-
> \t{chan_closed,C} ->
44c44
< \t self() ! {C, {relay, Nick, “I’m leaving the group”}},
—-
> \t self() ! {chan, C, {relay, Nick, “I’m leaving the group”}},

2007-08-08
218208TYPO

In the response sequence “0,2,77”, length should be 1, not 2.

2007-08-07
222DEFER

The sample Makefile does not work as is on Mac OS X.
Here is my version for Mac OS X:
.SUFFIXES: .erl .beam .yrl

.erl.beam:
\terlc -W $<

MODS = example1 example1_lid

all: ${MODS:.beam} example1 example1_drv.so

example1: example1.c erl_comm.c example1_driver.c
\tcc -o $@ $^

example1_drv.so: example1_lid.c example1.c
\tcc -o $@ -I/usr/local/lib/erlang/usr/include -fno-common -bundle -flat_namespace -undefined suppress $^

clean:
\trm example1 example1_drv.so *.beam

226DEFER

In ports/example1_lid.c, you include erl_driver.h that comes with the sample code package.
But it may fail under some reader’s configuration, due to version mismatch (driver_incorrect_version).
It would be better to write #include <erl_driver.h> so that the version installed to the reader’s system is used.

192181ERROR

The configuration string and the explanation in the “*Important” section both refer to ‘start_me_up’ but the process mentioned as being spawned is ‘mod_name_server:startmeUp(MM, nil, notUsed)’. Should this not read ‘mod_name_server:start_me_up(MM, nil, notUsed)’?

2007-08-07
196TYPO

In the sequence diagram you have a <> and a <>. I assume that these are really the same thing and so should have the same capitalization?

2007-08-07
193DEFER

Ok, I found the lib_chan code. The way it was presented to the reader did not make it clear that lib_chan was code that came with the book and needed to be downloaded. Just stating that it is out of stream did not clarify the situation and the first 4+ pages of Appendix D did not clarify the situation.

Please add a note that the code is part of the code for the book and needs to be downloaded as well as the code in the chapter.

8156OK

In the first paragraph you speak of BIFs. However this shorthand for for ‘builtin functions’ is only introduced on page 88. Therefore it would be handy to introduce the reader to the terminology before using it.
Bas Kok <bakotaco@gmail.com>

(Dave says: a previous footnote explains the term)

2007-08-07
8069TYPO

In the try..catch expression example the exception named ExceptionType occurs twice. It would be clearer to also number these, e.g. ExceptionType1, ExceptionType2

Thanks,

Bas <bakotaco@gmail.com>

2007-08-07
85DEFER

4.7 -> Catching Every Possible Exception:
you mention there ‘tags’, but from reading the book so far, I have no clue of what tags are… ( : vs. _). If would be nice if there was a link to the section where tags are being discussed in the book, e.g. “we’ll be discussing tags at page X…”.

22TYPO

2.2 Installing Erlang: in the key sequence to quit the shell, ‘Q’ (in upper case) should be ‘q’ (in lower case).

2007-08-07
224214TYPO

In the first sentence under 12.4, “an foreign-language program” should probably be “a foreign-language program”, or possibly “an external program”.

2007-08-07
362354TYPO

At the end of section 18.7, I enjoy the Terminator jokes as much as the next reader, but technically the function is terminate/2.

2007-08-08
375366TYPO

In the last sentence of 20.1, “google” (verb) is lower-case, yet it seems to be capitalized elsewhere in the book.

2007-08-07
27TYPO

Section 2.4, in the sidebar: pressing ‘A’ (in upper case) causes crash dump. In this sidebar, pressing ‘a’ is expected so that the shell is just aborted.

2007-08-07
395386ERROR

Maybe this doesn’t matter, but from here onward it’s very hard to tell when and where periods and other punctuation are required in type annotations.

2007-08-07
74OK

The semi-colon in the revised filter function is wrongly placed.

(Joe says: the semicolon is correct)

2007-08-07
4737ERROR

Is:
Tip for Windows users: Create a file called C:/Program
Files/erl5.4.12/.erlang (youmight have to change this if your installation details vary).
Should be:
Tip for Windows users: Create a file called C:/Program
Files/erl5.4.12/bin/.erlang (youmight have to change this if your installation
details vary).

Otherwise it doesn’t work

2007-08-07
352344TYPO

In the compute_area/1 function, an atom is called “rectonge”, shouldn’t it be “rectangle” ?

2007-08-07
3221SUGGEST

In sidebar “Absence of Side Effects Means We Can Parallelize Our Programs”: for the antonym of ‘mutable’, ‘immutable’ is often used instead of ‘nonmutable’.

2007-08-07
3624TYPO

In Section 2.9 Tuples, ‘Point’ variable referenced in the sentence “So to set
the x and y values in Point…” should be ‘P’ (as ‘point’ is the name of struct and not capitalized).

2007-08-07
3624TYPO

In Section 2.9 Tuples, ‘P’ in “This creates a tuple and binds it to the variable P.” should be in the typeface for variables.

2007-08-07
296290TYPO

is:

1> server3:start(name_server, name_server1).
true
2> name_server:add(joe, “at home”).
ok
3> name_server:add(helen, “at work”).
ok

should be:
1> server3:start(name_server, name_server1).
true
2> name_server1:add(joe, “at home”).
ok
3> name_server1:add(helen, “at work”).
ok

2007-08-07
328322TYPO

is:
(joe@doris.myerl.example.com) 1> mnesia:create_schema([node()]).
mnesia:create_schema([node()]).

should be:
(joe@doris.myerl.example.com)
1> mnesia:create_schema([node()]).

2007-08-07
294TYPO

Bottom line is cut off in this and other pages.

2007-07-17
5848TYPO

“Line 1 compiled the module lists.” should be “Line 1 compiled the module mylists.”

2007-08-07
23TYPO

The blue box at the bottom covers actual text on several pages. Is there a way to get rid of it ?

2007-07-17
378TYPO

text at the end of the page is cnot formated properly, so reader can only see this:
results. Ericsson is building commercial products that run almost twice

2007-07-17
294TYPO

The last line on this page is hidden behind the foot bar.

2007-07-17
56OK

The for function definition

for(Max, Max, F) -> [F (Max)];
for(I, Max, F) -> [F (I)|for(I+1, Max, F)].

leads to an infinite loop in case I > Max, what is undesired and unintuitive behavior I suppose.

2008-07-01
138130TYPO

In chapter 7, it says “This makes Erlang program inherently easy to manage and scale.” The word “program” should be plural. It should read: “This makes Erlang programs inherently easy to manage and scale.”

2007-08-07
6959TYPO

The description of node(X) reads: “…can be a process. An identifier, a reference….”

I believe it should read: “…can be a process, an identifier, a reference….”

2007-08-07
67OK

==, used at the end of the page, has not been introduced yet. Perhaps a reference could be useful?

2008-07-01
230TYPO

The next to the last paragraph states: “urls2htmlFile is as follows:” The following code fragment then defines urls2html().

2007-08-07
152TYPO

The last paragraph states: “If Pid dies with reason, Why and the Fun(Why) is evaluated.”

I believe this should read: “If Pid dies with reason Why, then Fun(Why) is evaluated.”

2007-08-07
353345TYPO

Supervision strategy all_for_one should be one_for_all

2007-08-07
51SUGGEST

In the box “Where Do I put Those Semicolons” Data Constructors are mentioned, but not defined anywhere in the book.
(btw the headline of this box is inconsitently cased)

2008-07-01
0SUGGEST

Manual pages are mentioned every now and then, but as a Windows user, I dont know where to find them from the book.
Thats especially bad, because after installing OTP you have it all on your computer, so it shouldnt be a problem at all. The problem is that there is no explanation about what is what. The BIF-list, say, is at my computer at
<otp-dir, e.g. erl5.5.5>\\lib\\kernel-2.11.5\\doc\\html\\erlang.html
to be found from the main doc
<otp-dir, e.g. erl5.5.5>\\doc\\index.html
via the module link, module name: erlang
Thats vital information, and not to be found anywhere.
(a one page systematic explanation of the documentation structure would be relieving.)

2008-07-01
114DEFER

“References are globally unique”
As far as i remember that means more than inside of one erlang machine.
Would be nice to give more details, e.g. Can i be sure that this ref will never be reproduced in any cluster whereever whenever of which name ever?

140132TYPO

“Pairs of processes can be linked together. If one processes ..” should read “.. If one of the processes ..”

2007-08-07
150ERROR

“When we exceed the system limit, the system crashes ..”
Actually not. It just refuses to start more processes, and utters some error messages.

2008-07-01
183OK

in BIFs for writing distributed programs.

disconnect_node(N). must get the prefix erlang:, it is not visible from the shell.

2010-12-09
195187ERROR

End of IRC user interface chapter.
Quote:
The default parser is the following function:
Parse(Str) -> Str end.
End Quote.

you probably mean
Parse = fun(Str) -> Str end.

2007-08-07
363OK

If you expect your PDF readers to use the links, you must giv ’em all. lib_lin.erl is not linked here, but used.

(Dave says: there’s no link to it because there’s nothing to link from. You can download the entire source code from the book’s home page)

2007-08-07
363357ERROR

program lib_primes.erl
the first clause in make_prime should not return 1, because thats no prime.

so it has to be

list:nth(random:uniform(4),[2,3,5,7]);

2007-08-07
267261SUGGEST

With the code formatting that happens in these snippets, the ….some pseudo-code here…. stuff ends up looking peculiar, especially when there is a keyword in there (such as “of” on this page). Couldn’t these just be comments?

2007-08-07
32ERROR

In the discussion of debugging with immutable variables, the statement:

“So once we know which variable is incorrect,
we can immediately infer the place in the program where the variable became bound, and this must be where the error occurred. ”

Isn’t true if there is more than one place where the variable can become bound. The chapter thus far hasn’t said, AFAIK, that a variable can only become bound at exactly one point in the program.

So this is either a note of error in the discussion, or a suggestion to make explicit the at-one-place if that’s the case.

2008-07-01
384378TYPO

In the last bulleted paragraph, the text states: “…we’d expect to find files called /usr/index/busterbuster, ….”

I believe the pathname should be “/usr/index/buster”.

2007-08-07
197ERROR

The code for IRC lite is buggy.

It sends messages like so: MM ! message (where MM is the middle man from lib_chan_mm). In reality this code must be changed to lib_chan_mm:send(MM, message) or lib_chan_mm’s code should be changed to allow sending of arbitrary messages.

Also, whenever code accepts responses in the form of message or {MM, message} it should wait for {chan, MM, message} etc.

Also, in client_group.erl the group_controller function waits on a {C, {relay, Nick, Str}} whereas it receives both this message (when the user joins the group) and {chan, C, {relay, Nick, Str}} in all other cases

The code for IRC lite should really be cleaned up… These bugs were kindly pointed out to me by Arbow, avindev at gmail dot com from Erlang mailing list

2007-08-08
155OK

The table that deals with exit signals of type kill does not show the difference which results of using either exit/1 or exit/2. Only the function exit/2 seems to generate untrappable exit signals as shown by the examples that follows in the next few pages (edemo1.erl vs edemo2.erl). The erlang documentation suggests this as well.

2008-07-01
181TYPO

on line 3, “mod_name_server:startmeUp(MM, nil, notUsed)” should be “mod_name_server:start_me_up(MM, nil, notUsed)”

2007-08-08
83ERROR

In the detailed description of the bit syntax, when it describes the contents of the TypeSpecifierList, there seems to be an error where it describes the Unit element.

Specifically, where it says:

@type Unit = 1|2|…255

I think it should read:

@type Unit = unit:1|2|…255

The current text is missing the ‘unit:’ before the integer for the unit size.

2008-07-01
404TYPO

The correct signature of start_raw_server should be start_raw_server(Port, Fun, Max, PacketLength)

2008-07-01
376SUGGEST

“SMP Erlang has been enabled … since R11B-0 on all platforms where SMP Erlang is known to work.”
PLEASE mention that Windows is NOT among them.

This is the biggest single drawback known to me for users of Erlang under Windows.

2008-07-01
337TYPO

“This provides a place to which to send events.” should probably read “This provides a place to send events.”

2008-07-01
438DEFER

Dynamic code loading. a:loop() not mentioned.

The possibility to load a new version for module a from inside module a by using the full qualified function name (prefixing the module name) should be mentioned.

87OK

Section “5.1 BIFs” gives the Web-Reference to find them all.
It would come very handy to add a hint to Appendix F18.
(I’m not a BEAM, I processed the book sequentially, you know?)

2008-07-01
203OK

I followed the instructions for getting the chat server working, and when I call “make chat_server”, and then in another shell call “make chat_client” I get these errors:

1> chat_client login unexpected:{’EXIT’,<0.46.0>,connectorFinished}
lib_chan_mm: protocol error:{login,“general”,“sue”}
chat_client login unexpected:{’EXIT’,<0.44.0>,connectorFinished}
lib_chan_mm: protocol error:{login,“general”,“jim”}
chat_client login unexpected:{’EXIT’,<0.42.0>,connectorFinished}
lib_chan_mm: protocol error:{login,“general”,“jane”}
chat_client login unexpected:{’EXIT’,<0.40.0>,connectorFinished}
lib_chan_mm: protocol error:{login,“general”,“joe”}

Presumably this is not supposed to happen; the text does not make it clear what exactly should occur, but I assume I should be able to send messages among the popped-up windows (and four windows do pop up).

2008-07-01
154TYPO

Inconsistent use of “ExpressionTimeout” and “ExpressionsTimeout”

receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard1] ->
Expressions1;

after
Time ->
ExpressionTimeout
end

6. If the timer elapses when we are waiting for a message, then evaluate
the expressions ExpressionsTimeout and put any saved messages
back into the mailbox in the order in which they arrived at the
process.

2008-07-01
261255DEFER

In the udp_test.erl server source:
loop(Socket) ->
receive
{udp, Socket, Host, Port, Bin} = Msg ->
The only explanation of the ‘= Msg’ syntax in the book is back on pdf-110, paper-101 in section ‘Match Operator in Patterns’ of Misc. Short Topics.
1. The first time through the book, I didn’t register this, maybe partly because the context was function definitions, further it’s time consuming to rediscover that explanation again. I feel it would be helpful in the udp server section to remind the reader of the meaning of this construct, maybe just with a reference or even footnote back to the Match Operator section.
2. It looks like ‘= Msg’ is used in the udp server as a convenience to simplify the io:format log messages, and so may be worth pointing out explicitly as a handy debugging technique.

77DEFER

The explanation of BIF is not until page 86, but is used on page 77 in the explanation of exceptions.

182DEFER

Couple of things about section 10.5:

$HOME/.erlang/lib_chan.conf as stated on p179 is $HOME/.erlang_config/lib_chan.conf on my system - this may be an Ubuntu-ism? Also might be useful to move where this file should be to where you actually write the config file - (page 180, not 179).

I also second the comment elsewhere that it should be clearer that lib_chan is not part of the distribution, and that if you are going to take the bare minimum you need lib_md5 as well as the lib_chan* files.

Some brief description of the sort of error messages early on in the book would be useful (maybe as part of chp 5/6?) - they are quite cryptic coming from a different programming background. I.e. it took me a while to spot the undef and figure out that I needed extra libraries because the function wasn’t defined.

152DEFER

The notion of mailboxes is not introduced until section 8.6, but are referred to in 8.5 (receive with a timeout of 0)

368TYPO

In the box “Why Should We Care About Multicore CPUs?”, IMHO Niagra should be spelled Niagara in the phrase “…has an eight-core (with four hardware threads per core) Niagra machine on the market today.”

2008-07-01
264258SUGGEST

In the brodcast.erl examle code, the function listen() pattern matches S, and passes it to loop(S). S is never used (it is just passed on through loop(S)), so either use S in the receive pattern, or rewrite to make it clearer:
listen() ->
{ok, _} = gen_udp:open(6000),
loop().

loop() ->
receive
\tAny ->
\t io:format(“received:~p~n”, [Any]),
\t loop()
end.

2008-07-01
00SUGGEST

I find the lack of model answers to the existing exercises in the book incredibly frustrating. If I knew what the answer was, I wouldn’t need the book.

I think that in general the explanations of erlang in this book have got compacted in order to produce a text that covers most things in a manageably sized volume.

I can’t help comparing “Programming Erlang” unfavourably with “Learning Perl” by Randall Schwartz et al which gets the programmer started with a thorough understanding of the basics but in no way attempts to cover everything perl’s got and takes the time to explain why things happen the way they do in perl.

2008-07-01
445441TYPO

The description of code:soft_purge(…) reads:
“Remove old code for a module, unless no process uses it.”
This is the opposite of the behaviour.
Rewrite e.g.:
“Remove old code for a module, unless a process uses it.”

2008-07-01
195TYPO

socket_dist/chat_group.erl
delete(Pid, [{Pid,Nick}|T], L) -> {Nick, reverse(T, L)};
..

I think ..
F: ..reverse(T, L)..
T: ..reverse(L, T)..

What intention is the function reverse(L1, L2) used?

2008-07-01
61TYPO

Duplicate excerpt “record pattern with the unbound variables W and Txt.”

2008-07-01
222ERROR

The use of:

@spec file:open(X,M) -> {ok, IODev}
X = string()
M = atom()

is, according to the source code, an old obsolete method. So,

file:open(X,write) should be file:open(X,[write])

I guess the reason is that the former doesn’t allow for the full range of modes, e.g.

file:open(X,append)

gives an error. This caused me a period of head scratching, until I looked at the kernel source!

Thanks for an excellent book!

2008-07-01
37ERROR

Footnote 10: “This method of extracting variables using pattern matching is called unification and is used in many functional and logic programming languages.”
Error: Pattern matching is not “called unification” - it’s a (much simpler) special case of unification where free variables can only occur on the left hand side.
Suggestion: “This method of extracting variables by pattern matching is used in many functional and logic programming languages.” - Shorter, correct, and more to the point. Don’t mention unification.

2008-07-01
45ERROR

End of first paragraph: “The patterns are matched in the order they appear in the function definition.” This sounds like it is (only) referring to left-to-right matching of patterns in a clause (which is misleading, since there is no such defined order).
Suggestion: “The clauses are tried in the order they appear in the function definition.”

2008-07-01
45OK

Paragraphs 2 and 3 (“Note that…” and “This is a rule…”) ought to be moved after the following two paragraphs (“Now we’ll compile…” and “So, what happened”), and could use a little rewriting. The phrase “the earlier pattern” in par. 3 is strange: what is earlier, in what way?

2008-07-01
48TYPO

First paragraph: bad use of semicolon and misuse of the word “only”.
Suggestion: comma instead of semicolon and “but” instead of “only” makes much more sense.

2008-07-01
39OK

The section “Extracting elements from a list” ends a bit of a sudden. I suggest you end by saying something like “Eventually, you will end up with an empty list ([]), which tells you that you are done.”

2008-07-01
53OK

Paragraph 5: “badarity means that Erlang couldn’t find a function with the given name (Hypot in this case) that took the number of parameters we passed…”
Error: This is misleading. badarity means that there is no doubt about which function you are trying to use, but you are giving it the wrong number of parameters. There is no searching going on. And please don’t mention the variable name (Hypot) here since variable names are never ever used for looking up a function by name.
Suggestion: “badarity means that a fun was called with the wrong number of arguments—-our fun takes two parameters, and we passed just one”. (This can generally only happen with funs anyway, so there is no point in talking about functions here.)

2008-07-01
57TYPO

Paragraph 2, “Or we can use to…” should be “Or we can use it to…”.

2008-07-01
72TYPO

Second paragraph from end (“Earlier, we used…”): Missing comma after “Now”, as in “Now, using pattern matching…”.
Last paragraph: “But this definition is rather ugly, so we have to invent an additional function…”, should be “But this definition is rather ugly—-we had to invent an additional function…”

2008-07-01
73DEFER

Last paragraph: “and computing some value” should be “and computes some value”

74DEFER

Paragraph 5 (“If you ever see code like this…”) doesn’t really explain the problem, and makes it look like “” is inherently bad somehow.
Suggestion: “If you ever see code like this (List [H]) where List is the ‘’accumulating part’‘, it should set alarm bells off in your brain. It means that every time around in the loop, the (append) operation has to do more and more work.{Footnote: This causes the dreaded ’‘quadratic behaviour’’ in programming, and can really sink your program.} This is because has to go through the list on the left hand side and create a new list that simply uses the right hand side as its tail. It is much cheaper if you build the new list by adding to the left hand side, and reverse the result when you’re done.”

62OK

Footnote 10 (about using ) should refer to section 3.11 (Building Lists in Natural Order) for more information.

2010-12-17I disagree - I think this would detract from the text. The *main* point here is about list comprehensions not '++'
75TYPO

Paragraph 1: “whether” should be “when”.

2008-07-01
77TYPO

Paragraph 5, spurious comma: “the call to the function, which raised…” should be “the call to the function that raised…”

2008-07-01
87TYPO

Section 5.1, “BIFs”: The text says “For example, it’s impossible to turn a list into a tuple…”, but the following examples use tuple_to_list/1, not list_to_tuple/1. (Note that it is possible, just inefficient, to implement tuple_to_list/1 in Erlang itself.)
Suggestion: rewrite examples to use list_to_tuple/1 instead, since that is the “otherwise impossible” case.

2008-07-01
93DEFER

Paragraphs 4 and 5 both start with the same sentence: “To find the sync point…” (only the last word differs). In any case, those two paragraphs are verbose, repetetive, and hard to follow.

101DEFER

The attributes “-compile(…)” and “-vsn(…)” are described as “predefined module attributes” along with “-module(…)” etc., but in fact, they are technically just user-defined attributes. They can be viewed as pragmas that some tools may or may not care about. For example, the Erlang compiler looks for compile() attributes, but this is not part of the language in itself it’s just a feature of that particular tool.
Furthermore, it might be worth mentioning that if you don’t specify a value yourself for ‘vsn’, the compiler fills it in for you with the MD5 sum of the module.

103DEFER

The subsection on Boolean Expressions should have a reference to the subsection on Short-Circuit Boolean Expressions on page 115, and vice versa. The “Note:…” part in the Short-Circuit section would be better to have in the normal Boolean Expressions section (together with the crossreferences).

106TYPO

Paragraph 1: “Things such as records and module attributes…” should be “Things such as record declarations and module attributes…”, or better: “Things such as function definitions, record declarations, and module attributes…”

2008-07-01
109DEFER

Subsection “Control Flow in Macros”: This talks consistently about control flow “within a macro”, “inside a macro definition”, etc. But in fact, you cannot write these things within a macro.
Suggestion: Break it out from the Macros section, change the heading to “Preprocessor Control Flow”, and talk about “During preprocessing” etc. Also, use the term “processed” instead of “evaluated”. Finally, it would be a good idea to note explicitly that one cannot write e.g. “-ifdef(x).” or “-endif.” within a function definition or any other declaration, but only before or after.

112OK

Numbered list, item 3: “$ syntax”. This only talks about ASCII, but ought to at least mention Latin-1 or refer to Section 2.11 about Strings and character sets.

2008-07-01
233ERROR

In the example id3_v1.erl, the return value of the function read_id3_tag(File) for the second clause of case file:open…. should be atom error and not tuple {File, Error}, in order to exclude any file in error in L2 in then function dir(Dir).

2010-12-09
139TYPO

Looks like a little error, the line “3> area_server2:rpc(Pid, {circle, 5}).” actually should be “2> area_server2:rpc(Pid, {circle, 5}).”

2008-07-01
91ERROR

“The only significance of this has to do with packing and unpacking integers from binaries”

should include: “packing and unpacking integers and floats from binaries”

2008-07-01
69SUGGEST

In section 3.9, the example of a record starts “-record(Name, {”. When I try this, I get an error, and need to make ‘Name’ into an atom (with lower case first letter): ‘name’. In later example in the same section, atoms are used.

The error I get when I try to compile with capitalized ‘Name’ is “bad record declaration”.

2008-07-01
438TYPO

Par. 3: “the process running version 1 of a’s code has died” should be “the processes running version 1 of a’s code have died” (since there were two of them).

2008-07-01
435DEFER

Chapter E.4: it is reloading, not recompilation in itself, which causes processes to call new code. Instead of saying “recompile”, say “reload” or “recompile and reload” (and clarify that the shell function c(Module) does both). Calling the compiler directly, e.g. using compile:file(…), or running erlc from an operating system shell, does not cause reloading.

157DEFER

Section 8.10, “Spawning with MFAs”: It is a misconception that spawns using funs would somehow cause problem with dynamic code loading. It is not! The fun is just used as a launch point when the process is created, and the body of the fun typically just tail calls immediately to another function which is where the new process actually lives. Hence, the spawned process will not have any references from its stack or heap back to the fun, and dynamic code loading will not be a problem. But somehow, this general warning against funs in spawn has achieved myth status, and I really wish that it was not perpetuated like this.

(If you were nutty enough to write a self-recursive fun using a Y combinator, and call spawn on that, I agree that code reloading would not work.)

196TYPO

This also occurs on subsequent pages. The function disconnected/3 is called disconnected/2 in the text description of it.

2008-07-01
40TYPO

In the third paragraph of Section 2.11, the string “Hello” starts with a double quote but ends with a single quote.

2008-07-01
36TYPO

The C code for getting the ht in the area function should read ht = s->shapeData.rectangleData.height; since there is no ht element in the rectangleData struct.

2008-07-01
79TYPO

When describing the example on the previous page, the term FuncOrExpressionSeq is used. However, the referenced example uses the term FuncOrExpressionSequence instead. The term should be consistently applied. Either term would be acceptable.

2008-07-01
120TYPO

When describing the function code:all_loaded(), “returns a list of all loaded module” should be “returns a list of all loaded modules”.

2008-07-01
153TYPO

The example in Section 8.6 refers to “Expression1” for both patterns. The second pattern should refer to “Expression2” as done by other examples (e.g. Section 8.5).

2008-07-01
245TYPO

First line in third paragraph from the bottom.

Instead of:
… returns {ok,Socket}
it shoud read
… returns {ok,Listen}

2008-07-01
402TYPO

9th line from the bottom.

‘contines’ should read ‘contains’

2008-07-01
468TYPO

FIrst line in F.26

Not trees but sets:

‘General balanced trees’ should read ‘General balanced sets’

2008-07-01
84OK

It is perhaps worth clarifying exactly what stacktrace is returned by erlang:get_stacktrace(). My first interpretation on reading the sample code was that it returned the stacktrace of the calling process - ie the trace to where get_stacktrace was called. Based on a quick search, it seems instead, that it returns the stacktrace of the ‘throw’ that the catch is dealing with - ie it is a contextual function… or have I got that wrong too?

2008-07-01
151OK

Mis-placed comma - “priority receive,” should be “priority receive”, ?

(Dave says: That’s the Chicago Manual style…)

2008-06-12
179OK

FYI, running emulator version 5.5.5 on OSX 10.5.1 (Leopard), the actual host name was required, instead of localhost.

For example, running “erl -sname n2” had a shell prompt of “n2@enki”. A “netstat -a” showed that the ports appeared to be listening on all interfaces. Any attempt to send an RPC to n2@localhost resulted in {badrpc,nodedown}, but n2@enki worked fine.

2008-07-01
285TYPO

The word “exiting” in the following sentence, which appears toward the bottom of the page, should be “existing”:

“Note that dets:open_file either creates a new file or opens an exiting file, which is why we have to check whether the file exists before calling dets:open_file.”

2008-07-01
347TYPO

I assume that the following function:
handle_call(_Request, N) -> Reply = N, {ok, N, N}.
should be:
handle_call(_Request, N) -> Reply = N, {ok, Reply, N}.

Shouldn’t the clear_alarm handler function decrement N when determining the new state, and perhaps only display the message when N reaches 0?

2008-07-01
143OK

I tried the 8.2 simple example but kept getting the error:

Error in process <0.33.0> with exit value: {undef,[{area_server0,loop,[]}]}

The reason was that I hadn’t compiled the module first using
1> c(area_server0).

Would it make sense to put that step in? Perhaps there was a step I missed along the way - I’m skimming the book first before doing a more thorough re-read.

Derek.

2008-07-01
346DEFER

Compiling my_error_handler (with erlc) produced the following warning:
./my_alarm_handler.erl:9: Warning: undefined callback function code_change/3 (behaviour ‘gen_event’)

Adding a basic implementation (and export) seemed appropriate, considering that code_change is part of the behaviour.

code_change(_OldVsn, N, _Extra) -> {ok, N}.

364OK

The lib_primes module requires lib_lin, which doesn’t appear to be referenced in the book, though the code can be found on the website.

As a suggestion, shouldn’t lib_primes, and lib_lin be introduced early in this chapter so that the example steps can be run in the order that they are presented?

2008-07-01
381TYPO

“F1(Pid, X) will be called for each value of X in L.Pid is a process…”
Missing space between “L.” and “Pid”

2008-07-01
476TYPO

In the description for “enter_loop” there is no whitespace around the term “gen_fsm.”

2010-12-09
478TYPO

In the description for “enter_loop” there is no whitespace around the term “gen_server.”

2010-12-09
65OK

Figure 3.1 describes bsl as “Arithmetic bitshift left..” and bsr as “Bitshift right..”.
In fact it is Bitshift right which needs the qualifier “Arithmetic”. (Bitshift left is always arithmetic, whereas bitshift right is arithmetic if and only if –1 bsr 1 =:= –1.)

2010-12-17yes
112TYPO

Range of representable real numbers should start at 10 to power –323, rather than minus 10 to power 323. (Perhaps best to reword as “real numbers with absolute value in the range..”.)

2008-07-01
440DEFER

It would be nice if the book included the proplists module among the modules it covers in Appendix F. That module is especially useful for handling JSON converted to Erlang structures.

242DEFER

There’s suggestion to use certain kinds of accumulation techniques for tcp fragments. Now the R12B-0 have brought efficient binary accumulation which should be preferred.

I.e. instead of doing
receive_data(Socket, SoFar) ->
receive
{tcp, Socket, Bin} ->
receive_data(Socket, [Bin|SoFar]);
{tcp_closed, Socket} ->
list_to_binary(reverse(SoFar))
end.

or

receive_data(Socket, SoFar) ->
receive
{tcp, Socket, Bin} ->
receive_data(Socket, list_to_binary([Bin,SoFar]));
{tcp_closed, Socket} ->
SoFar
end.

the R12-> preferred way (by Efficiency Guide chapter 4) would be

receive_data(Socket, SoFar) ->
receive
{tcp, Socket, Bin} ->
receive_data(Socket, <<SoFar/binary, Bin/binary>>);
{tcp_closed, Socket} ->
SoFar
end.

64OK

In the pythag example, the maximum side length that needs to be considered is N div 2.

2008-07-01
64OK

Your hint regarding how to understand the perms example is strange. The code itself reads easily: “Construct the permutations of a sequence by taking any of the original members to start with, and then permuting the ones that are left.”

2008-07-01
74DEFER

I think there should be a statement to clarify that the function odds_and_evens() use ‘commas’ in the body as it is made up of ‘sequence of expressions’.

It took me some time to wonder why the function body use ‘commas’ instead of semicolons. The previous pages that introduce ‘functions’ in erlang did not touch on this point, and most of the examples of function body are only one-liners.

71TYPO

“record pattern with the unbound variables W and Txt.” is writed twice.

2008-07-01
178OK

In section 10.4, the example shell command for explicitly setting the cookie value in the .erlang.cookie file will not work. I think it should be:

echo AFRTY12ESS3412735ASDF12378 > .erlang.cookie

2008-07-01
9283ERROR

The description of the “@type Unit” syntax contains 2 errors. For completeness:
Firstly, as in an existing errata, “unit:” must prefix the unit value, eg. “unit:48”.
Secondly, the legal range is 1 | 2 | … 256, and not 1 | 2 | … 255; 256 is a multiple of 8 which is copacetic with the segment size being a multiple of 8.

2008-07-01
9283SUGGEST

Enhance the description of “@type Type = integer | float | binary” to make the meaning more explicit, e.g. add “in matching, the extracted bits are converted to this type”, or some better words, to highlight the difference in effect of matching <<Var/integer, …>> and <<Var/binary,..,>>
Add some more examples of the bit syntax. In the only example incorporating Type integer (pg 96/87), the only value used is Characteristics, so only this case is available to clarifying what value types are built by match.
There is no float example anywhere, could just ‘crack’ or assemble a float?

2008-07-01
80TYPO

“Here’s a pair of functions that illustrates this” is “Here’s a pair of
functions that illustrate this” in modern English usage. (“pair of” is plural).

2008-07-01
66OK

The logic of this sentence escapes me. I think “since” implies a cause that doesn’t exist:

“Guards are an extension of pattern matching, and since pattern matching has no side effects, we don’t want guard evaluation to have side effects.”

2008-07-01
70TYPO

The expression that in page 69 is called “FuncOrExpressionSequence”, in page 70 is called “FuncOrExpressionSeq”.

2008-07-01
48ERROR

Tip for Windows users: Create a file called C:/Program
Files/erl5.4.12/bin/.erlang.
This does not work. The file apparently needs to be in C:/Program
Files/erl5.4.12/, not the bin subdirectory. The July version of the printed book does not have this error.

2008-06-12
223DEFER

The shared library must be called example1_drv.dll on Windows systems in order for erl_ddll:load_driver to find it. Otherwise you get

exception exit: {error,could_not_load_driver}
in function example1_lid:start/1
when you call example1_lid:start().
from the Erlang shell.

130OK

In the makefile template, perhaps the line “compile: ${MODS:.beam}” should be modified to “compile: ${MODS:.erl=.beam}” to make it work. My make tool version is GNU Make 3.80.

2008-07-01
343DEFER

When sasl_error_logger is configured to write to a file, on Windows at least, the directory must exist before sasl is started. Sasl will not create it. When using Msys on Windows , as explained in Appendix B, the syntax of the filename given in the config file must be Windows syntax but using ‘/’ instead of ‘\\’
e.g. “C:/Documents and Settings/joe/error_logs/THELOG”.

87TYPO

Third-bottom paragraph: <<’cat“>> should be <<”cat">>.

2008-07-01
75TYPO

“the [H filter(H)] type construction. ”

probably must be :“[H || filter(H)]”

2008-07-01
358DEFER

The is_prime function uses the Rabin-Miller primality test, but doesn’t properly cite it and doesn’t note that it is a probablistic test rather than one that gives certain results.

124TYPO

This is truly nit-picking, but “quote” should be “quotation”. To quote is to take somebody’s words; a quation mark is the symbol.

2008-07-01
124DEFER

not equivalent example

“C:\\Program Files\\erl5.5.3\\bin\\erl.exe” -noshell -s hello start -s init stop

#!/bin/sh
erl -noshell -pa /home/joe/2006/book/JAERANG/Book/code\\
-s hello start -s init stop

183TYPO

second spawn(Nod, Fun) wrong.

“Note: This for m of spawn is more robust than spawn(Node, Fun).
spawn(Nod, Fun) can break when the distributed nodes are not run-
ning exactly the same version of a particular module. ”

2008-07-01
54TYPO

The line “13> lists:map(Double, L).” should return “[2,4,6,8]”, not “[2,4,6,8].”.

2008-07-01
59TYPO

The line “1> L = [1,2,3,4,5].” should return “[1,2,3,4,5]”, not “[1,2,3,4,5].”.

2008-07-01
61TYPO

The line “1> Buy=[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}].” should return “[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]”, not “[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}].”.

2008-07-01
467TYPO

In the description of filelib functions is_dir/1, is_file/1, is_regular/1, there is no space areoung the “Name”.

2010-12-09
115TYPO

I believe that the path mentioned in hello.sh, at the top of the page, should refer to ‘…/JAERLANG/…’ and not ‘…/JAERANG/…’.

2008-07-01
142OK

The code fragment ends about 3mm from the bottom of the page. It would probably be better if it all started at the top of the next page.

2008-07-01
143DEFER

The concept of a mailbox is referred to and relied upon halfway down the page, but it is not introduced and described until p145, which is also the only place referred to by the index.

149OK

There is a missing ‘receive’ in the code fragment in the centre of the page. Consequently, the code is not correctly indented. Also, the ‘end’ should be in bold.

2008-07-01
153OK

The ‘receive’ and ‘end’ keywords in the two code fragments on the lower half of the page should be in bold.

2008-07-01
179OK

There should be more obvious warnings about and around the code fragment containing “cd /; rm- rf *”!

2008-07-01
94OK

In get_word/2 (in mp3_sync.erl) C (which appears to be the variable you’re unpacking the header into) takes 4 bits, but in the following paragraph it says 32. I think. Later in the chapter you seem to refer to <<2#11111…:11, … > as matching a binary with 11 1-bits.

2008-07-01
376SUGGEST

My remark about SMP is obsolete for Erlang/OTP R12B. It works on M$ windows too now.

2008-07-01
171OK

erlang:monitor(): Please don’t refer to the “man page” for a module (‘erlang’ in this case), but to the “documentation of the X module”.

2008-07-01
173OK

First paragraph: Please don’t refer to the “manual page” for a module (‘erlang’ in this case), but to the “documentation of the X module”.

2008-07-01
183OK

Footnote 7: Please avoid the term “manual page” and refer to “the documentation” instead.

2008-07-01
241TYPO

This sentence fragment does not seem to make sense:

“(…), so you’ll see is what a binary looks like (…)”

This is in the paragraph right after the first code example on that page.

2008-07-01
225TYPO

Last paragraph: Jinteface -> Jinterface

2008-07-01
226OK

Please refer to “documentation” instead of “manual pages”. (Twice on page 226.)

2008-07-01
230OK

Last paragraph: please refer to “documentation” instead of “manual pages”.

2008-07-01
235DEFER

Last paragraph: the ~n formatting command: the explanation that “~n is smart” is wrong! (Try it on Windows, or just look in the code for io_lib_format.erl.) It always produces a single newline character (ASCII 10), so it is equivalent to using the escape sequence “\
”, except that the latter is expanded at compile time.

What really happens (I think) is that when the newline is printed to the output stream, if the stream is open in text mode - which is normally the case if you are writing to it with io:format() - the newline will be converted to the correct sequence for the platform. (This is probably just as a consequence of the Erlang runtime system being implemented in C.) So Erlang, just like C, works on a normalized text format internally, and converts the newlines at the I/O boundaries.

236SUGGEST

Line 4: “~s The argument is a string” should be “~s The argument is a string or IO-list, or an atom, and will be printed without any surrounding quotes”

2008-07-01
235DEFER

I spoke too soon (#31742): there is no platform-dependent conversion happening at all. Opening a file with file:open() uses binary mode for read/write, not text mode, also on Windows. If you want to handle CRLF, you have to do it yourself. Not even io:format(“~n”,[]) to the emulator standard output stream will produce a CRLF on Windows, only LF.

241OK

Please refer to “documentation” instead of “manual pages” (twice on p. 241).

2008-07-01
242OK

2nd par.: please refer to “documentation”, not “manual pages”.

2008-07-01
261DEFER

In the UDP client/server example code, the server is parameterized with respect to ‘Port’, but the client code (both on p. 261 and p. 262) is hard-coded to contact the server on port 4000. This is not very elegant, and furthermore, there is no text that mentions how the “4000” suddenly turned up in the client code.

316DEFER

You note that qlc:q(LC) only works if LC is a literal list comprehension, and not if LC is a variable, but you do not mention that it is necessary to add a declaration -include_lib(“stdlib/include/qlc.hrl”) to the file (or what a parse transform is and why the qlc-expressions work at all). Readers who expect normal expression evaluation semantics get confused by this.

327TYPO

“we can use the syntax {attribute, …” should be “we can use the syntax {attributes, …”.

2008-07-01
327OK

Par. 3: please refer to “the documentation”, not “the manual page”.

2008-07-01
317DEFER

Section 17.2 “Adding and removing data…”:
It is frustrating to read about operations like mnesia:write(Row) when there has been no explanation at all how tables are created. Please insert forward references to 17.5 “Table types” and 17.6 “Creating the initial database”.
Preferably also give a short explanation about how the Name used when creating the table is implicitly used by mnesia:write(Record), which takes the record tag as the Table name and the first record field as the primary key.

392ERROR

3rd bullet point: “alternation type” should be “union type”.

2008-07-01
392SUGGEST

Third bullet point: note that [X|Y] as a type expression means “a list of X and/or Y elements”.

2008-07-01
393DEFER

2nd bullet point: “TypeVar::Type: A type variable followed by a type. This means that TypeVar has type Type.” This is a misunderstanding. The syntax means “Name::TypeVar: The argument name, followed by a type. Here, Name looks just like a variable, but is only for documentation purposes, to make it easy to talk about the different arguments.” Also, the 1st bullet point should be removed, as remarked in #31793, and the 3rd point be moved to 1st place. You could change “Type: A type expression” to “Type: A type expression, possibly just a type variable.”

430TYPO

Figure E.1 caption: “Table viewer initial screen” should be “The debugger window”.

2008-07-01
228OK

The unconsult function contains the format string “~p.~n” which should read “~p~n”. It is also incorrect in the code available online.

2008-07-01
248OK

Section: “A Parallel Server”, last paragraph.
“The crucial difference is the addition of a spawn, …”

It’s actually two spawns in the code above the text, so “a spawn” needs to be pluralized. :-)

2008-07-01
285OK

Second paragraph, “…- think of it as an application framework that is parameterized by a callback module”.

I have no clue at att what that means, perhaps you need to make it abit clearer to understand.

2008-07-01
337DEFER

SInce it’s explaining error logger config file it’s abit confusing to have “false” to represent something that is “turned on”. First I thought it was a typo.
Might need some explanation on why it only gives “error reports” and not “progress reports and so on”.

342TYPO

In paragraph starting with “In addition, …”, on the first line, “error_handler” should read “error_logger”.

2008-07-01
363DEFER

Due to this line in make_prime/1:
N = make_random_int(K),

2 * N - 3 may have more than K digits, which causes this kind of behaviour:
————————
Generating a 2 digit prime ..
101
————————
Using the (K-1)th power of 10 should make it work.

37OK

I noticed in Windows that .erlang needs to be wherever the “Start in:” setting is when you right mouse click on a shortcut that is created from erl.exe or werl.exe. If you go to the \\bin directory from explorer and double click, then .erlang would need to be there. If you make a shortcut, then .erlang needs to be wherever the “Start in:” is pointing. Oh boy—was that tricky!

2008-07-01
187TYPO

“The behavior of the server is determined by the file $HOME/.erlang/lib_chan.conf.” at very bottom of page — I think .erlang should be .erlang_config .

2008-07-01
209ERROR

I see that in io_widget.erl the top cell of the packer frame is being created with a PackOption of {stretch,10,120,100}. According to page 24 of this seemingly authoritative manual www.erlang.org/doc/pdf/gs.pdf , the format for PackOption is {stretch, Weight, MinPixelSize, MaxPixelSize}. So it appears that the io_widget.erl code is specifying a min > max.

2010-12-09
0SUGGEST

Most of the Errata have PDF page numbers but not physical page numbers. I want to print, cut up, and insert the errata throughout the book. First, I’d have to manually locate all of the errors. Subsequently, anyone else wanting to do the same would have to replicate that work.

Short of publishing my own blog page with the page number mappings: is there some way we could make physical page numbers available with only one person having to do the work?

(Dave says: not easily—there’s no algorithmic way of doing it)

2008-06-12
24TYPO

Talking about the 1> prompt after the example: the prompt looks like ell-ampersand rather than one-ampersand

2008-07-01
45TYPO

You spelled out “Width” so why are you abbreviating Height as “Ht”? For clarity in teaching, I would suggest spelling out “Height” also. (I think you have room to make it still fit on one line.)

2008-07-01
158SUGGEST

Note: the other erratum’s shown are not for this page. Section 8.11 is titled “Problems”. It appears these are most like “Exercises”. Since we had one section about what can go wrong with sequential programs, I assumed this was another section of similar ideas for concurrent programs.

2008-07-01
344OK

The 1.0 version had the “correct” (i.e. intentional) error of misspelling “rectangle” as “rectonge”. 2.0 “fixes” the problem, leading to confusion.

(The paragraph above the example says “it contains a deliberate error (can you find it?)” which refers to this error.)

2010-12-17This bug has an interesting history. An over zealous proof reader "corrected" the spelling of rectonge - making the deliberate error not an error. This crept into one of the PDfs - hopefully it is ok now -
1DEFER

As a Xp programmer, I was very disappointed that unit-testing wasn’t part of the book. It would be great, that in a future version of the book, you talk about unit-testing ; there are several frameworks around : eUnit (not very good in my opinion) and extremeForge.

2010-12-09
229TYPO

Missing period on line 5 in the erl session for reading a file, one term at a time.

2010-12-09
239TYPO

In the erl example for writing to a random-access file, all three lines are missing the ending period.

2010-12-09
239SUGGEST

It would be better if the file name in the example of writing to a random-access file were something other than “…”.

2010-12-09
241OK

When introducing the ls(dir) function in lib_misc.erl, you should also include an import statement for:

-import(lists, [map/2, sort/1]).

2010-12-09
242SUGGEST

In the description of the filename module, the end of the first sentence would read better if you used “from” instead of “for”. So it would read, “… rebuilding filenames from the component parts.”

2010-12-09
251OK

In the loop(Socket) function, you invoke lib_misc:string2value(Str) but you have not added this function to the lib_misc module. In searching the PDF, I see no other reference to this function so the user that is keying in the example code from the book has nothing to go on.

2010-12-09
258TYPO

In the first sentence of section 14.3, you have, “Suppose we write a some kind of online server …”. You should remove the word “a”.

2010-12-09
258ERROR

In the last sentence on the page, you say that both Ni and Ki are integers in the range of 0 to 255. For IPv6 addresses, the Ki should be in the range of 0 to 65535.

2010-12-09
266TYPO

In the second paragraph of item 3 in “How the SHOUTcast Server Works”, you have, “… uses the code developed in sections Section 13.2, …”. The word “sections” is redundant.

2010-12-09
279TYPO

In the fourth paragraph, third sentence, you have, “… is based on a set of measurement of the relative performances …” The word “measurement” should be plural.

2010-12-09
279TYPO

In item #3 toward the bottom of the page, you should add the word “it” so that it reads, “Measure the time it takes…”.

2010-12-09
314OK

I have noticed that as I get further into the book, that more and more details are being left out of the source code. For example, on this page, you only list the two -record lines for test_mnesia.erl. Then in the example of use, you have us execute test_mnesia:do_this_once(). If you are going to leave out the -module statement, you should probably warn the reader like you did earlier about leaving out compiling the source. If you don’t want to put the source for everything you are demonstrating, you should probably tell the reader that the full source is on page xxx like you did in earlier chapters. I know that I can download the example source but it for some reason I did not have access to it (maybe I am reading the dead-tree version of this book at my mother-in-laws house and she doesn’t have wifi) the book would make more sense with complete source examples.

Just a suggestion.

2010-12-09
328TYPO

in the erl script at the bottom of the page, the syntax coloring does not have the input in line 1 colored burgundy like the other inputs. Also, the prompt in line 2 should contain the node name like is does on line 1.

2010-12-09
346OK

When I compile my_alarm_handler.erl, it warns me that code_change/3 is not defined and that behaviour gen_event wants it defined. Maybe this is a change from the version of Erlang you had when writing the book. I am running R12B3. The BEAM emulator version is 5.6.3.

To fix the problem, I appended the following to the end of my_alarm_handler.erl:

code_change(_OldVsn, N, _Extra) -> {ok, N}.

I also added code_change/3 to the export list.

2010-12-09
354TYPO

In the paragraph describing the Type member of the data structure, second sentence, you left out the word “a”. It should read, “We can construct a tree of …”.

2010-12-09
363SUGGEST

At the top of lib_primes, you should also include the lines:

-module(lib_primes).

-export([make_prime/1, is_prime/1, make_random_int/1]).

And as mentioned in another errata, you should include the listing for lib_lin.erl.

Just a suggestion.

2010-12-09
364OK

The listing for lib_primes.erl does not include the make_random_int/1 and new_seed/0 functions.

2010-12-09
368TYPO

In the box, third paragraph, first sentence the word “at” after the word "producing’ should be removed.

2010-12-09
382SUGGEST

in the collect_replies function, the receive pattern {’EXIT’, , Why} causes a warning when compiled because the Why variable is not used anywhere. You should probably make the pattern be {’EXIT’,, _Why}.

2010-12-09
382OK

In the function generate_words, you refer to lib_misc:foreachWordInFile without defining it anywhere. You also don’t define foreachWordInString, isWordChar, get_word, and collect_word. Fortunately they do exist in the download version of the file.

2010-12-09
383SUGGEST

The transition from the listing of test_mapreduce.erl to the erlang shell is not well delimited. Also, the line number starts at 5 unlike all your other examples which start at 1. It makes me think something is missing from the book.

2010-12-09
358ERROR

sellaprime.app doesn’t include lib_lin in the list of modules, which is one of the dependencies of the application.

(Not that it really matters unless you make a release, in which case you’ll find lib_lin is omitted from the tarball)

2010-12-09
408OK

pg.90 states: “Warning: The use of apply should be avoided if possible.”

The Appendix D features lib_chan.erl which uses apply/3 on page 408, line 3.

Perhaps there should be an explanation as to why it is necessitated (within the scope of what the book teaches) in one of the descriptive areas.

2010-12-09
169OK

in the second example, at the very top of the page, process B receives {’EXIT’,<0.73.0>,kill}. Should that not be {’EXIT’,<0.73.0>,killed}?

2010-12-09
62OK

The new expression for total(L) using comprehensions is given as:
total(L) ->
lists:sum([shop:cost(A) * B || {A, B} <- L]).

Could it be made clearer that this should replace the expression in the file shop2.erl followed by a recompile?

It has been a few pages since that file was dealt with, so it may not be at the fingertips of some users. Or it could be a shop2a.erl file?

The code is by itself, and not following a shell prompt, but I thought the relation to the compiled file could be made clearer.

Thank you.

2010-12-09I think it's clear as it is. I think adding more text would \ndetract from the main point I want to make.
233TYPO

The -record(file_info….
omits minor_device,inode,uid,gid and the closing }

2010-12-09
247TYPO

The code at the bottom of the page should have
gen_tcp:close(Listen),
before loop(Socket).

2010-12-09
88OK

I think the <> expression in the “Unpacking COFF Data” section will byteswap the original DWORD, but this isn’t mentioned in the text. ?DWORD is defined as a little endian integer, but the default order for binaries is big endian, right? Perhaps this should be <<Characteristics:?DWORD>>? Or maybe the LHS of the match assumes byteswapping… I don’t know COFF. :)

2010-12-09The code is cut-and paste from working code so I think it's ok. At this stage I don't want to go into the nitty gritty details here.
47OK

This section describes how to change the working directory of the Erlang system in Windows. However, it suggests editing the .erlang file. In my Windows installation (5.6.4) running under Windows Vista, there is no such file. There is however a file called erl.ini, which seems to include similar information. Unfortunately, adding the lines suggested in the book causes the erlang system to crash on startup. The content of the erl.ini file is very simple:
[erlang]
Bindir=C:\\\\Program Files\\\\erl5.6.4\\\\erts-5.6.4\\\\bin
Progname=erl
Rootdir=C:\\\\Program Files\\\\erl5.6.4

I tried changing the Rootdir to my working directory, however that does not work either.

2010-12-09Thanks. I'm afraid exactly how to do this changes with \nwindows versions. I documented how it worked on the version of windows I had available. There is a brief warning that \nthis might vary on your system on page 47.
56OK

When entering the function definition in the erl shell:

1> for(Max, Max, F) -> [F (Max)];
1> for(I, Max, F) -> [F (I)|for(I+1, Max, F)].

  • 1: syntax error before: ‘->’
    1>

Running Erlang 5.6.3 under Mac OS 10.5.5. Erlang was built from source.

2010-12-09You can't enter this in the shell. It's part of a program \nThere a large box at the end of section 3.4 warning you \nthat the code in modules cannot be entered into the shell.
56OK

When entering the function definition in the erl shell:

1> for(Max, Max, F) -> [F (Max)];
1> for(I, Max, F) -> [F (I)|for(I+1, Max, F)].

  • 1: syntax error before: ‘->’
    1>

Running Erlang 5.6.3 under Mac OS 10.5.5. Erlang was built from source.

Name conflict error (the suspected cause for this issue) is not addressed until page 58.

2010-12-09You can't enter this in the shell. It's part of a program There a large box at the end of section 3.4 warning you that the code in modules cannot be entered into the shell.
21OK

Under Microsoft Windows XP (UK), when using the DOS command prompt (CMD.EXE) and typing erl (this calls erl.exe from C:\\Program Files\\erl5.6.5\\bin), then control G does not work: it prints ^G instead of the User switch command
—>
Calling the erlang Windows app (werl.exe) works as described.

2010-12-17Oh dear - I don't have a windows XP machine available to test this. This sounds like a bug in the XP version. The way \nI described works on most other systems (I hope).
49OK

Error message in Erlang 5.6.5 (R12B-5) is more useful for the beginner than the older cryptic error message in the book:
shop:cost(socks).

exception error: no function clause matching shop:cost(socks)

2010-12-09Great. We're always trying to improve the error messages. \n
47OK

For Erlang version 5.6.5 (R12B-5) on Windows, the .erlang file needs to be created in the usr folder inside C:\\erl5.6.5 (or wherever you installed Erlang).

2010-12-17This seems to vary between different versions of windows. \nThanks for pointing this out.
53OK

Error message in Erlang 5.6.5 (R12B-5) is more useful for the beginner than the older cryptic error message in the book (and would remove the need for the entire following paragraph that decyphers the obsolete error message):
Hypot(3).

exception error: interpreted function with arity 2 called with one argument

2010-12-09This has been fixed in the latest version of the PDF
344ERROR

the deliberate error seems to be that compute_area is only define for square and rectangle.

the erroneous call in #3 on on the bottom of page 348 actually succeeds with the code on page 344 and in the code available from the site.

calling area_server with a different shape than square or rectangle fails with the error shown in the book.

240OK

When sending a request to wwww.erlang.com, it will not work unless you send the host as well:

ok = gen_tcp:send(Socket, lists:concat([“GET / HTTP/1.0\\r\
Host: ”, Host, “\\r\
\\r\
”])), (2)

2010-12-17The example works fine - the fault must lie with the server. The client code is ok. The hostname is only needed in \nHttp 1.1 not http 1.0
234OK

ls function does not use the directory path.

function should look something like:
ls(Dir) ->
{ok, L} = file:list_dir(Dir),
map(fun(I) -> {I, file_size_and_type(lists:concat([Dir, “/”,I]))} end, sort(L)).

2010-12-17ls does not return the full path, only the base name of the files - this is intentional
234OK

Sorry, change should actually use:

map(fun(I) -> {I, file_size_and_type(filename:join([Dir, I]))} end, sort(L))

2010-12-17
354OK

sellaprim_supervisor.erl and sellaprim_app.erl in the file/content table are missing their e’s in sellaprime.

2010-12-17fixed in 4.0
37OK

On p37, the example of using “.erlang” file in [erlang installation directory]/bin/ to change directory automatically for Windows — this doesn’t work on my computer, Vista Home Premium with Erlang V5.6.5.

2010-12-17This is bit of a problem. There seems to be no generic \nway of specifying exactly where the .erlang file should go \nin different versions of windows. A bit of experimentation is often needed (especially when you have multiple user accounts on one machine).
88DEFER

It would be nice to mention bit strings and the /bits TypeSpecifier

75OK

In section 4.8, the second program fragment uses the syntax try foo(…) of. That of should not be there. The last sentence in section 4.8 ends with “write try … of ….” That of should be catch.

2010-12-17I think the text is ok here. For more details consult \nthe official erlang documentation at http://www.erlang.org/doc/reference_manual/expressions.html
303SUGGEST

You should mention that the ?SERVER needs to be defined as the name of the server in the start_link() function, as it is not defined by default.

2010-12-17I agree
437TYPO

In section F.3 Module: beam_lib the description of md5(Beam) is a copy of the description for version(Beam).

2010-12-17thanks will be fixed
51OK

It seems that this statement is invalid. I double checked; “Buy” is not referenced in the “shop1.erl” listing on page 50.

11> shop1:total(Buy).

2: variable ‘Buy’ is unbound

2010-12-17Actually it's ok. Buy is set in the line \n \n1> Buy = [{oranges, ...}] \non page 50. \n \nYou are looking at statement 11 in a sequence (that's \nwhat 11> means. It was set in statement 1. \n \nYour error is because you did not type in line 1. \n \n \n
158DEFER

The first exercise in the book isn’t until pg 158. It would be helpful for there to be exercises much sooner.

2010-12-17
163OK

jaerlang-p3_0.pdf (Pg#163)

There is an error in the table describing exit signal processing. In case of trap_exit=:= true and Exit Signal = kill (see the test results on Pg. 169, confirmed with my testing as well) the correct Action =:= Add {’EXIT’, Pid, X} to the mailbox. Correct table entries are:

trap_exit Exit Signal Action

true X Add {’EXIT’, Pid, X} to the mailbox.

false normal Continue: Do-nothing signal
vanishes.
false kill Die: Broadcast the exit signal
killed to the link set.
false X Die: Broadcast the exit signal X to
the link set.

2010-12-17next edition will have a better explanation
163OK

jaerlang-p3_0.pdf (Pg#163) - clarification
Untrappable exit signal is not clearly defined on Pg.163.
To make the definition clear and accurate, it should state that it is UNTRAPPABLE ONLY if the signal is received by the system process Pid if generated as exit(Pid,kill).
The exit(kill) does NOT generate untrappable exit signal.

2010-12-17the text says this implicitly. In the next ediiton \nI can be clearer
47OK

(This erratum is for P4.0 but that option is unavailable in the drop down menu)

On page 47, module lib_misc is used as follows

1> lib_misc:for(1,10,fun(I) -> I end).

but since this is actually the first time lib_misc.erl is used in an example (it’s referenced on p.42 but never explicitly imported), the example should probably be the following:

1> c(lib_misc).
2> lib_misc:for…

in order to avoid an exception on account of the .beam file not previously having been generated.

On the next page, p.48, a comment in the example notifies the reader that it will be the last time c(module) will be explicitly included in the examples.

2010-12-17On page 45 I've already explained how to compile \na module. By now the user should be familiar \nwith compilation, I don't want to add detail here that \nwould distract from the text.
377OK

Instead of:

for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\\
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

one could simply write:

for i in `seq 32`

The ‘seq’ command is supported in all shells that I know; there should be no problem with the succinct solution.

2010-12-17It's not my shell --- \nfor i in `seq 10`; do echo $i; done \n-bash: seq: command not found \n \nThis is bash on os-x developer tools
171OK

This is in the example “Client on one node, server on second node but same host”.

When I started the erlang nodes as specified in the book, with “erl -sname gandalf” and “erl -sname bilbo”, bilbo was unable to reach gandalf:

Starting gandalf:
jeff@asterix erl $ erl -sname gandalf
Erlang R13B (erts-5.7.1) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.1 (abort with ^G)
(gandalf@asterix)1> kvs:start().

jeff@asterix erl $ erl -sname bilbo
Erlang R13B (erts-5.7.1) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.1 (abort with ^G)
(bilbo@asterix)1> rpc:call(gandalf@localhost,kvs,store,[weather,fine]).
=ERROR REPORT 22-Jul-2009::20:26:09 ===
Error in process <0.42.0> on node ‘bilbo@asterix’ with exit value: {badarg,[{erlang,list_to_existing_atom,[“gandalf@asterix”]},{dist_util,recv_challenge,1},{dist_util,handshake_we_started,1}]}

{badrpc,nodedown}

Following the advice here (http cammacrae.com/blog/2007/06/27/erlang-example-error/> it seems I need to start the erlang nodes as “erl -sname bilbo@localhost” and “erl -sname gandalf@localhost”. Then it works.

2010-12-17
406TYPO

In the second paragraph, first sentence, you have, “When the client sends to a message X …”. The word “to” after “sends” should be removed. Also, this error is in the 2009-09-20 version: P4.0 which is not a version I can select on the web page for submitting errata.

2010-12-17Thank you. Will be fixed
414TYPO

In the wait_close function, in the after clause, the error message has too many r’s in the word error.

2010-12-17yes - thanks
210TYPO

Misspelled variable Satte instead of State in socket_dist/io_widget.erl listing, function loop/5, receive message {updateState, N, X}, in the format string for io:format.

2010-12-17well spotted - will be fixed
239TYPO

(Actually P4.0?) The section “Writing to a Random-Access File” says “Next, we use file:pwrite(Position, Bin)”, but file:pwrite is structured more like file:pwrite(IoDevice, Position, Bin).

2010-12-17Should be changed to \nfile:pwrite(IoDev, Position, Bin)
241TYPO

In paragraph 3, third sentence, there is a missing word “get”. The sentence should read, “If we just want to get the size of a file, …”.

2010-12-17well spotted - will be fixed
243DEFER

In the lib_find.erl example, you are using the regexp module, which is currently deprecated, instead of the re module. I have redone the source which I am including below. Since the re module does not have a sh_to_awk function or anything like it, I have added a fairly minimal sh_to_pcre function at the end of lib_find.erl. You would probably want to flesh it out more. I was just trying to handle this capability with minimal functionality.

re version of lib_find.erl

-module(lib_find).
-export([files/3, files/5]).
-import(lists, [reverse/1]).

-include_lib(“kernel/include/file.hrl”).

files(Dir, Re, Recursive) ->
Re1 = sh_to_pcre(Re),
case re:compile(Re1) of
{ok, MP} -> reverse(files(Dir, MP, Recursive, fun(File, Acc) -> [File | Acc] end, []));
_ -> error
end.

files(Dir, Re, Recursive, Fun, Acc) ->
case file:list_dir(Dir) of
{ok, Files} -> find_files(Files, Dir, Re, Recursive, Fun, Acc);
{error, _} -> Acc
end.

find_files([File | T], Dir, Re, Recursive, Fun, Acc0) ->
FullName = filename:join([Dir, File]),
case file_type(FullName) of
regular ->
case re:run(FullName, Re) of
{match, _} ->
Acc = Fun(FullName, Acc0),
find_files(T, Dir, Re, Recursive, Fun, Acc);
_ ->
find_files(T, Dir, Re, Recursive, Fun, Acc0)
end;
directory ->
case Recursive of
true ->
Acc = Fun(FullName, Acc0),
find_files(T, Dir, Re, Recursive, Fun, Acc);
false ->
find_files(T, Dir, Re, Recursive, Fun, Acc0)
end;
error ->
find_files(T, Dir, Re, Recursive, Fun, Acc0)
end;
find_files([], ,, ,, A) ->
A.

file_type(File) ->
case file:read_file_info(File) of
{ok, Facts} ->
case Facts#file_info.type of
regular -> regular;
directory -> directory;
_ -> error
end;
_ ->
error
end.

sh_to_pcre(Re) ->
Re1 = re:replace(Re, “\\\\.”, “\\\\\\\\.”, [global, {return, list}]),
Re2 = re:replace(Re1, “\\\\“, ”\\\\.”, [global, {return, list}]),
Re3 = re:replace(Re2, “\\\\?”, “\\\\.?”, [global, {return, list}]),
“^(” Re3 “)$”.

2010-12-17Thanks.
315OK

Version with error is Sep 20, 2009: P4.0. The web site does not give me the option of selecting this version.

The error is, in the second paragraph, last sentence, you refer to test_mnesia as mnesia_test.

2010-12-17Very strange - I cannot find this error
317ERROR

In the comments for the join example, you state that the equivalent SQL is SELECT shop.item, shop.quantity, cost.name, cost.price, FROM shop, cost …,
but the mnesia query only returns the shop.item field. You should either change the comment to read SELECT shop.item FROM shop, cost … or you should change the query to do(qlc:q([{X#shop.item, X#shop.quantity, Y#cost.name, Y#cost.price} || X <- mnesia:table(shop), ….

2010-12-17quite right \nshould be SELECT shop.item \n
318TYPO

In the output for the remove_shop_item example, there is a second row for orange in the output for test_mnesia:demo(select_shop). that looks like a cut-and-paste error when keying in the output.

2010-12-17yes - will be fixed
337TYPO

In the comment in the event_handler.erl code, you refer to the noOp function but in the code it is no_op. The same mistake is made in the last paragraph on the next page.

2010-12-17thanks will be fixed
360OK

In the list of files for the sellaprime application, you list elog4.config. However, all the example code in the chapter says to start erl with elog3.config. All the erl command lines are:

erl -boot start_sasl -config elog3

2010-12-17That's ok - I describe what will happen if you run this. \nbut didn't show the output. The command line is the same as the examples for elog3 only using elog4 instead
383OK

In the test_mapreduce.erl program, you use the function lib_misc:foreachWordInFile/2 function which is not defined anywhere in the book.

2010-12-17No all code is in the book. This is in the code that can be downloaded from the prag website
233OK

The CODE etc. might need to be modified for obsolete functions since R13B, like regexp

% erl
Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]

Eshell V5.7.3 (abort with ^G)
1> c(lib_find).
./lib_find.erl:16: Warning: regexp:sh_to_awk/1: the regexp module is deprecated (will be removed in R15A); use the re module instead
./lib_find.erl:29: Warning: regexp:match/2: the regexp module is deprecated (will be removed in R15A); use the re module instead
{ok,lib_find}
2>

2010-12-17not much point this will always change - the diagnostic is \npretty clear
381OK

I have compiled and run the code for the full text search engine and it doesn’t work properly. After doing indexer:cold_start(), then indexer:start(), and indexer:search(“rover”) the results return none. The index that is supposed to be constructed, which I have called c:/bigIndex, has an empty C:/bigIndex/index directory, though C:/bigIndex contains 1.check, 2.check, and filenames.dets. Coverage analysis reveals that handle_result and add_to_file in indexer.erl are never executed. I have added io:format statements to try to trace the bug and found that handle_result is being passed fine to indexer_misc:mapreduce as the variable F2 which is in turn passing F2 just fine to indexer_misc:reduce which passes F2 to dict:fold and then, for some reason, dict:fold appears not to be executing handle_result. Based on my io:format printouts the program seems to have no problem finding the input directories, which I have placed at C:/InputFiles, and arranged just as in the book’s example to have cars.txt, dogs.txt, and animals/cats.txt. What is the most likely source of this error? I have done nothing to change the substance of the code, only added io:format statements to try to trace the bug. It have spent hours on something I thought would compile and run as is.

2010-12-17it works for me. I have no idea why it doesn't work for you.
40TYPO

In the last paragraph, first sentence, you have an extra word “a” in the sentence. It currently reads, “… a string is a just a list of integers …”. The word “a” before the word “just” should be removed so that it reads, “… a string is just a list of integers …”.

2010-12-17You're right - it's a typo - should be fixed in next version thanks...
195OK

has:

delete(Pid, [{Pid,Nick}|T], L) -> {Nick, reverse(T,L)};

should have:

delete(Pid, [{Pid,Nick}|T], L) -> {Nick, reverse(L,T)};

(swap the parameters to reverse/2 from “T,L” to “L,T”)

It works in the other order, but confusingly reverses the entire list rather than deleting the element and leaving the rest of the list alone.

2010-12-17the order of the list is not important here - there is no reason to retain the original order
56OK

Reader reported ‘for’ example as an error, but it should be not typed directly into the shell, Instead, lib_misc.erl needs to be compiled (‘for’ function is defined and exported there).- Germán Siufi.

2010-12-17You can't enter this in the shell. It's part of a program There a large box at the end of section 3.4 warning you that the code in modules cannot be entered into the shell.
181DEFER

The book says: “Using -sname is also the only method that will work if no DNS service is available”

If node2 can’t resolve the name, just start node1 using the IP address: “erl -name gandalf@141.204.62.188”. Then on node2 set “Node1=‘gandalf@141.204.62.188’” and call the remote method like this: “rpc:call(Node1, kvs, store, [weather, sunny]).”

2010-12-17
75ERROR

Stack Traces

- It is untrue that “The stack trace contains a list of the functions in the stack to which the current function will return if it returns”.

erlang:get_stacktrace() returns stack content which was present when last error (exception) occured. get_stacktrace/0 so is relevent to the point WHERE exception occured/thrown/errored.

2010-12-17will be changed to \n "The stack trace contains information about recent calls that were made \n at the time when the exception occurred." \n
150DEFER

Spawning with MFAs - It is untrue that “The dynamic code upgrade mechanism does not work with spanwed funs”

There can be problems with funs in code upgrade mechanism, but this have nothing to do with spawn, or funs at all. One should also remember that there are two kind of funs (external and local), and exteral funs (fun m:f/0), should not have code upgrade problems like local funs (fun f/0, or fun() -> f(),… end). Still code upgrade with any kind of funs will work perfectly ok, if there is full function name (in ?MODULE:loop() for example), somewhere in the execution path (in tail position of course). As of Funs in tail position, this is totaly different matter, and using local funs in tail position COULD be problematic with conjuction with code upgrades. But it is supported, just process will be killed if i will not upgrade to newer version, and next code upgrade will happen.

2010-12-17Thanks for the comment will be fixed next edition.
59DEFER

Funtions bit_size/1 and byte_size/1 bifs which are allowed in guards are missing.

2010-12-17next edition
386DEFER

In Erlang there are two type specifications, one using -spec, second in comments using @spec. This can be clarified. Also information which one to use , in new sources, and what tools support which or will supports possibly.

2010-12-17This is still not finalised ... edoc and the erlang system \nare slightly different.
374TYPO

Extra comma after F1 = fun(Pid, X) -> void.

2010-12-17yes
324OK

Path as in “… /usr/…/mnesia-X.Y.Z/examples on my machine”. I doubt that you have mnesia-X.Y.Z directory. It is inconsitent with other places, where you put particular version numbers :)

2010-12-17on my machine it's \n/usr/local/lib/erlang/lib/mnesia-4.4.14/examples \nwhich is consistent with the above. Using X,Y,Z for variables \nas in Erlang :-)
312TYPO

Shell output in “7>” is very strange. Please fix commas, and brackets.

2010-12-17well spotted will be changed to \n \n[{shop,orange,236,2.80000}, \n{shop,banana,420,4.50000}, \n{shop,potato,2456,1.20000}, \n{shop,apple,20,2.30000}] \n
278OK

“If they are not properly closed, then they will be automatically reparied, …”. It is not really explained what this really mean. Will my last data which i put there be there? As i understand there is a log (for perfomance reasons and for safety), and on crash it is replayed to make all changes visible consistently. Right?

2010-12-17yes - this is a bit tricky. My understanding is that \na sequence of updates Xi,Xi+1,Xi+2,.... will be \nreplayed to the point where the error occured. \nie all the updates will succeed in order up to a certain point, thereafter they will be lost, so we don't know exactly \nhow many updates are lost when we crashed but we do know that previous updates were done in order. I won't change the text :-)
133DEFER

You reffer at the bottom to “spawn, send and receive” in bold font. But shows only “spawn” - new function, “receive..end” new keyword/syntax, and ! syntax for sending. Where is “send”. You should say on next page that “erlang:send/2, send/2, and !” are the same thing. there is also send/3, for sending with speciall options.

2010-12-17
134OK

Pid1 ! Pid2 ! Pid3 ! M. Will send messages in reverse order, so it should be “means send the message M to all processes Pid9, Pid8, Pid7, and so on”. This not have really big issue, but actually there is also one can use P ! Message. Where P is not a Pid, it can be atom or 2-tuple of atoms, for registered processes. And registered send can fail, becuase lookup of registered process will fail, this way there is subtle difference in this ordering in case of error.

2010-12-17no a problem. This is just brief intro to send. The details come later.
104DEFER

In operators precedense ! is not mentioned. Also function call/brackets, is not mentioned, this will not work F = fun(X) -> X end, F (F)(F)(F). One needs ((F (F))(F))(F).

2010-12-17next edition
72OK

You say “If you compare this with the output from the try..catch section you’ll see that we lose a lot of precision in analyzing the cause of the problem.” Well, but we clearly see that there is a stack trace in 5th element, which actually gives as much more information.

Much more important in catch/try discussion is that using catch we cannot return from function some tupples as they will collid (as in 3rd and 4th element).

2010-12-17The data included in the stack trace changes with time so \nI think I'll leave the text as it is. The main advantage of \ntry is that it is not possible to "fool" it with a "faked" \nerror return (as is the case with 'catch') - for example, we can 'fool' catch with a function that explicitly constructs a {'EXIT', ...} tuple
72OK

There should be {5, {’EXIT’, ….. }} in shell output. There is also no explanation what this ‘demo2/0-lc$^0/1-0’ means. Actually even in stack traces (4.9), there is no explicit information the it is {M,F,A} tuple, and it is possible that A is number or actually list of arguments (of length equal to arity).

2010-12-17This output sometimes changes with the version of Erlang involved. I don't want to change the text, since each time Erlang is changed the error message potentially change. I made a note about this earlier.
52OK

pseudo-quicksort. One can use lists:flatten/1, to make it better, but still it will not be a quick sort with it’s avarage O (n log n) time complexity behaviour. Also main bad aspect of this implementation is the fact that it is not in-place, as any in-place algorithm is basically impossible to implement in pure functional value language.

I think something more practical from real world usage should be there instead.

2010-12-17The footnote says "This code is shown for its elegance rather than its efficiency" - I'm making no claims \nabout the efficiency. The library function lists:sort \nshould be used when an efficient sort is needed.
411TYPO

In start_server/1, 10th line, inside the nested case block:

exit({eDeaemonConfig, Errors})

should be:

exit({eDaemonConfig, Errors})

2010-12-17yes - thanks
22ERROR

The instructions for installing on Debian need to include the package “erlang-dev” as well: erlang-dev provides kernel/include/file.hrl, without which libmisc.erl (p. 57) cannot be compiled.

357TYPO

The PDF files on erlang.org has been arranged making the links on for instance page 357 broken. Look at erlang.org/doc for current locations.
The same goes for the links on pragprog.com/articles/erlang.html
(already having submitted this, I noted that hyperlinks were not allowed. As I don’t see this on the errata page, I assume all urls are considered hyperlinks. I hope this goes better)

81TYPO

In the output of try_test:demo2(), the fifth tuple output should begin with the number 5 as the first term. The example should read:

2> try_test:demo2().
[{1,a},
{2,a},
{3,{’EXIT’,a}},
{4,{’EXIT’,a}},
{5,‘EXIT’,{a,[{try_test,generate_exception,1},

102TYPO

In the second paragraph of the section titled “Block Expressions”, you are missing the word “a” between “have” and “sequence”. It should read, “… but you want to have a sequence of expressions at this point in the code.”

115ERROR

In the last paragraph of the page, the one with the curve sign next to it, last sentence, you talk about multiple occurrences of _Int in a complex pattern but don’t actually show the pattern.

42TYPO

The last paragraph would read better like this “Now we’re comfortable…..” (take out “that”) or leave “that” and take out “so” after the “,”.

306TYPO

Under “Spontaneous Messages to the Server” section:

change

might suddenly receive a unexpected

to

might suddenly receive an unexpected

474TYPO

“Generic event handling behavior.g” The “.g” is a typo, I think.

314TYPO

In the paragraph after the source code for the demo(select_shop) function, the last sentence, the one in parenthesis, you refer to the name of the module as mnesia_test instead of test_mnesia.

277TYPO

In the box at the top of the page, second sentence, you have used the word “an” instead of “a”. It should read, “You can think of a protected ETS table …”.

385TYPO

In the last paragraph, second sentence, there is an extra word “a” between “is” and “achieved”. It should read, “This is achieved with indexer_checkpoint. …”.

309TYPO

Current text: “(The entire listing for mnesia_test appears at the end of this chapter.)”

The module included at the end of the chapter is “test_mnesia”, not “mnesia_test”.

189ERROR

{ok, Pid} = lib_chan:connect(“localhost”, 1234, nameServer, “ABXy45”, “”).

exception error: undefined function lib_md5:string/1
in function lib_chan:authenticate/4
in call from lib_chan:connect/5

100SUGGEST

User-Defined Attributes

(…)

In the attrs.erl example code, the following function is defined.

fac(1) -> 1;
fac(N) -> N * fac(N-1).

While it is not relevant in the context of the example, I suggest that the code is changed like this:

fac(0) -> 1;
fac(N) -> N * fac(N-1).

This would be the correct mathematical definition of the fac function.

Cheers,
Thomas

129SUGGEST

Chapter 7 is titled “Concurrency” and presents several of examples in the course of describing Erlang’s model of concurrent programming.

However, none of the examples are parallel programs, so none of them execute concurrently. They are all entirely sequential programs, that happen to be distributed over several processes. They all make using of functions that send messages and then block for responses. At no point, in any of the examples, are any of the programs running processes concurrently.

Seems a poor example of concurrency to present programs that are not parallel and cannot be run concurrently.

305TYPO

“…State is the current state of the client. …”
should read :
“State is the current state of the server.”

168TYPO

First line of the page reads:

7> edemo1:start(true, normal).

It should be:

7> edemo1:start(true, {divide, 0}).

Other it would not be the same tests as before, this time with the tuple {true, …}.

Cheers,
Thomas

rGUYVSGHKjERROR

I told my grandmother how you heepld. She said, “bake them a cake!”

201SUGGEST

There is no mention of the requirement of Tcl/Tk for gs to work properly, in fact how the code in io_widget is written if you don’t have Tcl/Tk installed (on Windows) then the erlang function executes with no indication of error but there is no GUI. I figured out what was going on by some diagnostic io:format calls eventually seeing a {gs, backend_died} result and through some web searching discovered you see that if Tcl/Tk isn’t installed, which it wasn’t on my system. Mentioning this might save people a lot of time.

203ERROR

The loop(W) on page 203 has an incorrect receive pattern. It is listed as

{W, {str, Str}} ->

but I believe it should be

{W, _State, {str, Str}} ->

as the dispatch happens as such (on page 202)

Pid ! {self(), State, Term}

where state, by default, is the atom nil. Changing the receive pattern to include the (ignored) State argument causes the correct match but seems to also reveal another problem around the editor atom, I will file a seperate errata item for that.

86TYPO

On 3rd paragraph of section 5.2, the construct <<‘cat’>> is invalid, the correct form is <<“cat”>>.

indexSUGGEST

the index entry for “|| (double
vertical bar)” should include page 198 (the section on List Comprehensions).

162TYPO

Under the heading ‘System processes’, in the first sentence of the first paragraph, it reads: “…, it too will die unless it is special kind of process…”.
I think an ‘a’ should be added so it would read: “…, it too will die unless it is a special kind of process…”.

53ERROR

3> Double = Z. should return #Fun<erl_eval.6.56006484> since 1> Z = fun(X) -> 2*X end. returned it. Checked with R11B-5, R15B (Windows) and R14A (Linux).

57SUGGEST

In the box function partition is mentioned, but has not been introduced yet. Perhaps a reference could be useful?

143NULLTYPO

Hah, Italy protesters rally against Berlusconi

88SUGGEST

4> list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).

The list [Bin1,1,[2,3,Bin2],4|Bin3] is improper. Furthermore, a binary is allowed in the tail position of a cons cell. (An integer in the tail position causes bad argument exception.) Perhaps some explanation could be useful?

115TYPO

Section Term Comparisons, seventh paragraph: “a integer” should be “an integer”.

125SUGGEST

The escript could be run on Windows by the following script:
foo.bat

@setlocal enableextensions & “C:\\Program Files\\erl5.9\\bin\\escript.exe” "~f0"* & goto :EOF

main(A) ->
io:format(“Command line args: ~p~n”,[A]).

124SUGGEST

The difference between “~n” and “\
” in the format string of io:format is not clear. Probably, some explanation could be useful.

zohtpzohtpERROR

L1i18q I notice that when I specifically invite comments that people leave them in higher numbers than when I don�t.

307ERROR

In the Code Change section, there is an annotation with an incorrect link. The line is “This topic is described in detail in the section on release handling in
the OTP design principles documentation.5” and the annotation is “5. Available from [erlang’s site]/doc/pdf/design_principles.pdf”, but that document has moved and the link gives a 404. An HTML version of that document is available at [erlang’s site]/doc_design_principles/des_princ.html or There’s a PDF that contains the design principles in Chapter 9 located at [erlang’s site]/doc/pdf/otp-system-documentation.pdf

tmknitmkniERROR

w0w this is good

flnoeflnoeERROR

Great tips!!!

lgszxlgszxERROR

thanx women

hkrtthkrttERROR

this is what i needed man

qatbsqatbsERROR

ok love that stuff

zshcrzshcrERROR

shoudlnt i try it?

oghacoghacERROR

WPKLKR hmm what them is that? selfmade?

ucmyoucmyoERROR

JG5rZI thanx women

ybmjbybmjbERROR

Comments do help

honamhonamERROR

i do not agree

honamhonamERROR

i do not agree

fdzqgfdzqgERROR

Looking forward to

244TYPO

Hi Joe, I refer to your errata above on the updated lib_find.erl using re module.

The following section in the above codes are in correct:

case Recursive of
true ->
Acc = Fun(FullName, Acc0),
find_files(T, Dir, Re, Recursive, Fun, Acc);

It should be:

case Recursive of
true ->
Acc1 = files(FullName, Re, Recursive, Fun, Acc0),
find_files(T, Dir, Re, Recursive, Fun, Acc1);

decdtdecdtERROR

i dont know if that is really true…..

decdtdecdtERROR

i dont know if that is really true…..

szgmyszgmyERROR

thissi sad.. maybe not..

47TYPO

Please note, this report looks similiar but actually differs in important detail to a previously reported Erratum. (The correction reported in the previous Erratum does not work)

Is: Tip for Windows users: Create a file called C:/Program Files/erl5.4.12/bin/.erlang (youmight have to change this if your installation details vary). Should be: Tip for Windows users: Create a file called C:/Program Files/erl5.4.12/usr/.erlang (youmight have to change this if your installation details vary). Otherwise it doesn’t work.

ckpjyckpjyERROR

hmm what them is that? custom?

chxsmchxsmERROR

thanx karen

xazrmxazrmERROR

love to read

swtovswtovERROR

can i comment here

psnhipsnhiERROR

my crew loves that

leswxleswxERROR

im subscribing to this rss totally

irpggirpggERROR

i had to write here

reguareguaERROR

so what do we do now?

euotoeuotoERROR

im a serial reader

lxlctlxlctERROR

good blog as usual

icotcicotcERROR

lool cool

roshmroshmERROR

sweet template

iirruiirruERROR

wat is at about hmmm

iirruiirruERROR

wat is at about hmmm

oolohoolohERROR

i agree woman

sdjrisdjriERROR

thanx for a great post mate

nprifnprifERROR

mumbo jumbo

sadeksadekERROR

this makes me sad

ufwaoufwaoERROR

nice suggestion

mkkyxmkkyxERROR

my crew loves that

tiwyatiwyaERROR

sweet not sure tho

hwtoihwtoiERROR

mmmm sandwitch

vyfwpvyfwpERROR

thanx karen

rulcurulcuERROR

thinkingof what?

mjtvqmjtvqERROR

this helped me as hell

vljldvljldERROR

good infos as always maine

glnsjglnsjERROR

kl8oQd omg loved this stuff

zyqgbzyqgbERROR

9zpO2F good blog as usual

sontxsontxERROR

tQwPuJ including specific questions in posts

sontxsontxERROR

tQwPuJ including specific questions in posts

sontxsontxERROR

tQwPuJ including specific questions in posts

mfihrmfihrERROR

TX69oF this helped me as much as it coulkd

fyyjpfyyjpERROR

g00d info as usual here

aftnmaftnmERROR

thanx women

fnqbwfnqbwERROR

i have to say this

rjymprjympERROR

thinkingof what?

tmdpetmdpeERROR

i had to write here

ldvdaldvdaERROR

bring that times back!

tnbextnbexERROR

i agree man

ffoazffoazERROR

thanx big man

xjhstxjhstERROR

Nigeria\t

czmybczmybERROR

Luxembourg\t\t\t

bkgpjbkgpjERROR

good one i luv it

mjsyamjsyaERROR

Ireland\t\t

47ERROR

In the section of “where has my code gone?” the instruction is to create the file “C:/Program Files/erl5.4.12/.erlang” but for erlang 5.10.3, the file will have to be created in “C:/Program Files/erl5.10.3/usr/.erlang”. In other words the “.erlang” file should be in the “usr” directory which is in the “erl*” directly and not directly in the “erl*” directory.

103ERROR

36Xwow is 30371, not 42368

233SUGGEST

In analyse1 function from file id3_tag_lengths.erl (for SHOUTcast server), I find file:pread(S,0,10000) is invalid for some big mp3 files. We have to enlarge this number, which is 10000, to 200000 or to work around it dynamically.(not predefined number)

Categories: