SlideShare a Scribd company logo
1 of 19
Uncover and Score
the Usages
of the Underscore
Rhein-Main Scala Meetup 02/02/16
Franck Valentin
var initialization to default value = _
class Foo
class DefaultValue[T] {
// 1. Declare instance vars with default values:
// -----------------------------------------------------------
var int:Int = _ // 0
var double: Double = _ // 0.0
var boolean: Boolean = _ // false
var foo: Foo = _ // null
// 2. It works also for type parameters:
// -----------------------------------------------------------
var t:T = _ // new DefaultValue[String].t == null
// new DefaultValue[Long].t == 0
// 3. Not allowed in methods
// -----------------------------------------------------------
def f() {
// Doesn't compile. "Local variables must be initialized"
// var x:Int = _ e
}
...
var initialization to default value = _
...
// 4. Note also:
// -----------------------------------------------------------
var any:Any = _ // null
var anyRef:AnyRef = _ // null
var anyVal:AnyVal = _ // null
var n:Null = _ // null
// Should the following compile as ‘Nothing’ doesn’t have any value?
// Instead, there is a java.lang.NullPointerException at runtime
// when trying to use it.
var nothing:Nothing = _
}
Tuples ._1
case class Bar(v:Int)
class Tuples {
// _ is a part of the name of tuple getters (_1, _2, ...)
// -----------------------------------------------------------
val myTuple = ("a", 3.141, Bar(0)) // An instance of Tuple3[String, Double, Foo]
val anotherTuple = Tuple2("b", 2.718)
}
// new Tuples().myTuple._1 == "a"
// new Tuples().myTuple._2 == 3.141
// new Tuples().myTuple._3 == Foo(0)
- _ can be part of a method name (more about that later)
- _1, _2, … _22 for Tuple
Unused variables _ =
case class Bar(par1: Int, par2: Int, par3: Int)
class UnusedVariables(bar: Bar) {
// 1. Unused variable (no real practical usage here!)
// -----------------------------------------------------
var _ = "whatever"
// 2. Unused variables in extractors
// -----------------------------------------------------
val myTuple = ("a", 3.141, "b")
val (_, pi, myString) = myTuple
// Not only for tuples:
val Bar(barP1, _, barP3) = bar
}
val uv = new UnusedVariables(Bar(10, 20, 30))
// uv.pi == 3.14
// uv.myString == "b"
// uv.barP1 == 10
// uv.barP3 30
Unused variables _ =
object UnusedVariables2 extends App {
val prefixes = List("p1", "p2")
val strings = List("aa", "bb", "cc")
val suffixes = List("s1", "s2")
// 3. Unused variables can be useful to debug for comprehensions.
// ----------------------------------------------------------------
val stringsWithPrefixesAndSuffixes = for {
prefix <- prefixes
string <- strings
stringWithPrefix = prefix + ">" + string
//println(stringWithPrefix) // This doesn't compile!
_ = println(stringWithPrefix)
suffix <- suffixes
stringWithPrefixAndsuffix= stringWithPrefix + "<" + suffix
} yield stringWithPrefixAndsuffix
// Because of the way Scala translates for comprehensions to foreach/map/flatMap/filter/withFilter
// http://docs.scala-lang.org/tutorials/FAQ/yield.html
// scalac -Xprint:parser UnusedVariables2.scala
}
Unused Parameters _ =>
object UnusedParameters extends App {
// 1. For anonymous functions:
// --------------------------------------------
List(1, 2, 3) map { _ => 0 } // == List(0, 0, 0)
}
...
Imports: wildcards and Hiding => _
object Imports1 {
// 1. _ Similar to * in Java
// ------------------------------------------------------------------
import java.util._
val uuid = UUID.randomUUID()
val date = new Date()
}
object Imports2 {
// 2. Add an exception (everything from java.util but Date and Calendar)
// ------------------------------------------------------------------
import java.util.{Date => _, Calendar => _, _}
val uuid = UUID.randomUUID()
// val date = new Date() // Doesn't compile.
}
...
Imports: wildcards and Hiding => _
...
object Imports3 {
// 3. Import all the members of an object (works with exceptions too)
// ------------------------------------------------------------------
object MyObj {
val m1: Int = 1
val m2: String = "a"
val m3: Double = 1.0
}
import MyObj.{m3 => _, _}
println(m1) // Instead of MyObj.m1
println(m2) // Instead of MyObj.m2
// println(MyObj.m3) // Doesn't compile.
}
Varargs (splat operator) _*
// 1. _* passes a sequence as multiple parameters
// -------------------------------------------------------------
def processParams(params: String*) = params.mkString(",")
processParams("p1", "p2") // == "p1,p2"
val parameters = List("param1", "param2", "param3")
//processParams(parameters) // Error: Type mismatch. expected:String, actual:Seq[String]
processParams(parameters: _*) // == param1,param2,param3
// 2. _* works in pattern matching too
// -------------------------------------------------------------
val res = parameters match {
case Seq(p1) =>
s"Only one element $p1"
case Seq(p1, seqOfStrings @ _*) =>
s"First elt is '$p1' and the rest is the sequence '${seqOfStrings}'"
}
println(res) // == First elt is 'param1' and the rest is the sequence List(param2, param3)'
Anonymous Function Placeholder _ + _
// 1. A placeholder for the parameters in an anonymous function
// -------------------------------------------------------------
val list = List(1, 2, 3, 4)
val by2 = list map (x => x * 2)
val alsoBy2 = list map (_ * 2)
// 2. It works for several parameters as well
// -------------------------------------------------------------
val sum = list reduceLeft ((a, b) => a + b)
val alsoSum = list reduceLeft (_ + _)
def printFctResult(tuple:(Int, String, Double), fct:(Int, String, Double) => String) = {
println(fct(tuple._1, tuple._2, tuple._3))
}
printFctResult((2, "a", 3.0), (i,s,d) => i + s + d) // == "2a3.0"
printFctResult((2, "a", 3.0), _ + _ + _) // It begins to be obscure!
def fct(i: Int, s: String, d: Double): String = s"${i * d} $s"
printFctResult((2, "a", 3.0), (i,s,d) => fct(i,s,d)) // == "6.0 a"
printFctResult((2, "a", 3.0), fct(_,_,_))
Pattern Matching case _
case class MyClass(nameOpt: Option[String], ints: List[Int])
def showMatch(c: Any) {
c match {
// Wilcard in a class parameter
case MyClass(None, _) => println("MyClass without any name.")
// Wilcard in a nested class
case MyClass(_, List(_)) => println("MyClass with only one element.")
// Wilcard in a nested class and splat operator
case MyClass(_, List(_, _*)) => println("MyClass with more than one element.")
// Wildcard on the type
case l:List[_] => println("It's a list !")
// Matches everything else
case _ => println("Matches everything else.")
}
}
showMatch(MyClass(None, List(1,2))) // == "MyClass without any name."
showMatch(MyClass(Some("c1"), List(1))) // == "MyClass with only one element."
showMatch(MyClass(Some("c2"), List(1,2,3))) // == "MyClass with more than one element."
showMatch(List("a", "b", "c")) // == "It's a list !"
showMatch(Set("a", "b", "c")) // == "Matches everything else."
Partially Applied Functions g = f(_,_)
// Partially applied function: function where only a few
// arguments are set during its invocation.
def sendMessage(priority: Int, recipient: String, msg: String) {
println(s"$priority: send '$recipient' the message $msg.'")
}
// sendMessageToFred == (Int, String) => Unit
def sendMessageToFred = sendMessage(_: Int, "Fred", _: String)
sendMessageToFred(1, "Hi Bro!")
// sendImportantMsgToFred == (String) => Unit
def sendImportantMsgToFred = sendMessage(0, "Fred", _: String)
sendImportantMsgToFred("An important message.")
Eta Expansion v = f _
// "Eta-expansion converts an expression of method type to an equivalent expression
// of function type."
// method: a member of the type the class represents.
// function: value of a Function[] type.
// Assign a method to a variable:
// ----------------------------------------------------------------------------
case class MyClass() {
def f1(int: Int):Unit = println(int)
val constant = 35
def f2(int1: Int, int2: Int):String = (int1 + int2 + constant).toString
}
// valF1: Int => Unit = <function1> (Function1[Int, Unit])
val valF1 = MyClass().f1 _
valF1(1)
// valF2: (Int, Int) => String = <function2> (Function2[Int, Int, String)
val valF2 = MyClass().f2 _
valF2(5, 2)
...
Eta Expansion v = f _
…
case class MyOtherClass() {
def f(g: () => Int):Int = 1
def f(i:Int):Int = 2
}
def g() = 3
MyOtherClass().f(g) // == 2
// You have to write the _ whenever the compiler is not explicitly expecting
// a Function object.
MyOtherClass().f(g _) // == 1. _ 'asks' the compiler to treat g a a Function object.
Existential Types
// Existential type: express that you have a type (e.g. List, Array) with an unknown
// element type (an unknown "type parameter") : List[<I don't know>].
// "List[<I don't know>]" could be rephrased as "List[T] forSome {type T}"
//
def count1(l: List[T] forSome {type T}) = l.size
count1(List(1, 2, 3))
count1(List("a", "b"))
// Equivalent to:
def count2(l: List[_]) = l.size
count2(List(1, 2, 3))
count2(List("a", "b"))
// It works for higher kinded types as well.
// Higher kinded type : A type constructor that takes type constructor(s)
// Higher kinded type 'Iterable' has the type constructor 'Container'.
trait Iterable[A, Container[_]] {
def map[B](f: A => B): Container[B]
def filter(p: A => Boolean): Container[A]
}
Identifier Names Ending with an operator _!
// 1. alphanumeric + _ + operator identifier (+, ++, :, ?, ~, # :> ...)
// ----------------------------------------------------------------------------
trait WhatATrait_! {
def isItUsefult_?()
// 2. _ followed by a letter(s), digit(s), or underscore(s).
// --------------------------------------------------------------------------
def _abc()
def _123()
def __()
}
Assignment Operator def f_=( )
// Special case for an identifier name ending with _=
// A way to define getters and setters.
// ------------------------------------------------------------------
class MyClass {
private var myInt0:Int = _
// Getter:
def myInt:Int = myInt0
// Setter:
def myInt_=(i:Int) {
require(i>0)
println(s"I'm setting myInt = $i")
myInt0 = i
}
}
val myClass = new MyClass
myClass.myInt = 5 // Setter: Desugared into myClass.myInt_=(5)
println(myClass.myInt) // Getter
myClass.myInt = -1 // java.lang.IllegalArgumentException: requirement failed
Uncover and score the usages of the underscore

More Related Content

What's hot

PERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsPERL for QA - Important Commands and applications
PERL for QA - Important Commands and applications
Sunil Kumar Gunasekaran
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
Lin Yo-An
 

What's hot (17)

PERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsPERL for QA - Important Commands and applications
PERL for QA - Important Commands and applications
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
Class 4 - PHP Arrays
Class 4 - PHP ArraysClass 4 - PHP Arrays
Class 4 - PHP Arrays
 
What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16
 
Perl
PerlPerl
Perl
 
Closure, Higher-order function in Swift
Closure, Higher-order function in SwiftClosure, Higher-order function in Swift
Closure, Higher-order function in Swift
 
Introduction to perl_lists
Introduction to perl_listsIntroduction to perl_lists
Introduction to perl_lists
 
Class 5 - PHP Strings
Class 5 - PHP StringsClass 5 - PHP Strings
Class 5 - PHP Strings
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
Mysql1
Mysql1Mysql1
Mysql1
 
Licão 09 variables and arrays v2
Licão 09 variables and arrays v2Licão 09 variables and arrays v2
Licão 09 variables and arrays v2
 
Marcs (bio)perl course
Marcs (bio)perl courseMarcs (bio)perl course
Marcs (bio)perl course
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
Frege is a Haskell for the JVM
Frege is a Haskell for the JVMFrege is a Haskell for the JVM
Frege is a Haskell for the JVM
 
Data transformation-cheatsheet
Data transformation-cheatsheetData transformation-cheatsheet
Data transformation-cheatsheet
 

Viewers also liked (9)

đề Thi speaking tháng 1 2 3 4 update
đề Thi speaking tháng 1 2 3 4 updateđề Thi speaking tháng 1 2 3 4 update
đề Thi speaking tháng 1 2 3 4 update
 
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...
Frontera: распределенный робот для обхода интернета в больших объемах - Алекс...
 
药怡良-毕业答辩
药怡良-毕业答辩药怡良-毕业答辩
药怡良-毕业答辩
 
Portrait / Ben Carson
Portrait / Ben CarsonPortrait / Ben Carson
Portrait / Ben Carson
 
Crypto cameraready(1) (2)
Crypto cameraready(1) (2)Crypto cameraready(1) (2)
Crypto cameraready(1) (2)
 
A2759 01 existing
A2759   01 existingA2759   01 existing
A2759 01 existing
 
Evaluation of posters l3
Evaluation of posters l3Evaluation of posters l3
Evaluation of posters l3
 
Komikia
KomikiaKomikia
Komikia
 
Social networking
Social networkingSocial networking
Social networking
 

Similar to Uncover and score the usages of the underscore

C++ projectMachine Problem 7 - HashingWrite a program to do the .pdf
C++ projectMachine Problem 7 - HashingWrite a program to do the .pdfC++ projectMachine Problem 7 - HashingWrite a program to do the .pdf
C++ projectMachine Problem 7 - HashingWrite a program to do the .pdf
feelinggift
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)
ujihisa
 
Using C++I keep getting messagehead does not name a type.pdf
Using C++I keep getting messagehead does not name a type.pdfUsing C++I keep getting messagehead does not name a type.pdf
Using C++I keep getting messagehead does not name a type.pdf
alokkesh1
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
Yy
YyYy
Yy
yygh
 
Yy
YyYy
Yy
yygh
 
Nouveau document texte
Nouveau document texteNouveau document texte
Nouveau document texte
Sai Ef
 
Hacking Parse.y with ujihisa
Hacking Parse.y with ujihisaHacking Parse.y with ujihisa
Hacking Parse.y with ujihisa
ujihisa
 

Similar to Uncover and score the usages of the underscore (20)

Scala Paradigms
Scala ParadigmsScala Paradigms
Scala Paradigms
 
C++ projectMachine Problem 7 - HashingWrite a program to do the .pdf
C++ projectMachine Problem 7 - HashingWrite a program to do the .pdfC++ projectMachine Problem 7 - HashingWrite a program to do the .pdf
C++ projectMachine Problem 7 - HashingWrite a program to do the .pdf
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)
 
C99
C99C99
C99
 
Funcitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayFuncitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional Way
 
Javascript
JavascriptJavascript
Javascript
 
Using C++I keep getting messagehead does not name a type.pdf
Using C++I keep getting messagehead does not name a type.pdfUsing C++I keep getting messagehead does not name a type.pdf
Using C++I keep getting messagehead does not name a type.pdf
 
学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキスト学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキスト
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
C99
C99C99
C99
 
C99
C99C99
C99
 
Yy
YyYy
Yy
 
Yy
YyYy
Yy
 
Nouveau document texte
Nouveau document texteNouveau document texte
Nouveau document texte
 
Hacking Parse.y with ujihisa
Hacking Parse.y with ujihisaHacking Parse.y with ujihisa
Hacking Parse.y with ujihisa
 
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswift
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswiftSwift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswift
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswift
 
全裸でワンライナー(仮)
全裸でワンライナー(仮)全裸でワンライナー(仮)
全裸でワンライナー(仮)
 
GeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheetGeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheet
 
Hello scala
Hello scalaHello scala
Hello scala
 

Recently uploaded

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 

Recently uploaded (20)

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 

Uncover and score the usages of the underscore

  • 1. Uncover and Score the Usages of the Underscore Rhein-Main Scala Meetup 02/02/16 Franck Valentin
  • 2. var initialization to default value = _ class Foo class DefaultValue[T] { // 1. Declare instance vars with default values: // ----------------------------------------------------------- var int:Int = _ // 0 var double: Double = _ // 0.0 var boolean: Boolean = _ // false var foo: Foo = _ // null // 2. It works also for type parameters: // ----------------------------------------------------------- var t:T = _ // new DefaultValue[String].t == null // new DefaultValue[Long].t == 0 // 3. Not allowed in methods // ----------------------------------------------------------- def f() { // Doesn't compile. "Local variables must be initialized" // var x:Int = _ e } ...
  • 3. var initialization to default value = _ ... // 4. Note also: // ----------------------------------------------------------- var any:Any = _ // null var anyRef:AnyRef = _ // null var anyVal:AnyVal = _ // null var n:Null = _ // null // Should the following compile as ‘Nothing’ doesn’t have any value? // Instead, there is a java.lang.NullPointerException at runtime // when trying to use it. var nothing:Nothing = _ }
  • 4. Tuples ._1 case class Bar(v:Int) class Tuples { // _ is a part of the name of tuple getters (_1, _2, ...) // ----------------------------------------------------------- val myTuple = ("a", 3.141, Bar(0)) // An instance of Tuple3[String, Double, Foo] val anotherTuple = Tuple2("b", 2.718) } // new Tuples().myTuple._1 == "a" // new Tuples().myTuple._2 == 3.141 // new Tuples().myTuple._3 == Foo(0) - _ can be part of a method name (more about that later) - _1, _2, … _22 for Tuple
  • 5. Unused variables _ = case class Bar(par1: Int, par2: Int, par3: Int) class UnusedVariables(bar: Bar) { // 1. Unused variable (no real practical usage here!) // ----------------------------------------------------- var _ = "whatever" // 2. Unused variables in extractors // ----------------------------------------------------- val myTuple = ("a", 3.141, "b") val (_, pi, myString) = myTuple // Not only for tuples: val Bar(barP1, _, barP3) = bar } val uv = new UnusedVariables(Bar(10, 20, 30)) // uv.pi == 3.14 // uv.myString == "b" // uv.barP1 == 10 // uv.barP3 30
  • 6. Unused variables _ = object UnusedVariables2 extends App { val prefixes = List("p1", "p2") val strings = List("aa", "bb", "cc") val suffixes = List("s1", "s2") // 3. Unused variables can be useful to debug for comprehensions. // ---------------------------------------------------------------- val stringsWithPrefixesAndSuffixes = for { prefix <- prefixes string <- strings stringWithPrefix = prefix + ">" + string //println(stringWithPrefix) // This doesn't compile! _ = println(stringWithPrefix) suffix <- suffixes stringWithPrefixAndsuffix= stringWithPrefix + "<" + suffix } yield stringWithPrefixAndsuffix // Because of the way Scala translates for comprehensions to foreach/map/flatMap/filter/withFilter // http://docs.scala-lang.org/tutorials/FAQ/yield.html // scalac -Xprint:parser UnusedVariables2.scala }
  • 7. Unused Parameters _ => object UnusedParameters extends App { // 1. For anonymous functions: // -------------------------------------------- List(1, 2, 3) map { _ => 0 } // == List(0, 0, 0) } ...
  • 8. Imports: wildcards and Hiding => _ object Imports1 { // 1. _ Similar to * in Java // ------------------------------------------------------------------ import java.util._ val uuid = UUID.randomUUID() val date = new Date() } object Imports2 { // 2. Add an exception (everything from java.util but Date and Calendar) // ------------------------------------------------------------------ import java.util.{Date => _, Calendar => _, _} val uuid = UUID.randomUUID() // val date = new Date() // Doesn't compile. } ...
  • 9. Imports: wildcards and Hiding => _ ... object Imports3 { // 3. Import all the members of an object (works with exceptions too) // ------------------------------------------------------------------ object MyObj { val m1: Int = 1 val m2: String = "a" val m3: Double = 1.0 } import MyObj.{m3 => _, _} println(m1) // Instead of MyObj.m1 println(m2) // Instead of MyObj.m2 // println(MyObj.m3) // Doesn't compile. }
  • 10. Varargs (splat operator) _* // 1. _* passes a sequence as multiple parameters // ------------------------------------------------------------- def processParams(params: String*) = params.mkString(",") processParams("p1", "p2") // == "p1,p2" val parameters = List("param1", "param2", "param3") //processParams(parameters) // Error: Type mismatch. expected:String, actual:Seq[String] processParams(parameters: _*) // == param1,param2,param3 // 2. _* works in pattern matching too // ------------------------------------------------------------- val res = parameters match { case Seq(p1) => s"Only one element $p1" case Seq(p1, seqOfStrings @ _*) => s"First elt is '$p1' and the rest is the sequence '${seqOfStrings}'" } println(res) // == First elt is 'param1' and the rest is the sequence List(param2, param3)'
  • 11. Anonymous Function Placeholder _ + _ // 1. A placeholder for the parameters in an anonymous function // ------------------------------------------------------------- val list = List(1, 2, 3, 4) val by2 = list map (x => x * 2) val alsoBy2 = list map (_ * 2) // 2. It works for several parameters as well // ------------------------------------------------------------- val sum = list reduceLeft ((a, b) => a + b) val alsoSum = list reduceLeft (_ + _) def printFctResult(tuple:(Int, String, Double), fct:(Int, String, Double) => String) = { println(fct(tuple._1, tuple._2, tuple._3)) } printFctResult((2, "a", 3.0), (i,s,d) => i + s + d) // == "2a3.0" printFctResult((2, "a", 3.0), _ + _ + _) // It begins to be obscure! def fct(i: Int, s: String, d: Double): String = s"${i * d} $s" printFctResult((2, "a", 3.0), (i,s,d) => fct(i,s,d)) // == "6.0 a" printFctResult((2, "a", 3.0), fct(_,_,_))
  • 12. Pattern Matching case _ case class MyClass(nameOpt: Option[String], ints: List[Int]) def showMatch(c: Any) { c match { // Wilcard in a class parameter case MyClass(None, _) => println("MyClass without any name.") // Wilcard in a nested class case MyClass(_, List(_)) => println("MyClass with only one element.") // Wilcard in a nested class and splat operator case MyClass(_, List(_, _*)) => println("MyClass with more than one element.") // Wildcard on the type case l:List[_] => println("It's a list !") // Matches everything else case _ => println("Matches everything else.") } } showMatch(MyClass(None, List(1,2))) // == "MyClass without any name." showMatch(MyClass(Some("c1"), List(1))) // == "MyClass with only one element." showMatch(MyClass(Some("c2"), List(1,2,3))) // == "MyClass with more than one element." showMatch(List("a", "b", "c")) // == "It's a list !" showMatch(Set("a", "b", "c")) // == "Matches everything else."
  • 13. Partially Applied Functions g = f(_,_) // Partially applied function: function where only a few // arguments are set during its invocation. def sendMessage(priority: Int, recipient: String, msg: String) { println(s"$priority: send '$recipient' the message $msg.'") } // sendMessageToFred == (Int, String) => Unit def sendMessageToFred = sendMessage(_: Int, "Fred", _: String) sendMessageToFred(1, "Hi Bro!") // sendImportantMsgToFred == (String) => Unit def sendImportantMsgToFred = sendMessage(0, "Fred", _: String) sendImportantMsgToFred("An important message.")
  • 14. Eta Expansion v = f _ // "Eta-expansion converts an expression of method type to an equivalent expression // of function type." // method: a member of the type the class represents. // function: value of a Function[] type. // Assign a method to a variable: // ---------------------------------------------------------------------------- case class MyClass() { def f1(int: Int):Unit = println(int) val constant = 35 def f2(int1: Int, int2: Int):String = (int1 + int2 + constant).toString } // valF1: Int => Unit = <function1> (Function1[Int, Unit]) val valF1 = MyClass().f1 _ valF1(1) // valF2: (Int, Int) => String = <function2> (Function2[Int, Int, String) val valF2 = MyClass().f2 _ valF2(5, 2) ...
  • 15. Eta Expansion v = f _ … case class MyOtherClass() { def f(g: () => Int):Int = 1 def f(i:Int):Int = 2 } def g() = 3 MyOtherClass().f(g) // == 2 // You have to write the _ whenever the compiler is not explicitly expecting // a Function object. MyOtherClass().f(g _) // == 1. _ 'asks' the compiler to treat g a a Function object.
  • 16. Existential Types // Existential type: express that you have a type (e.g. List, Array) with an unknown // element type (an unknown "type parameter") : List[<I don't know>]. // "List[<I don't know>]" could be rephrased as "List[T] forSome {type T}" // def count1(l: List[T] forSome {type T}) = l.size count1(List(1, 2, 3)) count1(List("a", "b")) // Equivalent to: def count2(l: List[_]) = l.size count2(List(1, 2, 3)) count2(List("a", "b")) // It works for higher kinded types as well. // Higher kinded type : A type constructor that takes type constructor(s) // Higher kinded type 'Iterable' has the type constructor 'Container'. trait Iterable[A, Container[_]] { def map[B](f: A => B): Container[B] def filter(p: A => Boolean): Container[A] }
  • 17. Identifier Names Ending with an operator _! // 1. alphanumeric + _ + operator identifier (+, ++, :, ?, ~, # :> ...) // ---------------------------------------------------------------------------- trait WhatATrait_! { def isItUsefult_?() // 2. _ followed by a letter(s), digit(s), or underscore(s). // -------------------------------------------------------------------------- def _abc() def _123() def __() }
  • 18. Assignment Operator def f_=( ) // Special case for an identifier name ending with _= // A way to define getters and setters. // ------------------------------------------------------------------ class MyClass { private var myInt0:Int = _ // Getter: def myInt:Int = myInt0 // Setter: def myInt_=(i:Int) { require(i>0) println(s"I'm setting myInt = $i") myInt0 = i } } val myClass = new MyClass myClass.myInt = 5 // Setter: Desugared into myClass.myInt_=(5) println(myClass.myInt) // Getter myClass.myInt = -1 // java.lang.IllegalArgumentException: requirement failed