SlideShare a Scribd company logo
Scott Sandler - June 2019
Scott Sandler
Senior Staff Engineer
@ Slack 2015 - Present
PHP to Hack at Slack
PHP to Hack at Slack
PHP to Hack at Slack
PHP to Hack at Slack
PHP to Hack at Slack
PHP to Hack at Slack
● Static type checker, hh_client
● Language Server Protocol
● VSCode, VIM, Emacs, and more
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
“Generic programming is a style of computer programming in
which algorithms are written in terms of types
to-be-specified-later that are then instantiated when needed
for specific types provided as parameters.”
- Wikipedia
Type Parameters like <T> allow classes, functions, and data
structures to act on multiple types
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Represent an array with known structure
● Named keys with known data types
○ Keys can be optional
● Structural subtyping
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
PHP to Hack at Slack
● Inconsistent Argument Order
○ array_map($callback, $array);
○ array_filter($array, $callback);
● Misleading return types
○ strpos() returns int OR false
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
Read from inside out…
or split into multiple lines and
name each intermediate value?
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Consistent Argument Order
● Consistent Return Types
○ null instead of false
● Namespaces:
○ Container Functions: Vec*, Dict*, Keyset*, C*
○ Basics: Str*, Regex*, Math*
○ More: IO*, PseudoRandom*, SecureRandom*
● |> Pipeline operator for chaining function calls
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● Overview
● Static Type Checking
● Generics
○ Arrays
○ Hack Arrays
○ Shapes
● Standard Library
○ Pipeline
○ Typed Regex
● XHP
● async/await cooperative multi-tasking
● is/as keywords for type assertion
● lambdas
● enums
● <<__Memoize>> caching
● hackfmt
● Function Autoloading
● VSCode debugging
Migrating Slack
PHP to Hack at Slack
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
Fix hh_client errors
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
● Hundreds of bugs
● Convince typechecker
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
New Linter: HHAST
● Hack Abstract Syntax Tree
● More rigorous linters
● Migrations as well
Old Linter: PHP_CodeSniffer
● Stream of tokens
● Each linter is a mini-PHP
parser
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into
functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
Foundational
Types
After: AsyncMysqlClient
● Shapes for each table
● Async queries
Before: mysqli
● Untyped arrays of strings
● Synchronous queries
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
Untyped code
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
Untyped code
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
Type Coverage
Colorized Type Coverage
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
Coverage Numbers
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
Track it and pipe it to Slack
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
<?hh // strict
1. All functions and arguments must be typed
2. No top-level code
3. Other dynamicism like $GLOBALS banned
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
Eliminate PHP Dependencies
1. Smarty to XHP migration
○ Smarty Parser -> hack-codegen
2. Other dependencies:
○ Convert to Hack
○ Remove dependency
○ Run as PHP7 web service
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
HHVM 4.0 Upgrade
● <?php to <?hh
● Fix hh_client errors
● Blocking CI tests
○ hh_client
○ Linter
● Move code into functions
● Foundational Types
○ DB Shapes
○ Inferred returns
○ Untyped code
● Coverage Competition
● <?hh // strict
● Eliminate PHP deps
● HHVM 4.0 upgrade
PHP to Hack at Slack
● Thousands of bugs found and fixed
● Entire classes of problems eliminated
○ Call to undefined function
○ Missing include/require
○ Missing array keys
○ Missing null checks
● Developer Surveys
● Increased confidence
● Increased productivity
● “When the type checker passes, my code usually works on
the first try”
PHP to Hack at Slack
UI
Integration
Unit
UI
Integration
Unit
Types
● Types are the cheapest unit test
○ ...but only when you have a lot of them
● Types are the cheapest documentation
○ Especially complex types like shapes
● Typing is best done as part of feature work
Lessons Learned
PHP to Hack at Slack
PHP to Hack at Slack
Yes, this is possible
● Generics RFC
● Arrow functions in 7.4
● Property type hints
● JIT in PHP8
● Static analysis:
○ phan: https://github.com/phan/phan
○ phpstan: https://github.com/phpstan/phpstan
○ psalm: https://github.com/vimeo/psalm
● eval(), create_function(), extract(), compact()
● $GLOBAL variables
● $$variable variables
● call_user_func()
● &$references
Avoid PHP’s most dangerous features
PHP to Hack at Slack

More Related Content

Similar to PHP to Hack at Slack (20)

PDF
Heterogenous Persistence
Jervin Real
 
PDF
RESTful Machine Learning with Flask and TensorFlow Serving - Carlo Mazzaferro
PyData
 
PDF
Let’s template
AllenKao7
 
PDF
The secret of PHP7's Performance
Xinchen Hui
 
PDF
Introduction to GraphQL with Ruby
Digital Natives
 
PDF
My 10 favorite haxe language features in 30 mins
Francis Bourre
 
PPTX
Php Tutorial
pratik tambekar
 
PDF
Typed Drupal - A great combination of Drupal 8 and PHP 7
Aditya Ghan
 
PDF
Frankfurt TYPO3 User Group (FTUG) 2017.11.15
ManuelSelbach
 
PDF
Quality Assurance in PostgreSQL
Aleksander Alekseev
 
PDF
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
VMware Tanzu
 
PDF
Build real time stream processing applications using Apache Kafka
Hotstar
 
PDF
Extract Method Refactoring Workshop (2016)
Peter Kofler
 
PDF
Goodpractice
Lorna Mitchell
 
PPTX
Php 5.6 vs Php 7 performance comparison
Tu Pham
 
PDF
IDE and Toolset For Magento Development
Abid Malik
 
PDF
PHP 7X New Features
Thanh Tai
 
PDF
Enforcing API Design Rules for High Quality Code Generation
Tim Burks
 
PDF
Os Koziarsky
oscon2007
 
PDF
MariaDB Paris Workshop 2023 - Performance Optimization
MariaDB plc
 
Heterogenous Persistence
Jervin Real
 
RESTful Machine Learning with Flask and TensorFlow Serving - Carlo Mazzaferro
PyData
 
Let’s template
AllenKao7
 
The secret of PHP7's Performance
Xinchen Hui
 
Introduction to GraphQL with Ruby
Digital Natives
 
My 10 favorite haxe language features in 30 mins
Francis Bourre
 
Php Tutorial
pratik tambekar
 
Typed Drupal - A great combination of Drupal 8 and PHP 7
Aditya Ghan
 
Frankfurt TYPO3 User Group (FTUG) 2017.11.15
ManuelSelbach
 
Quality Assurance in PostgreSQL
Aleksander Alekseev
 
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
VMware Tanzu
 
Build real time stream processing applications using Apache Kafka
Hotstar
 
Extract Method Refactoring Workshop (2016)
Peter Kofler
 
Goodpractice
Lorna Mitchell
 
Php 5.6 vs Php 7 performance comparison
Tu Pham
 
IDE and Toolset For Magento Development
Abid Malik
 
PHP 7X New Features
Thanh Tai
 
Enforcing API Design Rules for High Quality Code Generation
Tim Burks
 
Os Koziarsky
oscon2007
 
MariaDB Paris Workshop 2023 - Performance Optimization
MariaDB plc
 

Recently uploaded (20)

PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PDF
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
PDF
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
UiPath DevConnect 2025: Agentic Automation Community User Group Meeting
DianaGray10
 
DOCX
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
PDF
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
PPTX
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
PDF
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
PPTX
Seamless Tech Experiences Showcasing Cross-Platform App Design.pptx
presentifyai
 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PPTX
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
PDF
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
UiPath DevConnect 2025: Agentic Automation Community User Group Meeting
DianaGray10
 
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
Seamless Tech Experiences Showcasing Cross-Platform App Design.pptx
presentifyai
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
How do you fast track Agentic automation use cases discovery?
DianaGray10
 

PHP to Hack at Slack

  • 1. Scott Sandler - June 2019
  • 2. Scott Sandler Senior Staff Engineer @ Slack 2015 - Present
  • 9. ● Static type checker, hh_client ● Language Server Protocol ● VSCode, VIM, Emacs, and more ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 10. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 11. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 12. “Generic programming is a style of computer programming in which algorithms are written in terms of types to-be-specified-later that are then instantiated when needed for specific types provided as parameters.” - Wikipedia Type Parameters like <T> allow classes, functions, and data structures to act on multiple types ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 13. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 14. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 15. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 16. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 17. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 18. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 19. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 20. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 21. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 22. ● Represent an array with known structure ● Named keys with known data types ○ Keys can be optional ● Structural subtyping ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 23. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 24. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 25. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 26. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 28. ● Inconsistent Argument Order ○ array_map($callback, $array); ○ array_filter($array, $callback); ● Misleading return types ○ strpos() returns int OR false ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 29. Read from inside out… or split into multiple lines and name each intermediate value? ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 30. ● Consistent Argument Order ● Consistent Return Types ○ null instead of false ● Namespaces: ○ Container Functions: Vec*, Dict*, Keyset*, C* ○ Basics: Str*, Regex*, Math* ○ More: IO*, PseudoRandom*, SecureRandom* ● |> Pipeline operator for chaining function calls ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 31. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 32. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 33. ● Overview ● Static Type Checking ● Generics ○ Arrays ○ Hack Arrays ○ Shapes ● Standard Library ○ Pipeline ○ Typed Regex ● XHP
  • 34. ● async/await cooperative multi-tasking ● is/as keywords for type assertion ● lambdas ● enums ● <<__Memoize>> caching ● hackfmt ● Function Autoloading ● VSCode debugging
  • 37. ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 38. Fix hh_client errors ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 39. ● Hundreds of bugs ● Convince typechecker ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 40. ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 41. ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 42. ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 43. New Linter: HHAST ● Hack Abstract Syntax Tree ● More rigorous linters ● Migrations as well Old Linter: PHP_CodeSniffer ● Stream of tokens ● Each linter is a mini-PHP parser ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 44. ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 46. After: AsyncMysqlClient ● Shapes for each table ● Async queries Before: mysqli ● Untyped arrays of strings ● Synchronous queries ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 47. ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 48. ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 49. ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 50. Untyped code ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 51. Untyped code ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 53. Colorized Type Coverage ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 54. Coverage Numbers ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 55. Track it and pipe it to Slack ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 56. <?hh // strict 1. All functions and arguments must be typed 2. No top-level code 3. Other dynamicism like $GLOBALS banned ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 57. Eliminate PHP Dependencies 1. Smarty to XHP migration ○ Smarty Parser -> hack-codegen 2. Other dependencies: ○ Convert to Hack ○ Remove dependency ○ Run as PHP7 web service ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 58. HHVM 4.0 Upgrade ● <?php to <?hh ● Fix hh_client errors ● Blocking CI tests ○ hh_client ○ Linter ● Move code into functions ● Foundational Types ○ DB Shapes ○ Inferred returns ○ Untyped code ● Coverage Competition ● <?hh // strict ● Eliminate PHP deps ● HHVM 4.0 upgrade
  • 60. ● Thousands of bugs found and fixed ● Entire classes of problems eliminated ○ Call to undefined function ○ Missing include/require ○ Missing array keys ○ Missing null checks
  • 61. ● Developer Surveys ● Increased confidence ● Increased productivity ● “When the type checker passes, my code usually works on the first try”
  • 65. ● Types are the cheapest unit test ○ ...but only when you have a lot of them ● Types are the cheapest documentation ○ Especially complex types like shapes ● Typing is best done as part of feature work Lessons Learned
  • 68. Yes, this is possible ● Generics RFC ● Arrow functions in 7.4 ● Property type hints ● JIT in PHP8 ● Static analysis: ○ phan: https://github.com/phan/phan ○ phpstan: https://github.com/phpstan/phpstan ○ psalm: https://github.com/vimeo/psalm
  • 69. ● eval(), create_function(), extract(), compact() ● $GLOBAL variables ● $$variable variables ● call_user_func() ● &$references Avoid PHP’s most dangerous features