Elixir and Phoenix. fast, concurrent and explicit. Tobias pragtob.info

Similar documents
Elixir and Phoenix fast, concurrent and explicit Tobias pragtob.info

Elixir and Phoenix fast, concurrent and explicit Tobias pragtob.info

Ruby-like Syntax. defmodule MyMap do def map([], _func), do: [] def map([head tail], func) do [func.(head) map(tail, func)] end end

iex(1)> defmodule RepeatN do def repeat_n(function, count) do ...(1)> end repeat_n(function, count - 1) {:module, RepeatN,...}

The Actor Model. CSCI 5828: Foundations of Software Engineering Lecture 13 10/04/2016

Macros, and protocols, and metaprogramming - Oh My!

functional ErlangVM Parallelism

Reverse Sort. array = (1..1_000).to_a. array.sort do item, other other <=> item end

Organized by Jean-François Cloutier Held at Big Room Studios, Portland, ME. Holy Elixir, Batman! Meetup June 16, 2015

Taking Off with /

Clojure. The Revenge of Data. by Vjeran Marcinko Kapsch CarrierCom

Versioned APIs with Phoenix. Elvio Vicosa

CPS506 - Comparative Programming Languages Elixir

Look at all these toys!

MTAT Agile Software Development

The Actor Model, Part Two. CSCI 5828: Foundations of Software Engineering Lecture 18 10/23/2014

WeChat Adobe Campaign Integration - User Guide

Phoenix Is Not Your Application. Lance Halvorsen ElixirConf EU 2016

It s good to be here... I almost wasn t. Beautiful Tests by Bruce A. Tate icanmakeitbe*er

Effective Rails Testing Practices

Lead Delivery Options. Your leads sent your way. Lead delivery options for clients and partners.

CS177 Recitation. Functions, Booleans, Decision Structures, and Loop Structures

Rails Guide. MVC Architecture. Migrations. Hey, thanks a lot for picking up this guide!

Produced by. Web Development. Eamonn de Leastar Department of Computing, Maths & Physics Waterford Institute of Technology

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

Lecture 4. Ruby on Rails 1 / 49

The Future of the Realtime Web BETTER APIS WITH GRAPHQL. Josh

SCHOOL OF SCIENCE AND ENGINEERING WEB BASED APPLICATION FOR EQUIPMENT MANAGEMENT - OCP

Incrementally migratng large apps to Phoenix. Ruby Elixir Conf Taiwan 2018 Jake

Ruby: Introduction, Basics

Solution Composer. User's Guide

WE ARE ALL BLESSED. Bruce Tate

Lecture 8. Validations & Sessions 1 / 41

GRAPHIC WEB DESIGNER PROGRAM

This guide covers the installation, setup, and configuration of Sertifi for Salesforce CPQ.

Lab - Configure Wireless Router in Windows

LevelOne. Quick Installation Guide. WHG series Secure WLAN Controller. Introduction. Getting Started. Hardware Installation

Lecture 9. Forms & APIs 1 / 38

Your leads. Your way. Lead delivery options for BuyerZone clients and partners.

Clojure Web Security. FrOSCon Joy Clark & Simon Kölsch

How to Create a Campaign on Edbacker

Author: Paul Zenden. Hot-or-Not Elixir with José Valim

Setup Using Canon PRINT Inkjet/SELPHY ios

Robotics with Elixir

API Documentation. Release Version 1 Beta

STEAM Clown & Productions Copyright 2017 STEAM Clown. Page 1

Clojure is. A dynamic, LISP-based. programming language. running on the JVM

CSE 115. Introduction to Computer Science I

INTRODUCTION TO BLACKBOARD

PostgreSQL Database and C++ Interface (and Midterm Topics) ECE 650 Systems Programming & Engineering Duke University, Spring 2018

web.py Tutorial Tom Kelliher, CS 317 This tutorial is the tutorial from the web.py web site, with a few revisions for our local environment.

ECE 650 Systems Programming & Engineering. Spring 2018

A Small Web Server. Programming II - Elixir Version. Johan Montelius. Spring Term 2018

Creating an Adobe Connect Presentation: Using Your Personal Computer to Record and Publish

SignNow 2.0 for Salesforce User Guide

Lecture 4. Ruby on Rails 1 / 52

AngularJS. CRUD Application example with AngularJS and Rails 4. Slides By: Jonathan McCarthy

AngularJS. CRUD Application example with AngularJS and Rails 4. Slides By: Jonathan McCarthy

Guide to add as trusted site in Java 8 Update 51. Version of 24 OCBC Bank. All Rights Reserved

SureClose Product Line March 12, 2010 Release Notes SureClose Product Line Release Notes 1

HTML HTML/XHTML HTML / XHTML HTML HTML: XHTML: (extensible HTML) Loose syntax Few syntactic rules: not enforced by HTML processors.

Quick housekeeping Last Two Homeworks Extra Credit for demoing project prototypes Reminder about Project Deadlines/specifics Class on April 12th Resul

reinsight Mobile Quick Start Guide

porcelain Documentation

Perl 6 Hands-On Tutorial

MTAT Agile Software Development

Note that pcall can be implemented using futures. That is, instead of. we can use

EMC Documentum Composer

If we have a call. Now consider fastmap, a version of map that uses futures: Now look at the call. That is, instead of

It is better to have 100 functions operate one one data structure, than 10 functions on 10 data structures. A. Perlis

Databases - Have it your way

BETTER TOGETHER. Internet + TV from Elevate Fiber. TV User Guide

How to setup EW-7428HCn as a range extender for an existing Wi-Fi network

Authenticate an IIS Forms page with DIGIPASS Authentication Module for OWA. Creation date: 17/06/2016 Last Review: 17/06/2016 Revision number: 2

Lecture 7. Action View, Bootstrap & Deploying 1 / 40

Notes from a Short Introductory Lecture on Scala (Based on Programming in Scala, 2nd Ed.)

Marathon Documentation

What if Type Systems were more like Linters?

BASICS OF PORT FORWARDING ON A ROUTER

Customer Redirect Pro for Magento 2

RSA NetWitness Logs. Salesforce. Event Source Log Configuration Guide. Last Modified: Wednesday, February 14, 2018

Web System Development with Ruby on Rails

Elixir 1.6 Exercises. Chapter 2: Pattern Matching. Exercise: Pattern Matching-1 (Page 18) Which of the following would match? a = [1, 2, 3] a = 4

Customer Tips. Scanning with TCP/IP in Novell 5.x, 6.x Using Web Templates. for the user. Purpose. Network Setup. Xerox Multifunction Devices

June 27, 2014 EuroClojure 2014 Krakow, Poland. Components. Just Enough

Using the Pearson eportfolio System

Step 5: Plug the power adaptor into the PWR socket on the back of the modem. Plug the other end of the power adaptor into the wall socket.

Developers Care About the License Using SPDX to Describe License Information. Jilayne Lovejoy 6 October 2015

Metaprogramming. Concepts of Programming Languages. Alexander Schramm. 2. November Institut für Softwaretechnik und Programmiersprachen

MyFloridaMarketPlace (MFMP) Information Technology Staff Augmentation Services State Term Contract equote Training

User Monitoring Smartphone App

eclicker Host 2 Product Overview For additional information and help:

Automated SQL Ownage Techniques. OWASP October 30 th, The OWASP Foundation

STEP -BY-STEP REGISTRATION PROCESS

Mixed Signals Using Fusion s Signals API

Confluence User Training Guide

REQUIREMENT SPECIFICATION

Welcome to Mobile Banking. Personal Mobile Banking User Guide. First National 1870 a division of Sunflower Bank, N.A.

Rails 4 Quickly. Bala Paranj

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

Transcription:

Elixir and Phoenix fast, concurrent and explicit Tobias Pfeiffer @PragTob pragtob.info

Elixir and Phoenix fast, concurrent and explicit Tobias Pfeiffer @PragTob pragtob.info

defmodule MyMap do def map([], _func), do: [] def map([head tail], func) do [func.(head) map(tail, func)] end end MyMap.map [1, 2, 3, 4], fn(i) -> i * i end

Ruby-like Syntax defmodule MyMap do def map([], _func), do: [] def map([head tail], func) do [func.(head) map(tail, func)] end end MyMap.map [1, 2, 3, 4], fn(i) -> i * i end

Pattern Matching defmodule MyMap do def map([], _func), do: [] def map([head tail], func) do [func.(head) map(tail, func)] end end MyMap.map [1, 2, 3, 4], fn(i) -> i * i end

Pattern Matching defmodule Patterns do def greet(%{name: name, age: age}) do IO.puts "Hi there #{name}, what's up at #{age}?" end def greet(%{name: name}) do IO.puts "Hi there #{name}" end def greet(_) do IO.puts "Hi" end end Patterns.greet %{name: "Tobi", age: 26} Patterns.greet %{name: "Tobi"} Patterns.greet ["Mop"]

Pipe people orders tax filing = = = = DB.find_customers Orders.for_customers(people) sales_tax(orders, 2013) prepare_filing(tax)

Pipe filing = DB.find_customers > Orders.for_customers > sales_tax(2013) > prepare_filing

Pipe filing = prepare_filing(sales_tax(orders.for_cusstomers(db.find_c ustomers), 2013))

Pipe filing = DB.find_customers > Orders.for_customers > sales_tax(2013) > prepare_filing

Optional Type Annotations @spec all?(t) :: boolean @spec all?(t, (element -> as_boolean(term))) :: boolean def all?(enumerable, fun \\ fn(x) -> x end) def all?(enumerable, fun) when is_list(enumerable) do do_all?(enumerable, fun) end

Meta Programming defmacro plug(plug, opts \\ []) do quote do @plugs {unquote(plug), unquote(opts), true} end end

Functional Programming?

Where to call functions 2.2.2 :001 > [1, 2, 3, 4].map { i i + 1 } => [2, 3, 4, 5] vs iex(2)> Enum.map [1, 2, 3, 4], fn(i) -> i + 1 end [2, 3, 4, 5]

Transformation of Data

Minimize state vs Hiding State

Same Input, Same Output

Testing++

Immutable Data variable = 10 do_something(variable) insert_in_db(variable)

Immutable Data person = Person.new(attributes) do_something(person) insert_in_db(person)

Immutable Data person = Person.new(attributes) person = do_something(person) insert_in_db(person)

First class actor support

Flow connection > endpoint > router > pipelines > controller > model > view

Controller def new(conn, _params) do changeset = User.new_changeset(%User{}) render conn, "new.html", changeset: changeset end

Model defmodule Rumbl.User do use Rumbl.Web, :model schema "users" do field :name, field :username, field :password, field :password_hash, has_many timestamps end #... end :string :string :string, virtual: true :string :videos, Rumbl.Video

View defmodule Rumbl.UserView do use Rumbl.Web, :view alias Rumbl.User def first_name(%{name: name}) do name > String.split(" ") > Enum.at(0) end end

<%= form_for @changeset, user_path(@conn, :create), fn form -> %> Template <div class="form-group"> <%= text_input form, :name, placeholder: "Name", class: "form-control" %> <%= error_tag form, :name %> </div> <div class="form-group"> <%= text_input form, :username, placeholder: "Username", class: "form-control" %> <%= error_tag form, :username %> </div> <div class="form-group"> <%= password_input form, :password, placeholder: "Password", class: "form-control" %> <%= error_tag form, :password %> </div> <%= submit "Create User", class: "btn btn-primary" %> <% end %>

Changesets def new_changeset(model, params \\ :empty) do model > cast(params, ~w(name username), []) > unique_constraint(:username) > validate_length(:username, min: 1, max: 20) end def registration_changeset(model, params) do model > new_changeset(params) > cast(params, ~w(password), []) > validate_length(:password, min: 6, max: 100) > put_pass_hash() end

Changesets def create(conn, %{"user" => user_params}) do changeset = User.registration_changeset(%User{}, user_params) case Repo.insert changeset do {:ok, user} -> conn > Rumbl.Auth.login(user) > put_flash(:info, "You successfully registered as #{user.name}!") > redirect(to: user_path(conn, :index)) {:error, changeset}-> render conn, "new.html", changeset: changeset end end

defmodule Rumbl.VideoChannel do use Rumbl.Web, :channel Channels def join("videos:" <> video_id, _params, socket) do {:ok, socket} end def handle_in("new_annotation", params, socket) do broadcast! socket, "new_annotation", %{ user: %{username: "anon"}, body: params["body"], at: params["at"] } {:reply, :ok, socket} end end

iex(13)> user = Repo.get_by(User, name: "Homer") iex(14)> user.videos #Ecto.Association.NotLoaded<association :videos is not loaded> iex(15)> Repo.preload(user, :videos) Explicit preloading iex(16)> user.videos #Ecto.Association.NotLoaded<association :videos is not loaded> iex(17)> user = Repo.preload(user, :videos) iex(18)> user.videos [%Rumbl.Video{ meta : #Ecto.Schema.Metadata<:loaded>, category: #Ecto.Association.NotLoaded<association :category is not loaded>, category_id: nil, description: "such great many wow", id: 3, inserted_at: #Ecto.DateTime<2016-02-28T18:42:41Z>, title: "Hubidubiee", updated_at: #Ecto.DateTime<2016-02-28T18:42:41Z>, url: "www.lol.com", user: #Ecto.Association.NotLoaded<association :user is not loaded>, user_id: 5}]

iex(13)> user = Repo.get_by(User, name: "Homer") iex(14)> user.videos #Ecto.Association.NotLoaded<association :videos is not loaded> iex(15)> Repo.preload(user, :videos) Explicit preloading iex(16)> user.videos #Ecto.Association.NotLoaded<association :videos is not loaded> iex(17)> user = Repo.preload(user, :videos) iex(18)> user.videos [%Rumbl.Video{ meta : #Ecto.Schema.Metadata<:loaded>, category: #Ecto.Association.NotLoaded<association :category is not loaded>, category_id: nil, description: "such great many wow", id: 3, inserted_at: #Ecto.DateTime<2016-02-28T18:42:41Z>, title: "Hubidubiee", updated_at: #Ecto.DateTime<2016-02-28T18:42:41Z>, url: "www.lol.com", user: #Ecto.Association.NotLoaded<association :user is not loaded>, user_id: 5}]

iex(13)> user = Repo.get_by(User, name: "Homer") iex(14)> user.videos #Ecto.Association.NotLoaded<association :videos is not loaded> iex(15)> Repo.preload(user, :videos) Explicit preloading iex(16)> user.videos #Ecto.Association.NotLoaded<association :videos is not loaded> iex(17)> user = Repo.preload(user, :videos) iex(18)> user.videos [%Rumbl.Video{ meta : #Ecto.Schema.Metadata<:loaded>, category: #Ecto.Association.NotLoaded<association :category is not loaded>, category_id: nil, description: "such great many wow", id: 3, inserted_at: #Ecto.DateTime<2016-02-28T18:42:41Z>, title: "Hubidubiee", updated_at: #Ecto.DateTime<2016-02-28T18:42:41Z>, url: "www.lol.com", user: #Ecto.Association.NotLoaded<association :user is not loaded>, user_id: 5}]

Umbrella apps

So we all go and do Elixir and Phoenix now?

Baggage

Eco-System

Thanks & Enjoy Elixir Tobias Pfeiffer @PragTob pragtob.info

Photo Attribution CC BY-ND 2.0 CC BY 2.0 https://www.flickr.com/photos/-jule/2728475835/ CC BY-NC-ND 2.0 https://flic.kr/p/ekgrrj CC BY-NC 2.0 https://www.flickr.com/photos/mmmswan/8918529543/ https://flic.kr/p/eyc7zt CC BY-SA 2.0 https://commons.wikimedia.org/wiki/file:heckert_gnu_white.svg