SlideShare a Scribd company logo
BRIDGESPERE VILLEGA (@PVILLEGA)
BRIDGES - BY @PVILLEGA
WHAT IS THE PROBLEM
BACK-END
MODEL
ELM
DECODER
S
ELM
MODEL
BRIDGES - BY @PVILLEGA
CIRCE SHAPELES
S JSON
ADT SHAPELES
S ELM
BRIDGES - BY @PVILLEGA
BRIDGES - BY @PVILLEGA
BRIDGES - BY @PVILLEGA
HTTPS://GITHUB.COM/DAVEGURNELL/B
RIDGES
BRIDGES - BY @PVILLEGA
WHAT IS THE SOLUTION
ADT BRIDGES ELM *
BRIDGES - BY @PVILLEGA
ELM
TYPESCRIP
T
FLOW
Types
Guards
Decoders
Encoders
BRIDGES - BY @PVILLEGA
case class Color(red: Int, green: Int, blue: Int)
Elm.buildFile("CustomModule", decl[Color])
BRIDGES - BY @PVILLEGA
module CustomModule.Color exposing (..)
import Json.Decode as Decode
import Json.Decode.Pipeline exposing (..)
import Json.Encode as Encode
type alias Color = { red: Int, green: Int, blue:
Int }
decoderColor : Decode.Decoder Color
decoderColor = decode Color |> required "red"
Decode.int |> required "green" Decode.int |>
required "blue" Decode.int
encoderColor : Color -> Encode.Value
encoderColor obj = Encode.object [ ("red",
Encode.int obj.red), ("green", Encode.int
obj.green), ("blue", Encode.int obj.blue) ]
BRIDGES - BY @PVILLEGA
sealed trait ADTAndObjects
case class MyClass(value: Int) extends ADTAndObjects
case object MyObject extends ADTAndObjects
case class ValueClass(value: String) extends AnyVal
case class ClassWithUUID(a: UUID)
final case class ComplexTypes(color: Color, nav: Navigation)
final case class RecursiveType(head: Int, tail: Option[RecursiveType])
val customErrorMsg = "ErrorMessage" := prod(
"error" := Ref("ErrorMessage")
)
case class ClassWithRefinedType(name: RefinedString)
BRIDGES - BY @PVILLEGA
WORKFLOW WITH BRIDGES
BACK-END
MODEL
RUN SBT
TASK *
BRIDGES - BY @PVILLEGA
case class Color(red: Int, green: Int, blue: Int)
sealed abstract class Shape
case class Circle(r: Double, c: Color) extends Shape
case class Rectangle(w: Double, h: Double, c: Color) extends Shape
case class ShapeGroup(left: Shape,right: Shape) extends Shape
Elm.render(decl[Shape])
type Shape = Circle Float Color
| Rectangle Float Float Color
| ShapeGroup Shape Shape
BRIDGES - BY @PVILLEGA
sealed abstract class Type
case object Str extends Type
case object Bool extends Type
case class Arr(tpe: Type) extends Type
//Others...
case class Ref(id: String) extends Type
case class Prod(fields: List[Decl]) extends Type
case class Sum(products: List[ProdDecl]) extends Type
BRIDGES - BY @PVILLEGA
case class DeclF[+A](name: String, tpe: A)
type Decl = DeclF[Type]
case class Pair(a: String, b: Int)
DeclF(“Pair”, prod(
"a" := Str,
"b" := Intr
)
BRIDGES - BY @PVILLEGA
case class DeclF[+A](name: String, tpe: A)
type TsDecl = DeclF[TsType]
DeclF("A",
Ref("B") & Ref("C") & Ref("D")
)
export type A = B & C & D;
BRIDGES - BY @PVILLEGA
trait Renderer[A] {
def render(decl: DeclF[A]): String
}
trait ElmRenderer extends Renderer[Type] {
def render(decl: Decl): String =
decl.tpe match {
case Sum(products) ⇒ …
case other ⇒ …
}
// ...
}
BRIDGES - BY @PVILLEGA
def decl[A](implicit
tpeTag: WeakTypeTag[A],
encoder: Lazy[Encoder[A]]): Decl =
DeclF(
getCleanTagName[A],
encoder.value.encode)
trait Encoder[A] {
def encode: Type
}
type Decl = DeclF[Type]
trait FlowRenderer extends Renderer[FlowType] {
def render(decl: FlowDecl): String =
s"""export type ${decl.name} = ${renderType(decl.tpe)};"""
private def renderType(tpe: FlowType): String =
tpe match {
case Ref(id) => id
case Str => "string"
case Chr => "string"
case Intr => "number"
case Real => "number"
case Bool => "boolean"
case Null => "null"
case Undefined => "undefined"
case StrLit(value) => s""""${escape(value)}""""
case ChrLit(value) => s""""${escape(value.toString)}""""
case IntrLit(value) => value.toString
case RealLit(value) => value.toString
case BoolLit(value) => value.toString
case tpe @ Opt(arg) => s"""?${renderParens(tpe)(arg)}"""
case tpe @ Arr(arg) => s"""${renderParens(tpe)(arg)}[]"""
case Struct(fields) => renderStruct(fields)
case tpe @ Inter(types) => types.map(renderParens(tpe)).mkString(" & ")
case tpe @ Union(types) => types.map(renderParens(tpe)).mkString(" | ")
}
private def renderStruct(fields: List[FlowDecl]): String =
fields.map(renderField).mkString("{ ", ", ", " }")
private def renderField(field: FlowDecl): String =
s"""${field.name}: ${renderType(field.tpe)}"""
private def renderParens(outer: FlowType)(inner: FlowType): String =
if (precedence(outer) > precedence(inner)) s"(${renderType(inner)})"
else renderType(inner)
BRIDGES - BY @PVILLEGA
HTTPS://UNDERSCORE.IO/BLOG/POSTS/
2018/12/12/BRIDGES.HTML
HTTPS://GITHUB.COM/DAVEGURNELL/B
RIDGES
IF YOU WORK AT
UK’S HOME
OFFICE (OR KNOW
SOMEONE) TALK
TO ME!Questions welcome, too!
THE END!

More Related Content

What's hot

Constructor in c++
Constructor in c++Constructor in c++
Constructor in c++
Jay Patel
 
Monad Fact #2
Monad Fact #2Monad Fact #2
Monad Fact #2
Philip Schwarz
 
Fp in scala part 1
Fp in scala part 1Fp in scala part 1
Fp in scala part 1
Hang Zhao
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional Patterns
Debasish Ghosh
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
Hang Zhao
 
Extending Gremlin with Foundational Steps
Extending Gremlin with Foundational StepsExtending Gremlin with Foundational Steps
Extending Gremlin with Foundational Steps
Stephen Mallette
 
Lightning Talk - Call Graphs
Lightning Talk - Call GraphsLightning Talk - Call Graphs
Lightning Talk - Call Graphs
James Moriarty
 
Deck: A Go Package for Presentations
Deck: A Go Package for PresentationsDeck: A Go Package for Presentations
Deck: A Go Package for Presentations
Anthony Starks
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
Srikanth Shreenivas
 
Anthony Starks - deck
Anthony Starks - deckAnthony Starks - deck
Anthony Starks - deck
Artem Kovardin
 
Mono + .NET Core = ❤️
Mono + .NET Core =  ❤️Mono + .NET Core =  ❤️
Mono + .NET Core = ❤️
Egor Bogatov
 

What's hot (11)

Constructor in c++
Constructor in c++Constructor in c++
Constructor in c++
 
Monad Fact #2
Monad Fact #2Monad Fact #2
Monad Fact #2
 
Fp in scala part 1
Fp in scala part 1Fp in scala part 1
Fp in scala part 1
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional Patterns
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
 
Extending Gremlin with Foundational Steps
Extending Gremlin with Foundational StepsExtending Gremlin with Foundational Steps
Extending Gremlin with Foundational Steps
 
Lightning Talk - Call Graphs
Lightning Talk - Call GraphsLightning Talk - Call Graphs
Lightning Talk - Call Graphs
 
Deck: A Go Package for Presentations
Deck: A Go Package for PresentationsDeck: A Go Package for Presentations
Deck: A Go Package for Presentations
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
 
Anthony Starks - deck
Anthony Starks - deckAnthony Starks - deck
Anthony Starks - deck
 
Mono + .NET Core = ❤️
Mono + .NET Core =  ❤️Mono + .NET Core =  ❤️
Mono + .NET Core = ❤️
 

Similar to Bridges

Towards Reliable Lookups - Scala By The Bay
Towards Reliable Lookups - Scala By The BayTowards Reliable Lookups - Scala By The Bay
Towards Reliable Lookups - Scala By The Bay
BoldRadius Solutions
 
Demystifying Type Class derivation with Shapeless
Demystifying Type Class derivation with ShapelessDemystifying Type Class derivation with Shapeless
Demystifying Type Class derivation with Shapeless
Yurii Ostapchuk
 
How to Handle NoSQL with a Relational Database
How to Handle NoSQL with a Relational DatabaseHow to Handle NoSQL with a Relational Database
How to Handle NoSQL with a Relational Database
DATAVERSITY
 
Lambdaconf2019 talk
Lambdaconf2019 talkLambdaconf2019 talk
Lambdaconf2019 talk
Dominic Egger
 
Hive Functions Cheat Sheet
Hive Functions Cheat SheetHive Functions Cheat Sheet
Hive Functions Cheat Sheet
Hortonworks
 
Managing model-to-model transformations at scale with YAMTL (lowcomote)
Managing model-to-model transformations at scale with YAMTL (lowcomote)Managing model-to-model transformations at scale with YAMTL (lowcomote)
Managing model-to-model transformations at scale with YAMTL (lowcomote)
Artur Boronat
 
Type level programming in Scala
Type level programming in ScalaType level programming in Scala
Type level programming in Scala
Ikhoon Eom
 
Functional Scala 2020
Functional Scala 2020Functional Scala 2020
Functional Scala 2020
Alexander Ioffe
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scala
b0ris_1
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
Debasish Ghosh
 
05 - Scala. List type
05 - Scala. List type05 - Scala. List type
05 - Scala. List type
Roman Brovko
 
Peeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdfPeeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdf
JaroslavRegec1
 
Java 5 New Feature
Java 5 New FeatureJava 5 New Feature
Java 5 New Feature
xcoda
 
Type Classes in Scala and Haskell
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and Haskell
Hermann Hueck
 
Establishing a Bridge from Graph-based Modeling Languages to Ontology Languages
 Establishing a Bridge from Graph-based Modeling Languages to Ontology Languages Establishing a Bridge from Graph-based Modeling Languages to Ontology Languages
Establishing a Bridge from Graph-based Modeling Languages to Ontology Languages
Tobias Walter
 
Expression trees in C#
Expression trees in C#Expression trees in C#
Expression trees in C#
Oleksii Holub
 
Oleksii Holub "Expression trees in C#"
Oleksii Holub "Expression trees in C#" Oleksii Holub "Expression trees in C#"
Oleksii Holub "Expression trees in C#"
Fwdays
 
Lecture05sql 110406195130-phpapp02
Lecture05sql 110406195130-phpapp02Lecture05sql 110406195130-phpapp02
Lecture05sql 110406195130-phpapp02
Lalit009kumar
 
Expressive and Efficient Model Transformation with an Internal DSL of Xtend
Expressive and Efficient Model Transformation with an Internal DSL of XtendExpressive and Efficient Model Transformation with an Internal DSL of Xtend
Expressive and Efficient Model Transformation with an Internal DSL of Xtend
Artur Boronat
 
Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languages
Arthur Xavier
 

Similar to Bridges (20)

Towards Reliable Lookups - Scala By The Bay
Towards Reliable Lookups - Scala By The BayTowards Reliable Lookups - Scala By The Bay
Towards Reliable Lookups - Scala By The Bay
 
Demystifying Type Class derivation with Shapeless
Demystifying Type Class derivation with ShapelessDemystifying Type Class derivation with Shapeless
Demystifying Type Class derivation with Shapeless
 
How to Handle NoSQL with a Relational Database
How to Handle NoSQL with a Relational DatabaseHow to Handle NoSQL with a Relational Database
How to Handle NoSQL with a Relational Database
 
Lambdaconf2019 talk
Lambdaconf2019 talkLambdaconf2019 talk
Lambdaconf2019 talk
 
Hive Functions Cheat Sheet
Hive Functions Cheat SheetHive Functions Cheat Sheet
Hive Functions Cheat Sheet
 
Managing model-to-model transformations at scale with YAMTL (lowcomote)
Managing model-to-model transformations at scale with YAMTL (lowcomote)Managing model-to-model transformations at scale with YAMTL (lowcomote)
Managing model-to-model transformations at scale with YAMTL (lowcomote)
 
Type level programming in Scala
Type level programming in ScalaType level programming in Scala
Type level programming in Scala
 
Functional Scala 2020
Functional Scala 2020Functional Scala 2020
Functional Scala 2020
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scala
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
05 - Scala. List type
05 - Scala. List type05 - Scala. List type
05 - Scala. List type
 
Peeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdfPeeking inside the engine of ZIO SQL.pdf
Peeking inside the engine of ZIO SQL.pdf
 
Java 5 New Feature
Java 5 New FeatureJava 5 New Feature
Java 5 New Feature
 
Type Classes in Scala and Haskell
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and Haskell
 
Establishing a Bridge from Graph-based Modeling Languages to Ontology Languages
 Establishing a Bridge from Graph-based Modeling Languages to Ontology Languages Establishing a Bridge from Graph-based Modeling Languages to Ontology Languages
Establishing a Bridge from Graph-based Modeling Languages to Ontology Languages
 
Expression trees in C#
Expression trees in C#Expression trees in C#
Expression trees in C#
 
Oleksii Holub "Expression trees in C#"
Oleksii Holub "Expression trees in C#" Oleksii Holub "Expression trees in C#"
Oleksii Holub "Expression trees in C#"
 
Lecture05sql 110406195130-phpapp02
Lecture05sql 110406195130-phpapp02Lecture05sql 110406195130-phpapp02
Lecture05sql 110406195130-phpapp02
 
Expressive and Efficient Model Transformation with an Internal DSL of Xtend
Expressive and Efficient Model Transformation with an Internal DSL of XtendExpressive and Efficient Model Transformation with an Internal DSL of Xtend
Expressive and Efficient Model Transformation with an Internal DSL of Xtend
 
Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languages
 

Recently uploaded

What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
Peter Muessig
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise EditionWhy Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Envertis Software Solutions
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
lorraineandreiamcidl
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
Yara Milbes
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 

Recently uploaded (20)

What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise EditionWhy Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 

Bridges

  • 2. BRIDGES - BY @PVILLEGA WHAT IS THE PROBLEM BACK-END MODEL ELM DECODER S ELM MODEL
  • 3.
  • 4.
  • 5. BRIDGES - BY @PVILLEGA CIRCE SHAPELES S JSON ADT SHAPELES S ELM
  • 6. BRIDGES - BY @PVILLEGA
  • 7. BRIDGES - BY @PVILLEGA
  • 8. BRIDGES - BY @PVILLEGA HTTPS://GITHUB.COM/DAVEGURNELL/B RIDGES
  • 9. BRIDGES - BY @PVILLEGA WHAT IS THE SOLUTION ADT BRIDGES ELM *
  • 10. BRIDGES - BY @PVILLEGA ELM TYPESCRIP T FLOW Types Guards Decoders Encoders
  • 11. BRIDGES - BY @PVILLEGA case class Color(red: Int, green: Int, blue: Int) Elm.buildFile("CustomModule", decl[Color])
  • 12. BRIDGES - BY @PVILLEGA module CustomModule.Color exposing (..) import Json.Decode as Decode import Json.Decode.Pipeline exposing (..) import Json.Encode as Encode type alias Color = { red: Int, green: Int, blue: Int } decoderColor : Decode.Decoder Color decoderColor = decode Color |> required "red" Decode.int |> required "green" Decode.int |> required "blue" Decode.int encoderColor : Color -> Encode.Value encoderColor obj = Encode.object [ ("red", Encode.int obj.red), ("green", Encode.int obj.green), ("blue", Encode.int obj.blue) ]
  • 13. BRIDGES - BY @PVILLEGA sealed trait ADTAndObjects case class MyClass(value: Int) extends ADTAndObjects case object MyObject extends ADTAndObjects case class ValueClass(value: String) extends AnyVal case class ClassWithUUID(a: UUID) final case class ComplexTypes(color: Color, nav: Navigation) final case class RecursiveType(head: Int, tail: Option[RecursiveType]) val customErrorMsg = "ErrorMessage" := prod( "error" := Ref("ErrorMessage") ) case class ClassWithRefinedType(name: RefinedString)
  • 14. BRIDGES - BY @PVILLEGA WORKFLOW WITH BRIDGES BACK-END MODEL RUN SBT TASK *
  • 15. BRIDGES - BY @PVILLEGA case class Color(red: Int, green: Int, blue: Int) sealed abstract class Shape case class Circle(r: Double, c: Color) extends Shape case class Rectangle(w: Double, h: Double, c: Color) extends Shape case class ShapeGroup(left: Shape,right: Shape) extends Shape Elm.render(decl[Shape]) type Shape = Circle Float Color | Rectangle Float Float Color | ShapeGroup Shape Shape
  • 16.
  • 17. BRIDGES - BY @PVILLEGA sealed abstract class Type case object Str extends Type case object Bool extends Type case class Arr(tpe: Type) extends Type //Others... case class Ref(id: String) extends Type case class Prod(fields: List[Decl]) extends Type case class Sum(products: List[ProdDecl]) extends Type
  • 18. BRIDGES - BY @PVILLEGA case class DeclF[+A](name: String, tpe: A) type Decl = DeclF[Type] case class Pair(a: String, b: Int) DeclF(“Pair”, prod( "a" := Str, "b" := Intr )
  • 19. BRIDGES - BY @PVILLEGA case class DeclF[+A](name: String, tpe: A) type TsDecl = DeclF[TsType] DeclF("A", Ref("B") & Ref("C") & Ref("D") ) export type A = B & C & D;
  • 20. BRIDGES - BY @PVILLEGA trait Renderer[A] { def render(decl: DeclF[A]): String } trait ElmRenderer extends Renderer[Type] { def render(decl: Decl): String = decl.tpe match { case Sum(products) ⇒ … case other ⇒ … } // ... }
  • 21. BRIDGES - BY @PVILLEGA def decl[A](implicit tpeTag: WeakTypeTag[A], encoder: Lazy[Encoder[A]]): Decl = DeclF( getCleanTagName[A], encoder.value.encode) trait Encoder[A] { def encode: Type } type Decl = DeclF[Type]
  • 22. trait FlowRenderer extends Renderer[FlowType] { def render(decl: FlowDecl): String = s"""export type ${decl.name} = ${renderType(decl.tpe)};""" private def renderType(tpe: FlowType): String = tpe match { case Ref(id) => id case Str => "string" case Chr => "string" case Intr => "number" case Real => "number" case Bool => "boolean" case Null => "null" case Undefined => "undefined" case StrLit(value) => s""""${escape(value)}"""" case ChrLit(value) => s""""${escape(value.toString)}"""" case IntrLit(value) => value.toString case RealLit(value) => value.toString case BoolLit(value) => value.toString case tpe @ Opt(arg) => s"""?${renderParens(tpe)(arg)}""" case tpe @ Arr(arg) => s"""${renderParens(tpe)(arg)}[]""" case Struct(fields) => renderStruct(fields) case tpe @ Inter(types) => types.map(renderParens(tpe)).mkString(" & ") case tpe @ Union(types) => types.map(renderParens(tpe)).mkString(" | ") } private def renderStruct(fields: List[FlowDecl]): String = fields.map(renderField).mkString("{ ", ", ", " }") private def renderField(field: FlowDecl): String = s"""${field.name}: ${renderType(field.tpe)}""" private def renderParens(outer: FlowType)(inner: FlowType): String = if (precedence(outer) > precedence(inner)) s"(${renderType(inner)})" else renderType(inner)
  • 23. BRIDGES - BY @PVILLEGA HTTPS://UNDERSCORE.IO/BLOG/POSTS/ 2018/12/12/BRIDGES.HTML HTTPS://GITHUB.COM/DAVEGURNELL/B RIDGES
  • 24. IF YOU WORK AT UK’S HOME OFFICE (OR KNOW SOMEONE) TALK TO ME!Questions welcome, too! THE END!

Editor's Notes

  1. Welcome everyone. I’m Pere Villega, Scala contractor, and in this presentation I’m going to talk about Bridges, a library by Dave Gurnell
  2. Let’s first talk about the problem we want to solve. A project I was working on had a service build in Scala, with Elm used for the front-end. Elm! Describe. As we worked with the service, due to its nature many of the changes ended up following a familiar pattern: edit the back-end, including changes to the model. Modify the Elm model, and then edit Json decoders. A tedious repetitive loop for every change.
  3. Repetitive tasks. There must be a better way, we are supposed to automate them.
  4. And one way is to use Scala.js, in which case then problem solved. Talk is over. Ok, unfortunately we have Elm, not Scala.js
  5. I knew what I wanted: many libraries, like Circe, use Shapeless to generate Json for your case classes. So, why not to use the same mechanism to generate front-end code, going from an ADT via Shapeless to Elm code? It must be a common problem, so there must be a solution out there.
  6. So I did what all developers do: I went to stack overflow and I checked for solutions.
  7. And when that didn’t work I searched a bit more…
  8. And, as it happens, it’s not an uncommon problem. There are some libraries out there that help with this. Unfortunately, many I tested weren’t actively maintained or had crippling issues. Until I found Bridges, by Dave Gurnell
  9. So, what is Bridges? Bridges is the solution to the problem. It allows me to define my ADT in scala, call a method, and obtain Elm code from it. Not only Elm, it also supports Typescript and Flow.
  10. What can you get with Bridges? These are the current capabilities: Elm allows you to generate types, and json encoders and decoders. Typescript provides types, guards (to verify a json blob is the valid type) and decoders. Flow only generates types, currently.
  11. In more practical terms, Bridges allows me to do this: I have a case class that I want to use in Elm. I use a method provided by the library, which says build me a file in that module for Color, and I will get a String as an output
  12. That String contains what is in the slide: fully functional Elm code. Notice we have created module, imports, the type, Color, and both Json Encoder and Decoder for the type.
  13. What Scala types does Bridges support? You can use it with most common structures. Case objects, value Classes. With complex types. With UUID as a first class citizen. With Recursive types. Custom types you create by hand using Bridges . And if you use Refined, you can use it too.
  14. So this is how my workflow has changed now, using Bridges. I modify the back-end model. If I need to work with the front-end, I run an sbt task to generate the necessary code. Note that the sbt task is something that you create yourself, currently it is not included in Bridges.
  15. This is another example with a more complex structure. That’s how you can use it. Simple, not getting in your way. Feels underwhelming when I prepared the slides but there is really not anything else to it.
  16. Let’s check how does Bridges work under the hood to generate code. The answer, obviously, involves shapeless. But we are going to focus on other parts of the machinery in here.
  17. There are a few key components in Bridges. The first component is the Type ADT. It is used to map a Scala ADT into an intermediate language. As you can see we can map basic types like String, references to complex types (like UUID) using Ref, or the Products and Sums in our ADT. Why do we need this structure? The reason we need an intermediate language is that Elm doesn’t have the same capabilities than Typescript, for example, so by doing this step first, we can then create more accurate representations in the target language.
  18. The second important component is Declaration. A named declaration is a parameterised class that stores a name along a Type, and can be either top-level or a field in a sum, product, or in another structure. With it and Type we can manually build representations of a case class in our intermediate language, as the custom types we mentioned before.
  19. Declaration has a type parameter. This allows us to swap the intermediate language. For example the Typescript components use the declaration you see in this slide, TsDecl, which allows us to build Intersection types (which don’t exist in Scala nor Elm) and use it to generate a valid Typescript type.
  20. The final component is Renderer. It is a trait that given a declaration, will generate a string representation in the target language. In this example we see a partial implementation of the Elm renderer, which uses Type as seen before, and how it starts generating either a type or a type alias according to the type of Declaration we receive.
  21. Obviously we don’t want to manually generate the Declarations for our ADT, so here is where shapeless gets involved. The helper method `decl` requires a witness `encoder` of type `A`, our own ADT. Shapeless magic happens and this encoder is generated for us, providing an encoding in an intermediate language, in this case `Type` as per the Decl definition.
  22. As this is a lightning talk I can’t go into more detail on the way Bridges works. But I pasted this code here so you can see how simple can it be to extend it. This is the code for the Flow renderer, which given a declaration generates a syntactically valid type in Flow
  23. For a more detailed description on Bridges, check this blog post at the Underscore blog, and you can always read the source code (and contribute pull requests for new target languages, of course).
  24. And that is all. Now, questions time, but before, if you know someone that works at the home office as a developer please come to talk to me :)