SlideShare ist ein Scribd-Unternehmen logo
1 von 160
2 Years of
Real World
FP at REA
@KenScambler
Scala Developer at
λ
Me
14 years
5 years
5 years
when possible
when bored
when forced
@
Jul 13 Jan 14 Jul 14 Jan 15
- 3 teams
- 17 codebases
- 43K LOC
Why Functional
Programming?
Compelling,
tangible software
engineering
benefits
Modularity
Abstraction
Composability
Modular, abstract,
composable programs
are simple programs
Modularity
Can you reason about
something in isolation?
Or do you need to fit
everything in your head at
once?
A
B C K
Is the cost of replacing B
with K just writing K?
A
B CK
Is the cost of replacing B
with K just writing K?
AK
B CKK
…or rewriting half the
program?
glue
glue
A pure function is just
input  output; no side effects
You can tell what it does without
Looking at surrounding context.
Consider:
Let’s parse a string like “Richmond, VIC 3121”
def parseLocation(str: String): Location = {
val parts = str.split(“,”)
val secondStr = parts(1)
val parts2 = secondStr.split(“ “)
Location(
parts(0), parts2(0), parts(1).toInt)
}
Could be null
Possible errors: 1
def parseLocation(str: String): Location = {
val parts = str.split(“,”)
val secondStr = parts(1)
val parts2 = secondStr.split(“ “)
Location(
parts(0), parts2(0), parts(1).toInt)
}
def parseLocation(str: String): Location = {
val parts = str.split(“,”)
val secondStr = parts(1)
val parts2 = secondStr.split(“ “)
Location(
parts(0), parts2(0), parts(1).toInt)
}
Might not have enough elements
Possible errors: 2
def parseLocation(str: String): Location = {
val parts = str.split(“,”)
val secondStr = parts(1)
val parts2 = secondStr.split(“ “)
Location(
parts(0), parts2(0), parts(1).toInt)
}
Might not have enough elements
Possible errors: 3
def parseLocation(str: String): Location = {
val parts = str.split(“,”)
val secondStr = parts(1)
val parts2 = secondStr.split(“ “)
Location(
parts(0), parts2(0), parts(1).toInt)
}
Might not have enough elements
Possible errors: 4
def parseLocation(str: String): Location = {
val parts = str.split(“,”)
val secondStr = parts(1)
val parts2 = secondStr.split(“ “)
Location(
parts(0), parts2(0), parts(1).toInt)
}
Might not have enough elements
Possible errors: 5
def parseLocation(str: String): Location = {
val parts = str.split(“,”)
val secondStr = parts(1)
val parts2 = secondStr.split(“ “)
Location(
parts(0), parts2(0), parts(1).toInt)
}
Might not be an int
Possible errors: 6
def doSomethingElse(): Unit = {
// ...Do other stuff
parseLocation(“Melbourne, VIC 3000”)
}
Possible errors: 6 + 3 = 9
6
3
def anotherThing(): Unit = {
// ...Do even more stuff
doSomethingElse()
}
Possible errors: 9 + 4 = 13
4
9
Code inherits all the
errors and side-effects of
code it calls.
Local reasoning becomes
impossible; modularity is
lost.
def parseLocation(str: String):
Option[Location] = {
val parts = str.split(”,")
for {
locality <- parts.optGet(0)
theRestStr <- parts.optGet(1)
theRest = theRestStr.split(" ")
subdivision <- theRest.optGet(0)
postcodeStr <- theRest.optGet(1)
postcode <- postcodeStr.optToInt
} yield
Location(locality, subdivision, postcode)
}
Possible errors: 0
All possibilities have
been elevated into the
type system
Local reasoning is possible!
Local reasoning is possible
about things that call it, etc…
Abstraction
Know as little as
you need
Know as little as
you need
Produce as little as
you can
def sumInts(
list: List[Int]): Int = {
var result = 0
for (x <- list) {
result = result + x
}
return result
}
def flatten[A](
list: List[List[A]]): List[A] = {
var result = List()
for (x <- list) {
result = result ++ x
}
return result
}
def all[A](
list: List[Boolean]): Boolean = {
var result = true
for (x <- list) {
result = result && x
}
return result
}
def sumInts(
list: List[Int]): Int = {
var result = 0
for (x <- list) {
result = result + x
}
return result
}
def flatten[A](
list: List[List[A]]): List[A] = {
var result = List()
for (x <- list) {
result = result ++ x
}
return result
}
def all[A](
list: List[Boolean]): Boolean = {
var result = true
for (x <- list) {
result = result && x
}
return result
}
trait Monoid[M] {
def zero: M
def append(m1: M, m2: M): M
}
Extract the essence!
def fold[M](list: List[M])
(implicit m: Monoid[M]): M
= {
var result = m.zero
for (x <- list) {
result = m.append(result,x)
}
result
}
def fold[M](list: List[M])
(implicit m: Monoid[M]): M
= list.foldLeft(m.zero)(m.append)
fold(List(1, 2, 3, 4))
 10
fold(List(List("a", "b"), List("c")))
 List("a", "b", "c")
fold(List(true, true, false, true))
 false
Abstraction is always a good thing!
Less repetition More reuse
Less decay, because code can’t
grow tumours around
unnecessary detail
Composability
Functions compose.
A => B
B => C
C => D
D => E
A => E
Functions compose.
Sideways too.
A => E
X => Y
(A,X) => (E,Y)
Sideways too.
This works in the large,
as well as the small!
Entire systems can be
composable like
functions…. without
side effects
Truly composable
systems can accrue
more and more stuff
without getting more
complex!
Simplicity
• Modularity – Reason locally
• Abstraction – say only what you need, hide
everything you don’t
• Composability – scale without accruing complexity
The human process
Technical excellence
isn’t enough!
Software
development is a
human process
Coffee Tea
Quiet
time
GSD
Ponies
Reconsider!
Xi’an offshore team
Team
Team
Team
Team
Xi’an offshore team
• Many teams are partly based in Xi’an.
• They’re very good, but…
• Communication is hard!
• It works, but requires great investment of time and
money
Bottom-up tech decisions
GET /foo/bar
PUT
{"mode":
"banana"}
POST {"partyTime": "5:00"}
GET /buzz/5/
Architect
Mountain
Architect
Mountain
Architect
Mountain
Architect
Mountain
Just needs
more Agile
Don’t forget
your
velocity
More
meetings,
but littler
NO
No no no no no no no
no no no no no no no
no no no no no no no
no no no no no no no
no no no no not like
this. Wake up it’s a
school day
Bottom-up tech decisions
You have to win
Bottom-up tech decisions
You have to win
Bottom-up tech decisions
You have to win
Software Paleontology
Everyone’s got
a history…
Scriptozoic era
1995 – 2010
Mostly Perl
Monolithocene epoch
2010 – 2012
Ruby, Java
Scriptozoic era
1995 – 2010
Mostly Perl
AWS
Monolithocene epoch
2010 – 2012
Ruby, Java
Scriptozoic era
1995 – 2010
Mostly Perl
Microservices
2012 –
Ruby, Scala, JS
Adoption
June, 2013
λ
λ
λ
λ
λ
λ
λ
λ
λ
λ
λ
λ
λ
λ
Language choice
Object Oriented
Powerful static types
Functional
JVM
Object Oriented
Powerful static types
Functional
JVM
Functional
JVM
Functional
JVM
Functional
JVM
Functional
JVM
Whatever works for you!
The journey
Jul 13 Jan 14
1
LOC
Web
JSON
DB
Dep Inj
Play2
Play2
6K
Squeryl / Play2
Constructors
Type API
#1
LOC
Web
JSON
DB
Dep Inj
Play2
Play2
6K
Squeryl / Play2
Constructors
Type API
• Mentor
• Code reviews
Learning Investment
#1
LOC
Web
JSON
DB
Dep Inj
Play2
Play2
6K
Squeryl / Play2
Constructors
Type API
• Mentor
• Code reviews
Learning Investment Report card
Learning curve
Technical result
Productivity
Sentiment
Steep but ok
OK; slight dip
Great; but FWs
too heavy
#1
Jul 13 Jan 14
1 2
Some infrastructure
LOC
Web
JSON
DB
Dep Inj
Play2
Argonaut
3K
Squeryl / Play2
Constructors
Type API
#2
LOC
Web
JSON
DB
Dep Inj
Play2
Argonaut
3K
Squeryl / Play2
Constructors
Type API
• Almost none
Learning Investment
#2
LOC
Web
JSON
DB
Dep Inj
Play2
Argonaut
3K
Squeryl / Play2
Constructors
Type API
• Almost none
Learning Investment Report card
Learning curve
Technical result
Productivity
Sentiment
Learning?
Meh
Needed rework;
OK in the end
#2
!!!
Lesson #1
New tech, mindset
requires investment in
learning
Invest in your people!
λ
Another team!
λ
“We’ll have some of that!”
λ
Jul 13 Jan 14
1 2
4
6
5
New team; new ideas!
3
LOC
Web
JSON
DB
Dep Inj
Unfinagled
Argonaut
2K, 3K, 4K, 1K
Slick
Constructors
Type Web app, libs, API x 2
• 2 x Mentor
Learning Investment Report card
Learning curve
Technical result
Productivity
Sentiment
Not bad
Great
Great
#3,4,
5,6
Jul 13 Jan 14
1 2
4
6
5
3
7
Theft & innovation
Jul 14
Lesson #2
Having multiple teams
is great, because you can
steal from each other
LOC
Web
JSON
DB
Dep Inj
Unfinagled
Argonaut
4K
Slick
Monad Transformers
Type API
#7
LOC
Web
JSON
DB
Dep Inj
Unfinagled
Argonaut
4K
Slick
Monad Transformers
Type API
• 2 x Mentor
Learning Investment
#7
LOC
Web
JSON
DB
Dep Inj
Unfinagled
Argonaut
4K
Slick
Monad Transformers
Type API
• 2 x Mentor
Learning Investment Report card
Learning curve
Technical result
Productivity
Sentiment
Vertical
Great
Great
#7
Monad Transformers
Good technical benefits, but…
Only 2 people could understand the code
Experienced engineers felt totally helpless
Learning curve way too steep
Devops
All-rounders
Gurus
All-rounders
Gurus
JS / CSS / HTML
AWS
All-rounders
Gurus
Scala (originally!)
Gurus
All-rounders
Scala (now)
Gurus
• Smooth learning curve
is utterly essential
• We need more all-
rounders
• We can’t leave people
behind
Lesson #3
Familiar, but technically
unsound concepts have
limited value.
However… if we can’t make a
concept learnable, then we
can’t use it.
λ
A Ruby team considers its options…
λ
λ
Jul 13 Jan 14
1 2
4
6
5
3
7
A 3rd team dips its toe in
the water
8
Jul 14
LOC
Web
JSON
DB
Dep Inj
Play2
Play2
2K
Anorm
Constructors
Type Web app
#8
LOC
Web
JSON
DB
Dep Inj
Play2
Play2
2K
Anorm
Constructors
Type Web app
• Trial and error
• Code Katas
Learning Investment
#8
LOC
Web
JSON
DB
Dep Inj
Play2
Play2
2K
Anorm
Constructors
Type Web app
• Trial and error
• Code Katas
Learning Investment Report card
Learning curve
Technical result
Productivity
Sentiment
Steep
Meh
OK
#8
Lesson #4
It’s really hard learning
from scratch
Be prepared for pain up
front
λ
Jul 13 Jan 14
1 2
4
6
5
3
7
Latest iteration
8
Jul 14 Jan 15
17
Design trends
Inheritance/mixins Static functions
Design trends
Inheritance/mixins Static functions
Partial functions Total functions
Design trends
Inheritance/mixins Static functions
Partial functions Total functions
Exceptions Sum types
Design trends
Inheritance/mixins Static functions
Partial functions Total functions
Strings/primitives Wrapper types
Exceptions Sum types
FP Guild
Every Thursday, in work hours
7 – 12 people each week
Reading, exercises, talks, live coding
LOC
Web
JSON
DB
Dep Inj
Unfiltered
Argonaut
3K
Slick
Free Monads
Type API
#17
LOC
Web
JSON
DB
Dep Inj
Unfiltered
Argonaut
3K
Slick
Free Monads
Type API
• 2 x Mentors
• Pull Requests
• Code reviews
• Pairing
• FP Guild
Learning Investment
#17
LOC
Web
JSON
DB
Dep Inj
Unfiltered
Argonaut
3K
Slick
Free Monads
Type API
• 2 x Mentors
• Pull Requests
• Code reviews
• Pairing
• FP Guild
Learning Investment Report card
Learning curve
Technical result
Productivity
Sentiment
Smooth
Great
Brilliant
#17
Pure core
Routes Controllers Logic Script
Interpreter
Actual DB
“Authenticate”
“Use config”
“Get from DB”
“Update DB”
“Log result”
Web Framework
Server
App runtime
Pure core
Routes Controllers Logic Script
Pure Interpreter
Pure tests
Input
Output
Assert
“Authenticate”
“Use config”
“Get from DB”
“Update DB”
“Log result”
Pure core
Interpreter
Actual DB
Web Framework
Server
App runtimeWafer thin
E2E tests
Input
Output
Assert
object SearchController {
def getList(uid: UserId): Script[Response]
= {
for {
searches <- getSearches(uid)
cfg <- getConfig
results <- addLinks(searches, cfg)
} yield Ok ~> Response(result.toJson)
}
}
Learning curve:
Learning curve:
Smooooth
Mocks
Stubs
Flaky pretend servers
just to check
a response code
Flaky tests
that take
30 min to run
Side effects
everywhere
Exceptions
Intrusive
DI frameworks
You shouldn’t be
dealing with all
that complexity
and crap!
Most business software
isn’t rocket science.
There is a
better way
FP is a tall tree
But there is so much
low hanging fruit!
Thank you!

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvm
 
Monte Carlo C++
Monte Carlo C++Monte Carlo C++
Monte Carlo C++
 
Goodparts
GoodpartsGoodparts
Goodparts
 
Kotlin hands on - MorningTech ekito 2017
Kotlin hands on - MorningTech ekito 2017Kotlin hands on - MorningTech ekito 2017
Kotlin hands on - MorningTech ekito 2017
 
Elixir for rubysts
Elixir for rubystsElixir for rubysts
Elixir for rubysts
 
Kotlin cheat sheet by ekito
Kotlin cheat sheet by ekitoKotlin cheat sheet by ekito
Kotlin cheat sheet by ekito
 
Introduction to kotlin
Introduction to kotlinIntroduction to kotlin
Introduction to kotlin
 
eMan Dev Meetup: Kotlin For Android (part 03/03) 18.5.2017
eMan Dev Meetup: Kotlin For Android (part 03/03) 18.5.2017eMan Dev Meetup: Kotlin For Android (part 03/03) 18.5.2017
eMan Dev Meetup: Kotlin For Android (part 03/03) 18.5.2017
 
A quick and fast intro to Kotlin
A quick and fast intro to Kotlin A quick and fast intro to Kotlin
A quick and fast intro to Kotlin
 
Elixir
ElixirElixir
Elixir
 
Introduction to kotlin for android app development gdg ahmedabad dev fest 2017
Introduction to kotlin for android app development   gdg ahmedabad dev fest 2017Introduction to kotlin for android app development   gdg ahmedabad dev fest 2017
Introduction to kotlin for android app development gdg ahmedabad dev fest 2017
 
Building a website in Haskell coming from Node.js
Building a website in Haskell coming from Node.jsBuilding a website in Haskell coming from Node.js
Building a website in Haskell coming from Node.js
 
C# 7.0 Hacks and Features
C# 7.0 Hacks and FeaturesC# 7.0 Hacks and Features
C# 7.0 Hacks and Features
 
Gremlin 101.3 On Your FM Dial
Gremlin 101.3 On Your FM DialGremlin 101.3 On Your FM Dial
Gremlin 101.3 On Your FM Dial
 
Introducing: A Complete Algebra of Data
Introducing: A Complete Algebra of DataIntroducing: A Complete Algebra of Data
Introducing: A Complete Algebra of Data
 
NLP using JavaScript Natural Library
NLP using JavaScript Natural LibraryNLP using JavaScript Natural Library
NLP using JavaScript Natural Library
 
Async and Parallel F#
Async and Parallel F#Async and Parallel F#
Async and Parallel F#
 
Kotlin for Android Development
Kotlin for Android DevelopmentKotlin for Android Development
Kotlin for Android Development
 
Open Problems in the Universal Graph Theory
Open Problems in the Universal Graph TheoryOpen Problems in the Universal Graph Theory
Open Problems in the Universal Graph Theory
 

Ähnlich wie 2 Years of Real World FP at REA

Debugging and Testing ES Systems
Debugging and Testing ES SystemsDebugging and Testing ES Systems
Debugging and Testing ES Systems
Chris Birchall
 
Linq 1224887336792847 9
Linq 1224887336792847 9Linq 1224887336792847 9
Linq 1224887336792847 9
google
 
ooc - A hybrid language experiment
ooc - A hybrid language experimentooc - A hybrid language experiment
ooc - A hybrid language experiment
Amos Wenger
 
Douglas Crockford Presentation Goodparts
Douglas Crockford Presentation GoodpartsDouglas Crockford Presentation Goodparts
Douglas Crockford Presentation Goodparts
Ajax Experience 2009
 
Building DSLs On CLR and DLR (Microsoft.NET)
Building DSLs On CLR and DLR (Microsoft.NET)Building DSLs On CLR and DLR (Microsoft.NET)
Building DSLs On CLR and DLR (Microsoft.NET)
Vitaly Baum
 

Ähnlich wie 2 Years of Real World FP at REA (20)

Beyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisBeyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic Analysis
 
Debugging and Testing ES Systems
Debugging and Testing ES SystemsDebugging and Testing ES Systems
Debugging and Testing ES Systems
 
Effective Object Oriented Design in Cpp
Effective Object Oriented Design in CppEffective Object Oriented Design in Cpp
Effective Object Oriented Design in Cpp
 
Tips And Tricks For Bioinformatics Software Engineering
Tips And Tricks For Bioinformatics Software EngineeringTips And Tricks For Bioinformatics Software Engineering
Tips And Tricks For Bioinformatics Software Engineering
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987
 
Data oriented design and c++
Data oriented design and c++Data oriented design and c++
Data oriented design and c++
 
不深不淺,帶你認識 LLVM (Found LLVM in your life)
不深不淺,帶你認識 LLVM (Found LLVM in your life)不深不淺,帶你認識 LLVM (Found LLVM in your life)
不深不淺,帶你認識 LLVM (Found LLVM in your life)
 
Remix Your Language Tooling (JSConf.eu 2012)
Remix Your Language Tooling (JSConf.eu 2012)Remix Your Language Tooling (JSConf.eu 2012)
Remix Your Language Tooling (JSConf.eu 2012)
 
Linq 1224887336792847 9
Linq 1224887336792847 9Linq 1224887336792847 9
Linq 1224887336792847 9
 
ooc - A hybrid language experiment
ooc - A hybrid language experimentooc - A hybrid language experiment
ooc - A hybrid language experiment
 
ooc - A hybrid language experiment
ooc - A hybrid language experimentooc - A hybrid language experiment
ooc - A hybrid language experiment
 
Go Beyond Higher Order Functions: A Journey into Functional Programming
Go Beyond Higher Order Functions: A Journey into Functional ProgrammingGo Beyond Higher Order Functions: A Journey into Functional Programming
Go Beyond Higher Order Functions: A Journey into Functional Programming
 
ELAVARASAN.pdf
ELAVARASAN.pdfELAVARASAN.pdf
ELAVARASAN.pdf
 
Douglas Crockford Presentation Goodparts
Douglas Crockford Presentation GoodpartsDouglas Crockford Presentation Goodparts
Douglas Crockford Presentation Goodparts
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
 
Programming Languages: some news for the last N years
Programming Languages: some news for the last N yearsProgramming Languages: some news for the last N years
Programming Languages: some news for the last N years
 
You Might Just be a Functional Programmer Now
You Might Just be a Functional Programmer NowYou Might Just be a Functional Programmer Now
You Might Just be a Functional Programmer Now
 
Building DSLs On CLR and DLR (Microsoft.NET)
Building DSLs On CLR and DLR (Microsoft.NET)Building DSLs On CLR and DLR (Microsoft.NET)
Building DSLs On CLR and DLR (Microsoft.NET)
 
React Native Evening
React Native EveningReact Native Evening
React Native Evening
 
Thinking In Swift
Thinking In SwiftThinking In Swift
Thinking In Swift
 

Mehr von kenbot

Mehr von kenbot (9)

Grow your own tech leads
Grow your own tech leadsGrow your own tech leads
Grow your own tech leads
 
Responsible DI: Ditch the Frameworks
Responsible DI: Ditch the FrameworksResponsible DI: Ditch the Frameworks
Responsible DI: Ditch the Frameworks
 
FP adoption at REA
FP adoption at REAFP adoption at REA
FP adoption at REA
 
Lenses for the masses - introducing Goggles
Lenses for the masses - introducing GogglesLenses for the masses - introducing Goggles
Lenses for the masses - introducing Goggles
 
Data made out of functions
Data made out of functionsData made out of functions
Data made out of functions
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mocks
 
Your data structures are made of maths!
Your data structures are made of maths!Your data structures are made of maths!
Your data structures are made of maths!
 
Category theory for beginners
Category theory for beginnersCategory theory for beginners
Category theory for beginners
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monads
 

Kürzlich hochgeladen

The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 

Kürzlich hochgeladen (20)

8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 

2 Years of Real World FP at REA