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

Bring your calculations to Scala!

Jul 02, 2015

Download

Software

Quickie talk to be held at Devoxx
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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