Slide 1

Slide 1 text

What Python can learn from Erlang? benoît chesneau @benoitc PYCON US 2015 - Montreal

Slide 2

Slide 2 text

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late- binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them. Alan Kay http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en

Slide 3

Slide 3 text

It’s about reliability

Slide 4

Slide 4 text

What is reliable program ? ‣Resistant to failures ‣Recover easily ‣Hot-Upgrade

Slide 5

Slide 5 text

Problem?
 Stay alive

Slide 6

Slide 6 text

Reliability ‣Pattern matching ‣Process isolation ➡ assertion ‣Message passing ‣No Shared memory

Slide 7

Slide 7 text

Process isolation

Slide 8

Slide 8 text

P P P P Each process is isolated

Slide 9

Slide 9 text

P P P P Failure The system continues to operate

Slide 10

Slide 10 text

P P P P Recover Detect the failures and relaunch

Slide 11

Slide 11 text

Program to Systems ‣Supervisor ‣Load-balancer & Proxy ‣Containers

Slide 12

Slide 12 text

• Everything run in 1 thread • GIL • Use OS processes (multiprocessing, gunicorn, …) • PyParallel ? • PyPy STM ? Process isolation is hard in Python

Slide 13

Slide 13 text

• Fail fast • Crash early • Don’t catch too much • Crash in a way it can recover fast Let it crash

Slide 14

Slide 14 text

Immutability

Slide 15

Slide 15 text

• For one input we will always get the same output • An expression can be replaced b its value: F(I) = V, V = F(I) Immutability

Slide 16

Slide 16 text

• Easier to think about it • Easy to test • Easy to share even between different processes • Thread-Safe Immutability

Slide 17

Slide 17 text

Immutability • real world is mutable • but at some time, each mutation is immutable • Need to reference at some point the value of a data (identity) • snapshots can easily be stored

Slide 18

Slide 18 text

Identity class Person(object): def __init__(self, occupation, age): self.occupation = occupation self.age = age

Slide 19

Slide 19 text

Identity dev1 = Person("student", 23) dev1.occupation = "developer" dev1.age = 28 developers = dict( dev1 = dev1, ... devN = devN)

Slide 20

Slide 20 text

Identity developers = { "dev1": Person("dev", 20), ... "devN": .. }

Slide 21

Slide 21 text

dict should also be immutable for devid, dev in developers.items(): developers[devid] = dev.update()

Slide 22

Slide 22 text

immutable data structures • dict should also be immutable • Funktown: https://github.com/zhemao/funktown • Pysistence https://pythonhosted.org/pysistence • fn.py https://github.com/kachayev/fn.py • Need more.

Slide 23

Slide 23 text

immutable data structures • dict should also be immutable • Funktown: https://github.com/zhemao/funktown • Pysistence https://pythonhosted.org/pysistence • fn.py https://github.com/kachayev/fn.py • Need more.

Slide 24

Slide 24 text

Don’t be too catchy

Slide 25

Slide 25 text

try…except but not so much • Try to fail fast, do not catch everything • reraise once logged • Pattern-Matching

Slide 26

Slide 26 text

Pattern matching in Erlan {ok, Socket} = connect() {error, Error} will crash receive {say, Msg} -> say(Msg); quit -> quit(); _ -> % other value will crash throw(Error); end case msg() of {say, Msg} -> say(Msg); quit -> quit() % other value will crash end

Slide 27

Slide 27 text

patterns from patterns import patterns, Mismatch @patterns def factorial(): if 0: 1 if n is int: n * factorial(n-1) if []: [] if [x] + xs: [factorial(x)] + factorial(xs) if {'n': n, 'f': f}: f(factorial(n)) assert factorial(0) == 1 assert factorial(5) == 120 assert factorial([3,4,2]) == [6, 24, 2] assert factorial({'n': [5, 1], 'f': sum}) == 121 factorial('hello') # raises Mismatch https://github.com/Suor/patterns

Slide 28

Slide 28 text

separate actions from decision class Action(object): ... class SendMessage(Action): ... class Log(Action): ... def send_message(to, msg): if is_exists(to): SendMessage(to, msg) else: Log("error %s not found" % to) run(): for action in actions: action.do()

Slide 29

Slide 29 text

? @benoitc http://enkim.eu