scala 2.10
DESCRIPTION
Presentation about new features of Scala 2.10. It was presented by Jakub Janeček at the May's Czech Scala Enthusiasts meetup held at Faculty of Information Technology in Prague.TRANSCRIPT
Scala 2.10
Czech Scala Enthusiasts May 28th 2013
Jakub Janeček
What does it bring?
Language Modularization
Language Modularization
• some features are confusing, “dangerous” or still experimental
Language Modularization
• some features are confusing, “dangerous” or still experimental
• since 2.10 they have to be explicitly enabled (otherwise warning or error is emitted)
Language Modularization
• some features are confusing, “dangerous” or still experimental
• since 2.10 they have to be explicitly enabled (otherwise warning or error is emitted)
• for example: – implicit conversions
Language Modularization
• some features are confusing, “dangerous” or still experimental
• since 2.10 they have to be explicitly enabled (otherwise warning or error is emitted)
• for example: – implicit conversions – macros
Example: Postfix Operators
List(1, 2, 3) reverse
Example: Postfix Operators
List(1, 2, 3) reverse
import language.postfixOps
Example: Postfix Operators
List(1, 2, 3) reverse
> scalac –language:postfixOps
What does it bring?
String Interpolation
String Interpolation
• Remember?
"1 + 1 = " + (1 + 1)
String Interpolation
• Remember?
"1 + 1 = " + (1 + 1)
• No more!
s"1 + 1 = ${1 + 1}"
String Interpolation
"1 + 1 = " + (1 + 1)
• No more!
s"1 + 1 = ${1 + 1}"
Standard interpolator We also have f and raw
Escape character
• Remember?
Example: Interpolator rev
def rev(args: Any*): String = … • Extension method of StringContext:
Example: Interpolator rev
def rev(args: Any*): String = …
rev”this will be reversed"
• Extension method of StringContext:
What does it bring?
“value”
Value Classes
Value Classes
• allow extends AnyVal
Value Classes
• allow extends AnyVal • compiler can usually avoid allocating runtime
objects à performance with type safety
Value Classes
• allow extends AnyVal • compiler can usually avoid allocating runtime
objects à performance with type safety • they have limitations
Example: MyInt
case class MyInt(val underlying: Int) extends AnyVal { def plusOne = MyInt(underlying + 1) } MyInt(5).plusOne
Example: MyInt
case class MyInt(val underlying: Int) extends AnyVal { def plusOne = MyInt(underlying + 1) } MyInt(5).plusOne
Example: MyInt
case class MyInt(val underlying: Int) extends AnyVal { def plusOne = MyInt(underlying + 1) } MyInt(5).plusOne
MyInt$.MODULE$.plusOne$extension(5)
What does it bring?
Cute Puppy
Cute Puppy Implicit Classes
Implicit Classes
• remove a lot of boilerplate code
Implicit Classes
• remove a lot of boilerplate code • class must have only one parameter in its
constructor's first parameter list
Implicit Classes
• remove a lot of boilerplate code • class must have only one parameter in its
constructor's first parameter list • implicit conversion is generated
Implicit Classes
• remove a lot of boilerplate code • class must have only one parameter in its
constructor's first parameter list • implicit conversion is generated • often used with Value Classes
Implicit Classes
• remove a lot of boilerplate code • class must have only one parameter in its
constructor's first parameter list • implicit conversion is generated • often used with Value Classes • must be defined inside other class/trait/object
Example: MyInt
implicit class MyInt(val i: Int) extends AnyVal { def plusOne = i + 1 } 2.plusOne
Example: MyInt
implicit class MyInt(val i: Int) extends AnyVal { def plusOne = i + 1 } 2.plusOne
What does it bring?
Trait Dynamic
Trait Dynamic
• allows calling methods not existing in the static type
Trait Dynamic
• allows calling methods not existing in the static type
• useful for DSLs and integration with dynamic languages
Trait Dynamic
• allows calling methods not existing in the static type
• useful for DSLs and integration with dynamic languages
• empty marker trait Dynamic
Trait Dynamic
• allows calling methods not existing in the static type
• useful for DSLs and integration with dynamic languages
• empty marker trait Dynamic • if type check fails it is rewritten to one of
– applyDynamic – applyDynamicNamed – selectDynamic – updateDynamic
Example: Dynamic DB
case class Record(id: Long, name: String)
Example: Dynamic DB
case class Record(id: Long, name: String) object Record extends Dynamic { def applyDynamic(sel: String) (arg: Any): Record = … }
Example: Dynamic DB
case class Record(id: Long, name: String) object Record extends Dynamic { def applyDynamic(sel: String) (arg: Any): Record = … }
Record.findById(1)
Example: Dynamic DB
case class Record(id: Long, name: String) object Record extends Dynamic { def applyDynamic(sel: String) (arg: Any): Record = … }
Record.findById(1) Record.applyDynamic("findById")(1)
What does it bring?
Macros
Macros
• compile-time metaprogramming
Macros
• compile-time metaprogramming • basically functions that are loaded and
executed by the compiler
Macros
• compile-time metaprogramming • basically functions that are loaded and
executed by the compiler – given context and AST of arguments
Macros
• compile-time metaprogramming • basically functions that are loaded and
executed by the compiler – given context and AST of arguments – returned AST inlined and type-checked at the
call site
Example: logging
logger.debug(s"${expensive} message!")
Example: logging
if (logger.isDebugEnabled) { logger.debug(s"${expensive} message!") }
Example: logging
if (logger.isDebugEnabled) { logger.debug(s"${expensive} message!") }
macro
Example: logging
if (logger.isDebugEnabled) { logger.debug(s"${expensive} message!") }
macro expanded at compile-time
And last…
Triple Question Mark
def complexMethod() = ??? • Defined in class Predef def ??? : Nothing = throw new NotImplementedError