Skip to content

Instantly share code, notes, and snippets.

@lucperkins
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucperkins/0883be60d150037f4a4b to your computer and use it in GitHub Desktop.
Save lucperkins/0883be60d150037f4a4b to your computer and use it in GitHub Desktop.
Feedback on Learning Scala (for Jason Swartz)

Learning Scala Feedback

Chapter 1

  • Instructions to install Java 7 followed by a java -version command that yields Java 8 is a bit odd. I'd recommend providing sample output for Java 7 instead.
  • Might be a good idea to provide example commands for installing via Homebrew, yum, apt-get, etc.
  • For code snippets inside of paragraphs, it's always helpful IMHO to distinguish the code bits from the ordinary language bits. /usr/local in the middle of a paragraph always comes across as more clear than /usr/local.
  • You should also provide instructions on adding directories to PATH, restarting the shell, and checking to make sure that the directory has been added, i.e. echo $PATH. I know that's super basic stuff, but the install guide should be the most dumbed down part of the book. Experienced users will know to skip over this.
  • I see later on, on page 5, that "println()" is in a code-specific font, as it should be. Make sure to keep this consistent. I see this pop up in a variety of places throughout the book, and might not always be caught by editors later.
  • I think that it's great to start out by going straight to the REPL, so that readers can instantly get a concrete, hands-on feel, as well as a sense of accomplishment. More books should do the same!

Chapter 2

  • When defining variables, you should explicitly use the word "mutable" to make the distinction from values clear. "Reassigned data over and over again" is good but doesn't quite do enough.

  • When you say that vals can be redefined in the REPL on p. 9, the example assignments after that paragraph, e.g. val x = 20, should reflect that. I'd recommend providing new assignments, e.g. val x = 10, val greeting = "Something or other", etc.

  • "a discretion left up to developers" (p. 10) should be "left to the developer's discretion"

  • You should point out that using uppercase letters for class, trait, and type names is not mandatory, but rather considered best practice, enhances readability for other devs, etc.

  • The term type inference should first be introduced in the discussions of vals rather than in the discussion on vars

  • I like this section on the type hierarchy. This would've saved me a lot of grief over the years!

  • You make it explicit in the section on variables that best practices call for values over variables in most situations, and the discussion there is good. It might be worthwhile, though, to make a a brief note of it in the section on values.

  • I'm a bit torn between thinking you should expand the regex section to be a bit more full and agreeing on your approach to keep it short and defer to the Java documentation. I suppose it depends on how necessary a regex understanding will be later on in the book, which I will soon find out!

  • The explanation of Nothing versus Null is good, but I would suggest saying something more about the relationship with null in Java, because that's something that's always a big sticking point and thorn in Java. I honestly don't know much about Null in Scala, so I don't have any concrete suggestions about what to do here, but this strikes me as something that Java devs will want to know more about. Are there NullPointerExceptions in Scala? Does Scala deal with null differently? This chapter may be a good place for that discussion. Or if there's a section on Null later, make note of that and indicate where more info can be found.

  • I see two uses of the term "scalar" on page 22/23. I think this term needs explanation (especially given that some less knowledgeable types may think that scalar is somehow particular to Scala the language).

  • In the note on p. 24, I find the to<type> construction awkward. I'm not sure what to replace it with, though.

  • There's no closing parenthesis in the example tuple on p. 24. Should be:

    ( <value 1>, <value 2>[, <value 3>...] )
  • On page 25, the code examples have -> while the text has . That should be made consistent.

Chapter 3

  • I think it's hugely important that blocks are also scopes. I'd suggest making a bigger deal out of that.
  • This sentence on page 35 should be more clear: "However, since the input to the match expression can be accessed anywhere in the match expression, having a named value that equals the input is usually not a necessity."
  • Boolean should be capitalized everywhere. It's a happy coincidence that Boolean is capitalized in Scala as well. The mismatch between writing "boolean expression" and having Boolean in code samples is minor but could be easily fixed.
  • On page 38, I think it's perfectly okay to introduce the Vector type, but you should make it clear that the reader doesn't need to worry about understanding it at this point
  • You should include a brief note that <- means something like "contained within"
  • Value binding in for loops is really powerful and, I think, underdiscussed. It'd be great to see one extra simple example to hammer it home a bit.

Chapter 4

  • At the beginning of this chapter, I think it might be best to either provide a brief explanation of MapReduce or not include a mention of it, as some readers might interpret it as something they need to know rather than as an off-hand reference
  • In a few places a familiarity with string formatting is presupposed, as on page 48: def log(d: Double) = println(f"Got value $d%.2f"). I'd recommend either explaining what's going on there or simplifying the examples.
  • The recursive function example you give is totally fine, but any reason why Fibonacci wasn't chosen? It should be immediately familiar to most devs and might be a good opportunity to use pattern matching.
  • I would recommend mentioning somewhere that vars or vals can be function inputs.
  • You mention method overloading briefly in passing on p. 52 and 53, but I think that it's widely used enough to deserve its own brief section in this chapter.
  • You should mention the term "generics" somewhere because that will form an immediate conceptual bridge for those who aren't familiar with the expression "type parameters." The section on type parameters is great, but it would have even better to see "generics" right off the bat.

Chapter 5

  • When describing declarative programming, it would be helpful to drawn an analogy to interfaces
  • Perhaps draw a comparison to Haskell when discussing function type syntax
  • You should also mention currying at some point. Because this chapter is so conceptual, provide as many bridges as possible to things that some readers might already know.
  • This statement on p. 70 could use some clarification: "When you pass a function to a by-name pa‐ rameter, make sure that you understand any cost of repeated accesses of your function." I have a sense of what those costs might mean, but develop that thought some more.
  • The "Partial Functions" section on p. 71/72 leaves us hanging a little bit because it suggests that partial functions are more useful with collections. A brief example using, say, a List would be useful, although it might be a bit early in the book for dealing with collections.

Chapter 6

  • In fairness to Java, you should point out that a lot of the map/reduce/filter-style operations available in Scala are available in Java 8, though they are not as elegant :)

  • Flesh out what a reduce() function does a little bit further. I couldn't quite figure it out on the first pass. I would suggest this: "reduce() takes a function that is performed on members of the list in an iterative fashion, resulting in a single element" or something along those lines.

  • On page 80, the symbol is used in the normal text, while -> is used in code samples. This should be made consistent.

  • On page 81, you mention in passing that lists are zero-indexed. You might want to make it clear earlier in the chapter that all Scala collections (as far as I know) are zero-indexed. Most readers will assume that they are given that virtually all widely used modern languages have zero-indexed collections, but still worth noting, I think.

  • The collect/flatMap/map table (6-2) has solid explanations, but I think this section would be more helpful if you displayed the results of the example operations. In table 6-1 I think it's okay to not include the results of the example operations because the operations are far more simple. But I know that flatMap is particularly tricky and not as immediately intuitive as map or filter or sortBy, to give just a few examples.

  • On page 89, it's not clear in the REPL sample that the boolReduce function should return a Boolean. It looks half that line may have been accidentally left off. It seems like the line should be

    def boolReduce(l: List[Int], start: Boolean)(f: (Boolean, Int) => Boolean): boolean = {
  • I know that it might be somewhat unavoidable given size constraints, but there are occasional line breaks in tables that should be avoided at all costs, especially when it involves reserved terms and code snippets. In table 6-5, for example, reduceRight should be on a single line but it's broken up into reduce and Right on separate lines. Astute readers will know what's going on, but it can still occasionally be jarring. It might be a norm in O'Reilly books, however, that that's okay. I'm not sure.

  • In the code sample at the top of p. 95, it's not clear to me what the case x :: xs syntax means. Could use a brief explanation.

Chapter 7

  • For those familiar with FP concepts, a quick note drawing an analogy between Options and Haskell's Maybe might be helpful (I imagine there might be similar concepts in other languages as well), e.g. operation match { case Some(x) => x; case None => y }
  • You use some operations on Maps early in this chapter, such as removing a key/value pair using the - operator, that would be nice to have in the section on Maps in the previous chapter.
  • Using pattern matching with Option is, in my opinion, one of the best things in Scala. Providing an example would round out this chapter very nicely, especially as pattern matching + Option is used so often in, for example, database interactions.
  • This chapter is phenomenal. I read it very carefully and have almost no criticism! Great introduction to difficult concepts.

Chapter 8

  • In the code example on page 133 (where you create val misc = List(new C, new A, new B)) it might help to demonstrate the class hierarchy a little more directly. Maybe something like this:

    val misc = List(new C, new A, new B)
    val as = misc filter (_.isInstanceOf[A]) // List(C, B, A)
    val bs = misc filter (_.isInstanceOf[B]) // List(C, B)
    val cs = misc filter (_.isInstanceOf[C]) // List(C)
  • The first paragraph on page 136 could use a brief example. It's not immediately clear to the reader how using this solves the problem that you (quite rightly) point out here. In fact, this might be a good chance to briefly explain how this works in Scala (or at least to mention that it works much like it does in Java).

  • The section on abstract classes could use a brief mention of how Scala's abstract classes relate to interfaces and abstract classes in Java. The differences are subtle but would be helpful to folks with a Java background.

  • In the section on lazy values, I'd include one sentence that makes it clear that vars absolutely cannot be lazy. The section makes it more or less clear, but might as well go all the way.

  • In the section on privacy control (beginning on page 149) you note that vals, vars, and defs can be marked as protected. You should also note that lazy vals and other types of var/val/defs can be protected/private/implicit/whatever as well.

  • I love the private variable example on p. 150! I plan on shamelessly stealing that example in the future...

  • I was about to be shocked that you don't bring up case classes. I'm glad you do immediately in the next chapter :)

Chapter 9

  • You should mention that there is a limit the number of allowable fields in a case class. I believe it's 22 or 23.
  • The paragraph on page 168 that begins "The process of linearization may seem odd" is similar to the paragraph on page 167 that begins "The process of taking an (sic) horizontal list." It feels to me like those two should be combined.
  • The "Isn't SBT Hard to Learn?" link on p. 174 doesn't seem to go anywhere.
  • For whatever reason, the footer on the very last page of this chapter (p. 184) says Chapter 0 instead of Chapter 9.

Chapter 10

  • I think it would help to mention a more easily recognizable use case for implicit classes. I know that lots of JSON and other data format libraries rely on them pretty heavily, enabling you to simply plop a helper object into a scope and conversion works like magic. No need to provide an example of this per se, just a mention.
  • This is another great chapter. One of the best things about this book is that the quality actually improves over the course of the book, which is welcome contrast to other books that seem to have later paragraphs tacked on at the last minute.

General Comments

  • First off, great stuff! Very readable and lively, and a solid introduction. Hence the general nitpickiness of the comments.
  • I'm not sure how many more stages of editing lie ahead, but there were a lot of places in the text where code syntax should have been used instead of parentheses and other forms of syntax. In some cases this is okay but in others it's very confusing. If there are indeed later editing stages, fixing this should be a priority.
  • In general, I understand the desire to use generalized syntax to explain certain constructs, e.g. <identifier>: => <type>. In a lot of places, though, I found it more confusing than helpful. Scala is tricky here because it's so syntactically diverse. Perhaps consider removing these altogether? Or jumping straight into real examples instead?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment