By Developers, For Developers
PDF Pg | Paper Pg | Type | Description | Fixed on | Comments |
---|---|---|---|---|---|
xi | TYPO | Changes in the Beta… “Mention the data and time functions added in 1.5, along with the Date::Range module.” ‘data’ -> date | 2018-02-17 | ||
37 | TYPO | func5ion | 2018-02-17 | ||
xi | TYPO | “the new implicir child specifications” | 2018-02-17 | ||
xii | TYPO | dialyxr => dialyxir? | 2018-02-17 | ||
xvi | TYPO | looks like the link address and link text for ‘1. online Elixir code; https-colon-slash-slash-codestool-dot-coding-gnome-dot-com’ have been swapped. | 2018-02-17 | ||
34 | TYPO | “If you are using dates and times in your code, might want to augment these” should add “you” | 2018-02-17 | ||
37 | TYPO | “In particular, the binding of line_no to 50” binding to 0 instead ? | 2018-02-17 | ||
38 | TYPO | “Here’s an example of code that isn’t in the cannonical Elixir format” -> “canonical” | 2018-02-17 | ||
48 | TYPO | Since the “J” in “José” is in upper case, the “d” in “dave” should also be in the same case instead of lower case. IO.puts mr_valim.(“José”) # => Oi! José | 2018-02-17 | ||
60 | TYPO | The box named “Guard Clauses vs. Conditional Logic”. We see HTML/XML entity references “>” and “<” instead of > and <. | 2018-02-17 | ||
35 | TYPO | We’ll look at this in on page 192. | 2018-02-17 | ||
xi | TYPO | Last bullet point “The OTP section….” | 2018-02-17 | ||
xvi | TYPO | I just completed by second year … -> my second year | 2018-02-17 | ||
299 | TYPO | “Wee the Task documentation” Wee => See | 2018-02-18 | ||
259 | TYPO | In the first sentence of the section “A Little More Detail”, “…but as some one always asks” should be “…but as someone always asks” with “someone” as one word, not two. | 2018-02-18 | ||
271 | TYPO | Footnotes 2 and 3 at the bottom of PDF page 271 are incomplete. Paragraph 2 on page 271 (beginning with “:simple_one_for_one”) is the completion of footnote 2, and the second to last paragraph on page 271 (beginning with “multiple child servers”) is the completion of footnote 3 | 2018-02-18 | ||
275 | TYPO | The first word on the page, “exists”, should be “exits”, to complete the thought from the previous page, “When the init function exits, the server is then free…” | 2018-02-18 | ||
276 | TYPO | In the second full text paragraph on page 276, the second sentence begins “Otherwise, we call a proviate function…”, where “proviate” is a typo for “private”. | 2018-02-18 | ||
292 | TYPO | In the last command line example before the section titled “Migrating Server State” (about 3/4 of the way down the page), the command ends with “upgrade 0.0.2”, but based on the previous examples in the section, this should be “upgrade 0.2.0” instead. | 2018-02-18 | ||
295 | TYPO | On page 295, in the command line example for upgrading about 1/3 of the way down the page, the command ends with “upgrade 0.0.3”, but based on the rest of the example, this should be “upgrade 0.3.0” instead. | 2018-02-18 | ||
53 | OK | Maybe it’s a typo, Idk, in with-scope.exs file, in my case it does not work with _lp. It works with plain lp. | 2018-02-17 | OS X uses _lp; Linux lp | |
xvi | TYPO | ”as an adjust professor” => as an adjunct professor? | 2018-02-17 | ||
71 | ERROR | Third paragraph under “Heads and Tails” says “[…] using a pipe character, The code tag should not be here.. The single […]” presumably “The code tag should not be here” (shown in bold) is a sign of some kind of markup failure. | 2018-02-17 | ||
252 | TYPO | “and so fee free to skip” should be “and so feel free to skip” | 2018-02-18 | ||
106 | TYPO | In the “Stream.cycle” section, on the line where we map our infinite green/white stream into an HTML tag: …> ~s{ | |||
#{value} |
2018-02-18 | ||||
156 | ERROR | There’s duplicate function defs in the project3/issues/lib/issues/cli.ex file, specifically these two: decode_response({:ok, body}) | 2018-02-18 | ||
37 | SUGGEST | In a discussion of block scoping, a purposely chosen non-working example is used to demonstrate the Elixir philosophy of transformation through functions. I suggest also adding a working example to show how it should look in Elixir. | 2018-02-17 | ||
10 | SUGGEST | Footnote #3 - Elixir mailing list moved in 2016. New address appears to be elixirforum dot com. | 2018-02-17 | ||
38 | 23 | OK | In the garbage collection section of Chapter 3. Immutability, in this part | 2018-02-17 | `divvied` is an actual word... :) |
33 | TYPO | “iex> first_half = Date.range(d1, d2)” is listed twice in the examples. | 2018-02-17 | ||
38 | TYPO | The green header background for “basic-types/with-scope-fmt.exs” starts after “basic-”. | 2018-04-06 | ||
38 | SUGGEST | In the example “basic-types/with-scope.exs”, I’d put a caret at the start of the regex (eg, ~r/^_lp:…), to bind it to the start of the line. | 2018-02-17 | ||
39 | SUGGEST | In the example “basic-types/with-match.exs”, I’d put a caret at the start of the regex (eg, ~r/^xxx:…), to bind it to the start of the line. | 2018-02-17 | ||
41 | SUGGEST | I’d change “Elixir is a functional language, therefore it is …” to “Elixir is a functional language; therefore, it is …”. | 2018-02-17 | ||
44 | SUGGEST | I’d change “… hundreds of years of effort …” to “… hundreds of developer-years of effort …”. | 2018-02-17 | ||
59 | SUGGEST | The function lists under the headings “Type-check functions” and “Other functions” are hard for me to read. I’d add commas and perhaps a bit more whitespace between the entries. | 2018-02-17 | ||
73 | SUGGEST | In “How iex Displays Lists”, I’d change “… represents strings as a list of integer codepoints.” to “represents strings as lists of integer codepoints.”. | 2018-02-18 | ||
77 | TYPO | “reduce([ head |tail ], value, fun)” is missing a space; it should be “reduce([ head | tail ], value, fun)”. | 2018-02-17 | ||
83 | TYPO | The text “_If so, use a struct.” should be “If so, use a struct.” and be in italics. (The problem is actually a missing trailing underscore). | 2018-02-17 | ||
86 | ERROR | The sentence ending “… and the do block prints the whole map.” is somewhat misleading. The do block returns the whole map; IO.inspect prints it. | 2018-02-18 | ||
102 | SUGGEST | After “… if you want the sort to be stable.”, I’d add a brief explanation of stable sorts. | 2018-02-18 | ||
118 | SUGGEST | I’d change “Heredocs are used extensively to add documentation to functions and modules.” to “Heredocs (aka here documents) are used extensively to add documentation to functions and modules. Though their form may vary, the basic idea goes back at least as far as the Unix shell.” | 2018-02-18 | ||
119 | ERROR | “… it returns atoms, a list, or strings of characters.” should be “… it returns atoms, character lists, or strings of characters.”. | 2018-02-18 | ||
124 | SUGGEST | In the IEEE 754 example, the transformation is incomplete, because the variable “sign” is never used. | 2018-02-18 | ||
126 | TYPO | In the result from String.codepoints, there’s an extra space in: … “e”, "… | 2018-02-18 | ||
139 | SUGGEST | I’d change “If the pattern match on the first line fails, …” to “If the pattern match on the first line above fails, …”. | 2018-02-18 | ||
148 | SUGGEST | The paragraph beginning “Three of the four tests ran successfully.” mingles two kinds of presentation issues. I’d discuss the layout (eg, lhs/rhs) in one paragraph, then discuss terminal-specific (and possibly inaccessible) issues (eg, green, red) in a following paragraph. | 2018-02-18 | ||
150 | SUGGEST | Under “Task: Use Libraries”, I’d explain that while …/elixir-lang.org/docs.html is a great starting point, …/hexdocs.pm/elixir/Kernel.html is a more direct path to library documentation. “To prevent spam, hyperlinks are not allowed in errata”. This is a ridiculous restriction. | 2018-02-18 | ||
151 | SUGGEST | I’d change “Next, check if any standard Erlang libraries do what you need.” to “Next, check for standard Erlang libraries that do what you need.”. | 2018-02-18 | ||
151 | SUGGEST | I’d change “… are already available to your application.” to “… are already available for your application.”. | 2018-02-18 | ||
155 | ERROR | There are liberties being taken with the display of the output from “Issues.GithubIssues.fetch”. Specifically, it would appear more like this: {:ok, “[\ The reformatting is a fine idea, but I’d change the example to be something (eg, IO.puts) that actually produces the displayed result. | 2018-02-18 | ||
155 | TYPO | “This tuple the body of the GitHub response. The first element set to :ok.” should be “This tuple is the body of the GitHub response. The first element is set to :ok.”. | 2018-02-18 | ||
157 | SUGGEST | In “Dependencies That Aren’t in Hex”, I’d change “The dependencies you need are likely in hex, so …” to “The dependencies you need are likely to be available on hex.pm, so …”. | 2018-02-18 | ||
157 | ERROR | “… for a successful response is a list of maps, …” should be “… for a successful response has now been converted to a list of maps, …”. | 2018-02-18 | ||
160 | SUGGEST | The example could save a line (and processing time) by reversing the sort order and removing the first call to Enum.reverse. | 2018-02-18 | ||
160 | SUGGEST | I’d change “… so we’ll show the listing.” to “… so we’ll just show the listing.”. | 2018-02-18 | ||
161 | SUGGEST | As far as I can tell, the “with” construct is pointless in print_table_for_columns/2 . I’d remove it or explain why it’s there. | 2018-02-18 | ||
164 | SUGGEST | I’d edit the earmark output so that the lines don’t fold. | 2018-02-18 | ||
167 | SUGGEST | I’d change “The first time you run it, this will install ExDoc.” to “The first time you run this command, it will install ExDoc.”. | 2018-02-18 | ||
171 | SUGGEST | I’d change “… the core team have spent …” to “… the core team has spent …”. (But then, I’m a yank.) | 2018-02-18 | ||
172 | ERROR | The code display has “division::bits-16”, which is correct, but doesn’t lead to the bug that the following text describes. So, it should be changed to “division::integer-16” for the moment. | 2018-02-18 | ||
172 | SUGGEST | I’d change “beats::15>>” to “beats::15 >>” and “beats::8>>” to “beats::8 >>”. | 2018-02-18 | ||
173 | TYPO | “… source lines surroundingnthe breakpoint.” should be “… source lines surrounding the breakpoint.”. | 2018-02-18 | ||
173 | TYPO | “Ah ha! ‘decode is expecting …” should be “Ah ha! decode is expecting”. (This looks like a markup error.) | 2018-02-18 | ||
175 | SUGGEST | I’d change “beats::15>>” to “beats::15 >>” and “beats::8>>” to “beats::8 >>”. | 2018-02-18 | ||
176 | SUGGEST | As far as I can tell, the “with” construct is pointless in print_table_for_columns/2 . I’d remove it or explain why it’s there. | 2018-02-18 | ||
176 | SUGGEST | In the second @doc, there is a blank line following “## Example”. This is inconsistent with the format used elsewhere. | 2018-02-18 | ||
180 | SUGGEST | When the “describe” and “test” strings are concatenated, the result should read smoothly. | 2018-02-18 | ||
183 | SUGGEST | When the “describe” and “propertry” strings are concatenated, the result should read smoothly. This is not the case, for example, in “Stats on lists of ints single element lists are their own sum”. I’d add terminal colons to the “describe” strings, as: “Stats on lists of ints: single element lists are their own sum”. | 2018-02-18 | ||
186 | SUGGEST | I’d change “… by a test, the code is incomplete.” to “… by a test, the testing is incomplete.”. | 2018-02-18 | ||
186 | SUGGEST | When explanatory text follows a heading such as “mix xref unreachable” and “mix xref warnings”, I’d like it to take the form of complete sentences. So, for example, there should be capital letters at the front, periods at the ends, etc. | 2018-02-18 | ||
193 | TYPO | The markup is confused in “This magic is done using the mix format command. It can format single files, directory trees, and whole projects (see mix help format‘ for information).”. Further down the page, “… looks like a dogs dinner:” should be “… looks like a dog’s dinner:”. | 2018-02-18 | ||
194 | SUGGEST | I’d change “I find it much, …” to “I find this much, …”. (and I’m in violent agreement with Dave on this!) | 2018-02-18 | ||
195 | SUGGEST | Inline spacing can be used to good effect to make parallel construction more evident. | 2018-02-18 | ||
207 | SUGGEST | The text says “The create_processes function is probably the densest piece of Elixir we’ve encountered so far.”. Indeed it is. Worse, the density is exacerbated by the fact that an anonymous function is intertwingled into the Enum.reduce call. I generally prefer to decomplect (per Rich Hickey) the code by defining anonymous functions first, then using them by name. This makes both their definition and use simpler. | 2018-02-18 | ||
208 | SUGGEST | I’d change “… to the last process. It will …” to “… to the last process, which will …”. | 2018-02-18 | ||
210 | ERROR | In the example, sad_function/0 exits with a value of :boom, rather than 99 (as stated in the preceding text). | 2018-02-18 | ||
219 | SUGGEST | I’d change “We see a dramatic reduction in elapsed time when we increase the …” to “We saw a dramatic reduction in elapsed time when we increased the …”. | 2018-02-18 | ||
235 | TYPO | “Then exception is the …” should be “The exception is the …”. | 2018-02-18 | ||
240 | SUGGEST | I’d change “… the server does.” to “… the server does (roughly, one function call).”. | 2018-02-18 | ||
245 | TYPO | “… and so fee free to skip …” should be “… and so feel free to skip …”. | 2018-02-18 | ||
255 | TYPO | “The answer depends of the …” should be “The answer depends on the …”. | 2018-02-18 | ||
256 | TYPO | “… in the list of children and terminated, …” should be “… in the list of children are terminated, …”. Also, the sentences should start with capital letters. | 2018-04-07 | ||
262 | TYPO | “… to processes all the files at once.” should be “… to process all the files at once.” “… need to cater for both big …” should be “… need to cater to both big …”. | 2018-02-18 | ||
263 | SUGGEST | In “… when it has stopped. When it does stop, it fetches …”, the pronoun “it” is used three times. This seems awkward. | 2018-02-18 | ||
265 | TYPO | “We want to protect the accumlating results, but that we’re …” should be “We want to protect the accumulating results, but we’re …”. (two errors) | 2018-02-18 | ||
266 | TYPO | “… could create a poll of workers …” should be “… could create a pool of workers …”. | 2018-02-18 | ||
269 | SUGGEST | I’d change “… is the dirwalker pid.” to “… is the dir_walker pid.”. | 2018-02-18 | ||
271 | TYPO | The markup for both footnotes is broken, causing them to steal text from the main paragraphs. Also, “… this can only be stragegy: one_for_one.” should be “… this can only be strategy: one_for_one.”. | 2018-02-18 | ||
269 | SUGGEST | I’d change “as the code it is testing.” to “as the code they are testing.”. I’d also change “trivial genserver” to “trivial GenServer”. | 2018-02-18 | ||
273 | TYPO | “… that is has run our of work …” should be “… that it has run out of work …” (two errors) | 2018-02-18 | ||
274 | TYPO | “Javascript” should be “JavaScript”. “0mS” should be “0ms” (or perhaps “0 ms”) In “When the init function …”, “init” should be in monospace font. | 2018-02-18 | ||
278 | TYPO | “30Gb” should be “30GB” (or perhaps “30 GB”). The phrase “duplicates in that.” is missing the rest of its sentence. “… and so one, …” should be “… and so on, ”. | 2018-02-18 | ||
287 | TYPO | “But how do we version the data.” should be “But how do we version the data?”. | 2018-02-18 | ||
288 | SUGGEST | On pages 288 and 289, the vertical bars in the file tree lines containing ellipses use a different font than they do elsewhere. | 2018-02-18 | ||
290 | TYPO | Shouldn’t “ | 2018-02-18 | ||
291 | SUGGEST | I’d change “Now that’s in place, this …” to “Now that that’s in place, this …”. | 2018-02-18 | ||
294 | TYPO | “… version number ( Also, it appears that the font handling needs work. | 2018-02-18 | ||
297 | SUGGEST | I’d change “… but insulate us from these details.” to “… but insulate us from low-level details.”. | 2018-02-18 | ||
310 | SUGGEST | I’d change “… to ensure the named module is …” to “… to ensure that the named module is …”. | 2018-02-18 | ||
318 | SUGGEST | I’d change “Instead the macro definition …” to “Instead, the macro definition …”. I’d also change “… distinct to the scope …” to “… distinct from the scope …”. | 2018-02-18 | ||
320 | SUGGEST | I’d change “… we rewrite the …” to “… we can rewrite the …”. OTOH, the word “can” is being rather heavily used here, so I might just rewrite things a bit.. | 2018-04-07 | ||
324 | ERROR | The book says “… see Appendix 2, Type Specifications and Type Checking.” I’d love to, if it were present… | 2018-04-07 | ||
332 | SUGGEST | I’d change “… what we hard-core folks call strings).” to “… what we hard-core folks call a string).”. | 2018-02-18 | ||
337 | SUGGEST | I’d call the module “MIDI”, rather than “Midi”. | 2018-02-18 | ||
339 | SUGGEST | I’d change “Here’s the versions …” to “Here are the versions …”. “The next two function heads to the actual iteration.” should be “The next two function heads do the actual iteration.”. I’d change “… in the documentation you’ll recognize …” to “… in the documentation, you’ll recognize …”. I’d change “Instead of doing list …” to “However, instead of doing list …”. Finally, the name of the standard is “MIDI”, not “midi” (as used several times in the text). | 2018-02-18 | ||
341 | TYPO | “… I happen to know what we won’t be …” should be “… I happen to know that we won’t be …”. “… got back 2 Midi.Frame structures.” should be “… got back two Midi.Frame structures.”. I’d change “… it is being read piece at a time …” to “… it is being read one piece at a time …”. | 2018-02-18 | ||
348 | SUGGEST | I’d change “beats::15>>)” to “beats::15 >>)” and “beats::8>>)” to “beats::8 >>)”. | 2018-02-18 | ||
356 | SUGGEST | I’d change “Verify it builds …” to “Verify that it builds …”. | 2018-02-18 | ||
285 | ERROR | Sequence.Supervisor.start_link() is undefined, meanwhile module Sequence.Supervisor has nowhere been introduced. Probably relating to “mismatched code” of page 283 ? | 2018-02-18 | ||
268 | ERROR | This page adds Duper.PathFinder, Duper.WorkerSupervisor, and Duper.Gatherer to application.ex, which causes the “mix test” on the next page to fail because they don’t exist yet. | 2018-02-18 | ||
271 | TYPO | “Let’s create the supervisor (in lib/worker_supervisor.ex)” has the wrong path; it should be lib/duper/worker_supervisor.ex | 2018-02-18 | ||
61 | TYPO | Appears to be a stray “IO” between the mm/default_params1.exs code and “If you compile this”… | 2018-02-17 | ||
266 | TYPO | “has on elasped time” -> elapsed | 2018-02-18 | ||
264 | TYPO | “Notice that we have a mixture of synchronous messaging (the double-headed arrows) and” Mistake on schema? | 2018-02-18 | ||
273 | TYPO | “gatherer that is has run our of work” -> should be “it has” | 2018-02-18 | ||
9 | OK | In section “Compile and Run” : “tired” instead of “tire” (See below) | 2018-02-17 | I think it is correct as is. \n \n | |
186 | 175 | TYPO | Instead of ‘You can start by getting help for IEx.break/4’ use | 2018-02-18 | |
320 | ERROR | The book says that the Macro module has two functions to list the unary and binary operators. It seems that Elixir 1.6.1 no longer has those. Elixir 1.5.3 did. Elixir 1.6.1: Interactive Elixir (1.6.1) - press Ctrl+C to exit (type h() ENTER for help) (UndefinedFunctionError) function Macro.binary_ops/0 is undefined or private (UndefinedFunctionError) function Macro.unary_ops/0 is undefined or private Book: iex> require Macro | 2018-02-18 | ||
7 | SUGGEST | the information displayed when using the i helper is missing the Implemented protocols section (1.6.1) | 2018-02-17 | ||
259 | TYPO | In ‘Going up one more level, when you use GenServer in a server module, Elixir will See the Elixir source code for GenServer, line 66 (sorry, can not hyperlink due to spam prevention) | 2018-02-18 | ||
263 | TYPO | In ‘to maximize our use of the CPU and IO bandwodth’, change to ‘bandwidth’ | 2018-02-18 | ||
298 | TYPO | In ‘Supervisor.start_Link(children,strategy::one_for_one)’ change ‘start_Link’ to ‘start_link’ | 2018-02-18 | ||
288 | TYPO | To deploy it, we’d basically copy it just as we did before, the stop s/the stop/then stop/ | 2018-04-07 | ||
38 | 37 | TYPO | “For that reason, you’ll a warning:” should probably read “For that reason, you’ll get a warning:” | 2018-04-06 | |
152 | SUGGEST | We’re adding httpoison v0.13.0 lib to the issues project. The lates (stable?_) version is actually 1.0.0 | 2018-04-06 | ||
153 | SUGGEST | I’d love to see what’s your recommendation for testing such module as Issues.GithubIssues. In particular, how do we mock HTTPoison.get responses. | 2018-04-06 | Split the fetching from the processing, and you can feed mock responses directly to the processing. | |
257 | ERROR | “Elixir will define a default check_spec function” should be “Elixir will define a default child_spec/1 function” | 2018-04-07 | ||
257 | ERROR | Supervisor.child_spec has arity 2, not 1. Error in sentence: “You can create a child spec map using the Supervisor.child_spec/1 function.” | 2018-04-07 | ||
269 | TYPO | “which it turn” should be “which in turn” | 2018-04-07 | ||
273 | SUGGEST | When a worker is done, like in the add_result(nil) case, it should return {:stop, :normal, nil} instead of {:noreply, nil}. This will stop the process and it won’t restart since it is marked as :transient. | 2018-04-07 | ||
210 | ERROR | Can not open the link Exercise: WorkingWithMultipleProcesses-2 | |||
231 | 223 | OK | iex(node_one@light-boy)> Node.spawn(:“node_one@light-boy”, func) My machine shows node name first and pid. elixir -v Elixir 1.6.1 (compiled with OTP 20) | 2018-04-07 | Can you think why that might be? Try doing the same thing 10 times? |
84 | SUGGEST | It isn’t obvious why the code uses the access operator for options[:fg], but not for :bg or :font. A bit more explanation might be helpful. | 2018-04-06 | Just to show options... | |
93 | ERROR | The purported output for maps/access1.exs contains the strings “Ewes” and “EWES”. To match the map definition above, these should be “Elwes” and “ELWES”. | 2018-04-06 | ||
119 | ERROR | At the end of the page, the description of the ~W and ~w sigils is “… whether it returns atoms, a list, or strings of characters.”. These sigils always return a list; the type specifier determines the encoding of the list elements. So, the text should read “… it returns lists of atoms, character lists, or strings of characters.”. | 2018-04-06 | ||
155 | TYPO | “The first element set to :ok.” should be “The first element is set to :ok.”. | 2018-04-06 | ||
160 | SUGGEST | The …/table_formatter.ex listing uses the “with” expression. On pp. 37-38, a couple of reasons are given for using “with”. One is pattern matching, which isn’t being used. The other is scope control, which isn’t needed. So, why does this code use “with”? Note that this same question applies to the code on page 174. | 2018-04-06 | 'cos I like the way it looks :) | |
162 | SUGGEST | There are certainly benefits to using escript (e.g., dependency management, startup latency, use of mix), but there is also a substantial cost in terms of storage space, convenience of integration with the command line, etc. It might be worthwhile to discuss (whether and) how one can use Elixir as a scripting language. | 2018-04-06 | ||
170 | SUGGEST | I’d change “three 16 bit fields” to “three 16-bit fields”. | 2018-04-06 | ||
38 | ERROR | with-scope.exs does not match for me with change introduced by #82566 (leading ^ in regex). Version in 1.3 book works fine. I think the “m” option might be needed for regex here? | 2018-04-06 | ||
171 | TYPO | The “iex -S mix” output shows three blank lines (9, 10, 12). Only one of these appears in the corresponding code (shown above.) | 2018-04-06 | ||
171 | TYPO | In “The value in division … to decode.”, “decode” should be “decode/1”. Also, “division” and “decode/1” should be printed in code font. | 2018-04-06 | ||
181 | SUGGEST | There is no explanation for the use of " | 2018-04-07 | ||
191 | TYPO | “dogs dinner” should be “dog’s dinner”. | 2018-04-07 | ||
193 | TYPO | “code to an project” should be “code to a project” | 2018-04-07 | ||
206 | SUGGEST | The text says “All this is done on line 14.”, but it’s not clear what “All this” refers to, given that the preceding paragraph is about the definition of code_to_run. | 2018-04-07 | ||
206 | SUGGEST | The sentence starting “It will increment it …” uses “it” to refer to two different things (the process and the initial value). Later in the paragraph, “it” is used to refer to a third thing (the computed result). This seems awkward and needlessly confusing. | 2018-04-07 | ||
217 | SUGGEST | The paragraph starting “Cody Russell” starts in past tense (ran), changes to present tense (see, increase), then changes back to past tense (hit). I’d use the same tense throughout. | 2018-04-07 | ||
243 | TYPO | “a free standing chunk” should be “a free-standing chunk” | 2018-04-07 | ||
260 | TYPO | “We definely will” should be “We definitely will” | 2018-04-07 | ||
263 | TYPO | “the accumlating results” should be “the accumulating results” | 2018-04-07 | ||
267 | TYPO | “trivial genserver” should be “trivial GenServer” | 2018-04-07 | ||
335 | TYPO | On pages 335, 337, 338, and 339, “midi file” should be MIDI file. | 2018-04-07 | ||
356 | SUGGEST | The text above the mix.exs code says “… our mix.exs gets a little more complicated”, | |||
111 | TYPO | “iex> Enum.into 1..5, [100, 101 ]” should be “iex> Enum.into 1..5, [100, 101]” (remove space after 101) | 2018-04-06 | ||
38 | ERROR | In this line of code: As when you run the code it throw this error: (MatchError) no match of right hand side value: nil (CompileError) compile error But when you remove that symbol, code runs successfully and return the expected value. | 2018-04-06 | ||
222 | TYPO | Inside “If You Run OS X , second sentence: ”If the aren’t enabled," -> “If they aren’t enabled” | 2018-04-07 | ||
246 | TYPO | Paragraph 3, last sentence: “no need to run in inside a server for that.” -> “it” | 2018-04-07 | ||
76 | TYPO | linked exercise text in not formatted and is very difficult to understand Hints: You may need to implement helper functions with an additional parameter (the currently guessed number). | 2018-04-06 | Strange: it looks of to me... | |
9 | TYPO | “Once you tire of” should probably be “Once you are tired of”. | 2018-04-06 | https://www.merriam-webster.com/dictionary/tire%20of | |
10 | TYPO | Footnote 2 points to “…/elixir13”, not sure whether it should point to “…/elixir16” | 2018-04-06 | ||
11 | TYPO | Footnote 4 points to the forum of the previous version. | 2018-04-06 | ||
33 | SUGGEST | Sigils, i.e. for Date are employed on this page, without being introduced, yet. Maybe a few words will help newcomers. | 2018-04-06 | ||
113 | TYPO | There is a type in function call. On page 113 pdf, where Bullet Point == Select elements by position or criteria: In the last example there is a typo: iex> Enum.reject(list, &Integer.is_even/1) I believe the correct function call is: | 2018-04-06 | Reject is fine here. It illustrates an additional function. | |
44 | TYPO | “there are hundreds of years of effort in there just waiting for you to use.”, probably “hundreds of years” must be “decades” | 2018-04-06 | No, it's easily hundreds of years of effort, even though it is decades of elapsed time. | |
257 | TYPO | There’s a reference to `check_spec` which should probably be `child_spec`. | 2018-04-07 | ||
250 | SUGGEST | One of the sentences is “Copy the Sequence.Server module from the last chapter”. The reference to the “module from the last chapter” is thus ambiguous. It’s not a big deal, as the rest of the chapter makes it clear which version is being used, but it would help to have add a note to make explicit. | 2018-04-07 | ||
260 | TYPO | “for example what sequence things happen it” should probably be “for example what sequence things happen IN”. | 2018-04-07 | ||
266 | SUGGEST | In the code snippet that refers to application.ex, the line that says “Duper.Results,” should be highlighted, as it’s effectively the only part of that file that needs to change (everything else stays as it was created by mix). | 2018-04-07 | ||
267 | SUGGEST | I may be wrong, but I think that adding dir_walker to mix.exs won’t be enough: it will be necessary to run “mix deps.get” before the dependency is available. | 2018-04-07 | ||
93 | TYPO | The application of String.upcase/1 on “Elwes” should be “ELWES”, not “EWES”. | 2018-04-06 | ||
100 | TYPO | The outcome of iex> require Integer is not “nil” but “Integer”. | 2018-04-06 | ||
1661 | ERROR | The .mobi version has an issue at location 1564 that is not present in the PDF — spurious extra lines and colons in the code listing . I can’t cut and paste it in a way that illustrates the problem. | |||
38 | ERROR | Thanks for writting the book Dave and all you do! :-) A small error/typo on page 38: Regexp ~r/^_lp:.*?:(\\d):(\\d)/ should have “m” modifier at the end or it returns always nil. So the line should read: Regex.run(~r/^lp:.*?:(\\d):(\\d)/m, content) do Additionally when I have read the example it really felt quite awkward and far from what a real use-case for getting uid and gid would be. One probably would like to have gid and uid returned from the with block to do some sort of comparison/safe-guard like checking if the group is what it should be and whether the uid is greater or equal 1000 or something like this. The more less-awkward code would probably look more like this: content = “Now is the time” IO.puts “Group: #{gid}, User: #{uid}” but then it doesn’t yeld itself to show the point you are making next so I’m not sure if anything could be done with it. Just wanted to pass the felling I got when reading the example. | 2018-04-06 | ||
86 | SUGGEST | The terms ‘comprehension’ and ‘generator’ are used on this page for the first time in the book, without taking a pause to explain them or point to material later in the book. I’d suggest either deferring use of the terminology or taking a moment to define it. | 2018-04-06 | The explanation is just before the code. | |
222 | TYPO | In the .mobi format, at the equivalent point to PDF page 222, the stacked vertical windows show up in a very narrow (roughly 1") column. | |||
167 | SUGGEST | In the screenshot of the TableFormatter documentation you’re showing elements which are not added until page 175. Maybe you could add a note saying something like, “Your version is plainer than this… You’ll fix that in the Testing section which follows.” | |||
167 | TYPO | This is a really minor one but the output from invoking ‘mix docs’ is different for me (using Elixir 1.6.4, ex_doc 0.18.3 and earmark 1.2.5). I get: Docs successfully generated. | |||
181 | TYPO | In the section at the bottom of the page where you break the test you change it to ’ It’s also not brilliantly clear what is the new code and what the output from the failed test is. | |||
184 | SUGGEST | The testing code in Structuring Tests (starting on page 177) is done in the pbt project rather than the issues project. It wasn’t too jarring at the start of the section but you jump back to using the issues project for test coverage and it took me a few seconds to realise. It might be worth either moving all of the Structuring Tests code into the issues project (my preference) or stating that you’re switching back to issues. Further, in the mix.exs file in issues in the Test Coverage section you’ve added ‘override: true’ to the earmark dependency. It might be worth explaining why. | |||
156 | ERROR | In some parts it says to use “mix deps.get” to install the dependencies, after adding in “mix.exs”. However, it will only be possible to use “mix deps.get”. As the mix says:
With: | |||
37 | TYPO | “However, Elixir thinks that this is a risk way to write code.” “risk” should be changed to “risky.” | |||
206 | SUGGEST | The github issue (1050) referred to in the footnote of this page has now been closed. | |||
267 | ERROR | The code for path_finder.ex has the line ‘ | |||
21 | SUGGEST | I think “At your very core, you believe that 99 will always have the value 99.” | |||
37 | TYPO | “However, Elixir thinks that this is a risk way to write code.” I think “risk” should be changed to “risky” | |||
iv | TYPO | On page iv, line 3 of text, “I just completed by second year …” should read “I just completed my second year …” | |||
191 | TYPO | The code before formatted is the same code after formatted in both examples: “no_vowels string” and “@names”. I’ve checked in Beta 2 and it is OK, but in the Beta 3 it is not. | |||
192 | TYPO | The code before formatted is the same code after formatted in the trailing comma example. I’ve checked in Beta 2 and it is OK, but in the Beta 3 it is not. | |||
178 | SUGGEST | In this discussion of using the setup block in ExUnit, it seems odd that you could return a keyword list from the setup block and then access it using `fixture.list` syntax. But that is what is described here (on page 179 in the second paragraph)… > This data is passed to our tests as a second parameter, following the test name. In my tests, I’ve called this parameter fixture. I then access the individual fields using the fixture.list syntax. After studying Keyword Lists, that doesn’t sound right. You have to actually reference the ExUnit documentation in the Callbacks module to discover the magic of returning a keyword list, map, or `{:ok, keyword | map}` tuple from the setup block which merges that list into the Context which is what gets passed to the test macro. That Context is a map (which you can obviously access using the `fixture.list` syntax. My suggestion would be to add a paragraph explaining that magic since most of Elixir is more explicit than that. So I think most readers will be in a “everything is more explicit in Elixir” mindset and might miss that. ``` test “calculates sum”, fixture do …omitted for brevity… It seems like it might be a bit much to explain in a comment as I attempted above, so perhaps a paragraph would be the best option. | |||
160 | TYPO | Following the words “we discover the built-in Enum.take:” there’s a code excerpt. | |||
38 | TYPO | in the ode listing the underscoreefore lp is missing IS:" Regex.run(~r/^lp:" SHOULD: “Regex.run(~r/^_lp:” fortunately it is correct in the following section about Code Formatting | |||
270 | 265 | SUGGEST | In duper/1/duper/lib/duper/path_finder.ex it says @me PathFinder while in duper/1/duper/lib/duper/results.ex it says @me MODULE Why not use @me MODULE in both files for consistency? | ||
257 | TYPO | “Well call it Duper” is missing the apostrophe in “We’ll” | |||
281 | ERROR | This section of code seems to be out of date: It refers to Sequence.Supervisor, but that wasn’t previously set up. Supervision happens in application.ex, as shown on page 252. | |||
199 | TYPO | In send pid, { self, “World!” } slef should be self() to be consistent with the code sample. | |||
92 | TYPO | In the example ‘maps/dynamic_nested.exs’, the value nested.westley.actor.last (“Elwes”) is called a typo by a comment. However, the example that replaces this using put_in doesn’t change the value. It seems like the original value in nested.westley.actor.last was correct, when it should have been a typo. | |||
89 | TYPO | In describing the ‘swap’ function immediately above the ‘List of Lists’ section: Text says “Given that we take two values off the list on each cycle, the initial list must have had an odd number of elements.” Text should be “Given that we take two values off the list on each cycle, the initial list must have had an even number of elements.” | |||
92 | TYPO | " Missing ‘do’ statement on line 1 of this code: def for_location([ [ time, target_loc, temp, rain ] | tail], target_loc) should be: | |||
171 | TYPO | There is a line that reads `iex> continue()` and it should read `pry> continue()` | |||
174 | ERROR | The syntax highlighting is all off. Whatever program produced the syntax formatting for code in the PDF must not realize that the code is a continuation from page 173, and so the docstrings appear formatted as code, and the code appears formatted as docstrings. This is a common occurrence throughout the code in the book. | |||
182 | TYPO | “The two new tests use a different generator: list(int) generates a number of lists, each containing zero or more ints.” list(int) should be list_of(integer()) like the code. Also, Arithmeticerror towards the end of the page should be ArithmeticError. | |||
298 | ERROR | In the source code for tasks/anagrams.exs on PDF pages 297-298, the stated goal is to load the 4 word list files in parallel using Task.async/Task.await. This is implemented in the WordlistLoader.load_from_files function on PDF page 298. The code uses Stream.map to build a lazy list of Task.async calls that, in turn, initiate the loading of the specified list files. This list is then pipelined into Enum.map(&Task.await/1). The problem is that since Stream.map is used, the Task.async calls are not executed until they are referenced somehow due to lazy evaluation. They are referenced, one-by-one, by the Enum.map calling Task.await. This effectively makes the files load serially rather than in parallel. One way to fix this would be to use Enum.map instead of Stream.map. | |||
284 | TYPO | “If you’re following along at home, have a look at rel.config.exs” should be “If you’re following along at home, have a look at rel/config.exs” The dot became a slash. | |||
78 | ERROR | There is an error in the solution for the exercise at the top of the page. The exercise says to define caesar(list, n), which wraps if the character is greater than ‘z’. Here’s what the solution provide in Elixir_1.6_Exercises.pdf does: def caesar([], _n), do: [] iex(57)> c “ex_listsrecursion1.exs” [Lists] iex(58)> Lists.caesar(‘a’, 100) That result certainly doesn’t wrap. | |||
78 | SUGGEST | My caesar(list, n) solution: def caesar([], _n), do: [] | |||
89 | SUGGEST | Steven McClain’s errata report is erroneous. The sentence he reported explains the previous sentence: This will happen [i.e. the third definition of the swap function will match] if we get to the end of the recursion and have only one element left. Given that we take two values off the list on each cycle [and we are left with one element, which is how the third function definition matches], the initial list must have had an odd number of elements. | |||
92 | SUGGEST | Either get rid of the author example where you pass a function to get_in(), or explain what’s going on. For instance, Elixir calls the function with a third argument that is also a function, which is bound to the parameter variable next_fn. Where in the docs does it describe how many arguments that next_fn takes? I can see in the author example that it takes at least one argument, but what does next_fn do? How are we supposed to use it? | |||
95 | SUGGEST | There are no exercises in Chapter 8. How come? Please add some exercises. | |||
102 | ERROR | Exercise: ListsAndRecursion-5 The instructions say. “Implement the following Enum functions using no library functions….”, yet the solution for implementing Enum.split() uses Enum.reverse(). Unless I’m misunderstanding some technical meaning of “no library functions”, then a solution cannot use Enum.reverse(). If we are allowed to use Enum functions in our solutions, then here are my solutions: def all?(list, func), do: Enum.all?(list, func) Stupid. | |||
114 | TYPO | In the section titled “Your Turn”, the Exercise: ListsAndRecursion-7 says: In your last exercise of Chapter 7, Lists and Recursion, on page 71…. The page number is wrong. The page number is actually page 81. | |||
114 | ERROR | In the section titled “Your Turn” the Exercise:ListsAndRecursion-7 says to use a comprehension to find all the prime numbers between 2 and n. However, the provided solution does not obey those rules. A list comprehension alone cannot provide the solution, yet the directions make is sound like that is indeed the case. Instead, I believe the instructions should say something like: “Use a list comprehension in your answer”. In addition, the provided solution is not written in Elixir 1.6. The solution may as well be written in C because no one whose first exposure to Elixir is “Programming Elixir 1.6” will have any idea what those hieroglyphics in the solution mean. At this point, I have to comment on the sloppy editing in this book. This book’s editors should be dismissed—not thanked profusely in the forward. | |||
160 | ERROR | When following “Transformation: Take First n Items” , page 160, calling last(count) method fails in compilation: mix test warning: variable “list” does not exist and is being expanded to “list()”, please use parentheses to remove the ambiguity or change the variable name Compilation error in file lib/issues/cli.ex (CompileError) lib/issues/cli.ex:29: undefined function count/0 | |||
164 | ERROR | Run app locally fails to have the results formatted. Instead, when running “./issues pragdave earmark 4” I’m getting the following error and results: (Protocol.UndefinedError) protocol Enumerable not implemented for | |||
156 | SUGGEST | In the first paragraph of text up from the bottom of the page, the book says, We also have to deal with the possible error response from the fetch, so back in the CLI module we write a function…. First, there is only one error response we are dealing with, so there is no “also” error. The text makes it seem like there is an additional error that we have to deal with. Second, the error response is not from the fetch(). HTTPoison does not return a response tuple that contains :error, e.g. {:error, body}, nor does the Github APi—rather our code returns the :error tuple in handle_response(). handle_response() returns an :error tuple anytime the response from HTTPoison has a status code that is not 200, and the status code can easily be seen in the %HTTPoison.Response{} struct. Now, it is true that fetch() calls handle_response() so the :error tuple ends up being returned by handle_response() to fetch() and then fetch() returns the :error tuple, but simply saying that fetch() returns the :error tuple had me digging through the HTTPoison docs and the Github API trying to discover when either of them returned an error tuple. I think the project is too convoluted and confusing. It’s not always best to write the most efficient code when explaining something to beginners. For instance, dividing the code up into 3 functions, just makes the code harder to follow. Writing less efficient code that is simpler to follow is always better. Here is my suggested rewrite of the paragraph quoted at the top of this suggestion: Now we have to deal with the possible error tuple returned by the handle_response() function, which is returned to fetch(), so back in the CLI module in the process() function where fetch() is called we write a function… Even that rewrite sounds convoluted, but at least it describes the path that the execution follows. | |||
137 | SUGGEST | In the last two code examples on this page, the code does this: dave = %{….} case dave do and: dave = %{….} case dave do There is no reason to introduce the person variable. The dave variable is in scope, and the person variable cannot be anyone other than dave. So, the IO.puts statements can simple be: IO.puts “#{dave.name} lives in #{some_state}” Or, change the name of the dave variable to person to create some suspense: person = %{ name: “Dave”, state: “TX”, age: 27} case person do | |||
152 | ERROR | > In this case, we give the version as “~> 1.0.0”. This matches any version of HTTPoison with a major version of 1 and a minor version of 0 or greater. In IEx, type h Version for more details. I am not sure if this is correct. I followed the book and used { :httpoison, “~> 1.0.0”} as a dependency but mix deps.get pulled in httpoison 1.0.0 and not 1.2.0. stefan@arentz.ca | |||
160 | SUGGEST | The second def from the top of the page is the definition of the function last(), which by the way is the worst name for that function that I can think of besides xYzT(). The last line of the definition of last() does this: |> Enum.reverse There is absolutely no reason to reverse the n most recent issues. No one in their right mind would ever suggest printing a table with the n most recent issues—then sneakily reversing their order to leave the reader of the table bewildered. What the code should present is the n most recent issues with the most recent issue being the first line in the table. Right minded people can understand that ordering. | |||
161 | SUGGEST | I guess beginners to Elixir are expected to know the Erlang format sequences. For anyone who doesn’t know Erlang, there is something that looks like a “typo” in the format_for() function: fn width -> “~-#{width}s” end If width is 10, then that function will create a string that looks like this: iex(11)> width = 10 iex(12)> “~-#{width}s” (That’s the characters tilde, dash, 10, and s) And in Erlang, you can format a string like this: 3> io:format(“|~–10s|~n”, [“hello”]). (I added the pipes to show the field width. The control sequence ~n represents the operating system’s version of a newline e.g. “\ The control sequence ~s prints the argument inside the list—the second argument to io:format()— as a string (instead of a list of character codes): 5> io:format(“~s~n”, [“hello”]). Compare to: 7> io:format(“~w~n”, [“hello”]). For the control sequence ~s, you can also specify the field width (right justified by default): 10> io:format(“|~10s|~n”, [“hello”]). And, if you specify a minus sign, then the string will be left justified: 11> io:format(“|~–10s|~n”, [“hello”]). As a result, the format_for() function on p. 161 creates a bunch of formatting control sequences for the Erlang function io:format/2, which can be accessed in Elixir by calling :io.format(). This chapter was supposed to teach us how to organize a project—not write code that could win an obfuscation contest. A project that contained some simple code, perhaps demonstrating some Elixir idioms, that depended on a few modules and some configuration would have been more instructive. | |||
156 | SUGGEST | In my earlier errata for this page, I stated: Second, the error response is not from the fetch(). HTTPoison does not return a response tuple that contains :error, e.g. {:error, body}, nor does the Github API… That is incorrect—but the code in the book assumes that that statement is true because the definition of handle_response() on p. 156 has been reduced to a single function clause that cannot handle an error tuple returned by HTTPoison. I got the following HTTPoison error when I turned my wifi off:
The following arguments were given to Issues.GithubIssues.handle_response/1: # 1 Attempted function clauses (showing 1 out of 1): def handle_response({_, %{status_code: status_code, body: body}}) (issues) lib/issues/github_issues.ex:29: Issues.GithubIssues.handle_response/1 The function clause error is pretty cryptic, so I added another handle_response() def that will eventually cause the book’s code to output the HTTPoison error: def handle_response({:error, httpoison_error}) do That additional function clause creates the necessary tuple for decode_response() to output the error message from HTTPoison. | |||
160 | ERROR | At the bottom of the page there is some code: def print_table_for_columns(rows, headers) do end As far as I can tell, that is a superfluous use of “with”. There would be no difference in scope for the with variables if the code was written as follows: def print_table_for_columns(rows, headers) do
| |||
161 | ERROR | At the bottom of the page is a code listing with this line: import ExUnit.CaptureIO #And allow us to capture stuff sent to stdout The comment is false. We still would be able to capture stuff sent to stdout without the import statement. All the import statement does is allow us to call the functions defined in the ExUnit.CaptureIO without having to qualify them with the module name: ExUnit.CaputureIO.some_func() v. some_func() Although the book hasn’t covered macros yet, I believe the use statement: use ExUnit.Case performs some black magic that inserts the test functions into the current scope. | |||
160 | SUGGEST | Here’s what I would consider a much simpler version of the Issues.TableFormatter module. My interface allows the user to specify both the header and width of a column: def process_args({user, project, count}) do I also added the curtail module to my project as a dependency. The curtail module allows you to shorten text to fit into a specified column width, which is useful to shorten the issue’s title to fit in the specified column width. The curtail module has a few quirks, and to get curtail to truncate the strings correctly, I had to specify width+3. You’ll have to play around with curtail in iex to see how it works (also check out the omission: parameter). defmodule Issues.TableFormatter do def print_table(issues, fields_and_widths) do def print_headers(fields_and_widths) do header1 |> Enum.join(“|”) |> IO.puts def print_rows(issues, fields_and_widths) do def print_row(issue, fields_and_widths) do end The book uses keyword lists for the test data, which seems like an error to me because the issues returned from github are maps, so I used maps for my test data. Also, the book’s test data uses atoms for the keys (as required for keyword lists) and the test data doesn’t use any numbers for the values, yet the maps returned by github have strings for keys and some of the values are integers. I adjusted my test data to account for that. Here are my tests: defmodule TableFormatterTest do @simple_test_data [ @fields_and_widths [ test “print_headers()” do assert result == “”" test “print_row()” do assert result == “”" test “print_rows()” do assert result == “”" end One thing you have to be careful about is getting the correct number of trailing spaces for the “assert result ==” comparisons. In my tests, the last column has a specified width of 12, so I added enough spaces at the end of each line to make the last column 12 characters wide. | |||
289 | ERROR | In the code sample for “otp-app/sequence_v2/lib/sequence/server.ex”: But here, the “current_number” should be the state struct instead of the previous version. Hence, if only need to preserve the current_number, it should not send whole state to Stash. The code should be changed to: def terminate(_reason, state) do | |||
171 | ERROR | The command pry> continue() …ends up freezing iex. According to the docs: — I guess if there are no more breakpoints, like in the example code, the iex shell freezes, and therefore to get a new iex shell, you need to call respawn() rather than continue(). | |||
181 | TYPO | After the code example at the top of the page, the second sentence says: We have to include use ExCheck at the top to include the property test framework. But there is no “include ExCheck” statement in the code. | |||
326 | TYPO | The code snipet in the explanation for Exercise:LinkingModules-BehavioursAndUse-1, the function name dump_dfn should be dump_defn to be consistent with the code above. | |||
203 | SUGGEST | In my opinion, this is a much clearer Chain example: defmodule Chain do def create_processes(n) do def create_processes(prev_pid, 1) do end defmodule Test do receive do end def timeit(n) do Using the Enum.reduce() trick just servers to obfuscate the code. If you run the example above with n=10, you’ll see the output: iex(3)> c “chain.exs” iex(4)> Test.go(10) The output is proof that the processes are being created. Who knows if the processes are actually being created in the book’s example? Then, if you comment out the statement: IO.puts “process ##{num} saying hi (#{inspect self()})” you can run the timeit() function from the command line and see how long it takes to create n processes: ~/elixir_programs$ elixir -r chain.exs -e “Test.timeit(10)” ~/elixir_programs$ elixir -r chain.exs -e “Test.timeit(100)” ~/elixir_programs$ elixir -r chain.exs -e “Test.timeit(1_000)” ~/elixir_programs$ elixir -r chain.exs -e “Test.timeit(10_000)” ~/elixir_programs$ elixir -r chain.exs -e “Test.timeit(400_000)” 21:13:36.313 [error] Too many processes (SystemLimitError) a system limit has been reached ~/elixir_programs$ elixir —erl “+P 1000000” -r chain.exs -e “Test.timeit(400_000)” ~/elixir_programs$ elixir —erl “+P 1000000” -r chain.exs -e “Test.timeit(1_000_000)” If you are wondering why the count is always n+1, that also happens with the books example—it’s just that the book cheats and send()’s 0 to the last process. The code creates n processes — in addition to the main process — so there are n+1 total processes receiving a message. | |||
81 | SUGGEST | The exercise description is vague enough that I was unable to understand what it was asking me to do; consider rewording this exercise to make it clearer, please. | |||
208 | SUGGEST | The first line of text after the code example says, This time we see an :EXIT message when the spawned process terminates. Well, I saw an :EXIT message when the spawned process terminated and the process WASN’T trapping exits—which is shown in the last line on p. 207. The text should read: This time we “receive” an :EXIT message when the spawned process terminates. But, then again, “we” aren’t receiving anything, so even better would be: This time “the main process received” an :EXIT message when the spawned process “terminated”. | |||
168 | SUGGEST | The exercise at the bottom of p. 168 instructs us to parse the hourly weather data from (omitted link here), but the xml contains only one observation, so unlike in the book where we got the last N issues from github, there is no way to get the last N weather observations in xml. There is a link you can click to get a 2-day history of observations, but that is presented in html—not xml. | |||
240 | ERROR | This page says “Even though we’ve recompiled the code, the old version is still running. The VM doesn’t hot-swap code until you explicitly access it by module name.”. But for me the new code worked without having to create a new server | |||
358 | TYPO | “Exceptions in Elixir are basically records” Shouldn’t it be “Exceptions in Elixir are basically structs”? | |||
363 | TYPO | In the 2nd paragraph tuple(atom,integer} should be tuple(atom,integer) | |||
167 | ERROR | Trying to run ‘mix docs’ using Elixir v1.7.3 produced this error: (RuntimeError) module Issues.CLI. was not compiled with flag —d This appears to be due to a version incompatibility. The ExDoc docs suggest that Elixir versions 1.7 and up require ex_doc version 0.19. Updating the dependency fixes the issue: { :ex_doc, “~> 0.19”, only: :dev, runtime: false } | |||
181 | TYPO | “We have to include use ExCheck at the top to include the property test framework.” Seems this should be ExUnitProperties, as in the preceding code example. | |||
284 | ERROR | “mix release” fails on Elixir 1.7.3 when distillery is set to the recommended version (“1.5“). Changing the dependency to ”>2.0” fixes the problem. | |||
164 | ERROR | The command to run the generated `issues` escript is incorrect for windows. First, the generated file is not an executable (console) application. It is an “escript application” (as determined by the cygwin “file” command). This will not run from the commandline. The way to execute the resulting file is: escript issues … | |||
99 | ERROR | The link in the footnote does not work. I guess you meant https :// elixir-lang .org/ docs.html ? (without the blanks) | |||
80 | 69 | TYPO | At the bottom of the page, when showing the link to Elixir documentation, the current link gives 404. It says: “4. (…)elixir-lang.org/docs/”, but should say “4. (…)elixir-lang.org/docs” or even “4. (…)elixir-lang.org/docs.html” (I cant write the url complete, because to prevent spam, the hyperlinks are not allowed here. | ||
179 | TYPO | The link to ExUnit docs is not valid and broken (returns 404). | |||
166 | SUGGEST | After adding some logging to github_issues.ex, a reader is invited to play with the new code in IEx: iex> Issues.CLI.process {“pragdave”, “earmark”, 1} In this case, no matter where you are in your terminal (on the issues root, or in ‘../issues/lib/issues’, you will get an error: (UndefinedFunctionError) function Issues.CLI.process/1 is undefined (module Issues.CLI is not available) What is wrong with that? Where a reader should navigate (cd) in his/her terminal to run the above command? | |||
167 | ERROR | Whenever you run mix command, you will get a warning: warning: function Poison.Parser.parse!/1 is undefined or private. Did you mean one of: * parse!/2 lib/issues/github_issues.ex:29 I downloaded the code source and to the latest version of github_issues.ex file. Maybe the error is due to the versions of “poison” (4.0) and “httppoison” (1.5) packages I use ? Thank you | |||
1363 | TYPO | In both the Kindle version of the book and the code example online (basic-types/with-scope.exs): [_, uid, gid] = Regex.run(~r/^lp:.*?:(\\d):(\\d)/m, content) An underscore is missing. It should be: [_, uid, gid] = Regex.run(~r/^_lp:.*?:(\\d):(\\d)/m, content) | |||
131 | TYPO | Exercise: StringsAndBinaries-7 | |||
354 | TYPO | “But if we simply run this in the apps/evaluator directort,” should be “But if we simply run this in the apps/evaluator directory,” The keys are, like, right next to each other. | |||
216 | SUGGEST | There is really no need to introduce Agent code here just to make the fibonacci code more performant. | |||
156 | ERROR | Shouldn’t the “decode_response” function should be using the “defp” declaration? The same page uses “defp” for the “check_for_error” function. It does not seem like it will be used outside the module later on. | |||
82 | ERROR | The code snippet to add a hashed password to each of the three users that are in the database has some errors. The code will not work unless the user also runs “alias Rumbl.Accounts.User” and the Repo.update! command is missing a parenthesis at the end. | |||
181 | TYPO | After the example code tooling/pbt/test/stats_property_test.exs the narrative describing the code says “We have to include use ExCheck at the top to include the property test framework.” However the code example does not have a use ExCheck line. | |||
99 | TYPO | Link to Elixir docs in the page footer is broken, gives a 404 not found. | |||
144 | ERROR | Newer versions of “mix new” (e.g. 1.9.2) no longer create the “config” directory. | |||
92 | TYPO | The actor’s last name - Elwes - is spelled correctly where it is meant to be spelled incorrectly. The example is meant to begin with a typo and then show it being updated to be correct, but in fact it is already correct and the update does not make any change. | |||
325 | ERROR | Mix.Config is deprecated as of v1.9, in favor of Config.Reader As well, config directory is no longer automatically generated for new projects by “mix new”. Update text with instructions to to create import Config | |||
18 | SUGGEST | This applies to all of the “Your Turn” sections. Since your response to FOSTA-SESTA renders the help links like “Exercise: PatternMatching-1” useless to the reader, please consider an update simply linking to answers to the helpful questions, fulfilling their helpfulness. In this context, answers are actually the default expectation (granted, linking to a help forum is/was a cool idea). Also, thanks for the great advocacy tip — I’ll contact my senator as suggested. Cheers! | |||
51 | 39 | ERROR | The last example on page 39 doesn’t seem to work with Elixir 1.10. However, it /does/ work if you switch to using the short-form do. iex(66)> mean = with( (CompileError) iex:70: undefined function sum/0 /vs/ iex(69)> mean = with( | ||
84/95 | 84 | ERROR | Any link throughout the book to elixir-lang.org/docs is probably broken. In general, they can be replaced with https :// hexdocs. pm /elixir/Whatever.html (without the spaces). | ||
112 | 102 | ERROR | In the top code block on page 102 you use chunk/2, but that has since been deprecated and should be replaced with chunk_every/2. | ||
121 | 111 | ERROR | Enum.into generates a deprecation warning when used with a non-empty collection. | ||
155 | ERROR | The block of JSON returned by Issues.GithubIssues.fetch(“elixir-lang”, “elixir”) should be a string instead of JSON. In other words, like this: | |||
173 | TYPO | for IEx.break/4. should be for IEx.break!/4. (with the ! ) | |||
197 | ERROR | In the 4th paragraph you use code styling/formatting for the words “spawn” and “receive”. You probably want to use it for the word “send” as well. | |||
49 | 37 | ERROR | The code do not work as described on Elixir 1.7+ due to a breaking change on the language. On Elixir 1.7+ it will print 50 instead of 0. The warning will not be the same as the one in the book and will depend on the specific version, but none will give the useful warning talking about shadowing, complaining only about unused variables and the such. Reference: Issue 8076 of Elixir official repository on GitHub PS: It is Elixir’s fault, give it broke semantic versioning, but if you do not change it, the confusion will keep spreading. |