SlideShare une entreprise Scribd logo
1  sur  41
Télécharger pour lire hors ligne
RefineyourScalaCode
TechTriveni2.0|NewDelhi
AjayViswanathan
Aboutme
Sr.SoftwareEngineer@Agoda
MyFPjourneyhastakenmethroughBigData,BackEndandFrontEnd
LearningFPandScalaforthepast5years
Reachouttomeonmyblogscala.ninja
ThisPresentationwaswrittenin markdown andcompiledusing marp-cli
Somecodeexamplesmayrequireyoutouse Scala 2.13 or Dotty
Motivationforthistalk
InmyexperienceofworkingwithteamsbuildingproductsinScala,my#1gripehasalways
been
Ifyouwantedtowriteitthatway,whydon'tyoudoitinJava?WhyevenuseScala?
Instead,Iwouldratherwriteitusing<insertXYZpattern/library>
Justlikeyoucanhavemultiplesolutionstoamathproblem,buttheelegantsolutionsare
sparse
Similarly,justidiomaticScalacodeisnotenough,especiallyifyoudon'tutilizethefull
potentialofwhatisavailable
Controversialstatementalert!
ScalaislikeaLiberalOligarchy
Liberal-becauseitacceptsawidevarietyofcodingstyleswithoutmuchcomplaint
Oligarchy-becausethecorelanguageisinthehandsoffewpeopleandcannotcope
upwiththeadvancementsallaround
Typelevel101
BeforeIheadintothemaintopicofthispresentation,allowmetointroduceafew
terminologiesthatwouldcomeinhandyinkeepingupwithsomeoftheconcepts.
Scalaispoweredbyanunder-appreciatedtype-system
WithoutgettingjumbledinwordslikeSKICombinatorCalculus,letmesaythatScala's
typesystemisTuringComplete
Thisfactcomesinhandywhenthecompilerhastomakeinferencesaboutyour
untypedcode.
ThereisnothingmagicalaboutworkingwithTypes.Itisbasedoninductivelogic
Imakenopretenseofanymathematicalformalityinthefollowingoversimplifications
I'mabouttoexplain
AstaticallytypedlanguagelikeScalahastwodomains-atypedomain,andavalue
domain.
case class Name(firstName: String, lastName: String)
val n1 = Name("ajay", "viswanathan")
// Name -> Type
// n1 -> Value
Likeclasses,typescanalsohaveconstructors
type IntMap[T] = Map[Int, T]
Thekeyconcepttonoteis
TypescanbereasonedaboutatCompileTime,whereasValuescanonlybe
reasonedaboutRuntime
Whatthisimpliesis
TypelevelprogrammingallowsustocatcherrorsatCompileTimewhichwould
otherwisebedealtwithatRuntime
DesignPattern#1:PhantomTypes
Anabstracttypethatisneverinitialized,hencehasnoeffectonruntime
Itisonlyusedtoprovestaticpropertiesusingtypeevidences
Thecompilererasestheseonceitcanprovethattheconstraintshold
sealed trait Status
sealed trait Red extends Status
sealed trait Orange extends Status
sealed trait Green extends Status
class TrafficSignal[T <: Status] {
private def to[U <: Status]: TrafficSignal[U] = this.asInstanceOf[TrafficSignal[U]]
def stop(implicit ev: T =:= Orange): TrafficSignal[Red] = to[Red]
def start(implicit ev: T =:= Red): TrafficSignal[Orange] = to[Orange]
def go(implicit ev: T =:= Orange): TrafficSignal[Green] = to[Green]
def slow(implicit ev: T =:= Green): TrafficSignal[Orange] = to[Orange]
}
val signal = new TrafficSignal[Red]
signal.stop // Compilation Error: Cannot prove that TrafficLight.Red =:= TrafficLight.Orange
signal.start.go // Compilation Successful
DesignPattern#2:Pathdependenttypes
Scalaallowsyoutodefinetypesinsideatype
Thisisusefulwhenonlypartialtypeinformationisavailableatcompiletime
Theruntimetypecanbeencapsulated
case class Cart(user: String, value: Int = 0) {
case class Item(name: String, amount: Int)
def add(item: this.Item): Cart = copy(value = value + item.amount)
}
val cart = Cart("suresh")
val item: cart.Item = cart.Item("perk", 2)
val valid = cart.add(item) // Cart(suresh, 2)
val invalid = Cart("ramesh").add(item) // Compilation Error
DesignPattern#2PathDependentTypesRedux:AUXpattern
Wedon'talwayshavetheluxuryofknowingcertaindatatypesatcompiletime
Whenwewantafunctiontodependentonaruntimetype,wecanuseTypeclassesto
workaroundthisproblem
Saythereexistsafunctionthatlooksforatypeclassbasedontheruntimevalue
trait Param[T, U] {
def convert(obj: T): Option[U]
}
trait Predicate[U] {
def eval(values: List[U], value: U): Boolean
}
def evaluate[T, U](request: T, values: List[U])(implicit param: Param[T, U], predicate: Predicate[U]): Boolean = {
param.convert(request).exists(v => predicate.eval(values, v))
}
implicit val stringPredicate = new Predicate[String] {
def eval(values: List[String], value: String) = values.contains(value)
}
implicit val intPredicate = new Predicate[Int] {
def eval(values: List[Int], value: Int) = values.forall(_ > value)
}
implicit val stringIntParam = new Param[String, Int] {
def convert(obj: String): Option[Int] = Try(obj.toInt).toOption
}
...
evaluate("3", List(2, 3, 4)) // false
evaluate("3", List(4, 5, 6)) // true
WecouldrewritethesameusingPathdependenttypesas
trait Param[T] {
type U
def convert(obj: T): Option[U]
}
def evaluate[T, U](request: T, values: List[U])(implicit param: Param[T], predicate: Predicate[param.U]) // Does not compile
Weintroducethe Aux patternheretohelpthecompilerreasonaboutthetypeinference
object Param {
type Aux[T0, U0] = Param[T0] {
type U = U0
}
}
def evaluate[T, U](request: T, values: List[U])(implicit ev: Param.Aux[T, U], predicate: Predicate[U]): Boolean = {
ev.convert(request).exists(v => predicate.eval(values, v))
}
DesignPattern#3:Singletontypes
EverySingletonobjectinScalaisitsowntype
Singletontypesbridgethegapbetweenthevaluelevelandthetypelevel
object Data {
val v1: String = "data"
}
object FakeData {
val v1: String = "virus"
}
def process(obj: Data.type) = println(obj.v1) // data
DesignPattern#3(Experimental):Literal-BasedSingletonTypes
SIP23-ProposaltointegratewithScala3
WillallowLiteralstoappearintype-position
val one: 1 = 1
Sampleuse-case:MatrixMultiplication
type Dim = Singleton & Int
case class Matrix[A <: Dim, B <: Dim](a: A, b: B) {
def *[C <: Dim](other: Matrix[B, C]): Matrix[A, C] = Matrix(a, other.b)
}
DesigningyourDataTypes
Problemswith Stringly definedcode
Pronetobadinputsifnoterror-checked
Havetohandleplentyofmeaninglessinputsasedge-cases
Muchofenterprisecodeendsuprelyingontrustofdeveloperthattheywillnotbreak
it
Solution:Makebadinputimpossibletoconstruct
Whyshouldwewritecodethathandleswhatitshouldn'tbehandling?
Itonlyleadstomoretests,morestupidtests
WhataretheissuesyoumayfacewithsuchaDatadomain?
case class Timestamp(date: String, hour: Int)
case class Timestamp(date: String, hour: Int)
Somanyquestions:
Whatisthedateformatexpected?
Areallformatshandled?
Day/Month/Year???
Hourin12/24hformat?
Houris0-indexed?
Let'strytofixthis
// With Self-checks
def verifyDate(date: String, format: String = "yyyyMMdd"): Boolean
case class Timestamp(date: String, hour: Int) {
require(hour > 0 && hour <= 24)
require(verifyDate(date))
}
// With Structural Enforcement
def apply(year: Int, month: Int, day: Int, hour: Int) =
Timestamp(s"$year-$month-$day", hour)
OpaquevsTransparentDesign
ThefirstconsiderationwhiledesigningaDataTypeisthelevelofflexibilityor
encapsulationyouwishtoprovide
Inotherwords,how opaque or transparent doyouwantyourDataTypetobe?
// opaque DataType
class ParseError(index: Int, input: String) {
def line(): Int
def position(): Int
def message(): String
}
// transparent DataType
case class ParseError(line: Int, position: Int, message: String)
OpacityandTransparencyisaSpectrum
Opacityenforcesinvariants
ParseError(-1,-3,"randomlog")vsParserError.message="[ERROR]Message"
OpacitycansaveonDefensiveness
Transparentdesigncanenforceinvariantsbutbyaddingassertsandotherchecks
usingSelf-checksorStructuralEnforcements
Transparencyreducescomplexity
Istheopaquedatacomputingatinitialization?recomputing?caching?Howmuch
memorydoesituseinstoringinput?
Exampleofbaddatadomain
case class Request(guid: String)
Approach#1:Usingtypealias
type GUID = String
case class Request(guid: GUID)
Doesnothingmorethanmakingiteasiertoread
Approach2:Usinga(value)class
case class GUID(value: String)
Compilercancheckfortherightinstance,butstillnothingintermsofsafetyofinput
Boxingoverhead
class GUID(val value: String) extends AnyVal
Stilldoesn'tsolvethevalidationproblem
Valueclassescanstillgetinitializedifusedincollections,methodsignaturesetc
Approach3:UsingSmartConstructors
case class GUID private (value: String)
object GUID {
def apply(value: String): Option[GUID] = if (value.startsWith("valid")) Some(new GUID(value)) else None
}
new GUID("valid") // Does not compile - Good!
GUID("valid") // GUID(valid) - Validations work - Great!!
GUID("valid").map(_.copy("invalid")) // GUID(invalid) - Copy constructor is vulnerable - Bad!!!
Bythistime,we'vealreadyintroducedimmensecomplexitytoasimpleDataType
ReturntypeofOptionisabitfrustratingtohandlefordevelopers
TheNarrow-Widenapproach
String => GUID notallstringsarevalid
String => Option[GUID] widentheoutputtoaccommodate
List[Char] => Option[GUID]
NonEmptyList[Char] => Option[GUID] slightrefinementtotheinput
NonEmptyList[HexDigit] => Option[GUID] furtherrefininingtheinput
ThirtyTwoList[HexDigit] => Option[GUID] => GUID totalrefinementofthe
input,plusun-wideningoftheoutput
Whenyouwanttonarrowtheinput,youendupWideningtheoutput,butifyounarrow
theinputenough,youcanun-widentheoutput
Approach#4:Refiningtheconstructor
Arefinementtypeisbasically Base Type + Predicate
Subtypingofrefinements
type T + P <: T
type T + P <: type T + Q if forall t in T + P, Q(t) is true
Eg.
A - Set of Int > 10
B - Set of Int > 5
A <: B
type HexDigit = Char Refined LetterOrDigit
type ThirtyTwoList[T] = List[T] Refined Size[32]
type GUID = ThirtyTwoList[HexDigit]
case class Request(guid: GUID)
val r1 = Request("2312k3j123...123dasd") // Compiles
val r2 = Request("asdas_asda_21#!@##$@#$...2234") // Does not compile
// At runtime
refineV[GUID]("asdasd2323...12312asd") // Either[String, GUID]
Typeserasedatcompiletimeleavingyouwithonlyprimitives
Atruntime,predicatescomputedonvaluesaswouldbethecasenormally
YoucandomuchmorewithRefined
Thelibrarycomeswiththesepredefinedpredicates
Boolean
True: constant predicate that is always true
False: constant predicate that is always false
Not[P]: negation of the predicate P
And[A, B]: conjunction of the predicates A and B
Or[A, B]: disjunction of the predicates A and B
Xor[A, B]: exclusive disjunction of the predicates A and B
Nand[A, B]: negated conjunction of the predicates A and B
Nor[A, B]: negated disjunction of the predicates A and B
AllOf[PS]: conjunction of all predicates in PS
AnyOf[PS]: disjunction of all predicates in PS
OneOf[PS]: exclusive disjunction of all predicates in PS
Char
Digit: checks if a Char is a digit
Letter: checks if a Char is a letter
LetterOrDigit: checks if a Char is a letter or digit
LowerCase: checks if a Char is a lower case character
UpperCase: checks if a Char is an upper case character
Whitespace: checks if a Char is white space
Collection
Contains[U]: checks if a Traversable contains a value equal to U
Count[PA, PC]: counts the number of elements in a Traversable which satisfy the predicate PA and passes the result to the predicate PC
Empty: checks if a Traversable is empty
NonEmpty: checks if a Traversable is not empty
Forall[P]: checks if the predicate P holds for all elements of a Traversable
Exists[P]: checks if the predicate P holds for some elements of a Traversable
Head[P]: checks if the predicate P holds for the first element of a Traversable
Index[N, P]: checks if the predicate P holds for the element at index N of a sequence
Init[P]: checks if the predicate P holds for all but the last element of a Traversable
Last[P]: checks if the predicate P holds for the last element of a Traversable
Tail[P]: checks if the predicate P holds for all but the first element of a Traversable
Size[P]: checks if the size of a Traversable satisfies the predicate P
MinSize[N]: checks if the size of a Traversable is greater than or equal to N
MaxSize[N]: checks if the size of a Traversable is less than or equal to N
Generic
Equal[U]: checks if a value is equal to U
Numeric
Less[N]: checks if a numeric value is less than N
LessEqual[N]: checks if a numeric value is less than or equal to N
Greater[N]: checks if a numeric value is greater than N
GreaterEqual[N]: checks if a numeric value is greater than or equal to N
Positive: checks if a numeric value is greater than zero
NonPositive: checks if a numeric value is zero or negative
Negative: checks if a numeric value is less than zero
NonNegative: checks if a numeric value is zero or positive
Interval.Open[L, H]: checks if a numeric value is in the interval (L, H)
Interval.OpenClosed[L, H]: checks if a numeric value is in the interval (L, H]
Interval.ClosedOpen[L, H]: checks if a numeric value is in the interval [L, H)
Interval.Closed[L, H]: checks if a numeric value is in the interval [L, H]
Modulo[N, O]: checks if an integral value modulo N is O
Divisible[N]: checks if an integral value is evenly divisible by N
NonDivisible[N]: checks if an integral value is not evenly divisible by N
Even: checks if an integral value is evenly divisible by 2
Odd: checks if an integral value is not evenly divisible by 2
NonNaN: checks if a floating-point number is not NaN
String
EndsWith[S]: checks if a String ends with the suffix S
IPv4: checks if a String is a valid IPv4
IPv6: checks if a String is a valid IPv6
MatchesRegex[S]: checks if a String matches the regular expression S
Regex: checks if a String is a valid regular expression
StartsWith[S]: checks if a String starts with the prefix S
Uri: checks if a String is a valid URI
Url: checks if a String is a valid URL
Uuid: checks if a String is a valid UUID
ValidByte: checks if a String is a parsable Byte
ValidShort: checks if a String is a parsable Short
ValidInt: checks if a String is a parsable Int
ValidLong: checks if a String is a parsable Long
ValidFloat: checks if a String is a parsable Float
ValidDouble: checks if a String is a parsable Double
ValidBigInt: checks if a String is a parsable BigInt
ValidBigDecimal: checks if a String is a parsable BigDecimal
Xml: checks if a String is well-formed XML
XPath: checks if a String is a valid XPath expression
Trimmed: checks if a String has no leading or trailing whitespace
HexStringSpec: checks if a String represents a hexadecimal number
TaggingTypes
Letstakeanothercommonexamplewhereaspecifictypeinadomaincanbecritical
def getWeight(): Double
def getHeight(): Double
def bmi(weight: Double, height: Double): Double // Let's assume SI units as input
bmi(getWeight(), getHeight()) // OK
bmi(getHeight(), getWeight()) // Still OK, but not ideal behavior
Besidesrefining,taggingtypesofferalow-costalternativetoValueclasses
type Tagged[U] = {
type Tag = U
}
type @@[T, U] = T with Tagged[U]
implicit class TaggedOps[T](val v: T) extends AnyVal {
@inline def taggedWith[U]: T @@ U = v.asInstanceOf[T @@ U]
@inline def @@[U]: T @@ U = taggedWith[U]
}
trait Kilogram
trait Metres
type Weight = Double @@ Kilogram
type Height = Double @@ Metres
def getWeight(): Weight
def getHeight(): Height
// Units are already encoded in the type now
def bmi(weight: Weight, height: Height): Double
bmi(getWeight(), getHeight()) // OK
bmi(getHeight(), getWeight()) // Compilation error, just like we wanted
Noruntimecostoftypetags
MinoroverheadofTaggedOps
Coderemainssaneandself-documenting
Scalaintroducing NewType and Opaque and Transparent typestoScalasoon
enough,whereTaggingandZero-overheadencapsulatedconstructorswouldbecome
partofthestandardlibrary
UseCase:LoadingConfigs
Whyconfigs?BecausewesanitizeeverythingelselikeDB,Userinput,butnever
configvalues
Dangeroustoblindlytrustyourdevelopers.Theyarehumansandmistakescanbe
madewhichcanbehardtofindandcostly
Validationofconfigshouldbemorethan value is present ,butthat value is
usable
case class Endpoint(host: String, port: Int)
// based on what we've learnt so far, let's rewrite that as
type Host = MatchesRegex["^[A-Z0-9-_]{1,255}$"]
type Port = Interval.Closed[1024, 65535]
case class Endpoint(host: String Refined Host, port: Int Refined Port)
Experimental:Addingside-effectstoRefinementtypes
case class OpenPort()
implicit val openPortValidate: Validate.Plain[Int, OpenPort] =
Validate.fromPartial(new ServerSocket(_).close(), "OpenPort", OpenPort())
type AvailablePort = Int Refined OpenPort
RefinedTypesforthewin
Typesafety++
Uniformvalidation
Compiletimerefinementofliteralvalues
Runtimesafeextractionofvalues
Self-documentedcodeandeasiertoreasonaboutanddebugerrors
Fewertestcasestowrite
Pushprimitivestotheedge-of-the-system
LimitationsofRefinementTypes
IntelliJsupportsucks
AvoidInfixnotations
String Refined XXX And YYY
String Refined And[XXX, YYY]
String Refined (XXX And YYY)
Refinedprimitivesarealwaysboxed,asisusualwithnormalScala
Validationerrorsnotclearalways
Increasedcompiletimes
Scalasupportstillnotverymature(Mightchangeafterv3)
QA
References
https://github.com/fthomas/refined
https://slideslive.com/38908213/strings-are-evil-methods-to-hide-the-use-of-primitive-
types
http://www.lihaoyi.com/post/StrategicScalaStyleDesigningDatatypes.html
https://slideslive.com/38907881/literal-types-what-they-are-good-for
https://kwark.github.io/refined-in-practice-bescala/#94
https://meta.plasm.us/slides/circe/tour/#36
https://beyondthelines.net/programming/refined-types/
http://leifwickland.github.io/presentations/configBomb/#67
https://github.com/wjlow/blog/blob/3c27de716b40660801e68561252883fd0428395e
/Tests.md
https://gigiigig.github.io/posts/2015/09/13/aux-pattern.html
https://docs.scala-lang.org/sips/42.type.html

Contenu connexe

Tendances

Advanced python concepts
Advanced python conceptsAdvanced python concepts
Advanced python conceptsManusha Dilan
 
Generative Adversarial Networks
Generative Adversarial NetworksGenerative Adversarial Networks
Generative Adversarial NetworksMark Chang
 
Probability distribution Function & Decision Trees in machine learning
Probability distribution Function  & Decision Trees in machine learningProbability distribution Function  & Decision Trees in machine learning
Probability distribution Function & Decision Trees in machine learningSadia Zafar
 
HTML5 workshop, forms
HTML5 workshop, formsHTML5 workshop, forms
HTML5 workshop, formsRobert Nyman
 
Introduction of Deep Reinforcement Learning
Introduction of Deep Reinforcement LearningIntroduction of Deep Reinforcement Learning
Introduction of Deep Reinforcement LearningNAVER Engineering
 
The Algebric Functions
The Algebric FunctionsThe Algebric Functions
The Algebric Functionsitutor
 
Converting Scikit-Learn to PMML
Converting Scikit-Learn to PMMLConverting Scikit-Learn to PMML
Converting Scikit-Learn to PMMLVillu Ruusmann
 
Automatic Forecasting at Scale
Automatic Forecasting at ScaleAutomatic Forecasting at Scale
Automatic Forecasting at ScaleSean Taylor
 
What's Wrong With Object-Oriented Programming?
What's Wrong With Object-Oriented Programming?What's Wrong With Object-Oriented Programming?
What's Wrong With Object-Oriented Programming?Yegor Bugayenko
 

Tendances (15)

Advanced python concepts
Advanced python conceptsAdvanced python concepts
Advanced python concepts
 
Generative Adversarial Networks
Generative Adversarial NetworksGenerative Adversarial Networks
Generative Adversarial Networks
 
Decision Tree.pptx
Decision Tree.pptxDecision Tree.pptx
Decision Tree.pptx
 
Introduction of VAE
Introduction of VAEIntroduction of VAE
Introduction of VAE
 
Haskell study 6
Haskell study 6Haskell study 6
Haskell study 6
 
Probability distribution Function & Decision Trees in machine learning
Probability distribution Function  & Decision Trees in machine learningProbability distribution Function  & Decision Trees in machine learning
Probability distribution Function & Decision Trees in machine learning
 
HTML5 workshop, forms
HTML5 workshop, formsHTML5 workshop, forms
HTML5 workshop, forms
 
Introduction of Deep Reinforcement Learning
Introduction of Deep Reinforcement LearningIntroduction of Deep Reinforcement Learning
Introduction of Deep Reinforcement Learning
 
The Algebric Functions
The Algebric FunctionsThe Algebric Functions
The Algebric Functions
 
Mathematical Logic
Mathematical LogicMathematical Logic
Mathematical Logic
 
Converting Scikit-Learn to PMML
Converting Scikit-Learn to PMMLConverting Scikit-Learn to PMML
Converting Scikit-Learn to PMML
 
Automatic Forecasting at Scale
Automatic Forecasting at ScaleAutomatic Forecasting at Scale
Automatic Forecasting at Scale
 
SEED - Halcyon Architecture
SEED - Halcyon ArchitectureSEED - Halcyon Architecture
SEED - Halcyon Architecture
 
What's Wrong With Object-Oriented Programming?
What's Wrong With Object-Oriented Programming?What's Wrong With Object-Oriented Programming?
What's Wrong With Object-Oriented Programming?
 
NLP_KASHK:Markov Models
NLP_KASHK:Markov ModelsNLP_KASHK:Markov Models
NLP_KASHK:Markov Models
 

Similaire à Let's refine your Scala Code

Qcon2011 functions rockpresentation_scala
Qcon2011 functions rockpresentation_scalaQcon2011 functions rockpresentation_scala
Qcon2011 functions rockpresentation_scalaMichael Stal
 
Java best practices
Java best practicesJava best practices
Java best practicesRay Toal
 
“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic DiabetesTzach Zohar
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummaryAmal Khailtash
 
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalOop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalMichael Stal
 
From android/java to swift (3)
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)allanh0526
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescriptDavid Furber
 
How to not write a boring test in Golang
How to not write a boring test in GolangHow to not write a boring test in Golang
How to not write a boring test in GolangDan Tran
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingGarth Gilmour
 
TypeScript Presentation - Jason Haffey
TypeScript Presentation - Jason HaffeyTypeScript Presentation - Jason Haffey
TypeScript Presentation - Jason HaffeyRalph Johnson
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaKonrad Malawski
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with framelessMiguel Pérez Pasalodos
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To ScalaPeter Maas
 

Similaire à Let's refine your Scala Code (20)

Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Qcon2011 functions rockpresentation_scala
Qcon2011 functions rockpresentation_scalaQcon2011 functions rockpresentation_scala
Qcon2011 functions rockpresentation_scala
 
Java best practices
Java best practicesJava best practices
Java best practices
 
“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalOop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
 
Einführung in TypeScript
Einführung in TypeScriptEinführung in TypeScript
Einführung in TypeScript
 
Scala - core features
Scala - core featuresScala - core features
Scala - core features
 
From android/java to swift (3)
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
How to not write a boring test in Golang
How to not write a boring test in GolangHow to not write a boring test in Golang
How to not write a boring test in Golang
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
 
TypeScript Presentation - Jason Haffey
TypeScript Presentation - Jason HaffeyTypeScript Presentation - Jason Haffey
TypeScript Presentation - Jason Haffey
 
Fancy talk
Fancy talkFancy talk
Fancy talk
 
Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
Java 5 Features
Java 5 FeaturesJava 5 Features
Java 5 Features
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and Akka
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with frameless
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To Scala
 

Plus de Tech Triveni

UI Dev in Big data world using open source
UI Dev in Big data world using open sourceUI Dev in Big data world using open source
UI Dev in Big data world using open sourceTech Triveni
 
Why should a Java programmer shifts towards Functional Programming Paradigm
Why should a Java programmer shifts towards Functional Programming ParadigmWhy should a Java programmer shifts towards Functional Programming Paradigm
Why should a Java programmer shifts towards Functional Programming ParadigmTech Triveni
 
Reactive - Is it really a Magic Pill?
Reactive - Is it really a Magic Pill?Reactive - Is it really a Magic Pill?
Reactive - Is it really a Magic Pill?Tech Triveni
 
Let’s go reactive with JAVA
Let’s go reactive with JAVALet’s go reactive with JAVA
Let’s go reactive with JAVATech Triveni
 
Tackling Asynchrony with Kotlin Coroutines
Tackling Asynchrony with Kotlin CoroutinesTackling Asynchrony with Kotlin Coroutines
Tackling Asynchrony with Kotlin CoroutinesTech Triveni
 
Programmatic Ad Tracking: Let the power of Reactive Microservices do talking
Programmatic Ad Tracking: Let the power of Reactive Microservices do talkingProgrammatic Ad Tracking: Let the power of Reactive Microservices do talking
Programmatic Ad Tracking: Let the power of Reactive Microservices do talkingTech Triveni
 
Supercharged imperative programming with Haskell and Functional Programming
Supercharged imperative programming with Haskell and Functional ProgrammingSupercharged imperative programming with Haskell and Functional Programming
Supercharged imperative programming with Haskell and Functional ProgrammingTech Triveni
 
Observability at scale with Neural Networks: A more proactive approach
Observability at scale with Neural Networks: A more proactive approachObservability at scale with Neural Networks: A more proactive approach
Observability at scale with Neural Networks: A more proactive approachTech Triveni
 
Semi-Supervised Insight Generation from Petabyte Scale Text Data
Semi-Supervised Insight Generation from Petabyte Scale Text DataSemi-Supervised Insight Generation from Petabyte Scale Text Data
Semi-Supervised Insight Generation from Petabyte Scale Text DataTech Triveni
 
Finding the best solution for Image Processing
Finding the best solution for Image ProcessingFinding the best solution for Image Processing
Finding the best solution for Image ProcessingTech Triveni
 
Proximity Targeting at Scale using Big Data Platforms
Proximity Targeting at Scale using Big Data PlatformsProximity Targeting at Scale using Big Data Platforms
Proximity Targeting at Scale using Big Data PlatformsTech Triveni
 
Effecting Pure Change - How anything ever gets done in functional programming...
Effecting Pure Change - How anything ever gets done in functional programming...Effecting Pure Change - How anything ever gets done in functional programming...
Effecting Pure Change - How anything ever gets done in functional programming...Tech Triveni
 
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)Tech Triveni
 
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...Tech Triveni
 
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)Tech Triveni
 
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...Tech Triveni
 
UX in Big Data Analytics - Paramjit Jolly (Guavus)
UX in Big Data Analytics - Paramjit Jolly (Guavus)UX in Big Data Analytics - Paramjit Jolly (Guavus)
UX in Big Data Analytics - Paramjit Jolly (Guavus)Tech Triveni
 
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)Tech Triveni
 
Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Tech Triveni
 
Apache CarbonData+Spark to realize data convergence and Unified high performa...
Apache CarbonData+Spark to realize data convergence and Unified high performa...Apache CarbonData+Spark to realize data convergence and Unified high performa...
Apache CarbonData+Spark to realize data convergence and Unified high performa...Tech Triveni
 

Plus de Tech Triveni (20)

UI Dev in Big data world using open source
UI Dev in Big data world using open sourceUI Dev in Big data world using open source
UI Dev in Big data world using open source
 
Why should a Java programmer shifts towards Functional Programming Paradigm
Why should a Java programmer shifts towards Functional Programming ParadigmWhy should a Java programmer shifts towards Functional Programming Paradigm
Why should a Java programmer shifts towards Functional Programming Paradigm
 
Reactive - Is it really a Magic Pill?
Reactive - Is it really a Magic Pill?Reactive - Is it really a Magic Pill?
Reactive - Is it really a Magic Pill?
 
Let’s go reactive with JAVA
Let’s go reactive with JAVALet’s go reactive with JAVA
Let’s go reactive with JAVA
 
Tackling Asynchrony with Kotlin Coroutines
Tackling Asynchrony with Kotlin CoroutinesTackling Asynchrony with Kotlin Coroutines
Tackling Asynchrony with Kotlin Coroutines
 
Programmatic Ad Tracking: Let the power of Reactive Microservices do talking
Programmatic Ad Tracking: Let the power of Reactive Microservices do talkingProgrammatic Ad Tracking: Let the power of Reactive Microservices do talking
Programmatic Ad Tracking: Let the power of Reactive Microservices do talking
 
Supercharged imperative programming with Haskell and Functional Programming
Supercharged imperative programming with Haskell and Functional ProgrammingSupercharged imperative programming with Haskell and Functional Programming
Supercharged imperative programming with Haskell and Functional Programming
 
Observability at scale with Neural Networks: A more proactive approach
Observability at scale with Neural Networks: A more proactive approachObservability at scale with Neural Networks: A more proactive approach
Observability at scale with Neural Networks: A more proactive approach
 
Semi-Supervised Insight Generation from Petabyte Scale Text Data
Semi-Supervised Insight Generation from Petabyte Scale Text DataSemi-Supervised Insight Generation from Petabyte Scale Text Data
Semi-Supervised Insight Generation from Petabyte Scale Text Data
 
Finding the best solution for Image Processing
Finding the best solution for Image ProcessingFinding the best solution for Image Processing
Finding the best solution for Image Processing
 
Proximity Targeting at Scale using Big Data Platforms
Proximity Targeting at Scale using Big Data PlatformsProximity Targeting at Scale using Big Data Platforms
Proximity Targeting at Scale using Big Data Platforms
 
Effecting Pure Change - How anything ever gets done in functional programming...
Effecting Pure Change - How anything ever gets done in functional programming...Effecting Pure Change - How anything ever gets done in functional programming...
Effecting Pure Change - How anything ever gets done in functional programming...
 
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
Becoming a Functional Programmer - Harit Himanshu (Nomis Solutions)
 
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
Live coding session on AI / ML using Google Tensorflow (Python) - Tanmoy Deb ...
 
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
Distributing the SMACK stack - Kubernetes VS DCOS - Sahil Sawhney (Knoldus Inc.)
 
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
Blue Pill / Red Pill : The Matrix of thousands of data streams - Himanshu Gup...
 
UX in Big Data Analytics - Paramjit Jolly (Guavus)
UX in Big Data Analytics - Paramjit Jolly (Guavus)UX in Big Data Analytics - Paramjit Jolly (Guavus)
UX in Big Data Analytics - Paramjit Jolly (Guavus)
 
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
Simplified Scala Monads And Transformation - Harmeet Singh (Knoldus Inc.)
 
Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)Micro Frontends Architecture - Jitendra kumawat (Guavus)
Micro Frontends Architecture - Jitendra kumawat (Guavus)
 
Apache CarbonData+Spark to realize data convergence and Unified high performa...
Apache CarbonData+Spark to realize data convergence and Unified high performa...Apache CarbonData+Spark to realize data convergence and Unified high performa...
Apache CarbonData+Spark to realize data convergence and Unified high performa...
 

Dernier

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 

Dernier (20)

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 

Let's refine your Scala Code