SlideShare uma empresa Scribd logo
1 de 57
Effective way to code in ScalaEffective way to code in Scala
Satendra Kumar
Software Consultant
Knoldus Software LLP
Topics Covered
➢ Pattern match
➢ Pattern match vs if/else
➢ var vs val
➢ Try/catch
➢ Loop vs recursion
➢ Tuple usage
➢ getOrElse vs fold
➢ Future Composition
➢ Scala ExecutionContext
➢ Play ExecutionContext
➢ Akka ExecutionContext
Pattern Match
trait Arithmetic
case class Add(a: Int, b: Int) extends Arithmetic
case class Subtract(a: Int, b: Int) extends Arithmetic
case class Multiply(a: Int, b: Int) extends Arithmetic
def calculate(expr: Arithmetic): Int =
expr match {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
}
Pattern Match
trait Arithmetic
case class Add(a: Int, b: Int) extends Arithmetic
case class Subtract(a: Int, b: Int) extends Arithmetic
case class Multiply(a: Int, b: Int) extends Arithmetic
def calculate(expr: Arithmetic): Int =
expr match {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
}
Calling from another class:
calculate(Add(2,3))
// output => 5
Pattern Match
trait Arithmetic
case class Add(a: Int, b: Int) extends Arithmetic
case class Subtract(a: Int, b: Int) extends Arithmetic
case class Multiply(a: Int, b: Int) extends Arithmetic
def calculate(expr: Arithmetic): Int =
expr match {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
}
//Calling from another class:
case class IncrementByOne(number: Int) extends Arithmetic
calculate(IncrementByOne(2))
// output => ?
Pattern Match
trait Arithmetic
case class Add(a: Int, b: Int) extends Arithmetic
case class Subtract(a: Int, b: Int) extends Arithmetic
case class Multiply(a: Int, b: Int) extends Arithmetic
def calculate(expr: Arithmetic): Int =
expr match {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
}
//Calling from another class:
case class IncrementByOne(number: Int) extends Arithmetic
calculate(IncrementByOne(2))
// output => Match error
Pattern Match
sealed trait Arithmetic
case class Add(a: Int, b: Int) extends Arithmetic
case class Subtract(a: Int, b: Int) extends Arithmetic
case class Multiply(a: Int, b: Int) extends Arithmetic
def calculate(expr: Arithmetic): Int =
expr match {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
}
Alway use sealed keyword to avoid match error.
Pattern match
sealed trait Arithmetic
case class Add(a: Int, b: Int) extends Arithmetic
case class Subtract(a: Int, b: Int) extends Arithmetic
case class Multiply(a: Int, b: Int) extends Arithmetic
case class IncrementByOne(number: Int) extends Arithmetic
val exprs = List(Add(2, 3), Subtract(5, 3), Multiply(2, 3))
exprs map { expr =>
expr match {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
case IncrementByOne(a) => a + 1
}
}
Pattern match
sealed trait Arithmetic
case class Add(a: Int, b: Int) extends Arithmetic
case class Subtract(a: Int, b: Int) extends Arithmetic
case class Multiply(a: Int, b: Int) extends Arithmetic
case class IncrementByOne(number: Int) extends Arithmetic
val exprs = List(Add(2, 3), Subtract(5, 3), Multiply(2, 3))
exprs map { expr =>
expr match {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
case IncrementByOne(a) => a + 1
}
}
Improvement ?
Pattern Match
val exprs = List(Add(2, 3), Subtract(5, 3), Multiply(2, 3))
exprs map {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
case IncrementByOne(a) => a + 1
}
Pattern Match
def calculate(expr: Arithmetic): Int =
expr match {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
case IncrementByOne(a) => a + 1
case IncrementByTwo(a) => a + 2
case IncrementByThree(a) => a + 3
case IncrementByFour(a) => a + 4
case IncrementByFive(a) => a + 5
case IncrementBySix(a) => a + 6
case IncrementBySeven(a) => a + 7
case IncrementByEight(a) => a + 8
}
Cyclomatic complexity > 10
Pattern Match
def calculate(expr: Arithmetic): Int = binaryOperation.orElse(increment)(expr)
val binaryOperation: PartialFunction[Arithmetic, Int] = {
case Add(a, b) => a + b
case Subtract(a, b) => a + b
case Multiply(a, b) => a + b
}
val increment: PartialFunction[Arithmetic, Int] = {
case IncrementByOne(a) => a + 1
case IncrementByTwo(a) => a + 2
case IncrementByThree(a) => a + 3
case IncrementByFour(a) => a + 4
case IncrementByFive(a) => a + 5
case IncrementBySix(a) => a + 6
case IncrementBySeven(a) => a + 7
case IncrementByEight(a) => a + 8
}
Pattern Match
def method1(flag: Boolean):String =
flag match {
case true => "TRUE"
case false => "FALSE"
}
def method2(flag: Boolean): String =
if (flag)
"TRUE"
else
"FALSE"
public java.lang.String method1(boolean);
Code:
0: iload_1
1: istore_2
2: iconst_1
3: iload_2
4: if_icmpne 13
7: ldc #9
9: astore_3
10: goto 21
13: iconst_0
14: iload_2
15: if_icmpne 23
18: ldc #11
20: astore_3
21: aload_3
22: areturn
23: new #13
26: dup
27: iload_2
28: invokestatic #19
31: invokespecial #23
34: athrow
public java.lang.String method2(boolean);
Code:
0: iload_1
1: ifeq 9
4: ldc #9
6: goto 11
9: ldc #11
11: areturn
public java.lang.String method1(boolean);
Code:
0: iload_1
1: istore_2
2: iconst_1
3: iload_2
4: if_icmpne 13
7: ldc #9
9: astore_3
10: goto 21
13: iconst_0
14: iload_2
15: if_icmpne 23
18: ldc #11
20: astore_3
21: aload_3
22: areturn
23: new #13
26: dup
27: iload_2
28: invokestatic #19
31: invokespecial #23
34: athrow
public java.lang.String method2(boolean);
Code:
0: iload_1
1: ifeq 9
4: ldc #9
6: goto 11
9: ldc #11
11: areturn
Avoid pattern match on boolean value
If/else
def method(flag: Boolean): String =
if (flag == true)
"TRUE"
else
"FALSE"
What is the problem ?
If/else
//Incorrect
def method(flag: Boolean): String =
if (flag == true)
"TRUE"
else
"FALSE"
//correct
def method(flag: Boolean): String =
if (flag)
"TRUE"
else
"FALSE"
val vs var
Variable type Collection type Example
val vs var
Variable type Collection type Example
Immutable Immutable Best
val map = Map("name" -> "sky")
val vs var
Variable type Collection type Example
Immutable Immutable Best
Mutable Immutable Good
val map = Map("name" -> "sky")
var map = Map("name" -> "sky")
val vs var
Variable type Collection type Example
Immutable Immutable Best
Mutable Immutable Good
Immutable Mutable Ok
val map = Map("name" -> "sky")
val map = mutable.Map("name" -> "sky")
var map = Map("name" -> "sky")
val vs var
Variable type Collection type Example
Immutable Immutable Best
Mutable Immutable Good
Immutable Mutable Ok
Mutable Mutable worst
val map = Map("name" -> "sky")
val map = mutable.Map("name" -> "sky")
var map = Map("name" -> "sky")
var map = mutable.Map("name" -> "sky")
val vs var
Variable type Collection type Example
Immutable Immutable Best
Mutable Immutable Good
Immutable Mutable Ok
Mutable Mutable worst
val map = Map("name" -> "sky")
val map = mutable.Map("name" -> "sky")
var map = Map("name" -> "sky")
var map = mutable.Map("name" -> "sky")
Never use combination of both mutable variable and mutable collection
Try/catch
try {
doSomething()
} catch {
case th: Throwable =>
someHandler()
}
Try/catch
try {
doSomething()
} catch {
case th: Throwable =>
someHandler()
}
MUST NOT catch Throwable when catching Exceptions
Try/catch
import scala.util.control.NonFatal
try {
doSomething()
} catch {
case NonFatal(ex) =>
someHandler()
}
Try/catch
object NonFatal {
/**
* Returns true if the provided `Throwable` is to be considered non-fatal, or
false if it is to be considered fatal
*/
def apply(t: Throwable): Boolean = t match {
// VirtualMachineError includes OutOfMemoryError and other fatal errors
case _: VirtualMachineError | _: ThreadDeath |
_: InterruptedException | _: LinkageError | _: ControlThrowable => false
case _ => true
}
/**
* Returns Some(t) if NonFatal(t) == true, otherwise None
*/
def unapply(t: Throwable): Option[Throwable] = if (apply(t)) Some(t) else None
}
Loop vs recursion
def factorialUsingLoop(n: Int): Int = {
var accumulator = 1
var i = 1
while (i <= n) {
accumulator = i * accumulator
i += 1
}
accumulator
}
def factorialUsingRecursion(n: Int): Int = {
@tailrec
def fac(n: Int, acc: Int): Int = n match {
case _ if n == 1 => acc
case _ => fac(n - 1, n * acc)
}
fac(n, 1)
}
Tuple usage
def wordCount(text: String): List[(String, Int)] =
text.split(" +").groupBy(word => word)
.map { word => (word._1, word._2.length) }
.toList
.sortBy(_._2)
.reverse
Tuple usage
def wordCount(text: String): List[(String, Int)] =
text.split(" +").groupBy(word => word)
.map { word => (word._1, word._2.length) }
.toList
.sortBy(_._2)
.reverse
def wordCount(text: String): List[(String, Int)] =
text.split(" +").groupBy(identity)
.map { case (word, frequency) => (word, frequency.length) }
.toList
.sortBy { case (_, count) => count }
.reverse
// More Readable
Tuple usage
def wordCount(text: String): List[(String, Int)] =
text.split(" +").groupBy(word => word)
.map { word => (word._1, word._2.length) }
.toList
.sortBy(_._2)
.reverse
def wordCount(text: String): List[(String, Int)] =
text.split(" +").groupBy(identity)
.map { case (word, frequency) => (word, frequency.length) }
.toList
.sortBy { case (_, count) => count }
.reverse
// More Readable
Avoid _1 and _2 method for accessing tuple value
getOrElse vs fold
val optionalInt:Option[Int]=Some(1)
val intValue= optionalInt.getOrElse("0")
getOrElse vs fold
val optionalInt:Option[Int]=Some(1)
val intValue= optionalInt.getOrElse("0")
String value
getOrElse vs fold
val optionalInt:Option[Int]=Some(1)
val intValue= optionalInt.getOrElse("0")
String value
Type of intValue become Any
val intValue= optionalInt.fold("0")(v =>v)
getOrElse vs fold
val optionalInt:Option[Int]=Some(1)
val intValue= optionalInt.getOrElse("0")
String value
Type of intValue become Any
val intValue= optionalInt.fold("0")(v =>v)
Compilation Error
getOrElse vs fold
val optionalInt:Option[Int]=Some(1)
val intValue= optionalInt.getOrElse("0")
String value
Type of intValue become Any
val intValue= optionalInt.fold(0)(v =>v)
getOrElse is not typesafe so use fold instead of getOrElse
head and get
val list =List[Int]().head
head and get
val list =List[Int]().head
Exception: head of empty list
val list =List[Int]().headOption
val optionalInt: Option[Int] = None
val intValue = optionalInt.get
head and get
val list =List[Int]().head
Exception: head of empty list
val list =List[Int]().headOption
val optionalInt: Option[Int] = None
val intValue = optionalInt.get
scala.None$.get
val intValue = optionalInt.fold(0)(v=>v)
head and get
val list =List[Int]().head
Exception: head of empty list
val list =List[Int]().headOption
val optionalInt: Option[Int] = None
val intValue = optionalInt.get
scala.None$.get
val intValue = optionalInt.fold(0)(v=>v)
Alway Avoid head and get method
Loop vs recursion
def factorialUsingLoop(n: Int): Int = {
var accumulator = 1
var i = 1
while (i <= n) {
accumulator = i * accumulator
i += 1
}
accumulator
}
def factorialUsingRecursion(n: Int): Int = {
@tailrec
def fac(n: Int, acc: Int): Int = n match {
case _ if n == 1 => acc
case _ => fac(n - 1, n * acc)
}
fac(n, 1)
}
Avoid looping if possible and use tail recursion
Future Composition
def composingFuture(): Future[Int] = {
val firstFuture: Future[Int] = method1()
val secondFuture: Future[Int] = firstFuture.flatMap { v => method2(v) }
val thirdFuture: Future[Int] = secondFuture.flatMap { v => method3(v) }
val fourthFuture: Future[Int] = method4() // no composition
val result: Future[Int] = thirdFuture.flatMap { v => method5(v) }
result
}
def method1(): Future[Int] = ???
def method2(value: Int): Future[Int] = ???
def method3(value: Int): Future[Int] = ???
def method4(): Future[Int] = ???
def method5(value: Int): Future[Int] = ???
Future Composition
def composingFuture(): Future[Int] = {
val firstFuture: Future[Int] = method1()
val secondFuture: Future[Int] = firstFuture.flatMap { v => method2(v) }
val thirdFuture: Future[Int] = secondFuture.flatMap { v => method3(v) }
val fourthFuture: Future[Int] = method4() // no composition
val result: Future[Int] = thirdFuture.flatMap { v => method5(v) }
result
}
def method1(): Future[Int] = ???
def method2(value: Int): Future[Int] = ???
def method3(value: Int): Future[Int] = ???
def method4(): Future[Int] = ???
def method5(value: Int): Future[Int] = ???
what is the problem ?
Future Composition
def composingFuture(): Future[Int] = {
val firstFuture: Future[Int] = method1()
val secondFuture: Future[Int] = firstFuture.flatMap { v => method2(v) }
val thirdFuture: Future[Int] = secondFuture.flatMap { v => method3(v) }
val fourthFuture: Future[Int] = method4()
val result: Future[Int] = thirdFuture.flatMap { v => method5(v) }
fourthFuture.flatMap{ _=> result}// composing fourth future value
}
def method1(): Future[Int] = ???
def method2(value: Int): Future[Int] = ???
def method3(value: Int): Future[Int] = ???
def method4(): Future[Int] = ???
def method5(value: Int): Future[Int] = ???
Fixed Value for Future
import scala.concurrent.ExecutionContext.Implicits.global
def calculate(value: Option[Int]): Future[Int] =
value match {
case Some(v) => method(v)
case None => Future(0)
}
def method(value: Int): Future[Int] = ???
Fixed Value for Future
def calculate(value: Option[Int]): Future[Int] =
value match {
case Some(v) => method(v)
case None => Future.successful(0)
}
def method(value: Int): Future[Int] = ???
Alway use Future.successful for fixed value and Future.failed for exception
Scala ExecutionContext
➢ ForkJoinPool
➢ scala.concurrent.context.minThreads = “1”
➢ scala.concurrent.context.numThreads =”x1”
x1 means => Runtime.getRuntime.availableProcessors * 1
➢ scala.concurrent.context.maxThreads ="x1”
➢ Avalable in scala.concurrent.ExecutionContext.Implicits.global
Scala ExecutionContext
➢ ForkJoinPool
➢ scala.concurrent.context.minThreads = “1”
➢ scala.concurrent.context.numThreads =”x1”
x1 means => Runtime.getRuntime.availableProcessors * 1
➢ scala.concurrent.context.maxThreads ="x1”
➢ Avalable in scala.concurrent.ExecutionContext.Implicits.global
Don't use Scala ExecutionContext for IO operations
For heavy IO
import java.util.concurrent.Executors
object ExecutionContext {
///read from config or environment
val CONCURRENCY_FACTOR = 3
object IO {
/**
* Responsible to handle all DB calls
*/
implicit lazy val dbOperations: concurrent.ExecutionContext =
concurrent.ExecutionContext
.fromExecutor(
Executors.newFixedThreadPool(
Runtime.getRuntime.availableProcessors() * CONCURRENCY_FACTOR
)
)
}
}
For light weight IO
import java.util.concurrent.Executors
object ExecutionContext {
object IO {
/**
* Responsible to handle all light weight IO
*/
implicit lazy val simpleOperations: concurrent.ExecutionContext =
concurrent.ExecutionContext.fromExecutor(Executors.newCachedThreadPool())
}
}
Play ExecutionContext
● Available in play.api.libs.concurrent.Execution.Implicits.defaultContext
● default configuration for Play’s thread pool:
akka {
actor {
default-dispatcher {
fork-join-executor {
parallelism-factor = 1.0
parallelism-max = 24
# Setting this to LIFO changes the fork-join-executor
# to use a stack discipline for task scheduling. This usually
# improves throughput at the cost of possibly increasing
# latency and risking task starvation (which should be rare).
task-peeking-mode = LIFO
}
}
}
}
Akka ExecutionContext
The default Akka configuration:
akka {
actor {
default-dispatcher {
fork-join-executor {
parallelism-min = 8
parallelism-factor = 3.0
parallelism-max = 64
task-peeking-mode = "FIFO"
}
}
}
}
For light weight IO
For IO use thread-pool-executor.
For Example:
my-thread-pool-dispatcher {
type = Dispatcher
executor = "thread-pool-executor"
thread-pool-executor {
core-pool-size-min = 20
core-pool-size-factor = 20
core-pool-size-max = 100
}
throughput = 1
}
For Heavy IO
For IO use thread-pool-executor.
For Example:
my-thread-pool-dispatcher {
type = Dispatcher
executor = "thread-pool-executor"
thread-pool-executor {
core-pool-size-min = 8
core-pool-size-factor = 3
core-pool-size-max = 16
}
throughput = 1
}
Thump Rule
● In Scala, use Scala ExecutionContext
● In Play, use Play ExecutionContext
● In Akka, use Akka ExecutionContext
● In Akka, One ActorSystem per Application
References
● http://doc.akka.io
● https://www.playframework.com/documentation/2.5
● http://twitter.github.io/effectivescala
● https://github.com/alexandru/scala-best-practices
Thanks

Mais conteúdo relacionado

Mais procurados

Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1Philip Schwarz
 
Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Luka Jacobowitz
 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Philip Schwarz
 
TI1220 Lecture 8: Traits & Type Parameterization
TI1220 Lecture 8: Traits & Type ParameterizationTI1220 Lecture 8: Traits & Type Parameterization
TI1220 Lecture 8: Traits & Type ParameterizationEelco Visser
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystifiedAlessandro Lacava
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
 
Python programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operationsPython programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operationsMegha V
 
Monoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsMonoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsPhilip Schwarz
 
Arrays in Data Structure and Algorithm
Arrays in Data Structure and Algorithm Arrays in Data Structure and Algorithm
Arrays in Data Structure and Algorithm KristinaBorooah
 
[FLOLAC'14][scm] Functional Programming Using Haskell
[FLOLAC'14][scm] Functional Programming Using Haskell[FLOLAC'14][scm] Functional Programming Using Haskell
[FLOLAC'14][scm] Functional Programming Using HaskellFunctional Thursday
 
Scala 3 enum for a terser Option Monad Algebraic Data Type
Scala 3 enum for a terser Option Monad Algebraic Data TypeScala 3 enum for a terser Option Monad Algebraic Data Type
Scala 3 enum for a terser Option Monad Algebraic Data TypePhilip Schwarz
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...Philip Schwarz
 
Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsPhilip Schwarz
 

Mais procurados (20)

Functors
FunctorsFunctors
Functors
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
Python list
Python listPython list
Python list
 
Python programming : Strings
Python programming : StringsPython programming : Strings
Python programming : Strings
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1
 
Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020
 
Clojure basics
Clojure basicsClojure basics
Clojure basics
 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
 
TI1220 Lecture 8: Traits & Type Parameterization
TI1220 Lecture 8: Traits & Type ParameterizationTI1220 Lecture 8: Traits & Type Parameterization
TI1220 Lecture 8: Traits & Type Parameterization
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystified
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
Python data handling
Python data handlingPython data handling
Python data handling
 
Python programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operationsPython programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operations
 
Monoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsMonoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and Cats
 
Arrays in Data Structure and Algorithm
Arrays in Data Structure and Algorithm Arrays in Data Structure and Algorithm
Arrays in Data Structure and Algorithm
 
[FLOLAC'14][scm] Functional Programming Using Haskell
[FLOLAC'14][scm] Functional Programming Using Haskell[FLOLAC'14][scm] Functional Programming Using Haskell
[FLOLAC'14][scm] Functional Programming Using Haskell
 
Scala 3 enum for a terser Option Monad Algebraic Data Type
Scala 3 enum for a terser Option Monad Algebraic Data TypeScala 3 enum for a terser Option Monad Algebraic Data Type
Scala 3 enum for a terser Option Monad Algebraic Data Type
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
 
Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generators
 

Destaque

A Step to programming with Apache Spark
A Step to programming with Apache SparkA Step to programming with Apache Spark
A Step to programming with Apache SparkKnoldus Inc.
 
Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Knoldus Inc.
 
Akka Finite State Machine
Akka Finite State MachineAkka Finite State Machine
Akka Finite State MachineKnoldus Inc.
 
Meet Up - Spark Stream Processing + Kafka
Meet Up - Spark Stream Processing + KafkaMeet Up - Spark Stream Processing + Kafka
Meet Up - Spark Stream Processing + KafkaKnoldus Inc.
 
Introduction to Kafka connect
Introduction to Kafka connectIntroduction to Kafka connect
Introduction to Kafka connectKnoldus Inc.
 
Introduction to Apache Kafka- Part 1
Introduction to Apache Kafka- Part 1Introduction to Apache Kafka- Part 1
Introduction to Apache Kafka- Part 1Knoldus Inc.
 
Introduction to AWS IAM
Introduction to AWS IAMIntroduction to AWS IAM
Introduction to AWS IAMKnoldus Inc.
 
Introduction to Scala JS
Introduction to Scala JSIntroduction to Scala JS
Introduction to Scala JSKnoldus Inc.
 
Getting Started With AureliaJs
Getting Started With AureliaJsGetting Started With AureliaJs
Getting Started With AureliaJsKnoldus Inc.
 
Drilling the Async Library
Drilling the Async LibraryDrilling the Async Library
Drilling the Async LibraryKnoldus Inc.
 
Realm Mobile Database - An Introduction
Realm Mobile Database - An IntroductionRealm Mobile Database - An Introduction
Realm Mobile Database - An IntroductionKnoldus Inc.
 
Mailchimp and Mandrill - The ‘Hominidae’ kingdom
Mailchimp and Mandrill - The ‘Hominidae’ kingdomMailchimp and Mandrill - The ‘Hominidae’ kingdom
Mailchimp and Mandrill - The ‘Hominidae’ kingdomKnoldus Inc.
 
String interpolation
String interpolationString interpolation
String interpolationKnoldus Inc.
 
Shapeless- Generic programming for Scala
Shapeless- Generic programming for ScalaShapeless- Generic programming for Scala
Shapeless- Generic programming for ScalaKnoldus Inc.
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8Knoldus Inc.
 
An Introduction to Quill
An Introduction to QuillAn Introduction to Quill
An Introduction to QuillKnoldus Inc.
 
Introduction to Scala Macros
Introduction to Scala MacrosIntroduction to Scala Macros
Introduction to Scala MacrosKnoldus Inc.
 

Destaque (20)

BDD with Cucumber
BDD with CucumberBDD with Cucumber
BDD with Cucumber
 
A Step to programming with Apache Spark
A Step to programming with Apache SparkA Step to programming with Apache Spark
A Step to programming with Apache Spark
 
Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2
 
Akka Finite State Machine
Akka Finite State MachineAkka Finite State Machine
Akka Finite State Machine
 
Meet Up - Spark Stream Processing + Kafka
Meet Up - Spark Stream Processing + KafkaMeet Up - Spark Stream Processing + Kafka
Meet Up - Spark Stream Processing + Kafka
 
Introduction to Kafka connect
Introduction to Kafka connectIntroduction to Kafka connect
Introduction to Kafka connect
 
Introduction to Apache Kafka- Part 1
Introduction to Apache Kafka- Part 1Introduction to Apache Kafka- Part 1
Introduction to Apache Kafka- Part 1
 
Introduction to AWS IAM
Introduction to AWS IAMIntroduction to AWS IAM
Introduction to AWS IAM
 
Introduction to Scala JS
Introduction to Scala JSIntroduction to Scala JS
Introduction to Scala JS
 
Akka streams
Akka streamsAkka streams
Akka streams
 
Getting Started With AureliaJs
Getting Started With AureliaJsGetting Started With AureliaJs
Getting Started With AureliaJs
 
Drilling the Async Library
Drilling the Async LibraryDrilling the Async Library
Drilling the Async Library
 
Realm Mobile Database - An Introduction
Realm Mobile Database - An IntroductionRealm Mobile Database - An Introduction
Realm Mobile Database - An Introduction
 
Mailchimp and Mandrill - The ‘Hominidae’ kingdom
Mailchimp and Mandrill - The ‘Hominidae’ kingdomMailchimp and Mandrill - The ‘Hominidae’ kingdom
Mailchimp and Mandrill - The ‘Hominidae’ kingdom
 
String interpolation
String interpolationString interpolation
String interpolation
 
Shapeless- Generic programming for Scala
Shapeless- Generic programming for ScalaShapeless- Generic programming for Scala
Shapeless- Generic programming for Scala
 
Kanban
KanbanKanban
Kanban
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8
 
An Introduction to Quill
An Introduction to QuillAn Introduction to Quill
An Introduction to Quill
 
Introduction to Scala Macros
Introduction to Scala MacrosIntroduction to Scala Macros
Introduction to Scala Macros
 

Semelhante a Effective way to code in Scala

Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
 
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 worldDebasish Ghosh
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersTikal Knowledge
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming iiPrashant Kalkar
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaDaniel Sebban
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalazoxbow_lakes
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In ScalaSkills Matter
 
Built in classes in java
Built in classes in javaBuilt in classes in java
Built in classes in javaMahmoud Ali
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsVasil Remeniuk
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsPhilip Schwarz
 

Semelhante a Effective way to code in Scala (20)

Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in 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
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
 
Array
ArrayArray
Array
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
Array
ArrayArray
Array
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalaz
 
Built-in Classes in JAVA
Built-in Classes in JAVABuilt-in Classes in JAVA
Built-in Classes in JAVA
 
Scala by Luc Duponcheel
Scala by Luc DuponcheelScala by Luc Duponcheel
Scala by Luc Duponcheel
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In Scala
 
Built in classes in java
Built in classes in javaBuilt in classes in java
Built in classes in java
 
Monadologie
MonadologieMonadologie
Monadologie
 
Functional programming in scala
Functional programming in scalaFunctional programming in scala
Functional programming in scala
 
Algebraic Data Types and Origami Patterns
Algebraic Data Types and Origami PatternsAlgebraic Data Types and Origami Patterns
Algebraic Data Types and Origami Patterns
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
ddd+scala
ddd+scaladdd+scala
ddd+scala
 
Stacks.ppt
Stacks.pptStacks.ppt
Stacks.ppt
 

Mais de Knoldus Inc.

Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML ParsingMastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML ParsingKnoldus Inc.
 
Akka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On IntroductionAkka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On IntroductionKnoldus Inc.
 
Entity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptxEntity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptxKnoldus Inc.
 
Introduction to Redis and its features.pptx
Introduction to Redis and its features.pptxIntroduction to Redis and its features.pptx
Introduction to Redis and its features.pptxKnoldus Inc.
 
GraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdfGraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdfKnoldus Inc.
 
NuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptxNuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptxKnoldus Inc.
 
Data Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable TestingData Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable TestingKnoldus Inc.
 
K8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose KubernetesK8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose KubernetesKnoldus Inc.
 
Introduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptxIntroduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptxKnoldus Inc.
 
Robusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptxRobusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptxKnoldus Inc.
 
Optimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptxOptimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptxKnoldus Inc.
 
Azure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptxAzure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptxKnoldus Inc.
 
CQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptxCQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptxKnoldus Inc.
 
ETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake PresentationETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake PresentationKnoldus Inc.
 
Scripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics PresentationScripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics PresentationKnoldus Inc.
 
Getting started with dotnet core Web APIs
Getting started with dotnet core Web APIsGetting started with dotnet core Web APIs
Getting started with dotnet core Web APIsKnoldus Inc.
 
Introduction To Rust part II Presentation
Introduction To Rust part II PresentationIntroduction To Rust part II Presentation
Introduction To Rust part II PresentationKnoldus Inc.
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Configuring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRAConfiguring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRAKnoldus Inc.
 
Advanced Python (with dependency injection and hydra configuration packages)
Advanced Python (with dependency injection and hydra configuration packages)Advanced Python (with dependency injection and hydra configuration packages)
Advanced Python (with dependency injection and hydra configuration packages)Knoldus Inc.
 

Mais de Knoldus Inc. (20)

Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML ParsingMastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
 
Akka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On IntroductionAkka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On Introduction
 
Entity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptxEntity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptx
 
Introduction to Redis and its features.pptx
Introduction to Redis and its features.pptxIntroduction to Redis and its features.pptx
Introduction to Redis and its features.pptx
 
GraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdfGraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdf
 
NuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptxNuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptx
 
Data Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable TestingData Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable Testing
 
K8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose KubernetesK8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose Kubernetes
 
Introduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptxIntroduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptx
 
Robusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptxRobusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptx
 
Optimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptxOptimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptx
 
Azure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptxAzure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptx
 
CQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptxCQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptx
 
ETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake PresentationETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake Presentation
 
Scripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics PresentationScripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics Presentation
 
Getting started with dotnet core Web APIs
Getting started with dotnet core Web APIsGetting started with dotnet core Web APIs
Getting started with dotnet core Web APIs
 
Introduction To Rust part II Presentation
Introduction To Rust part II PresentationIntroduction To Rust part II Presentation
Introduction To Rust part II Presentation
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Configuring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRAConfiguring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRA
 
Advanced Python (with dependency injection and hydra configuration packages)
Advanced Python (with dependency injection and hydra configuration packages)Advanced Python (with dependency injection and hydra configuration packages)
Advanced Python (with dependency injection and hydra configuration packages)
 

Último

why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 

Último (20)

why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 

Effective way to code in Scala

  • 1. Effective way to code in ScalaEffective way to code in Scala Satendra Kumar Software Consultant Knoldus Software LLP
  • 2. Topics Covered ➢ Pattern match ➢ Pattern match vs if/else ➢ var vs val ➢ Try/catch ➢ Loop vs recursion ➢ Tuple usage ➢ getOrElse vs fold ➢ Future Composition ➢ Scala ExecutionContext ➢ Play ExecutionContext ➢ Akka ExecutionContext
  • 3. Pattern Match trait Arithmetic case class Add(a: Int, b: Int) extends Arithmetic case class Subtract(a: Int, b: Int) extends Arithmetic case class Multiply(a: Int, b: Int) extends Arithmetic def calculate(expr: Arithmetic): Int = expr match { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b }
  • 4. Pattern Match trait Arithmetic case class Add(a: Int, b: Int) extends Arithmetic case class Subtract(a: Int, b: Int) extends Arithmetic case class Multiply(a: Int, b: Int) extends Arithmetic def calculate(expr: Arithmetic): Int = expr match { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b } Calling from another class: calculate(Add(2,3)) // output => 5
  • 5. Pattern Match trait Arithmetic case class Add(a: Int, b: Int) extends Arithmetic case class Subtract(a: Int, b: Int) extends Arithmetic case class Multiply(a: Int, b: Int) extends Arithmetic def calculate(expr: Arithmetic): Int = expr match { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b } //Calling from another class: case class IncrementByOne(number: Int) extends Arithmetic calculate(IncrementByOne(2)) // output => ?
  • 6. Pattern Match trait Arithmetic case class Add(a: Int, b: Int) extends Arithmetic case class Subtract(a: Int, b: Int) extends Arithmetic case class Multiply(a: Int, b: Int) extends Arithmetic def calculate(expr: Arithmetic): Int = expr match { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b } //Calling from another class: case class IncrementByOne(number: Int) extends Arithmetic calculate(IncrementByOne(2)) // output => Match error
  • 7. Pattern Match sealed trait Arithmetic case class Add(a: Int, b: Int) extends Arithmetic case class Subtract(a: Int, b: Int) extends Arithmetic case class Multiply(a: Int, b: Int) extends Arithmetic def calculate(expr: Arithmetic): Int = expr match { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b } Alway use sealed keyword to avoid match error.
  • 8. Pattern match sealed trait Arithmetic case class Add(a: Int, b: Int) extends Arithmetic case class Subtract(a: Int, b: Int) extends Arithmetic case class Multiply(a: Int, b: Int) extends Arithmetic case class IncrementByOne(number: Int) extends Arithmetic val exprs = List(Add(2, 3), Subtract(5, 3), Multiply(2, 3)) exprs map { expr => expr match { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b case IncrementByOne(a) => a + 1 } }
  • 9. Pattern match sealed trait Arithmetic case class Add(a: Int, b: Int) extends Arithmetic case class Subtract(a: Int, b: Int) extends Arithmetic case class Multiply(a: Int, b: Int) extends Arithmetic case class IncrementByOne(number: Int) extends Arithmetic val exprs = List(Add(2, 3), Subtract(5, 3), Multiply(2, 3)) exprs map { expr => expr match { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b case IncrementByOne(a) => a + 1 } } Improvement ?
  • 10. Pattern Match val exprs = List(Add(2, 3), Subtract(5, 3), Multiply(2, 3)) exprs map { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b case IncrementByOne(a) => a + 1 }
  • 11. Pattern Match def calculate(expr: Arithmetic): Int = expr match { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b case IncrementByOne(a) => a + 1 case IncrementByTwo(a) => a + 2 case IncrementByThree(a) => a + 3 case IncrementByFour(a) => a + 4 case IncrementByFive(a) => a + 5 case IncrementBySix(a) => a + 6 case IncrementBySeven(a) => a + 7 case IncrementByEight(a) => a + 8 } Cyclomatic complexity > 10
  • 12. Pattern Match def calculate(expr: Arithmetic): Int = binaryOperation.orElse(increment)(expr) val binaryOperation: PartialFunction[Arithmetic, Int] = { case Add(a, b) => a + b case Subtract(a, b) => a + b case Multiply(a, b) => a + b } val increment: PartialFunction[Arithmetic, Int] = { case IncrementByOne(a) => a + 1 case IncrementByTwo(a) => a + 2 case IncrementByThree(a) => a + 3 case IncrementByFour(a) => a + 4 case IncrementByFive(a) => a + 5 case IncrementBySix(a) => a + 6 case IncrementBySeven(a) => a + 7 case IncrementByEight(a) => a + 8 }
  • 13. Pattern Match def method1(flag: Boolean):String = flag match { case true => "TRUE" case false => "FALSE" } def method2(flag: Boolean): String = if (flag) "TRUE" else "FALSE"
  • 14. public java.lang.String method1(boolean); Code: 0: iload_1 1: istore_2 2: iconst_1 3: iload_2 4: if_icmpne 13 7: ldc #9 9: astore_3 10: goto 21 13: iconst_0 14: iload_2 15: if_icmpne 23 18: ldc #11 20: astore_3 21: aload_3 22: areturn 23: new #13 26: dup 27: iload_2 28: invokestatic #19 31: invokespecial #23 34: athrow public java.lang.String method2(boolean); Code: 0: iload_1 1: ifeq 9 4: ldc #9 6: goto 11 9: ldc #11 11: areturn
  • 15. public java.lang.String method1(boolean); Code: 0: iload_1 1: istore_2 2: iconst_1 3: iload_2 4: if_icmpne 13 7: ldc #9 9: astore_3 10: goto 21 13: iconst_0 14: iload_2 15: if_icmpne 23 18: ldc #11 20: astore_3 21: aload_3 22: areturn 23: new #13 26: dup 27: iload_2 28: invokestatic #19 31: invokespecial #23 34: athrow public java.lang.String method2(boolean); Code: 0: iload_1 1: ifeq 9 4: ldc #9 6: goto 11 9: ldc #11 11: areturn Avoid pattern match on boolean value
  • 16. If/else def method(flag: Boolean): String = if (flag == true) "TRUE" else "FALSE" What is the problem ?
  • 17. If/else //Incorrect def method(flag: Boolean): String = if (flag == true) "TRUE" else "FALSE" //correct def method(flag: Boolean): String = if (flag) "TRUE" else "FALSE"
  • 18. val vs var Variable type Collection type Example
  • 19. val vs var Variable type Collection type Example Immutable Immutable Best val map = Map("name" -> "sky")
  • 20. val vs var Variable type Collection type Example Immutable Immutable Best Mutable Immutable Good val map = Map("name" -> "sky") var map = Map("name" -> "sky")
  • 21. val vs var Variable type Collection type Example Immutable Immutable Best Mutable Immutable Good Immutable Mutable Ok val map = Map("name" -> "sky") val map = mutable.Map("name" -> "sky") var map = Map("name" -> "sky")
  • 22. val vs var Variable type Collection type Example Immutable Immutable Best Mutable Immutable Good Immutable Mutable Ok Mutable Mutable worst val map = Map("name" -> "sky") val map = mutable.Map("name" -> "sky") var map = Map("name" -> "sky") var map = mutable.Map("name" -> "sky")
  • 23. val vs var Variable type Collection type Example Immutable Immutable Best Mutable Immutable Good Immutable Mutable Ok Mutable Mutable worst val map = Map("name" -> "sky") val map = mutable.Map("name" -> "sky") var map = Map("name" -> "sky") var map = mutable.Map("name" -> "sky") Never use combination of both mutable variable and mutable collection
  • 24. Try/catch try { doSomething() } catch { case th: Throwable => someHandler() }
  • 25. Try/catch try { doSomething() } catch { case th: Throwable => someHandler() } MUST NOT catch Throwable when catching Exceptions
  • 26. Try/catch import scala.util.control.NonFatal try { doSomething() } catch { case NonFatal(ex) => someHandler() }
  • 27. Try/catch object NonFatal { /** * Returns true if the provided `Throwable` is to be considered non-fatal, or false if it is to be considered fatal */ def apply(t: Throwable): Boolean = t match { // VirtualMachineError includes OutOfMemoryError and other fatal errors case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable => false case _ => true } /** * Returns Some(t) if NonFatal(t) == true, otherwise None */ def unapply(t: Throwable): Option[Throwable] = if (apply(t)) Some(t) else None }
  • 28. Loop vs recursion def factorialUsingLoop(n: Int): Int = { var accumulator = 1 var i = 1 while (i <= n) { accumulator = i * accumulator i += 1 } accumulator } def factorialUsingRecursion(n: Int): Int = { @tailrec def fac(n: Int, acc: Int): Int = n match { case _ if n == 1 => acc case _ => fac(n - 1, n * acc) } fac(n, 1) }
  • 29. Tuple usage def wordCount(text: String): List[(String, Int)] = text.split(" +").groupBy(word => word) .map { word => (word._1, word._2.length) } .toList .sortBy(_._2) .reverse
  • 30. Tuple usage def wordCount(text: String): List[(String, Int)] = text.split(" +").groupBy(word => word) .map { word => (word._1, word._2.length) } .toList .sortBy(_._2) .reverse def wordCount(text: String): List[(String, Int)] = text.split(" +").groupBy(identity) .map { case (word, frequency) => (word, frequency.length) } .toList .sortBy { case (_, count) => count } .reverse // More Readable
  • 31. Tuple usage def wordCount(text: String): List[(String, Int)] = text.split(" +").groupBy(word => word) .map { word => (word._1, word._2.length) } .toList .sortBy(_._2) .reverse def wordCount(text: String): List[(String, Int)] = text.split(" +").groupBy(identity) .map { case (word, frequency) => (word, frequency.length) } .toList .sortBy { case (_, count) => count } .reverse // More Readable Avoid _1 and _2 method for accessing tuple value
  • 32. getOrElse vs fold val optionalInt:Option[Int]=Some(1) val intValue= optionalInt.getOrElse("0")
  • 33. getOrElse vs fold val optionalInt:Option[Int]=Some(1) val intValue= optionalInt.getOrElse("0") String value
  • 34. getOrElse vs fold val optionalInt:Option[Int]=Some(1) val intValue= optionalInt.getOrElse("0") String value Type of intValue become Any val intValue= optionalInt.fold("0")(v =>v)
  • 35. getOrElse vs fold val optionalInt:Option[Int]=Some(1) val intValue= optionalInt.getOrElse("0") String value Type of intValue become Any val intValue= optionalInt.fold("0")(v =>v) Compilation Error
  • 36. getOrElse vs fold val optionalInt:Option[Int]=Some(1) val intValue= optionalInt.getOrElse("0") String value Type of intValue become Any val intValue= optionalInt.fold(0)(v =>v) getOrElse is not typesafe so use fold instead of getOrElse
  • 37. head and get val list =List[Int]().head
  • 38. head and get val list =List[Int]().head Exception: head of empty list val list =List[Int]().headOption val optionalInt: Option[Int] = None val intValue = optionalInt.get
  • 39. head and get val list =List[Int]().head Exception: head of empty list val list =List[Int]().headOption val optionalInt: Option[Int] = None val intValue = optionalInt.get scala.None$.get val intValue = optionalInt.fold(0)(v=>v)
  • 40. head and get val list =List[Int]().head Exception: head of empty list val list =List[Int]().headOption val optionalInt: Option[Int] = None val intValue = optionalInt.get scala.None$.get val intValue = optionalInt.fold(0)(v=>v) Alway Avoid head and get method
  • 41. Loop vs recursion def factorialUsingLoop(n: Int): Int = { var accumulator = 1 var i = 1 while (i <= n) { accumulator = i * accumulator i += 1 } accumulator } def factorialUsingRecursion(n: Int): Int = { @tailrec def fac(n: Int, acc: Int): Int = n match { case _ if n == 1 => acc case _ => fac(n - 1, n * acc) } fac(n, 1) } Avoid looping if possible and use tail recursion
  • 42. Future Composition def composingFuture(): Future[Int] = { val firstFuture: Future[Int] = method1() val secondFuture: Future[Int] = firstFuture.flatMap { v => method2(v) } val thirdFuture: Future[Int] = secondFuture.flatMap { v => method3(v) } val fourthFuture: Future[Int] = method4() // no composition val result: Future[Int] = thirdFuture.flatMap { v => method5(v) } result } def method1(): Future[Int] = ??? def method2(value: Int): Future[Int] = ??? def method3(value: Int): Future[Int] = ??? def method4(): Future[Int] = ??? def method5(value: Int): Future[Int] = ???
  • 43. Future Composition def composingFuture(): Future[Int] = { val firstFuture: Future[Int] = method1() val secondFuture: Future[Int] = firstFuture.flatMap { v => method2(v) } val thirdFuture: Future[Int] = secondFuture.flatMap { v => method3(v) } val fourthFuture: Future[Int] = method4() // no composition val result: Future[Int] = thirdFuture.flatMap { v => method5(v) } result } def method1(): Future[Int] = ??? def method2(value: Int): Future[Int] = ??? def method3(value: Int): Future[Int] = ??? def method4(): Future[Int] = ??? def method5(value: Int): Future[Int] = ??? what is the problem ?
  • 44. Future Composition def composingFuture(): Future[Int] = { val firstFuture: Future[Int] = method1() val secondFuture: Future[Int] = firstFuture.flatMap { v => method2(v) } val thirdFuture: Future[Int] = secondFuture.flatMap { v => method3(v) } val fourthFuture: Future[Int] = method4() val result: Future[Int] = thirdFuture.flatMap { v => method5(v) } fourthFuture.flatMap{ _=> result}// composing fourth future value } def method1(): Future[Int] = ??? def method2(value: Int): Future[Int] = ??? def method3(value: Int): Future[Int] = ??? def method4(): Future[Int] = ??? def method5(value: Int): Future[Int] = ???
  • 45. Fixed Value for Future import scala.concurrent.ExecutionContext.Implicits.global def calculate(value: Option[Int]): Future[Int] = value match { case Some(v) => method(v) case None => Future(0) } def method(value: Int): Future[Int] = ???
  • 46. Fixed Value for Future def calculate(value: Option[Int]): Future[Int] = value match { case Some(v) => method(v) case None => Future.successful(0) } def method(value: Int): Future[Int] = ??? Alway use Future.successful for fixed value and Future.failed for exception
  • 47. Scala ExecutionContext ➢ ForkJoinPool ➢ scala.concurrent.context.minThreads = “1” ➢ scala.concurrent.context.numThreads =”x1” x1 means => Runtime.getRuntime.availableProcessors * 1 ➢ scala.concurrent.context.maxThreads ="x1” ➢ Avalable in scala.concurrent.ExecutionContext.Implicits.global
  • 48. Scala ExecutionContext ➢ ForkJoinPool ➢ scala.concurrent.context.minThreads = “1” ➢ scala.concurrent.context.numThreads =”x1” x1 means => Runtime.getRuntime.availableProcessors * 1 ➢ scala.concurrent.context.maxThreads ="x1” ➢ Avalable in scala.concurrent.ExecutionContext.Implicits.global Don't use Scala ExecutionContext for IO operations
  • 49. For heavy IO import java.util.concurrent.Executors object ExecutionContext { ///read from config or environment val CONCURRENCY_FACTOR = 3 object IO { /** * Responsible to handle all DB calls */ implicit lazy val dbOperations: concurrent.ExecutionContext = concurrent.ExecutionContext .fromExecutor( Executors.newFixedThreadPool( Runtime.getRuntime.availableProcessors() * CONCURRENCY_FACTOR ) ) } }
  • 50. For light weight IO import java.util.concurrent.Executors object ExecutionContext { object IO { /** * Responsible to handle all light weight IO */ implicit lazy val simpleOperations: concurrent.ExecutionContext = concurrent.ExecutionContext.fromExecutor(Executors.newCachedThreadPool()) } }
  • 51. Play ExecutionContext ● Available in play.api.libs.concurrent.Execution.Implicits.defaultContext ● default configuration for Play’s thread pool: akka { actor { default-dispatcher { fork-join-executor { parallelism-factor = 1.0 parallelism-max = 24 # Setting this to LIFO changes the fork-join-executor # to use a stack discipline for task scheduling. This usually # improves throughput at the cost of possibly increasing # latency and risking task starvation (which should be rare). task-peeking-mode = LIFO } } } }
  • 52. Akka ExecutionContext The default Akka configuration: akka { actor { default-dispatcher { fork-join-executor { parallelism-min = 8 parallelism-factor = 3.0 parallelism-max = 64 task-peeking-mode = "FIFO" } } } }
  • 53. For light weight IO For IO use thread-pool-executor. For Example: my-thread-pool-dispatcher { type = Dispatcher executor = "thread-pool-executor" thread-pool-executor { core-pool-size-min = 20 core-pool-size-factor = 20 core-pool-size-max = 100 } throughput = 1 }
  • 54. For Heavy IO For IO use thread-pool-executor. For Example: my-thread-pool-dispatcher { type = Dispatcher executor = "thread-pool-executor" thread-pool-executor { core-pool-size-min = 8 core-pool-size-factor = 3 core-pool-size-max = 16 } throughput = 1 }
  • 55. Thump Rule ● In Scala, use Scala ExecutionContext ● In Play, use Play ExecutionContext ● In Akka, use Akka ExecutionContext ● In Akka, One ActorSystem per Application
  • 56. References ● http://doc.akka.io ● https://www.playframework.com/documentation/2.5 ● http://twitter.github.io/effectivescala ● https://github.com/alexandru/scala-best-practices