SlideShare ist ein Scribd-Unternehmen logo
1 von 24
Downloaden Sie, um offline zu lesen
Equality For All!
Scala by the Bay, 2014
BillVenners
Artima, Inc.
Escalate Software
Saturday, August 9, 2014
Equality: An equivalence relation with
one element per equivalence class
42 4341
42 = 4241 = 41 43 = 43
reflexive: x = x
symmetric: x = y iff y = x
transitive: if x = y and y = z then x = z
Saturday, August 9, 2014
How do I say forty two in code?
Let me count the ways...
42
42L
42.0
42.0F
42.toShort
'*'
42.toByte BigInt(42)
BigDecimal(42)
new java.lang.Integer(42)
new java.lang.Long(42L)
new java.lang.Double(42.0)
new java.lang.Float(42.0F) new java.lang.Short(42.toShort)
new java.lang.Character(42)
new java.lang.Byte(42.toByte)
new java.math.BigInteger("42")
new java.math.BigDecimal(42) Complex(42.0, 0.0)
DigitString("42") DigitString("042")
Saturday, August 9, 2014
The equals method implements an equivalence relation on non-null object references:
• It is reflexive: for any non-null reference value x, x.equals(x) should return true.
• It is symmetric: for any non-null reference values x and y, x.equals(y) should return true
if and only if y.equals(x) returns true.
• It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true
and y.equals(z) returns true, then x.equals(z) should return true.
• It is consistent: for any non-null reference values x and y, multiple invocations of
x.equals(y) consistently return true or consistently return false, provided no
information used in equals comparisons on the objects is modified.
• For any non-null reference value x, x.equals(null) should return false.
Java's equals contract
public boolean equals(Object obj)
final def == (other:Any): Boolean
Saturday, August 9, 2014
scala> 42 == 42L
res0: Boolean = true
scala> BigDecimal(42) == '*'
res1: Boolean = true
scala> 42.0F == BigInt(42)
res2: Boolean = true
scala> new java.lang.Float(42.0F) == 42.toShort
res3: Boolean = true
Co-operative Equality Between Types
Saturday, August 9, 2014
scala> import scala.collection.mutable
import scala.collection.mutable
scala> Set(BigInt(4), BigInt(2)) == mutable.Set(4.toByte,
2.toByte)
res4: Boolean = true
scala> Vector(Left(4), Right(2)) == List(Left(4L), Right(2L))
res5: Boolean = true
scala> List(mutable.Set(Map(Some(4L) -> BigInt(2)))) ==
Vector(Set(mutable.Map(Some(4.0) -> new java.lang.Long(2L))))
res6: Boolean = true
Co-operative Equality Between Types
Saturday, August 9, 2014
scala> Array(4, 2) == Array(4, 2)
res7: Boolean = false
scala> <forty><two></two></forty> == <forty> <two></two> </forty>
res8: Boolean = false
scala> new java.math.BigDecimal("42.0") ==
new java.math.BigDecimal("42.00")
res9: Boolean = false
scala> 42.0 == 41.9999999999
res10: Boolean = false
scala> "case" == "CASE"
res11: Boolean = false
Wanted: Alternate equalities
Saturday, August 9, 2014
scala> "forty two" == 42
res19: Boolean = false
scala> List(mutable.Set(Map(Some(4L) -> BigInt(2)))) ==
Vector(Set(mutable.Map(Some("4.0") -> new java.lang.Long(2L))))
res23: Boolean = false
Wanted: Type errors
But how to decide which comparisons compile?
Saturday, August 9, 2014
scala> "forty two" == 42
<console>:20: error: types String and Int do not adhere to the
type constraint selected for the === and !== operators; the
missing implicit parameter is of type
org.scalactic.EqualityConstraint[String,Int]
"forty two" === 42
^
scala> BigInt(42) === BigDecimal(42)
res1: Boolean = true
Fail to compile if L can never equal R.
Saturday, August 9, 2014
scala> Vector.empty === List.empty
<console>:20: error: ambiguous implicit values:
both method conflictingEmptySeqConstraint1 in object EqualityConstraint of type [LSEQ[e] <:
scala.collection.GenSeq[e], RSEQ[e] <: scala.collection.GenSeq[e]]=>
org.scalactic.EqualityConstraint[LSEQ[Nothing],RSEQ[Nothing]]
and method conflictingEmptySeqConstraint2 in object EqualityConstraint of type [LSEQ[e] <:
scala.collection.GenSeq[e], RSEQ[e] <: scala.collection.GenSeq[e]]=>
org.scalactic.EqualityConstraint[LSEQ[Nothing],RSEQ[Nothing]]
match expected type
org.scalactic.EqualityConstraint[scala.collection.immutable.Vector[A],List[Nothing]]
Vector.empty === List.empty
^
scala> Vector.empty === List.empty[Int]
res3: Boolean = true
scala> Vector.empty[String] === List.empty
res4: Boolean = true
Fail to compile if L will always equal R.
Saturday, August 9, 2014
Candidate rule:
To compile, an equality comparison
must be interesting: values of types L
and R can be either equal or unequal.
Saturday, August 9, 2014
scala> case class Complex(real: Double, imaginary: Double)
defined class Complex
scala> implicit def convertIntToComplex(i: Int): Complex = Complex(i, 0.0)
convertIntToComplex: (i: Int)Complex
scala> 42 === Complex(42, 0)
<console>:24: error: types Int and Complex do not adhere to the type constraint selected for the
=== and !== operators; the missing implicit parameter is of type
org.scalactic.EqualityConstraint[Int,Complex]
42 === Complex(42, 0)
^
scala> Complex(42, 0) === 42
<console>:24: error: types Complex and Int do not adhere to the type constraint selected for the
=== and !== operators; the missing implicit parameter is of type
org.scalactic.EqualityConstraint[Complex,Int]
Complex(42, 0) === 42
^
What about implicit conversions?
Saturday, August 9, 2014
scala> implicit val enabler = EqualityEnabledBetween[Int, Complex]
enabler: org.scalactic.EqualityEnabledBetween[Int,Complex] =
org.scalactic.EqualityEnabledBetween@e5d2d9b
scala> 42 === Complex(42, 0)
res2: Boolean = true
scala> Complex(42, 0) === 42
res3: Boolean = true
scala> new AnyShouldWrapper(1) === 1 // Probably shouldn't enable...
Intuition: enable some but not all
But what would the rule be?
Saturday, August 9, 2014
OK if the conversion is an injection
scala> case class DigitString(digits: String) {
| val toInt: Int = digits.toInt
| }
defined class DigitString
scala> implicit def convert(d: DigitString): Int =
| d.digits.toInt
convertDigitStringToInt: (d: DigitString)Int
scala> DigitString("42") === DigitString("042")
res0: Boolean = false
scala> DigitString("42").toInt === DigitString("042").toInt
res1: Boolean = true
John C. Reynolds: Using category theory to design implicit conversions and generic operators.
Saturday, August 9, 2014
How to decide:
1.To compile, an equality comparison must be
interesting: values of types L and R can be either
equal or unequal.
2.Allow select implicit conversions to be enabled,
and recommend that non-widening conversions
(non-injections) not be enabled.
Saturday, August 9, 2014
scala> (Some(1): Option[Int]) === Some(1)
res0: Boolean = true
scala> Some(1) === (Some(1): Option[Int])
res1: Boolean = true
scala> Some(1) === Some(1)
res2: Boolean = true
What about the implicit conversion
from subtype to supertype (<:<)?
Saturday, August 9, 2014
scala> def eqv[T](a: T, b: T): Boolean = a === b
eqv: [T](a: T, b: T)Boolean
scala> eqv(1, ())
res3: Boolean = false
scala> ((i: Int) => i + 1) === ((i: Int) => i + 1)
res4: Boolean = false
Even though <:< is an injection, is it
always desireable?
Saturday, August 9, 2014
EqualityPolicy
UncheckedEquality CheckedEquality EnabledEquality
Saturday, August 9, 2014
scala> import EnabledEquality._
import EnabledEquality._
scala> def eqv[T](a: T, b: T): Boolean = a === b
<console>:19: error: types T and T do not adhere to the type constraint selected for
the === and !== operators; the missing implicit parameter is of type
org.scalactic.EqualityConstraint[T,T]
def eqv[T](a: T, b: T): Boolean = a === b
^
scala> ((i: Int) => i + 1) === ((i: Int) => i + 1)
<console>:20: error: types Int => Int and Int => Int do not adhere to the type
constraint selected for the === and !== operators; the missing implicit parameter is
of type org.scalactic.EqualityConstraint[Int => Int,Int => Int]
((i: Int) => i + 1) === ((i: Int) => i + 1)
^
EnabledEquality benefit
Saturday, August 9, 2014
scala> case class Person(name: String)
defined class Person
scala> Person("Sue") === Person("Sue")
<console>:22: error: types Person and Person do not adhere to the type constraint
selected for the === and !== operators; the missing implicit parameter is of type
org.scalactic.EqualityConstraint[Person,Person]
Person("Sue") === Person("Sue")
^
scala> implicit val enabler = new EqualityEnabledFor[Person]
enabler: org.scalactic.EqualityEnabledFor[Person] =
org.scalactic.EqualityEnabledFor@1289d391
scala> Person("Sue") === Person("Sue")
res2: Boolean = true
EnabledEquality cost
Saturday, August 9, 2014
scala> 1 should === ("one")
<console>:23: error: types Int and String do not adhere to the type constraint selected for the === and !==
operators; the missing implicit parameter is of type org.scalactic.Constraint[Int,String]
1 should === ("one")
^
scala> 1 should equal ("one")
<console>:23: error: could not find implicit value for parameter typeClass1:
org.scalactic.enablers.EvidenceThat[String]#CanEqual[Int]
1 should equal ("one")
^
scala> 1 should be ("one")
<console>:23: error: could not find implicit value for parameter typeClass1:
org.scalactic.enablers.EvidenceThat[String]#CanEqual[Int]
1 should be ("one")
^
scala> 1 should be_== ("one")
org.scalatest.exceptions.TestFailedException: 1 was not equal to "one"
ScalaTest's equal, be, and be_==
Saturday, August 9, 2014
scala> List(1, 2, 3) should contain ("one")
<console>:23: error: could not find implicit value for parameter typeClass1:
org.scalactic.enablers.EvidenceThat[String]#CanBeContainedIn[List[Int]]
List(1, 2, 3) should contain ("one")
^
scala> List(1, 2, 3) should contain oneOf ("one", "two")
<console>:23: error: could not find implicit value for parameter evidence:
org.scalactic.enablers.EvidenceThat[String]#CanBeContainedIn[List[Int]]
List(1, 2, 3) should contain oneOf("one", "two")
^
scala> 1 isIn List(1, 2, 3)
res14: Boolean = true
scala> "one" isIn List(1, 2, 3)
<console>:23: error: Could not find evidence that String can be contained in List[Int]; the missing implicit
parameter is of type org.scalactic.enablers.ContainingConstraint[List[Int],String]
"one" isIn List(1, 2, 3)
^
ScalaTest's contain, Scalactic's isIn/isNotIn
Saturday, August 9, 2014
if sufficientTimeRemains then (Q => A) else thanks
artima.com/shop
15% discount
coupon code:
BYTHEBAY2014
Saturday, August 9, 2014
scala> 1L === 1
res0: Boolean = true
scala> 1 === 1L
<console>:14: error: could not find implicit value for parameter F0:
scalaz.Equal[Any]
1 === 1L
^
Scalaz or Spire
Scalactic
scala> 1L === 1
res7: Boolean = true
scala> 1 === 1L
res8: Boolean = true
Equal[T], Eq[T]
EqualityConstraint[L, R]
Equivalence[T]
Saturday, August 9, 2014

Weitere ähnliche Inhalte

Was ist angesagt?

Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
shinolajla
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
Eelco Visser
 
RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0
tutorialsruby
 

Was ist angesagt? (20)

Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in Scala
 
Chapter3
Chapter3Chapter3
Chapter3
 
5-minute intro to property-based testing in Python with hypothesis
5-minute intro to property-based testing in Python with hypothesis5-minute intro to property-based testing in Python with hypothesis
5-minute intro to property-based testing in Python with hypothesis
 
ECET 370 HELPS Redefined Education--ecet370helps.com
ECET 370 HELPS Redefined Education--ecet370helps.comECET 370 HELPS Redefined Education--ecet370helps.com
ECET 370 HELPS Redefined Education--ecet370helps.com
 
Collections
CollectionsCollections
Collections
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 
Scala case of case classes
Scala   case of case classesScala   case of case classes
Scala case of case classes
 
Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With Scala
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
 
Hello, Guava !
Hello, Guava !Hello, Guava !
Hello, Guava !
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
 
RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Functional programming in Scala
Functional programming in ScalaFunctional programming in Scala
Functional programming in Scala
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
 
Scala collections api expressivity and brevity upgrade from java
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from java
 
Introduction to programming in scala
Introduction to programming in scalaIntroduction to programming in scala
Introduction to programming in scala
 
Scala collections
Scala collectionsScala collections
Scala collections
 
Programming in Scala - Lecture Four
Programming in Scala - Lecture FourProgramming in Scala - Lecture Four
Programming in Scala - Lecture Four
 

Andere mochten auch

лекция № 1 кости черепа
лекция № 1 кости черепалекция № 1 кости черепа
лекция № 1 кости черепа
lali100226
 
Iisrt zz saravana kumar
Iisrt zz saravana kumarIisrt zz saravana kumar
Iisrt zz saravana kumar
IISRT
 

Andere mochten auch (14)

Tonka Waters West Girl Scout New Adult Members Training - Fast track v2
Tonka Waters West Girl Scout New Adult Members Training - Fast track v2Tonka Waters West Girl Scout New Adult Members Training - Fast track v2
Tonka Waters West Girl Scout New Adult Members Training - Fast track v2
 
foreveryoungasia
foreveryoungasiaforeveryoungasia
foreveryoungasia
 
The Scalactic Way
The Scalactic WayThe Scalactic Way
The Scalactic Way
 
Synthèse des travaux de groupe
Synthèse des travaux de groupeSynthèse des travaux de groupe
Synthèse des travaux de groupe
 
Sécurisation foncière des exploitations familiales dans les grands périmètres...
Sécurisation foncière des exploitations familiales dans les grands périmètres...Sécurisation foncière des exploitations familiales dans les grands périmètres...
Sécurisation foncière des exploitations familiales dans les grands périmètres...
 
Lecture du processus de sécurisation foncière en cours par les coopératives r...
Lecture du processus de sécurisation foncière en cours par les coopératives r...Lecture du processus de sécurisation foncière en cours par les coopératives r...
Lecture du processus de sécurisation foncière en cours par les coopératives r...
 
лекция № 1 кости черепа
лекция № 1 кости черепалекция № 1 кости черепа
лекция № 1 кости черепа
 
Antena Kaleng (raihan s & syis f)
Antena Kaleng (raihan s & syis f)Antena Kaleng (raihan s & syis f)
Antena Kaleng (raihan s & syis f)
 
Iisrt zz saravana kumar
Iisrt zz saravana kumarIisrt zz saravana kumar
Iisrt zz saravana kumar
 
Cisticercosis
CisticercosisCisticercosis
Cisticercosis
 
Indico Motor
Indico MotorIndico Motor
Indico Motor
 
HALDIA PETROCHEMICALS LIMITED
HALDIA PETROCHEMICALS LIMITEDHALDIA PETROCHEMICALS LIMITED
HALDIA PETROCHEMICALS LIMITED
 
Decorative House and Garden Flags
Decorative House and Garden FlagsDecorative House and Garden Flags
Decorative House and Garden Flags
 
Sharing is Caring - Web Development Resources
Sharing is Caring - Web Development ResourcesSharing is Caring - Web Development Resources
Sharing is Caring - Web Development Resources
 

Ähnlich wie Equality For All!

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Real World Haskell: Lecture 4
Real World Haskell: Lecture 4
Bryan O'Sullivan
 

Ähnlich wie Equality For All! (20)

Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Scala by Luc Duponcheel
Scala by Luc DuponcheelScala by Luc Duponcheel
Scala by Luc Duponcheel
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Programmation fonctionnelle Scala
Programmation fonctionnelle ScalaProgrammation fonctionnelle Scala
Programmation fonctionnelle Scala
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Scala intro workshop
Scala intro workshopScala intro workshop
Scala intro workshop
 
Spark workshop
Spark workshopSpark workshop
Spark workshop
 
Monadologie
MonadologieMonadologie
Monadologie
 
Scala for Java Devs
Scala for Java DevsScala for Java Devs
Scala for Java Devs
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_final
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Real World Haskell: Lecture 4
Real World Haskell: Lecture 4
 

Kürzlich hochgeladen

Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Kandungan 087776558899
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
dollysharma2066
 
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoorTop Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
dharasingh5698
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
dharasingh5698
 

Kürzlich hochgeladen (20)

Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
 
Double rodded leveling 1 pdf activity 01
Double rodded leveling 1 pdf activity 01Double rodded leveling 1 pdf activity 01
Double rodded leveling 1 pdf activity 01
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPT
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
Intro To Electric Vehicles PDF Notes.pdf
Intro To Electric Vehicles PDF Notes.pdfIntro To Electric Vehicles PDF Notes.pdf
Intro To Electric Vehicles PDF Notes.pdf
 
NFPA 5000 2024 standard .
NFPA 5000 2024 standard                                  .NFPA 5000 2024 standard                                  .
NFPA 5000 2024 standard .
 
Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank  Design by Working Stress - IS Method.pdfIntze Overhead Water Tank  Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torque
 
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoorTop Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
 
chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineering
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced LoadsFEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
 

Equality For All!

  • 1. Equality For All! Scala by the Bay, 2014 BillVenners Artima, Inc. Escalate Software Saturday, August 9, 2014
  • 2. Equality: An equivalence relation with one element per equivalence class 42 4341 42 = 4241 = 41 43 = 43 reflexive: x = x symmetric: x = y iff y = x transitive: if x = y and y = z then x = z Saturday, August 9, 2014
  • 3. How do I say forty two in code? Let me count the ways... 42 42L 42.0 42.0F 42.toShort '*' 42.toByte BigInt(42) BigDecimal(42) new java.lang.Integer(42) new java.lang.Long(42L) new java.lang.Double(42.0) new java.lang.Float(42.0F) new java.lang.Short(42.toShort) new java.lang.Character(42) new java.lang.Byte(42.toByte) new java.math.BigInteger("42") new java.math.BigDecimal(42) Complex(42.0, 0.0) DigitString("42") DigitString("042") Saturday, August 9, 2014
  • 4. The equals method implements an equivalence relation on non-null object references: • It is reflexive: for any non-null reference value x, x.equals(x) should return true. • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true. • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified. • For any non-null reference value x, x.equals(null) should return false. Java's equals contract public boolean equals(Object obj) final def == (other:Any): Boolean Saturday, August 9, 2014
  • 5. scala> 42 == 42L res0: Boolean = true scala> BigDecimal(42) == '*' res1: Boolean = true scala> 42.0F == BigInt(42) res2: Boolean = true scala> new java.lang.Float(42.0F) == 42.toShort res3: Boolean = true Co-operative Equality Between Types Saturday, August 9, 2014
  • 6. scala> import scala.collection.mutable import scala.collection.mutable scala> Set(BigInt(4), BigInt(2)) == mutable.Set(4.toByte, 2.toByte) res4: Boolean = true scala> Vector(Left(4), Right(2)) == List(Left(4L), Right(2L)) res5: Boolean = true scala> List(mutable.Set(Map(Some(4L) -> BigInt(2)))) == Vector(Set(mutable.Map(Some(4.0) -> new java.lang.Long(2L)))) res6: Boolean = true Co-operative Equality Between Types Saturday, August 9, 2014
  • 7. scala> Array(4, 2) == Array(4, 2) res7: Boolean = false scala> <forty><two></two></forty> == <forty> <two></two> </forty> res8: Boolean = false scala> new java.math.BigDecimal("42.0") == new java.math.BigDecimal("42.00") res9: Boolean = false scala> 42.0 == 41.9999999999 res10: Boolean = false scala> "case" == "CASE" res11: Boolean = false Wanted: Alternate equalities Saturday, August 9, 2014
  • 8. scala> "forty two" == 42 res19: Boolean = false scala> List(mutable.Set(Map(Some(4L) -> BigInt(2)))) == Vector(Set(mutable.Map(Some("4.0") -> new java.lang.Long(2L)))) res23: Boolean = false Wanted: Type errors But how to decide which comparisons compile? Saturday, August 9, 2014
  • 9. scala> "forty two" == 42 <console>:20: error: types String and Int do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.EqualityConstraint[String,Int] "forty two" === 42 ^ scala> BigInt(42) === BigDecimal(42) res1: Boolean = true Fail to compile if L can never equal R. Saturday, August 9, 2014
  • 10. scala> Vector.empty === List.empty <console>:20: error: ambiguous implicit values: both method conflictingEmptySeqConstraint1 in object EqualityConstraint of type [LSEQ[e] <: scala.collection.GenSeq[e], RSEQ[e] <: scala.collection.GenSeq[e]]=> org.scalactic.EqualityConstraint[LSEQ[Nothing],RSEQ[Nothing]] and method conflictingEmptySeqConstraint2 in object EqualityConstraint of type [LSEQ[e] <: scala.collection.GenSeq[e], RSEQ[e] <: scala.collection.GenSeq[e]]=> org.scalactic.EqualityConstraint[LSEQ[Nothing],RSEQ[Nothing]] match expected type org.scalactic.EqualityConstraint[scala.collection.immutable.Vector[A],List[Nothing]] Vector.empty === List.empty ^ scala> Vector.empty === List.empty[Int] res3: Boolean = true scala> Vector.empty[String] === List.empty res4: Boolean = true Fail to compile if L will always equal R. Saturday, August 9, 2014
  • 11. Candidate rule: To compile, an equality comparison must be interesting: values of types L and R can be either equal or unequal. Saturday, August 9, 2014
  • 12. scala> case class Complex(real: Double, imaginary: Double) defined class Complex scala> implicit def convertIntToComplex(i: Int): Complex = Complex(i, 0.0) convertIntToComplex: (i: Int)Complex scala> 42 === Complex(42, 0) <console>:24: error: types Int and Complex do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.EqualityConstraint[Int,Complex] 42 === Complex(42, 0) ^ scala> Complex(42, 0) === 42 <console>:24: error: types Complex and Int do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.EqualityConstraint[Complex,Int] Complex(42, 0) === 42 ^ What about implicit conversions? Saturday, August 9, 2014
  • 13. scala> implicit val enabler = EqualityEnabledBetween[Int, Complex] enabler: org.scalactic.EqualityEnabledBetween[Int,Complex] = org.scalactic.EqualityEnabledBetween@e5d2d9b scala> 42 === Complex(42, 0) res2: Boolean = true scala> Complex(42, 0) === 42 res3: Boolean = true scala> new AnyShouldWrapper(1) === 1 // Probably shouldn't enable... Intuition: enable some but not all But what would the rule be? Saturday, August 9, 2014
  • 14. OK if the conversion is an injection scala> case class DigitString(digits: String) { | val toInt: Int = digits.toInt | } defined class DigitString scala> implicit def convert(d: DigitString): Int = | d.digits.toInt convertDigitStringToInt: (d: DigitString)Int scala> DigitString("42") === DigitString("042") res0: Boolean = false scala> DigitString("42").toInt === DigitString("042").toInt res1: Boolean = true John C. Reynolds: Using category theory to design implicit conversions and generic operators. Saturday, August 9, 2014
  • 15. How to decide: 1.To compile, an equality comparison must be interesting: values of types L and R can be either equal or unequal. 2.Allow select implicit conversions to be enabled, and recommend that non-widening conversions (non-injections) not be enabled. Saturday, August 9, 2014
  • 16. scala> (Some(1): Option[Int]) === Some(1) res0: Boolean = true scala> Some(1) === (Some(1): Option[Int]) res1: Boolean = true scala> Some(1) === Some(1) res2: Boolean = true What about the implicit conversion from subtype to supertype (<:<)? Saturday, August 9, 2014
  • 17. scala> def eqv[T](a: T, b: T): Boolean = a === b eqv: [T](a: T, b: T)Boolean scala> eqv(1, ()) res3: Boolean = false scala> ((i: Int) => i + 1) === ((i: Int) => i + 1) res4: Boolean = false Even though <:< is an injection, is it always desireable? Saturday, August 9, 2014
  • 19. scala> import EnabledEquality._ import EnabledEquality._ scala> def eqv[T](a: T, b: T): Boolean = a === b <console>:19: error: types T and T do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.EqualityConstraint[T,T] def eqv[T](a: T, b: T): Boolean = a === b ^ scala> ((i: Int) => i + 1) === ((i: Int) => i + 1) <console>:20: error: types Int => Int and Int => Int do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.EqualityConstraint[Int => Int,Int => Int] ((i: Int) => i + 1) === ((i: Int) => i + 1) ^ EnabledEquality benefit Saturday, August 9, 2014
  • 20. scala> case class Person(name: String) defined class Person scala> Person("Sue") === Person("Sue") <console>:22: error: types Person and Person do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.EqualityConstraint[Person,Person] Person("Sue") === Person("Sue") ^ scala> implicit val enabler = new EqualityEnabledFor[Person] enabler: org.scalactic.EqualityEnabledFor[Person] = org.scalactic.EqualityEnabledFor@1289d391 scala> Person("Sue") === Person("Sue") res2: Boolean = true EnabledEquality cost Saturday, August 9, 2014
  • 21. scala> 1 should === ("one") <console>:23: error: types Int and String do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalactic.Constraint[Int,String] 1 should === ("one") ^ scala> 1 should equal ("one") <console>:23: error: could not find implicit value for parameter typeClass1: org.scalactic.enablers.EvidenceThat[String]#CanEqual[Int] 1 should equal ("one") ^ scala> 1 should be ("one") <console>:23: error: could not find implicit value for parameter typeClass1: org.scalactic.enablers.EvidenceThat[String]#CanEqual[Int] 1 should be ("one") ^ scala> 1 should be_== ("one") org.scalatest.exceptions.TestFailedException: 1 was not equal to "one" ScalaTest's equal, be, and be_== Saturday, August 9, 2014
  • 22. scala> List(1, 2, 3) should contain ("one") <console>:23: error: could not find implicit value for parameter typeClass1: org.scalactic.enablers.EvidenceThat[String]#CanBeContainedIn[List[Int]] List(1, 2, 3) should contain ("one") ^ scala> List(1, 2, 3) should contain oneOf ("one", "two") <console>:23: error: could not find implicit value for parameter evidence: org.scalactic.enablers.EvidenceThat[String]#CanBeContainedIn[List[Int]] List(1, 2, 3) should contain oneOf("one", "two") ^ scala> 1 isIn List(1, 2, 3) res14: Boolean = true scala> "one" isIn List(1, 2, 3) <console>:23: error: Could not find evidence that String can be contained in List[Int]; the missing implicit parameter is of type org.scalactic.enablers.ContainingConstraint[List[Int],String] "one" isIn List(1, 2, 3) ^ ScalaTest's contain, Scalactic's isIn/isNotIn Saturday, August 9, 2014
  • 23. if sufficientTimeRemains then (Q => A) else thanks artima.com/shop 15% discount coupon code: BYTHEBAY2014 Saturday, August 9, 2014
  • 24. scala> 1L === 1 res0: Boolean = true scala> 1 === 1L <console>:14: error: could not find implicit value for parameter F0: scalaz.Equal[Any] 1 === 1L ^ Scalaz or Spire Scalactic scala> 1L === 1 res7: Boolean = true scala> 1 === 1L res8: Boolean = true Equal[T], Eq[T] EqualityConstraint[L, R] Equivalence[T] Saturday, August 9, 2014