SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
First-Class Patterns
John A. De Goes - @jdegoes
Frontier Developers, February 26
Agenda
●
●
●
●
●
●

Intro
Pattern Matching 101
First-Class-ness 101
Magical Patterns
First-Class Patterns
Exercises
Intro
Pattern Matching
● Divides a (possibly infinite) set of values into
a discrete number of cases, where each case
can be handled in a uniform way
● “if” on steroids
○ Sometimes strictly more powerful (e.g. Haskell)
Intro - Examples
-- sign of a number
sign x |
|
|

x > 0
x == 0
x < 0

=
=
=

1
0
-1

-- take the first n elements from a list
take
take
take

0
_
n

_
[]
(x:xs)

=
=
=

[]
[]
x : take (n-1) xs

-- generate some javascript
valueToJs
valueToJs
valueToJs
valueToJs
...

:: Options -> ModuleName -> Environment -> Value -> JS
_ _ _ (NumericLiteral n) = JSNumericLiteral n
_ _ _ (StringLiteral s) = JSStringLiteral s
_ _ _ (BooleanLiteral b) = JSBooleanLiteral b
Intro - Examples
sealed trait Level
case object Level1 extends Level
case object Level2 extends Level

sealed trait Title
case object DBAdmin extends Title
case class SWEngineer(level: Level) extends Title

case class Employee(manager: Option[Employee], name: String, title: Title)

val employees = ???

val selfManagedLevel2Engineers = employees.collect {
case Employee(None, name, SWEngineer(Level2)) => name
}
Pattern Matching 101
Filter
Does it have the structure I
want? [Yes/No]
If so, extract out the pieces
that are relevant to me.

Extract
Pattern Matching 101
-- take the first n elements from a list
take 0
_
= []
take _
[]
= []
take n
(x:xs)
= x : take (n-1) xs

Filter - does it have non-empty list structure?

Extract - Give me ‘head’ and ‘tail’
Pattern Matching 101
Products

Sums

case class Employee(

sealed trait Title

manager: Option[Employee],
name:

String,

title:

case object DBAdmin extends Title

terms

Title

case class SWEngineer(level: Level)
extends Title

)
class Account {

interface Shape { }

...

class Rect extends Shape { … }

public Account(BigDecimal balance, User holder) {

class Ellipse extends Shape { … }

...
}
}

class Pentagon extends Shape { … }

terms
First-Class-ness 101
data Maybe a = Nothing | Just a deriving (Eq, Ord)

class Person {
public Person(String name, int age) {
...
}
}
First-Class-ness 101

Magic interferes with your ability to
abstract and compose.
Magical Patterns
Ordinary Duplication
sealed
object
…
case
case

trait Provenance
Provenance {
class Either(left: Provenance, right: Provenance) extends Provenance
class Both(left: Provenance, right: Provenance) extends Provenance

def allOf(xs: Seq[Provenance]): Provenance = {
if (xs.length == 0) Unknown
else if (xs.length == 1) xs.head
else xs.reduce(Both.apply)
}
def anyOf(xs: Seq[Provenance]): Provenance = {
if (xs.length == 0) Unknown
else if (xs.length == 1) xs.head
else xs.reduce(Either.apply)
}
}
Magical Patterns
Factoring
sealed
object
case
case
case
case
case

trait Provenance
Provenance {
object Unknown extends Provenance
object Value extends Provenance
class Relation(value: SqlRelation) extends Provenance
class Either(left: Provenance, right: Provenance) extends Provenance
class Both(left: Provenance, right: Provenance) extends Provenance

def allOf(xs: Seq[Provenance]): Provenance = reduce(xs)(Both.apply)
def anyOf(xs: Seq[Provenance]): Provenance = reduce(xs)(Either.apply)
private def reduce(xs: Seq[Provenance])(
f: (Provenance, Provenance) => Provenance): Provenance = {
if (xs.length == 0) Unknown
else if (xs.length == 1) xs.head
else xs.reduce(f)
}
}
Magical Patterns
Factoringz
sealed
object
case
case
case
case
case

trait Provenance
Provenance {
object Unknown extends Provenance
object Value extends Provenance
class Relation(value: SqlRelation) extends Provenance
class Either(left: Provenance, right: Provenance) extends Provenance
class Both(left: Provenance, right: Provenance) extends Provenance

private def strict[A, B, C](f: (A, B) => C): (A, => B) => C = (a, b) => f(a, b)
val BothMonoid
= Monoid.instance(strict[Provenance, Provenance, Provenance](Both.apply), Unknown)
val EitherMonoid = Monoid.instance(strict[Provenance, Provenance, Provenance](Either.apply), Unknown)
def allOf(xs: List[Provenance]): Provenance = Foldable[List].foldMap(xs)(identity)(BothMonoid)
def anyOf(xs: List[Provenance]): Provenance = Foldable[List].foldMap(xs)(identity)(EitherMonoid)
}
Magical Patterns
Toxic Duplication - Abstraction Fail
val Add = Mapping(
"(+)", "Adds two numeric values" NumericDomain,
,
(partialTyper {
case Type.Const(Data.Number(v1)) :: v2 :: Nil if (v1.signum == 0) => v2
case v1 :: Type.Const(Data.Number(v2)) :: Nil if (v2.signum == 0) => v1
case Type.Const(Data.
Int(v1)) :: Type.Const(Data.
Int(v2)) :: Nil =>
Type.Const(Data.
Int(v1 + v2))
case Type.Const(Data.Number(v1)) :: Type.Const(Data.Number(v2)) ::
Nil =>
Type.Const(Data.Dec(v1 + v2))
}) ||| numericWidening
)
Magical Patterns
Pattern Combinators - Composition Fail
● Product & sum
○ PartialFunction.orElse

● Negation
● Defaults
● Use-case specific
Magical Patterns
Magical patterns limit your ability
to abstract over patterns and to
compose them together to create new
patterns.
First-Class Patterns
First-class patterns are built using
other language features so you can
abstract and compose them.
First-Class Patterns
Haskell Example
ex4 :: Either (Int,Int) Int -> Int
ex4 a = match a $
(1+) <$> (left (pair var (cst 4)) ->> id
<|>

right var

->> id)

<|> left (pair __ var) ->> id

http://hackage.haskell.org/package/first-class-patterns
First-Class Patterns
“For the rest of us”
X match {
case Y => Z
}

type Pattern???
First-Class Patterns
Structure
Input

X match {
Output

case Y => Z
}

type Pattern???

Extraction
First-Class Patterns
One ‘Option’
Input

X match {
Output

case Y => Z
}

Extraction

type Pattern[X, Z] = X => Option[Z]
First-Class Patterns
Basic Patterns
def some[A, B](p: Pattern[A, B]): Pattern[Option[A], B] = _.flatMap(p)
def none[A, B]: Pattern[A, B] = Function.const( None)
def k[A](v0: A): Pattern[A, A] = v => if (v == v0) Some(v0) else None
def or[A, B](p1: Pattern[A, B], p2: Pattern[A, B]): Pattern[A, B] =
v => p1(v).orElse(p2(v))
scala> or(none, some(k( 2)))(Some(2))
res3: Option[Int] = Some(2)
https://gist.github.com/jdegoes/9240971
First-Class Patterns - JS
And Now in JavaScript….Because

http://jsfiddle.net/AvL4V/
First-Class Patterns
Limitations
● Extractors cannot throw away information,
leading to ‘dummy parameters’
● Negation not possible under any
circumstances
● No partiality warnings or built-in catch all
Exercises
1. Define a Pattern Combinator to Fix:
val Add = Mapping(
"(+)", "Adds two numeric values" NumericDomain,
,
(partialTyper {
case Type.Const(Data.Number(v1)) :: v2 :: Nil if (v1.signum == 0) => v2
case v1 :: Type.Const(Data.Number(v2)) :: Nil if (v2.signum == 0) => v1
case Type.Const(Data.
Int(v1)) :: Type.Const(Data.
Int(v2)) :: Nil =>
Type.Const(Data.
Int(v1 + v2))
case Type.Const(Data.Number(v1)) :: Type.Const(Data.Number(v2)) ::
Nil =>
Type.Const(Data.Dec(v1 + v2))
}) ||| numericWidening
)

EASY
Exercises
2. Define ‘Pattern’ and some core
patterns in the language of your choice

EASY
Exercises
3. Define an ‘And’ pattern that requires
both inputs match

EASY
Exercises
4. Define an alternate definition of
pattern (along with a few core patterns)
that permits pattern negation
4.b Optional: Use this to allow catch-alls
MODERATE
Exercises
5. Define an alternate definition of
pattern (along with a few core patterns)
that permits extractors to throw away
information

HARD
THANK YOU
First-Class Patterns
John A. De Goes - @jdegoes
Frontier Developers, February 26

Contenu connexe

Tendances

The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
John De Goes
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The Wild
StackMob Inc
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
John De Goes
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
Fwdays
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
John De Goes
 

Tendances (20)

The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskell
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Introduction to functional programming using Ocaml
Introduction to functional programming using OcamlIntroduction to functional programming using Ocaml
Introduction to functional programming using Ocaml
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The Wild
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scala
 
GUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingGUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programming
 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmer
 
O caml2014 leroy-slides
O caml2014 leroy-slidesO caml2014 leroy-slides
O caml2014 leroy-slides
 

Similaire à First-Class Patterns

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 

Similaire à First-Class Patterns (20)

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Scala for Jedi
Scala for JediScala for Jedi
Scala for Jedi
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
Scala
ScalaScala
Scala
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
From Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risksFrom Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risks
 
Introduction to-scala
Introduction to-scalaIntroduction to-scala
Introduction to-scala
 
ML-CheatSheet (1).pdf
ML-CheatSheet (1).pdfML-CheatSheet (1).pdf
ML-CheatSheet (1).pdf
 
Monadologie
MonadologieMonadologie
Monadologie
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Introducing scala
Introducing scalaIntroducing scala
Introducing scala
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Scala Bootcamp 1
Scala Bootcamp 1Scala Bootcamp 1
Scala Bootcamp 1
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Introduction to scala
Introduction to scalaIntroduction to scala
Introduction to scala
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 

Plus de John De Goes

Plus de John De Goes (16)

Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScript
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsSlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
 
The Dark Side of NoSQL
The Dark Side of NoSQLThe Dark Side of NoSQL
The Dark Side of NoSQL
 
Quirrel & R for Dummies
Quirrel & R for DummiesQuirrel & R for Dummies
Quirrel & R for Dummies
 
In-Database Predictive Analytics
In-Database Predictive AnalyticsIn-Database Predictive Analytics
In-Database Predictive Analytics
 
Analytics Maturity Model
Analytics Maturity ModelAnalytics Maturity Model
Analytics Maturity Model
 
Rise of the scientific database
Rise of the scientific databaseRise of the scientific database
Rise of the scientific database
 
Fun with automata
Fun with automataFun with automata
Fun with automata
 

Dernier

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
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Dernier (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - 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
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
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...
 
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...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
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
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 

First-Class Patterns

  • 1. First-Class Patterns John A. De Goes - @jdegoes Frontier Developers, February 26
  • 2. Agenda ● ● ● ● ● ● Intro Pattern Matching 101 First-Class-ness 101 Magical Patterns First-Class Patterns Exercises
  • 3. Intro Pattern Matching ● Divides a (possibly infinite) set of values into a discrete number of cases, where each case can be handled in a uniform way ● “if” on steroids ○ Sometimes strictly more powerful (e.g. Haskell)
  • 4. Intro - Examples -- sign of a number sign x | | | x > 0 x == 0 x < 0 = = = 1 0 -1 -- take the first n elements from a list take take take 0 _ n _ [] (x:xs) = = = [] [] x : take (n-1) xs -- generate some javascript valueToJs valueToJs valueToJs valueToJs ... :: Options -> ModuleName -> Environment -> Value -> JS _ _ _ (NumericLiteral n) = JSNumericLiteral n _ _ _ (StringLiteral s) = JSStringLiteral s _ _ _ (BooleanLiteral b) = JSBooleanLiteral b
  • 5. Intro - Examples sealed trait Level case object Level1 extends Level case object Level2 extends Level sealed trait Title case object DBAdmin extends Title case class SWEngineer(level: Level) extends Title case class Employee(manager: Option[Employee], name: String, title: Title) val employees = ??? val selfManagedLevel2Engineers = employees.collect { case Employee(None, name, SWEngineer(Level2)) => name }
  • 6. Pattern Matching 101 Filter Does it have the structure I want? [Yes/No] If so, extract out the pieces that are relevant to me. Extract
  • 7. Pattern Matching 101 -- take the first n elements from a list take 0 _ = [] take _ [] = [] take n (x:xs) = x : take (n-1) xs Filter - does it have non-empty list structure? Extract - Give me ‘head’ and ‘tail’
  • 8. Pattern Matching 101 Products Sums case class Employee( sealed trait Title manager: Option[Employee], name: String, title: case object DBAdmin extends Title terms Title case class SWEngineer(level: Level) extends Title ) class Account { interface Shape { } ... class Rect extends Shape { … } public Account(BigDecimal balance, User holder) { class Ellipse extends Shape { … } ... } } class Pentagon extends Shape { … } terms
  • 9. First-Class-ness 101 data Maybe a = Nothing | Just a deriving (Eq, Ord) class Person { public Person(String name, int age) { ... } }
  • 10. First-Class-ness 101 Magic interferes with your ability to abstract and compose.
  • 11. Magical Patterns Ordinary Duplication sealed object … case case trait Provenance Provenance { class Either(left: Provenance, right: Provenance) extends Provenance class Both(left: Provenance, right: Provenance) extends Provenance def allOf(xs: Seq[Provenance]): Provenance = { if (xs.length == 0) Unknown else if (xs.length == 1) xs.head else xs.reduce(Both.apply) } def anyOf(xs: Seq[Provenance]): Provenance = { if (xs.length == 0) Unknown else if (xs.length == 1) xs.head else xs.reduce(Either.apply) } }
  • 12. Magical Patterns Factoring sealed object case case case case case trait Provenance Provenance { object Unknown extends Provenance object Value extends Provenance class Relation(value: SqlRelation) extends Provenance class Either(left: Provenance, right: Provenance) extends Provenance class Both(left: Provenance, right: Provenance) extends Provenance def allOf(xs: Seq[Provenance]): Provenance = reduce(xs)(Both.apply) def anyOf(xs: Seq[Provenance]): Provenance = reduce(xs)(Either.apply) private def reduce(xs: Seq[Provenance])( f: (Provenance, Provenance) => Provenance): Provenance = { if (xs.length == 0) Unknown else if (xs.length == 1) xs.head else xs.reduce(f) } }
  • 13. Magical Patterns Factoringz sealed object case case case case case trait Provenance Provenance { object Unknown extends Provenance object Value extends Provenance class Relation(value: SqlRelation) extends Provenance class Either(left: Provenance, right: Provenance) extends Provenance class Both(left: Provenance, right: Provenance) extends Provenance private def strict[A, B, C](f: (A, B) => C): (A, => B) => C = (a, b) => f(a, b) val BothMonoid = Monoid.instance(strict[Provenance, Provenance, Provenance](Both.apply), Unknown) val EitherMonoid = Monoid.instance(strict[Provenance, Provenance, Provenance](Either.apply), Unknown) def allOf(xs: List[Provenance]): Provenance = Foldable[List].foldMap(xs)(identity)(BothMonoid) def anyOf(xs: List[Provenance]): Provenance = Foldable[List].foldMap(xs)(identity)(EitherMonoid) }
  • 14. Magical Patterns Toxic Duplication - Abstraction Fail val Add = Mapping( "(+)", "Adds two numeric values" NumericDomain, , (partialTyper { case Type.Const(Data.Number(v1)) :: v2 :: Nil if (v1.signum == 0) => v2 case v1 :: Type.Const(Data.Number(v2)) :: Nil if (v2.signum == 0) => v1 case Type.Const(Data. Int(v1)) :: Type.Const(Data. Int(v2)) :: Nil => Type.Const(Data. Int(v1 + v2)) case Type.Const(Data.Number(v1)) :: Type.Const(Data.Number(v2)) :: Nil => Type.Const(Data.Dec(v1 + v2)) }) ||| numericWidening )
  • 15. Magical Patterns Pattern Combinators - Composition Fail ● Product & sum ○ PartialFunction.orElse ● Negation ● Defaults ● Use-case specific
  • 16. Magical Patterns Magical patterns limit your ability to abstract over patterns and to compose them together to create new patterns.
  • 17. First-Class Patterns First-class patterns are built using other language features so you can abstract and compose them.
  • 18. First-Class Patterns Haskell Example ex4 :: Either (Int,Int) Int -> Int ex4 a = match a $ (1+) <$> (left (pair var (cst 4)) ->> id <|> right var ->> id) <|> left (pair __ var) ->> id http://hackage.haskell.org/package/first-class-patterns
  • 19. First-Class Patterns “For the rest of us” X match { case Y => Z } type Pattern???
  • 20. First-Class Patterns Structure Input X match { Output case Y => Z } type Pattern??? Extraction
  • 21. First-Class Patterns One ‘Option’ Input X match { Output case Y => Z } Extraction type Pattern[X, Z] = X => Option[Z]
  • 22. First-Class Patterns Basic Patterns def some[A, B](p: Pattern[A, B]): Pattern[Option[A], B] = _.flatMap(p) def none[A, B]: Pattern[A, B] = Function.const( None) def k[A](v0: A): Pattern[A, A] = v => if (v == v0) Some(v0) else None def or[A, B](p1: Pattern[A, B], p2: Pattern[A, B]): Pattern[A, B] = v => p1(v).orElse(p2(v)) scala> or(none, some(k( 2)))(Some(2)) res3: Option[Int] = Some(2) https://gist.github.com/jdegoes/9240971
  • 23. First-Class Patterns - JS And Now in JavaScript….Because http://jsfiddle.net/AvL4V/
  • 24. First-Class Patterns Limitations ● Extractors cannot throw away information, leading to ‘dummy parameters’ ● Negation not possible under any circumstances ● No partiality warnings or built-in catch all
  • 25. Exercises 1. Define a Pattern Combinator to Fix: val Add = Mapping( "(+)", "Adds two numeric values" NumericDomain, , (partialTyper { case Type.Const(Data.Number(v1)) :: v2 :: Nil if (v1.signum == 0) => v2 case v1 :: Type.Const(Data.Number(v2)) :: Nil if (v2.signum == 0) => v1 case Type.Const(Data. Int(v1)) :: Type.Const(Data. Int(v2)) :: Nil => Type.Const(Data. Int(v1 + v2)) case Type.Const(Data.Number(v1)) :: Type.Const(Data.Number(v2)) :: Nil => Type.Const(Data.Dec(v1 + v2)) }) ||| numericWidening ) EASY
  • 26. Exercises 2. Define ‘Pattern’ and some core patterns in the language of your choice EASY
  • 27. Exercises 3. Define an ‘And’ pattern that requires both inputs match EASY
  • 28. Exercises 4. Define an alternate definition of pattern (along with a few core patterns) that permits pattern negation 4.b Optional: Use this to allow catch-alls MODERATE
  • 29. Exercises 5. Define an alternate definition of pattern (along with a few core patterns) that permits extractors to throw away information HARD
  • 30. THANK YOU First-Class Patterns John A. De Goes - @jdegoes Frontier Developers, February 26