We try to keep our books accurate, but sometimes mistakes creep
in. This page lists the errors submitted by our astute readers.
If you've found a new error, please
submit it.
The latest version of the book is P2.0,
released 11 months ago.
If you've bought a PDF of the book and would like to upgrade
it to this version (for free), visit your
home page.
| PDF |
Paper |
Description |
Found in |
Fixed in |
|
0 |
#32364: 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)--Garth Roxburgh-Kidd #32364: 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. Fi ...more...
|
P2.0
|
|
| 0 |
|
#29357: 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.)--Falko #29357: 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, bec ...more...
|
P1.1
|
|
|
00 |
#29687: 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.--Simon #29687: 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 ...more...
|
P2.0
|
|
| 24 |
|
#32377: Talking about the 1> prompt after the example: the prompt looks like ell-ampersand rather than one-ampersand--Brandon CS Sanders
|
P2.0
|
|
| 32 |
|
#29369: 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.--Jeff Hayward #29369: In the discussion of debugging with immutable variables, the statement:
"So once we know which variable is incorrect,
we can immediately ...more...
|
P1.1
|
|
|
36 |
#29856: 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.--Thomas Ott #29856: 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 rec ...more...
|
P2.0
|
|
|
37 |
#32262: 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!--John A. Engstrom #32262: 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 fro ...more...
|
P2.0
|
|
| 37 |
|
#29709: 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.--Richard Carlsson #29709: Footnote 10: "This method of extracting variables using pattern matching is called unification and is used in many functional and logic progra ...more...
|
P2.0
|
|
| 39 |
|
#29713: 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."--Richard Carlsson #29713: 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 ...more...
|
P2.0
|
|
| 40 |
|
#29849: In the third paragraph of Section 2.11, the string "Hello" starts with a double quote but ends with a single quote.
|
P2.0
|
|
| 45 |
|
#29710: 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."--Richard Carlsson #29710: End of first paragraph: "The patterns are matched in the order they appear in the function definition." This sounds like it is (only) referrin ...more...
|
P2.0
|
|
| 45 |
|
#29711: 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?
--Richard Carlsson #29711: 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 " ...more...
|
P2.0
|
|
| 45 |
|
#32397: 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.)--David James #32397: You spelled out "Width" so why are you abbreviating Height as "Ht"? For clarity in teaching, I would suggest spelling out "Height" also. (I t ...more...
|
P2.0
|
|
| 48 |
|
#29712: 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.--Richard Carlsson #29712: First paragraph: bad use of semicolon and misuse of the word "only".
Suggestion: comma instead of semicolon and "but" instead of "only" makes ...more...
|
P2.0
|
|
| 48 |
|
#30736: 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.--Edwin Fine #30736: 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 ...more...
|
P2.0
|
|
| 51 |
|
#29356: 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)
--Falko #29356: 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 ...more...
|
P1.0
|
|
| 53 |
|
#29714: 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.)--Richard Carlsson #29714: 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 ...more...
|
P2.0
|
|
| 54 |
|
#31485: The line "13> lists:map(Double, L)." should return "[2,4,6,8]", not "[2,4,6,8].".
|
P2.0
|
|
| 56 |
|
#29331: 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.
--Robert Kasanicky #29331: 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 cas ...more...
|
P1.1
|
|
| 57 |
|
#29715: Paragraph 2, "Or we can use to..." should be "Or we can use it to...".--Richard Carlsson
|
P2.0
|
|
| 59 |
|
#31486: The line "1> L = [1,2,3,4,5]." should return "[1,2,3,4,5]", not "[1,2,3,4,5].".
|
P2.0
|
|
|
61 |
#29702: Duplicate excerpt "record pattern with the unbound variables W and Txt."--Alonso Andres
|
P2.0
|
|
| 61 |
|
#31487: 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}].". #31487: The line "1> Buy=[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]." should return "[{oranges,4},{newspaper,1},{apples,10},{pears,6}, ...more...
|
P2.0
|
|
| 62 |
|
#29719: Footnote 10 (about using ++) should refer to section 3.11 (Building Lists in Natural Order) for more information.--Richard Carlsson
|
P2.0
|
|
| 64 |
|
#30004: In the pythag example, the maximum side length that needs to be considered is N div 2.--Justin Forder
|
P1.1
|
|
| 64 |
|
#30005: 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."--Justin Forder #30005: Your hint regarding how to understand the perms example is strange. The code itself reads easily: "Construct the permutations of a sequence by ...more...
|
P1.1
|
|
| 65 |
|
#29942: 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.)
--Oliver Goodman #29942: Figure 3.1 describes bsl as "Arithmetic bitshift left.." and bsr as "Bitshift right..".
In fact it is Bitshift right which needs the qualifi ...more...
|
P2.0
|
|
| 66 |
|
#30718: 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."
--Hans Granqvist #30718: The logic of this sentence escapes me. I think "since" implies a cause that doesn't exist:
"Guards are an extension of pattern matching, an ...more...
|
P2.0
|
|
| 67 |
|
#29344: ==, used at the end of the page, has not been introduced yet. Perhaps a reference could be useful?
|
P1.1
|
|
| 69 |
|
#29787: 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".--Ben Bildstein #29787: 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 ...more...
|
P2.0
|
|
|
70 |
#30733: The expression that in page 69 is called "FuncOrExpressionSequence", in page 70 is called "FuncOrExpressionSeq".--Lásaro
|
P2.0
|
|
| 71 |
|
#30701: "record pattern with the unbound variables W and Txt." is writed twice.
|
P1.1
|
|
| 72 |
|
#29716: 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..."--Richard Carlsson #29716: Second paragraph from end ("Earlier, we used..."): Missing comma after "Now", as in "Now, using pattern matching...".
Last paragraph: "But th ...more...
|
P2.0
|
|
| 75 |
|
#29720: Paragraph 1: "whether" should be "when".--Richard Carlsson
|
P2.0
|
|
| 75 |
|
#31153: "the [H filter(H)] type construction. "
probably must be :"[H || filter(H)]"--Alexey Kuznetsov
|
P2.0
|
|
| 77 |
|
#29721: Paragraph 5, spurious comma: "the call to the function, which raised..." should be "the call to the function that raised..."--Richard Carlsson
|
P2.0
|
|
| 79 |
|
#29857: 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.--Joseph Crail #29857: When describing the example on the previous page, the term FuncOrExpressionSeq is used. However, the referenced example uses the term FuncOrE ...more...
|
P2.0
|
|
| 80 |
|
#30717: "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).
--hans granqvist #30717: "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" ...more...
|
P2.0
|
|
|
83 |
#29399: 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.--Dan Milstein #29399: In the detailed description of the bit syntax, when it describes the contents of the TypeSpecifierList, there seems to be an error where it de ...more...
|
P1.0
|
|
| 84 |
|
#29901: 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?
#29901: It is perhaps worth clarifying exactly what stacktrace is returned by erlang:get_stacktrace(). My first interpretation on reading the sample ...more...
|
P2.0
|
|
| 87 |
|
#29722: 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.--Richard Carlsson #29722: 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 ...more...
|
P2.0
|
|
| 87 |
|
#31107: Third-bottom paragraph: <<'cat">> should be <<"cat">>.--Philip Robinson
|
P2.0
|
|
| 87 |
|
#29417: 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?)--Falko #29417: 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 proc ...more...
|
P1.0
|
|
| 91 |
|
#29777: "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"--Sten Kvamme #29777: "The only significance of this has to do with packing and unpacking integers from binaries"
should include: "packing and unpacking integer ...more...
|
P2.0
|
|
| 92 |
83 |
#30710: 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.--G Bulmer #30710: The description of the "@type Unit" syntax contains 2 errors. For completeness:
Firstly, as in an existing errata, "unit:" must prefix the un ...more...
|
P2.0
|
|
| 92 |
83 |
#30711: 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?
--G Bulmer #30711: Enhance the description of "@type Type = integer | float | binary" to make the meaning more explicit, e.g. add "in matching, the extracted bit ...more...
|
P2.0
|
|
| 94 |
|
#31595: 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.--Kevin Clark #31595: 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 parag ...more...
|
P2.0
|
|
| 106 |
|
#29726: 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..."--Richard Carlsson #29726: Paragraph 1: "Things such as records and module attributes..." should be "Things such as record declarations and module attributes...", or bet ...more...
|
P2.0
|
|
| 112 |
|
#29728: 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.--Richard Carlsson #29728: 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 a ...more...
|
P2.0
|
|
| 112 |
|
#29944: 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..".)--Oliver Goodman #29944: 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 numb ...more...
|
P2.0
|
|
|
115 |
#31563: I believe that the path mentioned in hello.sh, at the top of the page, should refer to '.../JAERLANG/...' and not '.../JAERANG/...'.--Kevlin Henney
|
P2.0
|
|
| 120 |
|
#29862: When describing the function code:all_loaded(), "returns a list of all loaded module" should be "returns a list of all loaded modules".--Joseph Crail
|
P2.0
|
|
|
124 |
#31194: This is truly nit-picking, but "quote" should be "quotation". To quote is to take somebody's words; a quation mark is the symbol.--Jeff
|
P2.0
|
|
| 130 |
|
#31002: 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. #31002: In the makefile template, perhaps the line "compile: ${MODS:%=%.beam}" should be modified to "compile: ${MODS:%.erl=%.beam}" to make it work. ...more...
|
P2.0
|
|
|
139 |
#29762: Looks like a little error, the line "3> area_server2:rpc(Pid, {circle, 5})." actually should be "2> area_server2:rpc(Pid, {circle, 5})."--Alonso
|
P1.0
|
|
|
142 |
#31564: 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.--Kevlin Henney
|
P2.0
|
|
| 143 |
|
#29918: 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.--Derek McLoughlin #29918: 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,[]}]}
T ...more...
|
P2.0
|
|
|
149 |
#31566: 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.--Kevlin Henney #31566: 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' ...more...
|
P2.0
|
|
| 150 |
|
#29360: "When we exceed the system limit, the system crashes .."
Actually not. It just refuses to start more processes, and utters some error messages.
--Falko
|
P1.0
|
|
| 151 |
|
#29904: Mis-placed comma - “priority receive,” should be “priority receive”, ?
(Dave says: That's the Chicago Manual style...)
|
P2.0
|
|
|
153 |
#31567: The 'receive' and 'end' keywords in the two code fragments on the lower half of the page should be in bold.--Kevlin Henney
|
P2.0
|
|
| 153 |
|
#29866: 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).--Joseph Crail #29866: The example in Section 8.6 refers to "Expression1" for both patterns. The second pattern should refer to "Expression2" as done by other exam ...more...
|
P2.0
|
|
| 154 |
|
#29537: 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.--Dave Jack #29537: Inconsistent use of "ExpressionTimeout" and "ExpressionsTimeout"
receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard1] ...more...
|
P2.0
|
|
|
155 |
#29390: 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.--saint-sevin #29390: 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 func ...more...
|
P1.0
|
|
| 158 |
|
#32435: 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.--Perry Smith #32435: 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 ...more...
|
P2.0
|
|
| 171 |
|
#31733: 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".--Richard Carlsson
|
P2.0
|
|
| 173 |
|
#31734: 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".--Richard Carlsson
|
P2.0
|
|
|
178 |
#30708: 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--Ryan Pratt #30708: 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 ...more...
|
P1.0
|
|
|
179 |
#31568: There should be more obvious warnings about and around the code fragment containing "cd /; rm- rf *"!--Kevlin Henney
|
P2.0
|
|
| 179 |
|
#29905: 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.
#29905: 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 ...more...
|
P2.0
|
|
| 183 |
|
#29362: in BIFs for writing distributed programs.
disconnect_node(N). must get the prefix erlang:, it is not visible from the shell.
--Falko
|
P1.0
|
|
| 183 |
|
#31422: 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. "
--Alexey Kuznetsov #31422: 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 distrib ...more...
|
P2.0
|
|
| 183 |
|
#31735: Footnote 7: Please avoid the term "manual page" and refer to "the documentation" instead.--Richard Carlsson
|
P2.0
|
|
| 187 |
|
#32302: "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 .--Adam Duston #32302: "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 .erlan ...more...
|
P2.0
|
|
|
195 |
#29700: 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?--yuji #29700: socket_dist/chat_group.erl
delete(Pid, [{Pid,Nick}|T], L) -> {Nick, reverse(T, L)};
..
I think ..
F: ..reverse(T, L)..
T: ..reverse(L, ...more...
|
P1.0
|
|
| 196 |
|
#29836: This also occurs on subsequent pages. The function disconnected/3 is called disconnected/2 in the text description of it.--Andrew Stone
|
P2.0
|
|
| 203 |
|
#29458: 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). #29458: 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 ...more...
|
P2.0
|
|
| 209 |
|
#32325: 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.--Adam Duston #32325: 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 ...more...
|
P2.0
|
|
|
222 |
#29703: 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!--Rob Charlton #29703: 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 ...more...
|
P1.0
|
|
| 225 |
|
#31738: Last paragraph: Jinteface -> Jinterface--Richard Carlsson
|
P2.0
|
|
| 226 |
|
#31739: Please refer to "documentation" instead of "manual pages". (Twice on page 226.)--Richard Carlsson
|
P2.0
|
|
|
228 |
#31877: The unconsult function contains the format string "~p.~n" which should read "~p~n". It is also incorrect in the code available online.--Aron Sedlack
|
P2.0
|
|
| 230 |
|
#31740: Last paragraph: please refer to "documentation" instead of "manual pages".--Richard Carlsson
|
P2.0
|
|
| 233 |
|
#29730: 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).--Jean Antoine Goncalves #29730: 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 erro ...more...
|
P2.0
|
|
| 236 |
|
#31743: 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"--Richard Carlsson #31743: 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 surroun ...more...
|
P2.0
|
|
| 241 |
|
#31746: Please refer to "documentation" instead of "manual pages" (twice on p. 241).--Richard Carlsson
|
P2.0
|
|
|
241 |
#31737: 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.--Jerome Baum #31737: This sentence fragment does not seem to make sense:
"(...), so you'll see is what a binary looks like (...)"
This is in the paragraph ri ...more...
|
P2.0
|
|
| 242 |
|
#31747: 2nd par.: please refer to "documentation", not "manual pages".--Richard Carlsson
|
P2.0
|
|
|
245 |
#29868: First line in third paragraph from the bottom.
Instead of:
... returns {ok,Socket}
it shoud read
... returns {ok,Listen}
--Manfred Lotz
|
P2.0
|
|
|
248 |
#31956: 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. :-)
#31956: Section: "A Parallel Server", last paragraph.
"The crucial difference is the addition of a spawn, ..."
It's actually two spawns in the cod ...more...
|
P1.0
|
|
| 264 |
258 |
#29682: 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
Any ->
io:format("received:~p~n", [Any]),
loop()
end.--G Bulmer #29682: 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 thro ...more...
|
P1.0
|
|
| 285 |
|
#29910: 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."--Steve Vinoski #29910: The word "exiting" in the following sentence, which appears toward the bottom of the page, should be "existing":
"Note that dets:open_file ...more...
|
P2.0
|
|
|
285 |
#31976: 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. #31976: Second paragraph, "...- think of it as an application framework that is parameterized by a callback module".
I have no clue at att what tha ...more...
|
P1.0
|
|
| 307 |
|
#29182: In Calls and Casts, you might want to parenthetically mention that "cast" is short for "broadcast".--Jim Menard
|
P1.0rc3
|
|
| 327 |
|
#31779: "we can use the syntax {attribute, ..." should be "we can use the syntax {attributes, ...".--Richard Carlsson
|
P2.0
|
|
| 327 |
|
#31780: Par. 3: please refer to "the documentation", not "the manual page".--Richard Carlsson
|
P2.0
|
|
| 337 |
|
#29408: "This provides a place to which to send events." should probably read "This provides a place to send events."--Samuel Tesla
|
P2.0
|
|
| 342 |
|
#29227: In the type description for error_logger:error_report(Report), square brackets do not match.--Kazuya Sakakihara
|
P1.0rc3
|
|
| 342 |
|
#31991: In paragraph starting with "In addition, ...", on the first line, "error_handler" should read "error_logger".--Dominique Boucher
|
P2.0
|
|
|
344 |
#33108: 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.)--Steven Grady #33108: The 1.0 version had the "correct" (i.e. intentional) error of misspelling "rectangle" as "rectonge". 2.0 "fixes" the problem, leading to conf ...more...
|
P2.0
|
|
| 347 |
|
#29917: 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?
#29917: I assume that the following function:
handle_call(_Request, N) -> Reply = N, {ok, N, N}.
should be:
handle_call(_Request, N) -> Reply = N, ...more...
|
P2.0
|
|
| 364 |
|
#29920: 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?
#29920: 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 ...more...
|
P2.0
|
|
| 368 |
|
#29663: 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."
--Ludovic Kuty #29663: 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 ha ...more...
|
P2.0
|
|
| 376 |
|
#31687: My remark about SMP is obsolete for Erlang/OTP R12B. It works on M$ windows too now.
--Falko
|
P1.0
|
|
| 376 |
|
#29407: "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.--Falko #29407: "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 t ...more...
|
P1.0
|
|
| 381 |
|
#29921: "F1(Pid, X) will be called for each value of X in L.Pid is a process..."
Missing space between "L." and "Pid"
|
P2.0
|
|
| 392 |
|
#31790: 3rd bullet point: "alternation type" should be "union type".--Richard Carlsson
|
P2.0
|
|
| 392 |
|
#31791: Third bullet point: note that [X|Y] as a type expression means "a list of X and/or Y elements".--Richard Carlsson
|
P2.0
|
|
|
402 |
#29869: 9th line from the bottom.
'contines' should read 'contains'
--Manfred Lotz
|
P2.0
|
|
|
404 |
#29406: The correct signature of start_raw_server should be start_raw_server(Port, Fun, Max, PacketLength)--G. Zorn
|
P1.0
|
|
| 430 |
|
#31870: Figure E.1 caption: "Table viewer initial screen" should be "The debugger window".--Richard Carlsson
|
P2.0
|
|
| 438 |
|
#29801: 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).--Richard Carlsson #29801: 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 we ...more...
|
P2.0
|
|
| 445 |
441 |
#29690: 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."--G Bulmer #29690: The description of code:soft_purge(...) reads:
"Remove old code for a module, unless no process uses it."
This is the opposite of the behavi ...more...
|
P1.0
|
|
|
467 |
#31519: In the description of filelib functions is_dir/1, is_file/1, is_regular/1, there is no space areoung the "Name".--Petr Sturc
|
P2.0
|
|
|
468 |
#29870: FIrst line in F.26
Not trees but sets:
'General balanced trees' should read 'General balanced sets'
--Manfred Lotz
|
P2.0
|
|
| 476 |
|
#29930: In the description for "enter_loop" there is no whitespace around the term "gen_fsm."--Steve Vinoski
|
P2.0
|
|
| 478 |
|
#29931: In the description for "enter_loop" there is no whitespace around the term "gen_server."--Steve Vinoski
|
P2.0
|
|
| PDF |
Paper |
Description |
Found in |
Fixed in |
| 0 |
|
#29186: 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"!--Edwin Fine #29186: 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 ...more...
|
P1.0rc3
|
|
| 23 |
|
#29127: 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") --Marcello Presulli #29127: Because erlang is mainly for embedded developer interesting, mabe you could note some common size/memory footprints and in this context point ...more...
|
P1.0rc2
|
|
| 39 |
|
#29170: 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.
--David Peterson #29170: 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 betwe ...more...
|
P1.0rc3
|
|
| 65 |
|
#29215: 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--Bas Kok #29215: As someone with a Haskell background, I found the section about 'list comprehension' quite understandable. However I noted that my fellow coll ...more...
|
P1.0rc3
|
|
| 73 |
|
#29717: Last paragraph: "and computing some value" should be "and computes some value"--Richard Carlsson
|
P2.0
|
|
| 74 |
|
#29718: 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."--Richard Carlsson #29718: Paragraph 5 ("If you ever see code like this...") doesn't really explain the problem, and makes it look like "++" is inherently bad somehow.
...more...
|
P2.0
|
|
| 74 |
|
#30327: 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. #30327: 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 e ...more...
|
P2.0
|
|
| 77 |
|
#28933: 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.--Saimon Moore #28933: 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) ...more...
|
B1.15
|
|
| 77 |
|
#29631: The explanation of BIF is not until page 86, but is used on page 77 in the explanation of exceptions.--Matt Young
|
P2.0
|
|
| 85 |
|
#29255: 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...". #29255: 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... ( _: ...more...
|
P1.0rc3
|
|
| 93 |
|
#29723: 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.
--Richard Carlsson #29723: 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 paragra ...more...
|
P2.0
|
|
| 101 |
|
#29724: 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.--Richard Carlsson #29724: The attributes "-compile(...)" and "-vsn(...)" are described as "predefined module attributes" along with "-module(...)" etc., but in fact, th ...more...
|
P2.0
|
|
| 103 |
|
#29725: 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).--Richard Carlsson #29725: The subsection on Boolean Expressions should have a reference to the subsection on Short-Circuit Boolean Expressions on page 115, and vice ver ...more...
|
P2.0
|
|
| 109 |
|
#29727: 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.--Richard Carlsson #29727: Subsection "Control Flow in Macros": This talks consistently about control flow "within a macro", "inside a macro definition", etc. But in fac ...more...
|
P2.0
|
|
| 114 |
|
#29358: "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?--Falko #29358: "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, ...more...
|
P1.0
|
|
| 124 |
|
#29199: Maybe you like to link the pages 124 and 47. Both care about the .erlang file.
Kind regards,
Nils--Nils Muellner
|
P1.0rc3
|
|
| 124 |
|
#31251: 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 --Alexey Kuznetsov #31251: not equivalent example
"C:\Program Files\erl5.5.3\bin\erl.exe" -noshell -s hello start -s init stop
#!/bin/sh
erl -noshell -pa /hom ...more...
|
P2.0
|
|
|
143 |
#31565: 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.--Kevlin Henney #31565: 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 als ...more...
|
P2.0
|
|
| 152 |
|
#29644: The notion of mailboxes is not introduced until section 8.6, but are referred to in 8.5 (receive with a timeout of 0)--Matt Young
|
P2.0
|
|
| 154 |
|
#29002: 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.--Chris Holliday #29002: I thought the section on Selective Recieve went a little fast.
Since message passing/recieving is such a large portion of the language per ...more...
|
B1.15
|
|
| 157 |
|
#29803: 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.)--Richard Carlsson #29803: Section 8.10, "Spawning with MFAs": It is a misconception that spawns using funs would somehow cause problem with dynamic code loading. It is ...more...
|
P2.0
|
|
|
182 |
#29638: 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.--Roland #29638: 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 - thi ...more...
|
P2.0
|
|
| 193 |
|
#29243: 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.--Joe Jones #29243: 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 ...more...
|
P1.0rc3
|
|
| 222 |
|
#29238: 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:
erlc -W $<
MODS = example1 example1_lid
all: ${MODS:%=%.beam} example1 example1_drv.so
example1: example1.c erl_comm.c example1_driver.c
cc -o $@ $^
example1_drv.so: example1_lid.c example1.c
cc -o $@ -I/usr/local/lib/erlang/usr/include -fno-common -bundle -flat_namespace -undefined suppress $^
clean:
rm example1 example1_drv.so *.beam--Kazuya Sakakihara #29238: 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:
erlc -W $<
...more...
|
P1.0rc3
|
|
| 223 |
|
#30751: 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.--Bruce Gunderson #30751: 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
** exc ...more...
|
P2.0
|
|
| 226 |
|
#29239: 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.
--Kazuya Sakakihara #29239: 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, ...more...
|
P1.0rc3
|
|
| 235 |
|
#31745: 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.--Richard Carlsson #31745: I spoke too soon (#31742): there is no platform-dependent conversion happening at all. Opening a file with file:open() uses binary mode for re ...more...
|
P2.0
|
|
| 235 |
|
#31742: 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 "\n", 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.--Richard Carlsson #31742: 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_li ...more...
|
P2.0
|
|
|
242 |
#29973: 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.
--Jani Launonen #29973: There's suggestion to use certain kinds of accumulation techniques for tcp fragments. Now the R12B-0 have brought efficient binary accumulatio ...more...
|
P1.1
|
|
| 243 |
|
#29218: The file_info record shown here is missing the minor_device, inode, uid, and gid fields.--Steve Vinoski
|
P1.0rc3
|
|
| 261 |
|
#31749: 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.--Richard Carlsson #31749: 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 ...more...
|
P2.0
|
|
| 261 |
255 |
#29591: 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.--Garry Bulmer #29591: In the udp_test.erl server source:
loop(Socket) ->
receive
{udp, Socket, Host, Port, Bin} = Msg ->
The only explanation of ...more...
|
P2.0
|
|
| 295 |
|
#29181: 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.
--Jim Menard #29181: 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 ve ...more...
|
P1.0rc3
|
|
| 316 |
|
#31777: 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.--Richard Carlsson #31777: 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 neces ...more...
|
P2.0
|
|
| 317 |
|
#31781: 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.--Richard Carlsson #31781: Section 17.2 "Adding and removing data...":
It is frustrating to read about operations like mnesia:write(Row) when there has been no explanat ...more...
|
P2.0
|
|
|
337 |
#31987: 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". #31987: 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 ...more...
|
P1.0
|
|
| 338 |
|
#29021: 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.
--Brian Zhou #29021: Could you please mention OTP behaviors not covered by the "OTP Introduction" and "Making a System With OTP" chapters, and where to go for furt ...more...
|
B1.15
|
|
| 343 |
|
#31066: 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".--Bruce Gunderson #31066: 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 c ...more...
|
P2.0
|
|
| 346 |
|
#29919: 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}.
#29919: Compiling my_error_handler (with erlc) produced the following warning:
./my_alarm_handler.erl:9: Warning: undefined callback function code_ch ...more...
|
P2.0
|
|
|
358 |
#31192: 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.
--Aaron D. Ball #31192: 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 rathe ...more...
|
P2.0
|
|
| 363 |
|
#31992: 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.--Igor R. Sucupira #31992: 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:
--- ...more...
|
P1.1
|
|
| 393 |
|
#31793: 1st bullet point: "TypeVar: A type variable". This is just a special case of the 3rd bullet point: "Type: A type expression". You should remove this point and instead add a point to the definition of TypeExpression in the previous section: "* A type variable TypeVar is a type expression. This is like a variable in and Erlang expression, but represents some type, not some value."--Richard Carlsson #31793: 1st bullet point: "TypeVar: A type variable". This is just a special case of the 3rd bullet point: "Type: A type expression". You should remov ...more...
|
P2.0
|
|
| 393 |
|
#31794: 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." --Richard Carlsson #31794: 2nd bullet point: "TypeVar::Type: A type variable followed by a type. This means that TypeVar has type Type." This is a misunderstanding. The ...more...
|
P2.0
|
|
| 435 |
|
#29802: 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.--Richard Carlsson |