(Ok, I said I was going to post every issue in it's own thread, but these are just so small it makes more sense to group them)

Chapter 2 looks great. There are a few points I'd like to raise though:

1. In "2.4.2 Atoms" you describe atoms as similar to symbols in Ruby and enumerations in C/C++. I disagree with the C/C++ part. Atoms don't need to be predeclared and don't map to integers, furthermore atoms with a different name are automatically different. Enumerations on the other hand are more like constants wrapped in a type.

2. In "2.4.5 Immutability" under "Benefits" you say "This in turn makes it possible to perform atomic in-memory operations". I'm not sure "atomic" is the word you are looking for. Atomic refers to making a change that's not observable from the outside, it's either version A or version B but no half-A half-B. However you are not changing anything, you are rebinding. There is no concept of commit or rollback since there is no actual change, only function returning. I understand what you're trying to say but this seems to be a confusing use of terminology.

3. In "2.4.7 Strings" under "Character Lists" you say "In this case, you can convert a binary string to a character list version using the Kernel.to_char_list/1 function. Isn't `String.to_char_list!/1` more appropriate here? It's more explicit about exceptions and avoids calling the List.Chars protocol.

4. In "2.7 Summary" you say "There is no nullability. Atom nil can be used for this purpose.". I'm not quite sure about the terminology but it seems to me that this is effectively nullability.

What you're saying is definitely true, but I must think about whether to change the text or not. If I mention a "named function", then a reader might wonder what kind of other functions exist, so I would have to expand on this as well.

Perhaps it would be better to make this remark later in the chapter, when anonymous functions are introduced.