31
@MSkarsaune #DV14 #ScalaCalculations Bring Your Calculations to: [email protected] Kantega Norwegian software craftsmanship since 2003

Bring your calculations to Scala!

Embed Size (px)

DESCRIPTION

Quickie talk to be held at Devoxx

Citation preview

Page 1: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Bring Your Calculations to:[email protected]

Kantega – Norwegian software craftsmanship since 2003

高馬丁

Page 2: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

1.The Situation

Page 3: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

• Exact representation of values within range

• Interoperable through widening conversion

Integer

float double byte short int long

Java Number Types - Integer

Page 4: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

• Approximate representation of numeric values

• NEVER use for monetary amounts

• Interoperable with integer types through widening

conversion

Floating point Integer

float double byte short int long

Java Number Types – Floating point

Page 5: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

• Immutable

• Calculation possible via primitives

• Interoperability through widening conversion

Floating point Integer Number

Float Double Byte Short Integer Long BigInteger BigDecimal

float double byte short int long

boxingunboxin

g

Java Number Types - Boxed

Page 6: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

• To represent large numbers

• Calculations with methods

• Cumbersome conversions

“Infinite”Floating point Integer Number

Float Double Byte Short Integer Long BigInteger BigDecimal

float double byte short int long

Java Object Number - Extended

Poor

interoperabilit

y

Page 7: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

2. Inspiration

Page 8: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Smalltalk calculations

Numbers are objects

Binary message selectors (+, -, *, / , ….)

Built in decimals

Overflows handled

Precise division

Interoperable and extendable number types

Page 9: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

The Hope

Page 10: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Main Scala language number types

AnyVal

Double Int Long

ScalaNumber

BigDecimal BigInt

Page 11: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

1. Decimal Numbers

Page 12: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Decimal representation

• Integer value and scale

• 123456789

• Scale is important! Know your scale!

Scale = 3

1234567891000

Page 13: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Decimal notation

• Smalltalk: 2.5s2

• Java: new BigDecimal("2.50")

new BigDecimal(2.5).setScale(2)

• Scala: val dec : BigDecimal = 2.50

How is this possible?

Page 14: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Scala Implicit Type Conversion

• Implicit type conversion

• Compiler looks for implicit function to convert source type

to target type

• Object scala.math.BigDecimal:

/** Implicit conversion from `Double` to `BigDecimal`. */

implicit def double2bigDecimal(

d: Double): BigDecimal = decimal(d)

Page 15: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Decimal computation

• Task multiply decimal dec by 100:

• Smalltalk: dec * 100

• Java: dec.multiply(new BigDecimal(100));

• Scala: dec * 100

What does this mean?

Page 16: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Infix, symbols + implicit conversion

• Special characters as method identifiers (+ , - , ∙, √, ⊂, π

…)

• Infix notation: num.*(100) <==> num * 100

• Class scala.math.BigDecimal:

• Also works: 100 * num

/** Multiplication of BigDecimals */

def * (that: BigDecimal): BigDecimal

= new BigDecimal(

this.bigDecimal.multiply(that.bigDecimal, mc), mc)

Page 17: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Decimal calculation summary

• Natural syntax

• Operators and literals

• Interoperable with other number types

• Withouth having to change existing number types

Page 18: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Spire math

• Scala calculation library:

https://github.com/non/spire

• Generic algorithms

• Extended number types, such as

• Rational

• Real

• Complex

• Macros provide additional number literal syntax

Page 19: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

4. Overflow1_000_000 * 1_000_000 = ?

1_000_000_000_000 ?

-727_379_968

Page 20: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Overflow management

• Smalltalk:

Automatically converts SmallInteger <=> LargeInteger

• Java:

Libraries such as guava or Apache commons-math can

detect

Page 21: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

(Some) Spire number types

• SafeLong detects overflows and ensures optimal

representation

ScalaNumber

SafeLong Real Rational Complex

Page 22: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

SafeLong example

val trillion : SafeLong = 1000000000000l //SafeLongLong

val product = trillion * trillion //SafeLongBigInt

val other = product / trillion //SafeLongLong

Page 23: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

3. Division2 / 3 = ?

0 ?

0.6666666666666666 ?

0.6666666666666667 ?

2

3?

Page 24: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Precise division

• Smalltalk: 3 / 3 = 1

2 / 3 =2

3* 3 = 2

Page 25: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

(Some) Spire number types

• Real ensures exact division and always chooses the

most precise representation

ScalaNumber

SafeLong Real Rational Complex

Page 26: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Real example

val numerator: Real = 2 //Real$Exact(2)

val fraction = numerator / 3 //Real$Exact(2/3)

fraction * 3 //Real$Exact(2)

fraction * Real.pi

//Real$Inexact(2.0943951023931954923084289221863352561314)

Page 27: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Some conversion code of our own

….final class DoubleSyntax(val value : Double) {

def scaled(scale : Int) = BigDecimal(value).setScale(scale)

def i = Complex(0.0, value)

}

object DoubleSyntax {

implicit def doubleToDoubleConverter(value : Double) =

new DoubleSyntax(value)

}

Page 28: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

… that allows us to write

val dec : BigDecimal = 2.50

val dec = 2.5 scaled 2 // BigDecimal(2.50) “2.5s2”

val complex = -1.0 + 1.0.i // Complex(-1.0, 1.0)

Page 29: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Conclusion

• Scala brings

• Natural syntax: special characters + infix notation

• Extendability and interoperability: implicit type conversions

• Possible improvements (as demonstrated by spire math)

• New number types

• New calculations

Page 30: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

References

http://www.scala-lang.org/

Spire:

https://github.com/non/spire

Sample code:

https://github.com/skarsaune/devoxx.scala.calculations

Page 31: Bring your calculations to Scala!

@MSkarsaune#DV14 #ScalaCalculations

Thank you for your time