SlideShare una empresa de Scribd logo
1 de 26
Descargar para leer sin conexión
ELIXIR’S TYPE OF OPTIMISM
HOW YOU CAN BE A TYPE OPTIMIST WITH
DIALYZER AND TYPESPEC
INTRODUCTION
TYPE BASICS
▸ Fundamental types: integer, atom,
list, tuple, function
▸ Composite types: list of integers,
tuple with varied members
▸ System of types: use of fundamental
and composite types in functions,
variables and structs.
INTRODUCTION
ONE WAY TO THINK ABOUT A TYPE SYSTEM
▸ The function call structure is the wiring
▸ The types define the expected signal shapes going in and
out.
A type is a pattern, it defines
structure and can define legal
value ranges or enumerations.
INTRODUCTION
TYPE CHECKING
▸ Static type checking
▸ Enforced during compilation
▸ Everything has to be right, declared
▸ Dynamic type checking
▸ Defined by use
▸ Runtime evaluation of operations at the fundamental level
▸ Pattern matching
OH BOY
HOLY WAR OF TYPE TYPES
WHICH IS BETTER?
ELIXIR TYPESPEC
THE ELIXIR POSITION
▸ Dynamic typing
▸ Runtime enforcement of operations (“5” + 7)
▸ Pattern matching, guards on functions create some limits
▸ Testing can validate the intended use of a function
WHAT ABOUT TESTING
▸ Can test expected and unexpected inputs
▸ Exercise the code to validate type
handling
▸ Developers are optimistic testers
▸ Easy to have unexpected input conditions
▸ Doesn’t protect future code.
▸ Best at validating a function’s
transformation
ELIXIR TYPESPEC
ELIXIR TYPESPEC
THE SUPER POWER OF DIALYZER
▸ How is a function called by actual code?
▸ How does a function call other functions?
▸ Write signatures that are declarative
▸ Infer types up and down the call stack
▸ More exhaustive than what can be written as tests
▸ Your functions and structs are documented and validated
ELIXIR TYPESPEC
DOWNSIDE
▸ Not DRY
▸ Define a struct
▸ Define a @type
▸ Write a function
▸ Write a @spec
▸ dialyzer takes a little time to run, output can be cryptic
DIALYZER
DIALYZER READS ALL THE TYPES DECLARED
▸ Reads all the type specifications in the core modules,
dependencies
▸ This takes a while, but is cached, done once.
▸ aka PLT, persistent lookup table
▸ Reads all the types you’ve declared
LET’S DO IT
SET UP
ADD DIALYXIR TO MIX.EXS DEPS()
defmodule Talk.Mixfile do
use Mix.Project
. . .
defp deps do
[
{:dialyxir, "~> 0.4", only: [:dev], runtime: false},
]
end
end
$ mix deps.get
$ mix deps.compile
Then
SET UP
NEW MIX TASK
$ mix helpmix # Runs the default task (current: "mix run")
mix app.start # Starts all registered apps
mix app.tree # Prints the application tree
mix archive # Lists installed archives
mix archive.build # Archives this project into a .ez file
mix archive.install # Installs an archive locally
mix archive.uninstall # Uninstalls archives
mix clean # Deletes generated application files
mix cmd # Executes the given command
mix compile # Compiles source files
mix deps # Lists dependencies and their status
mix deps.clean # Deletes the given dependencies' files
mix deps.compile # Compiles dependencies
mix deps.get # Gets all out of date dependencies
mix deps.tree # Prints the dependency tree
mix deps.unlock # Unlocks the given dependencies
mix deps.update # Updates the given dependencies
mix dialyzer # Runs dialyzer with default or project-defined flags.
mix do # Executes the tasks separated by comma
mix escript # Lists installed escripts
mix escript.build # Builds an escript for the project
mix escript.install # Installs an escript locally
mix escript.uninstall # Uninstalls escripts
mix help # Prints help information for tasks
mix hex # Prints Hex help information
mix hex.build # Builds a new package version locally
mix hex.config # Reads, updates or deletes Hex config
mix hex.docs # Fetch or open documentation of a package
mix hex.info # Prints Hex information
mix hex.key # Manages Hex API key
mix hex.outdated # Shows outdated Hex deps for the current project
mix hex.owner # Manages Hex package ownership
mix hex.public_keys # Manages Hex public keys
mix hex.publish # Publishes a new package version
mix hex.retire # Retires a package version
mix hex.search # Searches for package names
mix hex.user # Registers or manages Hex user
mix loadconfig # Loads and persists the given configuration
mix local # Lists local tasks
mix local.hex # Installs Hex locally
mix local.phoenix # Updates Phoenix locally
mix local.public_keys # Manages public keys
mix local.rebar # Installs Rebar locally
mix new # Creates a new Elixir project
mix phoenix.new # Creates a new Phoenix v1.2.1 application
mix profile.fprof # Profiles the given file or expression with fprof
mix run # Runs the given file or expression
mix test # Runs a project's tests
mix xref # Performs cross reference checks
iex -S mix # Starts IEx and runs the default task
SET UP
FIRST RUN
flash:talk 03:32 525$ mix dialyzerChecking PLT...
[:compiler, :elixir, :kernel, :logger, :stdlib]
Finding suitable PLTs
Looking up modules in dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt
Looking up modules in dialyxir_erlang-19.2_elixir-1.4.1.plt
Looking up modules in dialyxir_erlang-19.2.plt
Finding applications for dialyxir_erlang-19.2.plt
Finding modules for dialyxir_erlang-19.2.plt
Creating dialyxir_erlang-19.2.plt
Looking up modules in dialyxir_erlang-19.2.plt
Removing 3 modules from dialyxir_erlang-19.2.plt
Checking 11 modules in dialyxir_erlang-19.2.plt
Adding 149 modules to dialyxir_erlang-19.2.plt
Finding applications for dialyxir_erlang-19.2_elixir-1.4.1.plt
Finding modules for dialyxir_erlang-19.2_elixir-1.4.1.plt
Copying dialyxir_erlang-19.2.plt to dialyxir_erlang-19.2_elixir-1.4.1.plt
Looking up modules in dialyxir_erlang-19.2_elixir-1.4.1.plt
Checking 160 modules in dialyxir_erlang-19.2_elixir-1.4.1.plt
Adding 220 modules to dialyxir_erlang-19.2_elixir-1.4.1.plt
Finding applications for dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt
Finding modules for dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt
Copying dialyxir_erlang-19.2_elixir-1.4.1.plt to dialyxir_erlang-19.2_elixir-1.
4.1_deps-dev.plt
Looking up modules in dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt
Checking 380 modules in dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt
Adding 57 modules to dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt
Starting Dialyzer
dialyzer --no_check_plt --fullpath --plt /Users/danj/Documents/elixir/typespec-
talk/talk/_build/dev/dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt /Users/danj
/Documents/elixir/typespec-talk/talk/_build/dev/lib/talk/ebin
Proceeding with analysis... done in 0m1.38s
done (passed successfully)
flash:talk 03:38 526$
‣ mix dialyzer
‣ First run on an empty
project ~6min
CARDS
CARD EXAMPLE
defmodule Card do
def kind({_suit,value}) when is_number(value), do: :number
def kind({_suit,_value}), do: :face
def check_cards(card) do
IO.puts("kind(#{inspect(card)}) -> #{inspect(kind(card))}")
end
def main do
check_cards({:spades, :king})
check_cards({:rubies, 10})
end
end
CARDS
DIALYZER NORMAL RESULT
$ mix dialyzer
Checking PLT...
[:compiler, :elixir, :kernel, :logger, :stdlib]
PLT is up to date!
Starting Dialyzer
dialyzer --no_check_plt --fullpath --plt /Users/danj/Documents/elixir/typespec-
talk/talk/_build/dev/dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt /Users/
danj/Documents/elixir/typespec-talk/talk/_build/dev/lib/talk/ebin
Proceeding with analysis... done in 0m1.61s
done (passed successfully)
CARDS
ADD TYPES AND A SPEC
1defmodule Card do
2
7
11
12 def check_cards(card) do
13 IO.puts("kind(#{inspect(card)}) -> #{inspect(kind(card))}")
14 end
15
16 def main do
17 check_cards({:spades, :king})
18 check_cards({:rubies, 10})
19 end
20end
3 @type suit :: ( :spade | :heart | :club | :diamond )
4 @type value :: ( 2..10 | :jack | :queen | :king | :ace )
5 @type card :: { suit, value }
6 @type card_kind :: { :number | :face }
8 @spec kind(card()) :: card_kind()
9 def kind({_suit,value}) when is_number(value), do: :number
10 def kind({_suit,_value}), do: :face
CARDS
Proceeding with analysis...
lib/card.ex:8: Invalid type specification for function
'Elixir.Card':kind/1. The success typing is ({_,_}) -> 'face' |
'number'
done in 0m1.72s
done (warnings were emitted)
8 @spec kind(card()) :: card_kind()
5 @type card :: { suit, value }
6 @type card_kind :: { :number | :face }
6 @type card_kind :: ( :number | :face )
oops
CARDS
Proceeding with analysis...
lib/card.ex:16: Function main/0 has no local return
lib/card.ex:17: The call
'Elixir.Card':check_cards({'spades','king'}) will never return
since it differs in the 1st argument from the success typing
arguments: ({'club','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4
| 5 | 6 | 7 | 8 | 9 | 10} | {'diamond','ace' | 'jack' | 'king' |
'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'heart','ace' |
'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} |
{'spade','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10})
lib/card.ex:18: The call 'Elixir.Card':check_cards({'rubies',10})
will never return since it differs in the 1st argument from the
success typing arguments: ({'club','ace' | 'jack' | 'king' |
'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'diamond','ace'
| 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10}
| {'heart','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6
| 7 | 8 | 9 | 10} | {'spade','ace' | 'jack' | 'king' | 'queen' |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10})
done in 0m1.75s
done (warnings were emitted)
CARDS
17 check_cards({:spades, :king})
lib/card.ex:17: The call
'Elixir.Card':check_cards({'spades','king'})
will never return since it differs in the 1st argument
from the success typing arguments:
({'club','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10}
| {'diamond','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| {'heart','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
| {'spade','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
)
CARDS
1defmodule Card do
2
3 @type suit :: ( :spade | :heart | :club | :diamond )
4 @type value :: ( 2..10 | :jack | :queen | :king | :ace )
5 @type card :: { suit, value }
6 @type card_kind :: ( :number | :face )
7
8 @spec kind(card()) :: card_kind()
9 def kind({_suit,value}) when is_number(value), do: :number
10 def kind({_suit,_value}), do: :face
11
12 @spec check_cards(card()) :: any()
13 def check_cards(card) do
14 IO.puts("kind(#{inspect(card)}) -> #{inspect(kind(card))}")
15 end
16
17 def main do
18 check_cards({:spade, :king})
19 check_cards({:diamond, 10})
20 end
21end
CARDS
CARD EXAMPLE
defmodule Card do
def kind({_suit,value}) when is_number(value), do: :number
def kind({_suit,_value}), do: :face
def check_cards(card) do
IO.puts("kind(#{inspect(card)}) -> #{inspect(kind(card))}")
end
def main do
check_cards({:spades, :king})
check_cards({:rubies, 10})
end
end
STRUCT
TYPES AND STRUCT
1defmodule Card do
2 defstruct [:suit, :value]
3
4 @type suit :: ( :spade | :heart | :club | :diamond )
5 @type value :: ( 2..10 | :jack | :queen | :king | :ace )
6
7 @type t :: %Card{ suit: suit(), value: value()}
8
9 @type card_kind :: ( :number | :face )
10
11 @spec kind(Card.t) :: card_kind()
12 def kind(%Card{value: value} = card) when is_number(value),
do: :number
13 def kind(_card), do: :face
14end
ADDITIONAL
RESOURCES
ADDITIONAL RESOURCES
DOCUMENTATION
▸ http://learnyousomeerlang.com/dialyzer
▸ https://hexdocs.pm/elixir/typespecs.html
▸ https://hex.pm/packages/dialyxir
▸ http://user.it.uu.se/~kostis/Papers/succ_types.pdf
▸ Elixir Conf 2016 Jason Voegele Dialyzer talk
THANK YOU

Más contenido relacionado

La actualidad más candente

ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015
qmmr
 

La actualidad más candente (20)

Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015
 
PerlScripting
PerlScriptingPerlScripting
PerlScripting
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Clean code
Clean codeClean code
Clean code
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)
 
Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
 
Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
Symfony2 - extending the console component
Symfony2 - extending the console componentSymfony2 - extending the console component
Symfony2 - extending the console component
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 

Destacado

Elixir – Peeking into Elixir's Processes, OTP and Supervisors
Elixir – Peeking into Elixir's Processes, OTP and SupervisorsElixir – Peeking into Elixir's Processes, OTP and Supervisors
Elixir – Peeking into Elixir's Processes, OTP and Supervisors
Benjamin Tan
 
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Elixir Club
 
Flowex: Flow-Based Programming with Elixir GenStage - Anton Mishchuk
Flowex: Flow-Based Programming with Elixir GenStage - Anton MishchukFlowex: Flow-Based Programming with Elixir GenStage - Anton Mishchuk
Flowex: Flow-Based Programming with Elixir GenStage - Anton Mishchuk
Elixir Club
 

Destacado (20)

How Elixir helped us scale our Video User Profile Service for the Olympics
How Elixir helped us scale our Video User Profile Service for the OlympicsHow Elixir helped us scale our Video User Profile Service for the Olympics
How Elixir helped us scale our Video User Profile Service for the Olympics
 
Elixir basics-2
Elixir basics-2Elixir basics-2
Elixir basics-2
 
Elixir – Peeking into Elixir's Processes, OTP and Supervisors
Elixir – Peeking into Elixir's Processes, OTP and SupervisorsElixir – Peeking into Elixir's Processes, OTP and Supervisors
Elixir – Peeking into Elixir's Processes, OTP and Supervisors
 
Learn Elixir at Manchester Lambda Lounge
Learn Elixir at Manchester Lambda LoungeLearn Elixir at Manchester Lambda Lounge
Learn Elixir at Manchester Lambda Lounge
 
Building a Network IP Camera using Erlang
Building a Network IP Camera using ErlangBuilding a Network IP Camera using Erlang
Building a Network IP Camera using Erlang
 
The Magic Of Elixir
The Magic Of ElixirThe Magic Of Elixir
The Magic Of Elixir
 
ELIXIR Webinar: Introducing TeSS
ELIXIR Webinar: Introducing TeSSELIXIR Webinar: Introducing TeSS
ELIXIR Webinar: Introducing TeSS
 
Spark as a distributed Scala
Spark as a distributed ScalaSpark as a distributed Scala
Spark as a distributed Scala
 
Big Data eBook
Big Data eBookBig Data eBook
Big Data eBook
 
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011
WEB MINING: PATTERN DISCOVERY ON THE WORLD WIDE WEB - 2011
 
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발
나프다 웨비너 1604: Elixir와 함수형 프로그래밍을 이용한 웹 개발
 
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
Magic Clusters and Where to Find Them 2.0 - Eugene Pirogov
 
Control flow in_elixir
Control flow in_elixirControl flow in_elixir
Control flow in_elixir
 
Spring IO for startups
Spring IO for startupsSpring IO for startups
Spring IO for startups
 
Flowex: Flow-Based Programming with Elixir GenStage - Anton Mishchuk
Flowex: Flow-Based Programming with Elixir GenStage - Anton MishchukFlowex: Flow-Based Programming with Elixir GenStage - Anton Mishchuk
Flowex: Flow-Based Programming with Elixir GenStage - Anton Mishchuk
 
Phoenix: Inflame the Web - Alex Troush
Phoenix: Inflame the Web - Alex TroushPhoenix: Inflame the Web - Alex Troush
Phoenix: Inflame the Web - Alex Troush
 
GenStage and Flow - Jose Valim
GenStage and Flow - Jose Valim GenStage and Flow - Jose Valim
GenStage and Flow - Jose Valim
 
Distributed system in Elixir
Distributed system in ElixirDistributed system in Elixir
Distributed system in Elixir
 
Elixir & Phoenix 推坑
Elixir & Phoenix 推坑Elixir & Phoenix 推坑
Elixir & Phoenix 推坑
 
Proteome array - antibody based proteome arrays
Proteome array - antibody based proteome arrays Proteome array - antibody based proteome arrays
Proteome array - antibody based proteome arrays
 

Similar a Elixir and Dialyzer, Types and Typespecs, using and understanding them

A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
旻琦 潘
 

Similar a Elixir and Dialyzer, Types and Typespecs, using and understanding them (20)

Introduction to Elixir
Introduction to ElixirIntroduction to Elixir
Introduction to Elixir
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
React Development with the MERN Stack
React Development with the MERN StackReact Development with the MERN Stack
React Development with the MERN Stack
 
RedisGears: Meir Shpilraien
RedisGears: Meir ShpilraienRedisGears: Meir Shpilraien
RedisGears: Meir Shpilraien
 
RedisGears
RedisGearsRedisGears
RedisGears
 
Meta Object Protocols
Meta Object ProtocolsMeta Object Protocols
Meta Object Protocols
 
React Native Evening
React Native EveningReact Native Evening
React Native Evening
 
Linux Shell Scripting Craftsmanship
Linux Shell Scripting CraftsmanshipLinux Shell Scripting Craftsmanship
Linux Shell Scripting Craftsmanship
 
What’s new in .NET
What’s new in .NETWhat’s new in .NET
What’s new in .NET
 
RHCSA EX200 - Summary
RHCSA EX200 - SummaryRHCSA EX200 - Summary
RHCSA EX200 - Summary
 
PE1 Module 4.ppt
PE1 Module 4.pptPE1 Module 4.ppt
PE1 Module 4.ppt
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Elixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsElixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental Concepts
 
The Ring programming language version 1.5.1 book - Part 78 of 180
The Ring programming language version 1.5.1 book - Part 78 of 180The Ring programming language version 1.5.1 book - Part 78 of 180
The Ring programming language version 1.5.1 book - Part 78 of 180
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987
 
Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
 

Último

Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 

Último (20)

tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 

Elixir and Dialyzer, Types and Typespecs, using and understanding them

  • 1. ELIXIR’S TYPE OF OPTIMISM HOW YOU CAN BE A TYPE OPTIMIST WITH DIALYZER AND TYPESPEC
  • 2. INTRODUCTION TYPE BASICS ▸ Fundamental types: integer, atom, list, tuple, function ▸ Composite types: list of integers, tuple with varied members ▸ System of types: use of fundamental and composite types in functions, variables and structs.
  • 3. INTRODUCTION ONE WAY TO THINK ABOUT A TYPE SYSTEM ▸ The function call structure is the wiring ▸ The types define the expected signal shapes going in and out. A type is a pattern, it defines structure and can define legal value ranges or enumerations.
  • 4. INTRODUCTION TYPE CHECKING ▸ Static type checking ▸ Enforced during compilation ▸ Everything has to be right, declared ▸ Dynamic type checking ▸ Defined by use ▸ Runtime evaluation of operations at the fundamental level ▸ Pattern matching
  • 5. OH BOY HOLY WAR OF TYPE TYPES WHICH IS BETTER?
  • 6. ELIXIR TYPESPEC THE ELIXIR POSITION ▸ Dynamic typing ▸ Runtime enforcement of operations (“5” + 7) ▸ Pattern matching, guards on functions create some limits ▸ Testing can validate the intended use of a function
  • 7. WHAT ABOUT TESTING ▸ Can test expected and unexpected inputs ▸ Exercise the code to validate type handling ▸ Developers are optimistic testers ▸ Easy to have unexpected input conditions ▸ Doesn’t protect future code. ▸ Best at validating a function’s transformation ELIXIR TYPESPEC
  • 8. ELIXIR TYPESPEC THE SUPER POWER OF DIALYZER ▸ How is a function called by actual code? ▸ How does a function call other functions? ▸ Write signatures that are declarative ▸ Infer types up and down the call stack ▸ More exhaustive than what can be written as tests ▸ Your functions and structs are documented and validated
  • 9. ELIXIR TYPESPEC DOWNSIDE ▸ Not DRY ▸ Define a struct ▸ Define a @type ▸ Write a function ▸ Write a @spec ▸ dialyzer takes a little time to run, output can be cryptic
  • 10. DIALYZER DIALYZER READS ALL THE TYPES DECLARED ▸ Reads all the type specifications in the core modules, dependencies ▸ This takes a while, but is cached, done once. ▸ aka PLT, persistent lookup table ▸ Reads all the types you’ve declared
  • 12. SET UP ADD DIALYXIR TO MIX.EXS DEPS() defmodule Talk.Mixfile do use Mix.Project . . . defp deps do [ {:dialyxir, "~> 0.4", only: [:dev], runtime: false}, ] end end $ mix deps.get $ mix deps.compile Then
  • 13. SET UP NEW MIX TASK $ mix helpmix # Runs the default task (current: "mix run") mix app.start # Starts all registered apps mix app.tree # Prints the application tree mix archive # Lists installed archives mix archive.build # Archives this project into a .ez file mix archive.install # Installs an archive locally mix archive.uninstall # Uninstalls archives mix clean # Deletes generated application files mix cmd # Executes the given command mix compile # Compiles source files mix deps # Lists dependencies and their status mix deps.clean # Deletes the given dependencies' files mix deps.compile # Compiles dependencies mix deps.get # Gets all out of date dependencies mix deps.tree # Prints the dependency tree mix deps.unlock # Unlocks the given dependencies mix deps.update # Updates the given dependencies mix dialyzer # Runs dialyzer with default or project-defined flags. mix do # Executes the tasks separated by comma mix escript # Lists installed escripts mix escript.build # Builds an escript for the project mix escript.install # Installs an escript locally mix escript.uninstall # Uninstalls escripts mix help # Prints help information for tasks mix hex # Prints Hex help information mix hex.build # Builds a new package version locally mix hex.config # Reads, updates or deletes Hex config mix hex.docs # Fetch or open documentation of a package mix hex.info # Prints Hex information mix hex.key # Manages Hex API key mix hex.outdated # Shows outdated Hex deps for the current project mix hex.owner # Manages Hex package ownership mix hex.public_keys # Manages Hex public keys mix hex.publish # Publishes a new package version mix hex.retire # Retires a package version mix hex.search # Searches for package names mix hex.user # Registers or manages Hex user mix loadconfig # Loads and persists the given configuration mix local # Lists local tasks mix local.hex # Installs Hex locally mix local.phoenix # Updates Phoenix locally mix local.public_keys # Manages public keys mix local.rebar # Installs Rebar locally mix new # Creates a new Elixir project mix phoenix.new # Creates a new Phoenix v1.2.1 application mix profile.fprof # Profiles the given file or expression with fprof mix run # Runs the given file or expression mix test # Runs a project's tests mix xref # Performs cross reference checks iex -S mix # Starts IEx and runs the default task
  • 14. SET UP FIRST RUN flash:talk 03:32 525$ mix dialyzerChecking PLT... [:compiler, :elixir, :kernel, :logger, :stdlib] Finding suitable PLTs Looking up modules in dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt Looking up modules in dialyxir_erlang-19.2_elixir-1.4.1.plt Looking up modules in dialyxir_erlang-19.2.plt Finding applications for dialyxir_erlang-19.2.plt Finding modules for dialyxir_erlang-19.2.plt Creating dialyxir_erlang-19.2.plt Looking up modules in dialyxir_erlang-19.2.plt Removing 3 modules from dialyxir_erlang-19.2.plt Checking 11 modules in dialyxir_erlang-19.2.plt Adding 149 modules to dialyxir_erlang-19.2.plt Finding applications for dialyxir_erlang-19.2_elixir-1.4.1.plt Finding modules for dialyxir_erlang-19.2_elixir-1.4.1.plt Copying dialyxir_erlang-19.2.plt to dialyxir_erlang-19.2_elixir-1.4.1.plt Looking up modules in dialyxir_erlang-19.2_elixir-1.4.1.plt Checking 160 modules in dialyxir_erlang-19.2_elixir-1.4.1.plt Adding 220 modules to dialyxir_erlang-19.2_elixir-1.4.1.plt Finding applications for dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt Finding modules for dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt Copying dialyxir_erlang-19.2_elixir-1.4.1.plt to dialyxir_erlang-19.2_elixir-1. 4.1_deps-dev.plt Looking up modules in dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt Checking 380 modules in dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt Adding 57 modules to dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt Starting Dialyzer dialyzer --no_check_plt --fullpath --plt /Users/danj/Documents/elixir/typespec- talk/talk/_build/dev/dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt /Users/danj /Documents/elixir/typespec-talk/talk/_build/dev/lib/talk/ebin Proceeding with analysis... done in 0m1.38s done (passed successfully) flash:talk 03:38 526$ ‣ mix dialyzer ‣ First run on an empty project ~6min
  • 15. CARDS CARD EXAMPLE defmodule Card do def kind({_suit,value}) when is_number(value), do: :number def kind({_suit,_value}), do: :face def check_cards(card) do IO.puts("kind(#{inspect(card)}) -> #{inspect(kind(card))}") end def main do check_cards({:spades, :king}) check_cards({:rubies, 10}) end end
  • 16. CARDS DIALYZER NORMAL RESULT $ mix dialyzer Checking PLT... [:compiler, :elixir, :kernel, :logger, :stdlib] PLT is up to date! Starting Dialyzer dialyzer --no_check_plt --fullpath --plt /Users/danj/Documents/elixir/typespec- talk/talk/_build/dev/dialyxir_erlang-19.2_elixir-1.4.1_deps-dev.plt /Users/ danj/Documents/elixir/typespec-talk/talk/_build/dev/lib/talk/ebin Proceeding with analysis... done in 0m1.61s done (passed successfully)
  • 17. CARDS ADD TYPES AND A SPEC 1defmodule Card do 2 7 11 12 def check_cards(card) do 13 IO.puts("kind(#{inspect(card)}) -> #{inspect(kind(card))}") 14 end 15 16 def main do 17 check_cards({:spades, :king}) 18 check_cards({:rubies, 10}) 19 end 20end 3 @type suit :: ( :spade | :heart | :club | :diamond ) 4 @type value :: ( 2..10 | :jack | :queen | :king | :ace ) 5 @type card :: { suit, value } 6 @type card_kind :: { :number | :face } 8 @spec kind(card()) :: card_kind() 9 def kind({_suit,value}) when is_number(value), do: :number 10 def kind({_suit,_value}), do: :face
  • 18. CARDS Proceeding with analysis... lib/card.ex:8: Invalid type specification for function 'Elixir.Card':kind/1. The success typing is ({_,_}) -> 'face' | 'number' done in 0m1.72s done (warnings were emitted) 8 @spec kind(card()) :: card_kind() 5 @type card :: { suit, value } 6 @type card_kind :: { :number | :face } 6 @type card_kind :: ( :number | :face ) oops
  • 19. CARDS Proceeding with analysis... lib/card.ex:16: Function main/0 has no local return lib/card.ex:17: The call 'Elixir.Card':check_cards({'spades','king'}) will never return since it differs in the 1st argument from the success typing arguments: ({'club','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'diamond','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'heart','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'spade','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10}) lib/card.ex:18: The call 'Elixir.Card':check_cards({'rubies',10}) will never return since it differs in the 1st argument from the success typing arguments: ({'club','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'diamond','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'heart','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'spade','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10}) done in 0m1.75s done (warnings were emitted)
  • 20. CARDS 17 check_cards({:spades, :king}) lib/card.ex:17: The call 'Elixir.Card':check_cards({'spades','king'}) will never return since it differs in the 1st argument from the success typing arguments: ({'club','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} | {'diamond','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | | {'heart','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {'spade','ace' | 'jack' | 'king' | 'queen' | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 )
  • 21. CARDS 1defmodule Card do 2 3 @type suit :: ( :spade | :heart | :club | :diamond ) 4 @type value :: ( 2..10 | :jack | :queen | :king | :ace ) 5 @type card :: { suit, value } 6 @type card_kind :: ( :number | :face ) 7 8 @spec kind(card()) :: card_kind() 9 def kind({_suit,value}) when is_number(value), do: :number 10 def kind({_suit,_value}), do: :face 11 12 @spec check_cards(card()) :: any() 13 def check_cards(card) do 14 IO.puts("kind(#{inspect(card)}) -> #{inspect(kind(card))}") 15 end 16 17 def main do 18 check_cards({:spade, :king}) 19 check_cards({:diamond, 10}) 20 end 21end
  • 22. CARDS CARD EXAMPLE defmodule Card do def kind({_suit,value}) when is_number(value), do: :number def kind({_suit,_value}), do: :face def check_cards(card) do IO.puts("kind(#{inspect(card)}) -> #{inspect(kind(card))}") end def main do check_cards({:spades, :king}) check_cards({:rubies, 10}) end end
  • 23. STRUCT TYPES AND STRUCT 1defmodule Card do 2 defstruct [:suit, :value] 3 4 @type suit :: ( :spade | :heart | :club | :diamond ) 5 @type value :: ( 2..10 | :jack | :queen | :king | :ace ) 6 7 @type t :: %Card{ suit: suit(), value: value()} 8 9 @type card_kind :: ( :number | :face ) 10 11 @spec kind(Card.t) :: card_kind() 12 def kind(%Card{value: value} = card) when is_number(value), do: :number 13 def kind(_card), do: :face 14end
  • 25. ADDITIONAL RESOURCES DOCUMENTATION ▸ http://learnyousomeerlang.com/dialyzer ▸ https://hexdocs.pm/elixir/typespecs.html ▸ https://hex.pm/packages/dialyxir ▸ http://user.it.uu.se/~kostis/Papers/succ_types.pdf ▸ Elixir Conf 2016 Jason Voegele Dialyzer talk