SlideShare a Scribd company logo
1 of 35
Download to read offline
From OOP to FP
✅ The Validation case
Emmanuel Nhan - JUG Toulouse 11 juin 2019
😡 😡 😡 🤬
Let’s see the code…
💡There gotta be a
better way ! 🤔
Sticking in Javaland ☕
• Standard is JSR 303 : Bean Validation

• Let’s give it a try: Fortunately it is built-in in Spring !
In Action 🛠
JSR 303 results : the good
( Accumulates the errors for us in (found that in the docs): 

Set<ConstraintViolation<…!>>
( Automatic 400 Bad Requests (although this is mostly
done by Spring)

( Support for basic use cases
JSR 303 results : the bad
) No support for the parse error of HostAndPort

) Need custom handling for inter-dependent fields

) Annotations are not type-checked

) Weird mix of custom/covered cases

) Smelling reflection down there…
JSR 303 results : the weirdo
🤔 Automatic translation of error messages
Why is presentation even related to Validation ???

*
💡There gotta be a
better way ! 🤔
(Again !!!)
Do It Yourself 🛠
Let’s go back to the essence of our problem…
Validating one
• Result of a validation is either an error or a value

• Validation is just the function producing that result

• It looks like Optional structure but with an error type 

• We need a way to use the validated result
Validated ✅ (Kotlin style)
sealed class Validated<E, V> {
data class Valid<E,V>(val value: V) :
Validated<E,V>()
data class Invalid<E, V>(val error: E):
Validated<E, V>()
}
So far…
We can :

• create a Validated with success with Valid(a)

• create a Validated with error with Invalid(e)
• map over a Valid value
Representing errors
• Let’s use an ADT. In Kotlin :

sealed class AlertCreationError {
data class ThresholdATooLow(!/*!!...!*/):
AlertCreationError()
data class ThresholdCTooHigh(!/*!!...!*/):
AlertCreationError()
data class ThresholdBNotGreater(!/*…!*/):
AlertCreationError()
!// And so on
}
So far…
We can :

• create a Validated with success with Valid(a)
• create a Validated with error with Invalid(e)
• map over a Valid value

• fix the type of field validation to
Validated<AlertCreationError, T>
Validating many 🤔
• Finding a way to compose validation errors

• Finding a way to compose valid results
We need Composition !
Error Accumulation 📋
• JSR 303 used a Set

• When in error, we will at least have one element

• Let’s add some precision
NonEmpty*
• Two types exists

• NonEmptyList (NEL)

• NonEmptyChain (NEC)

• Structures which look like a linked list 

but which contains at least one element

• Ensuring this condition via smart constructor
Keeping Validated generic
• We need the E type in Validated<E, R> to be
combinable

• That is a function combine: (E, E) !-> E
• In the jargon, it is called Semigroup

• We need to go from

Validated<E, R> to Validated<Nel<E>, R>
So far…
We can :

• create a Validated with success with Valid(a)
• create a Validated with error with Invalid(e)
• map over a Valid value

• fix the type of field validation to
Validated<AlertCreationError, T>
• lift the error type from E to Nel<E> (leftMap)
Validating many
• Validating field A is independent of validating field B

• We need a function, with the shape :

(F<A>,F<B>,(A,B) !-> C) !-> F<C>
• Where F is a type like ValidatedNel with a fixed type:

(ValidatedNel<E,A>,ValidatedNel<E,B>,

(A,B) !-> C) !-> ValidatedNel<E, C>
• In the jargon, this is called Applicative
So far…
We can :

• create a Validated with success with Valid(a)
• create a Validated with error with Invalid(e)
• map over a Valid value

• fix the type of field validation to
Validated<AlertCreationError, T>
• lift the error type from E to Nel<E> & accumulate errors

• Combine all values when all fields are in Valid state
• Keep invalid when at least one field is in Invalid state
Not really DIY
In Action 🛠 (Kotlin)
Take away 🥡🍜
Validation is a (simple) problem which can be solved with
just 2 things :

✓Appropriate data structures (some may say ADT) 

to model errors & validation results

✓An abstraction to express independent computations
(Applicative)
💡There gotta be a
better way ! 🤔
(Again & again !!!)
This is nice and all but…
Can we go further ? 🚀
💡We could try to make impossible states unrepresentable
possible
values for A
acceptable
values for A
acceptable
values for A
Validation :
Uses a predicate to determine
the acceptable subset of A
Is it possible to encode this in code ?
Type system ✨
• Predicate encoding in the type system

• Compiler automatic derivation

• There is this thing called Refined

• Let’s see some (hardcore) Scala… 

(sorry I’m not fluent in Haskell 🙊)
Refined in action
Not there yet ! 💫
• Clearly I’m not an expert (but if you are, let’s talk 🤩)

• Even for a simple case like Validation research is
important

• Mathematics are the (best) base tool at hand
Q&A time
Thanks for listening

@enhan on Github &
@nhanmanu on Twitter
References & credits
• Code: 

• https://github.com/enhan/oop-to-fp-validation

• https://github.com/enhan/refined-validation

• Articles: 

• https://typelevel.org/cats/datatypes/validated.html

• https://arrow-kt.io/docs/arrow/data/validated/

• https://www.enhan.eu/how-to-in-fp/

• http://lara.epfl.ch/~kuncak/papers/
SchmidKuncak16CheckingPredicate.pdf
References & credits
• Books:

• Functional Programming in Scala (Paul Chiusano and
Runar Bjarnason)

• Category Theory for Programmers (Bartosz Milewski)
References & credits
• Libs:

• Spring: https://spring.io/

• Arrow: https://arrow-kt.io/

• Cats: https://typelevel.org/cats/

• Refined: https://github.com/fthomas/refined
References & credits
• Pictures (all from unsplash, in order) :

• SpaceX

• Anthony Cantin

• Mirko Blicke

• Simon Caspersen

• Alexey Sukhariev

• Designecologist

More Related Content

What's hot

Test in action – week 1
Test in action – week 1Test in action – week 1
Test in action – week 1
Yi-Huan Chan
 

What's hot (20)

Writing tests
Writing testsWriting tests
Writing tests
 
Functions in javascript
Functions in javascriptFunctions in javascript
Functions in javascript
 
Introduction to kotlin for Java Developer
Introduction to kotlin for Java DeveloperIntroduction to kotlin for Java Developer
Introduction to kotlin for Java Developer
 
Can't Dance The Lambda
Can't Dance The LambdaCan't Dance The Lambda
Can't Dance The Lambda
 
How do i - create a native interface
How do i -  create a native interfaceHow do i -  create a native interface
How do i - create a native interface
 
JavaScript Introductin to Functions
JavaScript Introductin to FunctionsJavaScript Introductin to Functions
JavaScript Introductin to Functions
 
Battle of The Mocking Frameworks
Battle of The Mocking FrameworksBattle of The Mocking Frameworks
Battle of The Mocking Frameworks
 
Xtend - better java with -less- noise
Xtend - better java with -less- noiseXtend - better java with -less- noise
Xtend - better java with -less- noise
 
Test in action – week 1
Test in action – week 1Test in action – week 1
Test in action – week 1
 
EasyMock for Java
EasyMock for JavaEasyMock for Java
EasyMock for Java
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy Code
 
Rspec
RspecRspec
Rspec
 
Typed Drupal - A great combination of Drupal 8 and PHP7
Typed Drupal - A great combination of Drupal 8 and PHP7Typed Drupal - A great combination of Drupal 8 and PHP7
Typed Drupal - A great combination of Drupal 8 and PHP7
 
Java script basic
Java script basicJava script basic
Java script basic
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
 
Unit testing legacy code
Unit testing legacy codeUnit testing legacy code
Unit testing legacy code
 
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
 
Testdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMockTestdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMock
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Code
 
Functional programming with Xtend
Functional programming with XtendFunctional programming with Xtend
Functional programming with Xtend
 

Similar to From OOP to FP : the validation case

Agile latvia evening_unit_testing_in_practice
Agile latvia evening_unit_testing_in_practiceAgile latvia evening_unit_testing_in_practice
Agile latvia evening_unit_testing_in_practice
denis Udod
 
Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)
Damien Seguy
 
Test automation expert days
Test automation   expert daysTest automation   expert days
Test automation expert days
Oren Rubin
 

Similar to From OOP to FP : the validation case (20)

Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 
Unit tests & TDD
Unit tests & TDDUnit tests & TDD
Unit tests & TDD
 
CPP10 - Debugging
CPP10 - DebuggingCPP10 - Debugging
CPP10 - Debugging
 
DefensiveProgramming (1).pptx
DefensiveProgramming (1).pptxDefensiveProgramming (1).pptx
DefensiveProgramming (1).pptx
 
Getting Started With Testing
Getting Started With TestingGetting Started With Testing
Getting Started With Testing
 
Agile latvia evening_unit_testing_in_practice
Agile latvia evening_unit_testing_in_practiceAgile latvia evening_unit_testing_in_practice
Agile latvia evening_unit_testing_in_practice
 
Unit Testing and Behavior Driven Testing with AngularJS - Jesse Liberty | Fal...
Unit Testing and Behavior Driven Testing with AngularJS - Jesse Liberty | Fal...Unit Testing and Behavior Driven Testing with AngularJS - Jesse Liberty | Fal...
Unit Testing and Behavior Driven Testing with AngularJS - Jesse Liberty | Fal...
 
iOS Test-Driven Development
iOS Test-Driven DevelopmentiOS Test-Driven Development
iOS Test-Driven Development
 
DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)
 
Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)
 
Unit testing
Unit testingUnit testing
Unit testing
 
assertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
assertYourself - Breaking the Theories and Assumptions of Unit Testing in FlexassertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
assertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
 
2600 Thailand #50 From 0day to CVE
2600 Thailand #50 From 0day to CVE2600 Thailand #50 From 0day to CVE
2600 Thailand #50 From 0day to CVE
 
Exception handling in Ruby
Exception handling in RubyException handling in Ruby
Exception handling in Ruby
 
Test automation expert days
Test automation   expert daysTest automation   expert days
Test automation expert days
 
Angular Unit Test
Angular Unit TestAngular Unit Test
Angular Unit Test
 
Jest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWJest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRW
 
Working with Legacy Code
Working with Legacy CodeWorking with Legacy Code
Working with Legacy Code
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle GamesWe Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
 

Recently uploaded

Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Kandungan 087776558899
 
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
AldoGarca30
 
Integrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - NeometrixIntegrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - Neometrix
Neometrix_Engineering_Pvt_Ltd
 
Verification of thevenin's theorem for BEEE Lab (1).pptx
Verification of thevenin's theorem for BEEE Lab (1).pptxVerification of thevenin's theorem for BEEE Lab (1).pptx
Verification of thevenin's theorem for BEEE Lab (1).pptx
chumtiyababu
 

Recently uploaded (20)

Online food ordering system project report.pdf
Online food ordering system project report.pdfOnline food ordering system project report.pdf
Online food ordering system project report.pdf
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
PE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and propertiesPE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and properties
 
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
 
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptxOrlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
DC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationDC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equation
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torque
 
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced LoadsFEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
 
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
 
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxS1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the start
 
Integrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - NeometrixIntegrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - Neometrix
 
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxA CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . ppt
 
Wadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptxWadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptx
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdf
 
Verification of thevenin's theorem for BEEE Lab (1).pptx
Verification of thevenin's theorem for BEEE Lab (1).pptxVerification of thevenin's theorem for BEEE Lab (1).pptx
Verification of thevenin's theorem for BEEE Lab (1).pptx
 
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
 

From OOP to FP : the validation case

  • 1. From OOP to FP ✅ The Validation case Emmanuel Nhan - JUG Toulouse 11 juin 2019
  • 2. 😡 😡 😡 🤬 Let’s see the code…
  • 3. 💡There gotta be a better way ! 🤔
  • 4. Sticking in Javaland ☕ • Standard is JSR 303 : Bean Validation • Let’s give it a try: Fortunately it is built-in in Spring !
  • 6. JSR 303 results : the good ( Accumulates the errors for us in (found that in the docs): Set<ConstraintViolation<…!>> ( Automatic 400 Bad Requests (although this is mostly done by Spring) ( Support for basic use cases
  • 7. JSR 303 results : the bad ) No support for the parse error of HostAndPort ) Need custom handling for inter-dependent fields ) Annotations are not type-checked ) Weird mix of custom/covered cases ) Smelling reflection down there…
  • 8. JSR 303 results : the weirdo 🤔 Automatic translation of error messages Why is presentation even related to Validation ??? *
  • 9. 💡There gotta be a better way ! 🤔 (Again !!!)
  • 10. Do It Yourself 🛠 Let’s go back to the essence of our problem…
  • 11. Validating one • Result of a validation is either an error or a value • Validation is just the function producing that result • It looks like Optional structure but with an error type • We need a way to use the validated result
  • 12. Validated ✅ (Kotlin style) sealed class Validated<E, V> { data class Valid<E,V>(val value: V) : Validated<E,V>() data class Invalid<E, V>(val error: E): Validated<E, V>() }
  • 13. So far… We can : • create a Validated with success with Valid(a) • create a Validated with error with Invalid(e) • map over a Valid value
  • 14. Representing errors • Let’s use an ADT. In Kotlin : sealed class AlertCreationError { data class ThresholdATooLow(!/*!!...!*/): AlertCreationError() data class ThresholdCTooHigh(!/*!!...!*/): AlertCreationError() data class ThresholdBNotGreater(!/*…!*/): AlertCreationError() !// And so on }
  • 15. So far… We can : • create a Validated with success with Valid(a) • create a Validated with error with Invalid(e) • map over a Valid value • fix the type of field validation to Validated<AlertCreationError, T>
  • 16. Validating many 🤔 • Finding a way to compose validation errors • Finding a way to compose valid results We need Composition !
  • 17. Error Accumulation 📋 • JSR 303 used a Set • When in error, we will at least have one element • Let’s add some precision
  • 18. NonEmpty* • Two types exists • NonEmptyList (NEL) • NonEmptyChain (NEC) • Structures which look like a linked list 
 but which contains at least one element • Ensuring this condition via smart constructor
  • 19. Keeping Validated generic • We need the E type in Validated<E, R> to be combinable • That is a function combine: (E, E) !-> E • In the jargon, it is called Semigroup • We need to go from
 Validated<E, R> to Validated<Nel<E>, R>
  • 20. So far… We can : • create a Validated with success with Valid(a) • create a Validated with error with Invalid(e) • map over a Valid value • fix the type of field validation to Validated<AlertCreationError, T> • lift the error type from E to Nel<E> (leftMap)
  • 21. Validating many • Validating field A is independent of validating field B • We need a function, with the shape : (F<A>,F<B>,(A,B) !-> C) !-> F<C> • Where F is a type like ValidatedNel with a fixed type:
 (ValidatedNel<E,A>,ValidatedNel<E,B>,
 (A,B) !-> C) !-> ValidatedNel<E, C> • In the jargon, this is called Applicative
  • 22. So far… We can : • create a Validated with success with Valid(a) • create a Validated with error with Invalid(e) • map over a Valid value • fix the type of field validation to Validated<AlertCreationError, T> • lift the error type from E to Nel<E> & accumulate errors • Combine all values when all fields are in Valid state • Keep invalid when at least one field is in Invalid state
  • 24. In Action 🛠 (Kotlin)
  • 25. Take away 🥡🍜 Validation is a (simple) problem which can be solved with just 2 things : ✓Appropriate data structures (some may say ADT) 
 to model errors & validation results ✓An abstraction to express independent computations (Applicative)
  • 26. 💡There gotta be a better way ! 🤔 (Again & again !!!) This is nice and all but…
  • 27. Can we go further ? 🚀 💡We could try to make impossible states unrepresentable possible values for A acceptable values for A acceptable values for A Validation : Uses a predicate to determine the acceptable subset of A Is it possible to encode this in code ?
  • 28. Type system ✨ • Predicate encoding in the type system • Compiler automatic derivation • There is this thing called Refined • Let’s see some (hardcore) Scala… 
 (sorry I’m not fluent in Haskell 🙊)
  • 30. Not there yet ! 💫 • Clearly I’m not an expert (but if you are, let’s talk 🤩) • Even for a simple case like Validation research is important • Mathematics are the (best) base tool at hand
  • 31. Q&A time Thanks for listening @enhan on Github & @nhanmanu on Twitter
  • 32. References & credits • Code: • https://github.com/enhan/oop-to-fp-validation • https://github.com/enhan/refined-validation • Articles: • https://typelevel.org/cats/datatypes/validated.html • https://arrow-kt.io/docs/arrow/data/validated/ • https://www.enhan.eu/how-to-in-fp/ • http://lara.epfl.ch/~kuncak/papers/ SchmidKuncak16CheckingPredicate.pdf
  • 33. References & credits • Books: • Functional Programming in Scala (Paul Chiusano and Runar Bjarnason) • Category Theory for Programmers (Bartosz Milewski)
  • 34. References & credits • Libs: • Spring: https://spring.io/ • Arrow: https://arrow-kt.io/ • Cats: https://typelevel.org/cats/ • Refined: https://github.com/fthomas/refined
  • 35. References & credits • Pictures (all from unsplash, in order) : • SpaceX • Anthony Cantin • Mirko Blicke • Simon Caspersen • Alexey Sukhariev • Designecologist