Effective Scala: Programming Patterns
-
Upload
vasil-remeniuk -
Category
Technology
-
view
7.258 -
download
1
Transcript of Effective Scala: Programming Patterns
![Page 1: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/1.jpg)
Effective ScalaProgramming Patterns
![Page 2: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/2.jpg)
The most of the patterns you've got used to in a traditional OO-languages (C++, Java, C#) are just language constructs in a functional languages
![Page 3: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/3.jpg)
The key principle behind the most of techniques is functional languages is composition - ability to build assets that can be reused in different contexts unknown at the time they created
![Page 4: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/4.jpg)
Pimp My Library
![Page 5: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/5.jpg)
What if you wanted to add new method for Int?In Java you would write a wrapper class and use it everywhere you want your new Int on steroids.
In Scala you would use implicit conversions.
object RichInt { implicit def intToRichInt(i: Int) = new RichInt(i) }
class RichInt(private val value: Int) { def minutes = value + " minutes" }
// Usage exampleimport RichInt._ println(10 minutes) //println(intToRichInt(10).minutes)
![Page 6: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/6.jpg)
Pimp My Library
● Simple● Less boilerplate then ad-hoc conversion● Can be controlled with scoping
![Page 7: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/7.jpg)
CellGuess who's an evil twin
![Page 8: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/8.jpg)
Cell is an object behaving closely like a normal variableImplementation details are hidden from end user
Scala has two features in possesion helping us to implement such a semi-variable:
1. "First class object" functions
2. Syntactic sugar for update and applyx() == x.apply()andx(<arguments>*) = y == x.update(<arguments>*, y)
var f: Option[() => Int] = Some(() => 1)
![Page 9: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/9.jpg)
Let's design lazy value using Cell patternclass Lazy[T] { private var v: Option[T] = None private var t: Option[() => T] = None def update(t: => T) { this.t = Some(t _) v = None } def apply() = { if(v.isEmpty) v = Some(t.get()) v.get } } val l = new Lazy[Int] l() = { println("Evaluated"); 1} println("Before evaluated") println(l()) l() = 2 println(l())
![Page 10: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/10.jpg)
Cell actually is
● Simple once again● Used similar to a variable thanks to syntactic sugar● Still an object
![Page 11: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/11.jpg)
Type class
![Page 12: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/12.jpg)
Unified factoryimport java.util.Date trait Vendor[T] { def vend: T } implicit object DateVendor extends Vendor[Date] { def vend = new Date } object Vendor { def vend[T](implicit vendor: Vendor[T]):T = vendor.vend } val date = Vendor.vend[Date]
This guy is like a one man band.Tell him a type you wanna play with and he'll hand you off an instance.
![Page 13: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/13.jpg)
Type class
● Extendable through composition● Abstracts capabilities from data● Connects different class hierarchies together● Controlable with scoping
![Page 14: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/14.jpg)
Duck typing
![Page 15: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/15.jpg)
OMG, we're in J2EE environment
class DBDriver class Bean { private var driver: DBDriver = null def getDriver() = driver def setDriver(driver:DBDriver) { this.driver = driver } } class AnotherBeanFromAnotherParty { private var driver: DBDriver = null def getDriver() = driver def setDriver(driver:DBDriver) { this.driver = driver } } object Bean extends Bean { setDriver(new DBDriver) } object AnotherBeanFromAnotherParty extends AnotherBeanFromAnotherParty { setDriver(new DBDriver) }
Following dreaded pattern can often be seen in IOC container environment(well at least when it's a bad one)
Here is how we work this around with structural typingdef extractDriver(bean: { def getDriver(): DBDriver }): DBDriver = bean.getDriver() extractDriver(Bean) extractDriver(AnotherBeanFromAnotherParty)
![Page 16: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/16.jpg)
Structural typing
● Actually a workaround for poorly designed architecture● A typesafe workaround● Follows don't repeat yourself
![Page 17: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/17.jpg)
Cake Pattern
![Page 18: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/18.jpg)
..."Dependency Injection" is a 25-dollar term for a 5-cent concept... Dependency injection means giving an object its instance variables...
James Shore
![Page 19: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/19.jpg)
What do you need dependency injection for?● reduces coupling between
components● simplifies configuration of an
assembly○ useful for unit testing
![Page 20: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/20.jpg)
IoC containers take a simple, elegant, and useful concept, and make it something you have to study for two days with a 200-page manual
Joel Spolsky
![Page 21: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/21.jpg)
● in Scala you don't need any DI framework - forget Spring and Guice
● you make DI with mixins & self-type annotations and no boilerplate
![Page 22: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/22.jpg)
Some code...http://goo.gl/dWh2i
![Page 23: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/23.jpg)
What's so cool in Cake pattern?
● It's not a framework, thus any IDE supports it out-of-box
● If a dependency is missing, compiler will immediately let you know about it
![Page 24: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/24.jpg)
Phantom Types
![Page 25: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/25.jpg)
The brain of an average human is used by only 10% through the lifetime
The type system is used by an average programmer by only 10% of its power
![Page 26: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/26.jpg)
● never instantiated● used only to construct other
types
Phantom types is a simple yet powerful way to use the type system more effectively
2 facts about phantom types:
![Page 27: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/27.jpg)
Let's say, we need a data type to represent the form data extracted from an HTTP request:
case class FormData[+T <: Data](data: Map[String, String])
trait Datatrait Validated extends Datatrait Unvalidated extends Data
Validated and Unvalidated are phantom types
![Page 28: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/28.jpg)
trait Form { val readFormData: HttpServletRequest => FormData[Unvalidated]
val validate: FormData[Unvalidated] => FormData[Validated]
val printFormData: FormData[Validated] => Any}
(readFormData andThen validate andThen printFormData)(request)
(readFormData andThen printFormData)(request) // FAILS!!!
![Page 29: Effective Scala: Programming Patterns](https://reader031.fdocuments.us/reader031/viewer/2022020101/556491b7d8b42a5f6c8b4e84/html5/thumbnails/29.jpg)
Some code...http://goo.gl/QAwB3