Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Learning from "Effective Scala"

2 437 vues

Publié le


Publié dans : Technologie
  • Soyez le premier à commenter

Learning from "Effective Scala"

  1. 1. Learning from“Effective Scala” #akskscala 38Scala study group at Akasaka, Tokyo, Japan Kazuhiro Sera @seratch
  2. 2. Effective Scala?• http://twitter.github.com/effectivescala/• Best practices from Twitter engineers• Creative Commons BY 3.0 License• Japanese version is also available (great work by @okapies and @scova0731)
  3. 3. Introduction• A short essay that provides a set of best practices• Libraries from Twitter - Finagle, Ostrich, Util, Gizzard, Scalding and more...• Program in Scala, you’re not writing Java, nor Haskell, nor Python• Assumes the reader is familiar with Scala
  4. 4. Formatting 1• Consistent application of the same formatting rules will enhance readability• Particular importance to Scala because its grammar has a high degree of overwrap• Scala Style Guide and some additional rules
  5. 5. Formatting 2• Indent: 2spaces, Straight-line length: 100• External APIs should have longer and explanatory names• Use val (= don’t rebind names)• Avoid using ` to overload reserved names• Active names for ops with side effects
  6. 6. Formatting 3• Getters without `get` prefix• Don’t repeat names that are already encapsulated - e.g. User.getUser(123)• Wildcard import for more than 6 names• Don’t use relative imports• Put imports at the top (in one place)
  7. 7. Formatting 4• Avoid using braces for simple expressions• Use PartialFunction if possible• Comments to explain the behavior of your code are bad sign• Prefer “Obviously it works” to “it works, obviously” and restructure so
  8. 8. Types and Generics 1• Fascinating but avoid type level programming in production code• Use explicit return type annotations for public methods• Immutable collections should be covariant• Mutable collections should be invariant
  9. 9. Types and Generics 2• Use type alias for convenient naming or clarify purpose• Don’t subclassing when an alias will do• Using implicits sparingly• Ask yourself if there is a way to achieve the same thing without implicits• “Pimp my library” pattern - e.g. RichInt
  10. 10. Collections 1• Should read “collections design document”• Prefer using immutable collections• Use “mutable” namespace explicitly• Receive the most generic collection type appropriate in methods/constructors (Iterable, Seq, Set, Map ...)
  11. 11. Collections 2• Pipelining transformations leads to very succinct solutions but can also be confusing to the reader• “val votesByLang = votes groupBy { case (lang, _) => lang }” instead of just “groupBy(_._1) “• If you worry about namespace pollution, group expressions with {}
  12. 12. Collections 3• Read “Performance Characterisitics”• Use profiler (e.g.YourKit Java Profiler)• Use arrays instead of lists for large sequences• Use buffers when performance matters• Not JavaConversions but JavaConverters
  13. 13. Concurrency• Use Futures to manage concurrency• Futures are declarative, composable and have principled handling of failures• Prefer Future combinators (com.twitter.util.Future.join/collect)• Reach for a concurrent collection after trying with a synchronized collection
  14. 14. Control structures 1• Declarative style, more expression-oriented• Recursion makes your programs simple• Starts with a well-defined clean slate, no reference cells and invariants abound• Check the tail call optimization application by the @tailrec annotation
  15. 15. Control structures 2• Use returns to cut down branching and establish invariants• Avoid using returns as you would do in imperative languages• Avoid using returns inside of a closure because of hidden costs
  16. 16. Control structures 3• for-comprehensions provides succinct and natural expressions• Demerit: hidden costs to allocate and dispatch closures and unexpected semantics• require/assert are useful when the type system cannot express the required invariants
  17. 17. Functional programming 1• Value oriented programming (emphasizes the transformation of values over stateful mutation)• Referentially transparent, stronger invaliants• case classes as ADT(Algebraic Data Type)s
  18. 18. Functional programming 2• Option type is a container which provides a safe alternative to the use of null• Use “opt foreach { v => }” or pattern matching or getOrElse instead of “if(opt.isDefined) opt.get”• Use Option(v) instead of Some(v)
  19. 19. Functional programming 3• Might be more composability with a PartialFunction than returning an Option• Destructuring bindings are particularly useful for tuples and case classes• Lazy fields compute and memorizes a result• Should make the cost model explicit and precisely control side-effects
  20. 20. Functional programming 4• Use call-by-name only to construct natural DSLs (control constructs)• Use call-by-name only in the last position of the last argument list• Use explicit functions for multiple times execution or side-effecting
  21. 21. Object oriented programming 1• Dependency Injection by typically defining trait and subclassing• Injecting factories by using simple functions• Keep traits short and orthogonal - e.g. Reader/Writer instead of IOer
  22. 22. Object oriented programming 2• private[this] can aid performance optimizations• Constrain visibility of singleton class types - e.g. def foo(): Foo = new Foo with Bar {}• Don’t use structural types in normal use
  23. 23. Garbage collection• Functional Scala code tends to generate more short-lived garbage than Java• Don’t act without data, use profiling tools - e.g. heapster, gcprof
  24. 24. Java compatibility• Sometimes your Scala code is not directly usable from Java (traits that contain implementation, collections, functions...)• Sometimes need to separate Java APIs• Write unit tests in Java
  25. 25. Twitter’s standard libraries 1• Util: an extension to the Scala and Java standard libraries• Finagle: RPC system - the kernel distributed systems components
  26. 26. Twitter’s standard libraries 2• Future - a simple container(a type of collection) which hold the promise for the result of a computation which is not yet complete• 3 states: pending, failed or completed• Future#flatMap is useful to define composite operations
  27. 27. Twitter’s standard libraries 3• Use callbacks(onSuccess) instead of foreach• Future.value(), exception() creates pre- satisfied Futures• Future.collect(), join() provide combinators that turn futures into one• Future#cancel from consumers is propagated to its producer