SlideShare une entreprise Scribd logo
1  sur  74
Télécharger pour lire hors ligne
ENTERPRISE ALGEBRAS
Timothy Perrett
Scala World 2016
HELLO.
*waves*
“Tuesday”
WE’RE
HIRING!
WE ❤ FP.
It’s not just for academics!
OSS.
github.com/verizon
~1000 REPOS.
~ 85% are Scala projects (yes, built with SBT).
11 SBT PLUGINS.
Doing the nasty so users don't have too.
SUCH SIZE. SO WOW.
Requires scaling and automation of all the things.
METHOD.
Constraints liberate. Liberties constrain.
METHOD.
One uses frameworks. Frameworks use you.
Invest in the future, today.
EDUCATION.
EDUCATION.
➤ Evangelize functional programming
benefits to team.
➤ Users initially self-directed learning from
texts and online resources.
➤ Dissemination of techniques from staff
(typically the team lead or coworkers)
➤ Practice. Practice. Practice. Pull requests
provide a path to learn every day.
➤ Internal courses and materials for
learning more advanced FP techniques.
➤ Further practice and experience. Rinse
and repeat :-)
REAL-WORLD FP
it actually does work in production.
HLIST“seems like a good idea”
HLIST.
➤ It’s THE gateway drug for advanced Scala.
➤ Easy to understand.
➤ Untold numbers of business uses.
➤ One of the most used third-party
construct across our internal eco-system.
FREE &
COYONADA.
FREE.Certainly not an exhaustive guide.
sealed trait Free[F[_],A]
case class Return[F[_],A](a: A)
extends Free[F,A]
case class Suspend[F[_],A](s: F[Free[F, A]])
extends Free[F,A]
case class Return[F[_],A](a: A)
extends Free[F,A]
case class Suspend[F[_],A](s: F[Free[F, A]])
extends Free[F,A]
case class Return[F[_],A](a: A)
extends Free[F,A]
case class Suspend[F[_],A](s: F[Free[F, A]])
extends Free[F,A]
THE YONEDA LEMMA.
def apply[B](f: A => B): F[B]
abstract class Yoneda[F[_], A]{
def apply[B](f: A => B): F[B]
}
def toYoneda[F[_] : Functor, A](fa: F[A]) =
new Yoneda[F,A] {
def apply[B](f: A => B) =
Functor[F].map(fa)(f)
}
def fromYoneda[F[_], A](yo: Yoneda[F, A]) =
yo.apply(identity)
SO WHAT?
sealed abstract class Coyoneda[F[_], A]{
type I
val fi: F[I]
val k: I => A
}
sealed abstract class Coyoneda[F[_], A]{
type I
val fi: F[I]
val k: I => A
}
YAY!
case class Suspend[F[_],A](s: F[Free[F, A]])
extends Free[F,A]
type FreeC[S[_], A] =
Free[({type f[x] = Coyoneda[S, x]})#f, A]
NOMAD MONAD.Fun to say. Better to use.
sealed abstract class SchedulerOp[A]
extends Product with Serializable
final case class Delete(…)
extends SchedulerOp[Unit]
final case class Launch(…)
extends SchedulerOp[Unit]
type SchedulerF[A] =
Free.FreeC[SchedulerOp, A]
def delete(…): SchedulerF[Unit] =
Free.liftFC(Delete(x,y))
SchedulerOp ~> Task
def apply[A](s: SchedulerOp[A]): Task[A]
SchedulerOp ~> Task
def apply[A](s: SchedulerOp[A]): Task[A]
TESTABLE
CO-PRODUCTS.
for {
a <- free1.bar(123)
b <- free2.foo(a)
} yield b
for {
a <- free1.bar(123)
b <- free2.foo(a)
} yield b
final case class Coproduct[F[_], G[_], A](

run: F[A] / G[A])
final case class Coproduct[F[_], G[_], A](

run: F[A] / G[A])
algebra 1
algebra 2
type CombOp[A] = Coproduct[QuxOp, FooOp, A]
type CombF[A] = Free.FreeC[CombOp, A]
def example: CombF[String] =
for {
a <- useQux(1)
b <- useFoo(a)
} yield b
def useQux(x: Int): CombF[Int] =
QuxOp.gogogo(x).inject
def useFoo(x: Int): CombF[String] =
FooOp.gogogo(x).inject
final implicit class InjectCombF[F[_],A](

val fa: Free.FreeC[F,A])(

implicit I: Inject[F, Comb.CombOp]){
def inject[G[_]] = injectFC.apply(fa)
}
def injectFC[F[_], G[_]](implicit I: Inject[F, G]): FreeC[F, ?] ~> FreeC[G, ?] =
new (FreeC[F, ?] ~> FreeC[G, ?]) {
def apply[A](fa: FreeC[F, A]): FreeC[G, A] =
fa.mapSuspension[Coyoneda[G, ?]](
new (Coyoneda[F, ?] ~> Coyoneda[G, ?]) {
def apply[B](fa: Coyoneda[F, B]): Coyoneda[G, B] = fa.trans(I)
}
)
}
sorry, there aren’t really ways to simplify this.
def injectFC[F[_], G[_]](implicit I: Inject[F, G]): FreeC[F, ?] ~> FreeC[G, ?] =
new (FreeC[F, ?] ~> FreeC[G, ?]) {
def apply[A](fa: FreeC[F, A]): FreeC[G, A] =
fa.mapSuspension[Coyoneda[G, ?]](
new (Coyoneda[F, ?] ~> Coyoneda[G, ?]) {
def apply[B](fa: Coyoneda[F, B]): Coyoneda[G, B] = fa.trans(I)
}
)
}
transform

free algebras
sorry, there aren’t really ways to simplify this.
def injectFC[F[_], G[_]](implicit I: Inject[F, G]): FreeC[F, ?] ~> FreeC[G, ?] =
new (FreeC[F, ?] ~> FreeC[G, ?]) {
def apply[A](fa: FreeC[F, A]): FreeC[G, A] =
fa.mapSuspension[Coyoneda[G, ?]](
new (Coyoneda[F, ?] ~> Coyoneda[G, ?]) {
def apply[B](fa: Coyoneda[F, B]): Coyoneda[G, B] = fa.trans(I)
}
)
}
sorry, there aren’t really ways to simplify this.
transform

coyonedas
def injectFC[F[_], G[_]](implicit I: Inject[F, G]): FreeC[F, ?] ~> FreeC[G, ?] =
new (FreeC[F, ?] ~> FreeC[G, ?]) {
def apply[A](fa: FreeC[F, A]): FreeC[G, A] =
fa.mapSuspension[Coyoneda[G, ?]](
new (Coyoneda[F, ?] ~> Coyoneda[G, ?]) {
def apply[B](fa: Coyoneda[F, B]): Coyoneda[G, B] = fa.trans(I)
}
)
}
sorry, there aren’t really ways to simplify this.
F[A] => G[A]
APPLICATION DESIGN.
short-lived

request
response
free algebra
coproduct

algebra
alternitivly,

use kleisli
edge of 

the world
long-lived

stream
edge of 

the world
case GET -> Root / "v1" / "datacenters" / dcname & IsAuthenticated(session) =>
jsonF(Nelson.fetchDatacenterByName(dcname)){ option =>
option match {
case Some(dc) => Ok(dc.asJson)
case None => NotFound(s"datacenter '$dcname' does not exist")
}
}
sorry, there aren’t really ways to simplify this.
protocol specifics
case GET -> Root / "v1" / "datacenters" / dcname & IsAuthenticated(session) =>
jsonF(Nelson.fetchDatacenterByName(dcname)){ option =>
option match {
case Some(dc) => Ok(dc.asJson)
case None => NotFound(s"datacenter '$dcname' does not exist")
}
}
sorry, there aren’t really ways to simplify this.
domain function
BlazeBuilder
.bindHttp(8080, 127.0.0.1)
.mountService(service)
.start // Task[Server]
.run // Unit
sorry, there aren’t really ways to simplify this.
APPLICATION DESIGN.
➤ All your I/O boundaries - from a systems
perspective - should be a Free algebra.
➤ Database access.
➤ Network access.
➤ Any other random things you can’t
sensibly reason about.
➤ Be extremely selective about the edge of
the world.
➤ Understand the semantics of running
your Task.
TECHNICAL DEBT.
TECHNICAL DEBT
➤ Accept it will happen. Minimization is
the best you can hope for.
➤ Proactively push debt repositories to the
leaves of your system graph.
➤ Libraries are the key battleground in debt
avoidance. Choose wisely.
➤ Be consistent with different library
APIs; this drives adoption and avoids
accidental debt when users do the
unexpected.
CHALLENGES.
CHALENGES.
➤ Scala is not a pure FP language.
➤ Ironically a positive and enabling thing
for both beginners, and the business.
➤ Community libraries can be a mixed bag.
➤ Not everyone prioritizes maintaining
binary compatible releases.
➤ Many internal forks to stabilize deps.
➤ GC is a real and present danger.
➤ Ensuring users don’t revert to Java
without the semicolons is a definite and
on-going challenge.
* Both fleshy and technical challenges

* Generally speaking, hiring for Scala
has not been a big issue.
WINS.
WINS.
➤ Doing FP has allowed us to recruit and
retain some brilliant minds.
➤ The application of Free, Cofree, Fix and
other advanced type-level paradigms
make your software easier to refactor, and
cheaper over time.
➤
CONCLUSIONS.
CONCLUSIONS.
➤ Free & Coproduct allow us to build modular, testable, systems from discrete
programs.
➤ Your program has programs.
➤ Running Scala at scale is not zero-cost. Far from it.
➤ You need expertise in the JVM to understand corner cases (happens for Java too).
➤ Purely functional stream programming currently struggles at high-load due 

to GC pauses.
➤ Team education is a hard problem.
➤ Don’t hire for quantity. Hire for quality and aptitude.
SCALA CENTER.
https://github.com/scalacenter/advisoryboard/pulls
we need

the community!
EOF
timperrett
github.com/verizon

Contenu connexe

En vedette

DevOps, Agile methods and Continuous Improvement in the Software development ...
DevOps, Agile methods and Continuous Improvement in the Software development ...DevOps, Agile methods and Continuous Improvement in the Software development ...
DevOps, Agile methods and Continuous Improvement in the Software development ...
Paulo Traça
 

En vedette (13)

DevOps
DevOpsDevOps
DevOps
 
Logging in Scala
Logging in ScalaLogging in Scala
Logging in Scala
 
DevOps, Agile methods and Continuous Improvement in the Software development ...
DevOps, Agile methods and Continuous Improvement in the Software development ...DevOps, Agile methods and Continuous Improvement in the Software development ...
DevOps, Agile methods and Continuous Improvement in the Software development ...
 
Scala Helix
Scala HelixScala Helix
Scala Helix
 
Reasonable RPC with Remotely
Reasonable RPC with RemotelyReasonable RPC with Remotely
Reasonable RPC with Remotely
 
2016 Federal User Group Conference - DevOps Product Strategy
2016 Federal User Group Conference - DevOps Product Strategy2016 Federal User Group Conference - DevOps Product Strategy
2016 Federal User Group Conference - DevOps Product Strategy
 
Роман Яворский "Introduction to DevOps"
Роман Яворский "Introduction to DevOps"Роман Яворский "Introduction to DevOps"
Роман Яворский "Introduction to DevOps"
 
Dc scrum agile_eng_20130923
Dc scrum agile_eng_20130923Dc scrum agile_eng_20130923
Dc scrum agile_eng_20130923
 
DevOps - The Future of Application Lifecycle Automation
DevOps - The Future of Application Lifecycle Automation DevOps - The Future of Application Lifecycle Automation
DevOps - The Future of Application Lifecycle Automation
 
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
 
Refactoring terraform
Refactoring terraformRefactoring terraform
Refactoring terraform
 
Hashiconf AWS Lambda Breakout
Hashiconf AWS Lambda BreakoutHashiconf AWS Lambda Breakout
Hashiconf AWS Lambda Breakout
 
Getting started with AWS IoT on Raspberry Pi
Getting started with AWS IoT on Raspberry PiGetting started with AWS IoT on Raspberry Pi
Getting started with AWS IoT on Raspberry Pi
 

Similaire à Enterprise Algebras, Scala World 2016

Save time by applying clean code principles
Save time by applying clean code principlesSave time by applying clean code principles
Save time by applying clean code principles
Edorian
 
LECTURE 6 DESIGN, DEBUGGING, INTERFACES.pdf
LECTURE 6 DESIGN, DEBUGGING, INTERFACES.pdfLECTURE 6 DESIGN, DEBUGGING, INTERFACES.pdf
LECTURE 6 DESIGN, DEBUGGING, INTERFACES.pdf
SHASHIKANT346021
 
LECTURE 6 DESIGN, DEBasd, INTERFACES.pdf
LECTURE 6 DESIGN, DEBasd, INTERFACES.pdfLECTURE 6 DESIGN, DEBasd, INTERFACES.pdf
LECTURE 6 DESIGN, DEBasd, INTERFACES.pdf
ShashikantSathe3
 

Similaire à Enterprise Algebras, Scala World 2016 (20)

Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)Composing an App with Free Monads (using Cats)
Composing an App with Free Monads (using Cats)
 
The GO Language : From Beginners to Gophers
The GO Language : From Beginners to GophersThe GO Language : From Beginners to Gophers
The GO Language : From Beginners to Gophers
 
Scala, Functional Programming and Team Productivity
Scala, Functional Programming and Team ProductivityScala, Functional Programming and Team Productivity
Scala, Functional Programming and Team Productivity
 
purely_functional_play_framework_application
purely_functional_play_framework_applicationpurely_functional_play_framework_application
purely_functional_play_framework_application
 
Replace OutputIterator and Extend Range
Replace OutputIterator and Extend RangeReplace OutputIterator and Extend Range
Replace OutputIterator and Extend Range
 
Izumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala StackIzumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala Stack
 
Go and Object Oriented Programming
Go and Object Oriented ProgrammingGo and Object Oriented Programming
Go and Object Oriented Programming
 
Ontopia tutorial
Ontopia tutorialOntopia tutorial
Ontopia tutorial
 
CoffeeScript: A beginner's presentation for beginners copy
CoffeeScript: A beginner's presentation for beginners copyCoffeeScript: A beginner's presentation for beginners copy
CoffeeScript: A beginner's presentation for beginners copy
 
Dependency Injection Why is it awesome and Why should I care?
Dependency Injection Why is it awesome and Why should I care?Dependency Injection Why is it awesome and Why should I care?
Dependency Injection Why is it awesome and Why should I care?
 
Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015
 
QA Fest 2015. Яков Крамаренко. Polyglot automation
QA Fest 2015. Яков Крамаренко. Polyglot automation QA Fest 2015. Яков Крамаренко. Polyglot automation
QA Fest 2015. Яков Крамаренко. Polyglot automation
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
EuroPython 2017 - Bonono - Simple ETL in python 3.5+
EuroPython 2017 - Bonono - Simple ETL in python 3.5+EuroPython 2017 - Bonono - Simple ETL in python 3.5+
EuroPython 2017 - Bonono - Simple ETL in python 3.5+
 
Save time by applying clean code principles
Save time by applying clean code principlesSave time by applying clean code principles
Save time by applying clean code principles
 
C Programming Homework Help
C Programming Homework HelpC Programming Homework Help
C Programming Homework Help
 
LECTURE 6 DESIGN, DEBUGGING, INTERFACES.pdf
LECTURE 6 DESIGN, DEBUGGING, INTERFACES.pdfLECTURE 6 DESIGN, DEBUGGING, INTERFACES.pdf
LECTURE 6 DESIGN, DEBUGGING, INTERFACES.pdf
 
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides:  Let's build macOS CLI Utilities using SwiftMobileConf 2021 Slides:  Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
 
Making Steaks from Sacred Cows
Making Steaks from Sacred CowsMaking Steaks from Sacred Cows
Making Steaks from Sacred Cows
 
LECTURE 6 DESIGN, DEBasd, INTERFACES.pdf
LECTURE 6 DESIGN, DEBasd, INTERFACES.pdfLECTURE 6 DESIGN, DEBasd, INTERFACES.pdf
LECTURE 6 DESIGN, DEBasd, INTERFACES.pdf
 

Plus de Timothy Perrett

Scalalable Language for a Scalable Web
Scalalable Language for a Scalable WebScalalable Language for a Scalable Web
Scalalable Language for a Scalable Web
Timothy Perrett
 
Javazone 2011: Goal Directed Web Applications
Javazone 2011: Goal Directed Web ApplicationsJavazone 2011: Goal Directed Web Applications
Javazone 2011: Goal Directed Web Applications
Timothy Perrett
 
Concurrency and Parallelism with Scala
Concurrency and Parallelism with ScalaConcurrency and Parallelism with Scala
Concurrency and Parallelism with Scala
Timothy Perrett
 
Scaladays 2011: Task Driven Scala Web Applications
Scaladays 2011: Task Driven Scala Web ApplicationsScaladays 2011: Task Driven Scala Web Applications
Scaladays 2011: Task Driven Scala Web Applications
Timothy Perrett
 

Plus de Timothy Perrett (11)

Nelson: Rigorous Deployment for a Functional World
Nelson: Rigorous Deployment for a Functional WorldNelson: Rigorous Deployment for a Functional World
Nelson: Rigorous Deployment for a Functional World
 
Online Experimentation with Immutable Infrastructure
Online Experimentation with Immutable InfrastructureOnline Experimentation with Immutable Infrastructure
Online Experimentation with Immutable Infrastructure
 
Functional Programming at Verizon
Functional Programming at VerizonFunctional Programming at Verizon
Functional Programming at Verizon
 
Scalalable Language for a Scalable Web
Scalalable Language for a Scalable WebScalalable Language for a Scalable Web
Scalalable Language for a Scalable Web
 
BRUG - Hello, Scala
BRUG - Hello, ScalaBRUG - Hello, Scala
BRUG - Hello, Scala
 
Javazone 2011: Goal Directed Web Applications
Javazone 2011: Goal Directed Web ApplicationsJavazone 2011: Goal Directed Web Applications
Javazone 2011: Goal Directed Web Applications
 
Concurrency and Parallelism with Scala
Concurrency and Parallelism with ScalaConcurrency and Parallelism with Scala
Concurrency and Parallelism with Scala
 
Scaladays 2011: Task Driven Scala Web Applications
Scaladays 2011: Task Driven Scala Web ApplicationsScaladays 2011: Task Driven Scala Web Applications
Scaladays 2011: Task Driven Scala Web Applications
 
Bathcamp 2010-riak
Bathcamp 2010-riakBathcamp 2010-riak
Bathcamp 2010-riak
 
Javazone 2010-lift-framework-public
Javazone 2010-lift-framework-publicJavazone 2010-lift-framework-public
Javazone 2010-lift-framework-public
 
Devoxx 2009: The Lift Framework
Devoxx 2009: The Lift FrameworkDevoxx 2009: The Lift Framework
Devoxx 2009: The Lift Framework
 

Dernier

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Dernier (20)

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
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...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
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...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

Enterprise Algebras, Scala World 2016