Confessions of a used programming language salesperson ( an appeal to purity ) Erik Meijer

Preview:

DESCRIPTION

Confessions of a used programming language salesperson ( an appeal to purity ) Erik Meijer. Why Functional Programming Matters Reloaded. … 100 … 110 x = x+1 120 … …. Artificial Intelligence via massively parallel machines using logic programming. SASL, Miranda, SKI. - PowerPoint PPT Presentation

Citation preview

Confessions of a

used programming language

salesperson(an appeal to purity)

Erik Meijer

Why FunctionalProgramming

MattersReloaded

…100 …110 x = x+1120 ……

Artificial Intelligence via massively parallel machines using logic programming

SASL, Miranda, SKI

[f.x.(f (f x))]=(S (S (K S) (S (K K) I)) (S (S (K S) (S (K K) I)) (K I)))

Only need 3 instructions

and massively parallel reduction

machines

Presentation

Business logic

Data

Presentation (HaskellScript)

Business logic(HSP,XM)

Data(HaskellDB)

factors n = [ x Select | x <- [1..n] From , n `mod` x == 0 Where ]

isPrime n = factors n = [1,n]

primes n = [ p | p <- [2..n], isPrime p ]

List ComprehensionsExample

[ e | True ] = [ e ] [ e | q ] = [ e | q, True ] [ e | b, Q ] = filter b [ e | Q ][ e | x <- l, Q ] = concatMap (\x -> [e | Q ]) l [ e | let decls, Q ] = let decls in [ e | Q ]

List ComprehensionsSimplified translation

Syntactic sugar over standard list

operations

words :: IO [String]words = do{ putStr “enter a value …” ; x <- getLine ; return (words x) }

class Monad m where { (>>=) :: m a -> (a -> m b) -> m b ; return :: a -> m a }

Monad ComprehensionsExample

Syntactic sugar over standard

monad operations

Parametrized over type constructor

IO monad generalize lists

SELECT X.FirstName, X.LastNameFROM Authors AS XWHERE X.City = 'OakLand'

oaklands = do{ x <- table authors ; restrict (x!city .==. constant "Oakland") ; project ( au_fname = x!au_fname , au_lname = x!au_lname ) }

HaskellDb Query Monad

Query monadgeneralizes IO

monad

intentional representation for expressions

table :: TABLEtable = <TABLE border="1"> <% mkRows cells %> </TABLE>

cells :: [[(Int,Int)]]cells = [[ (x,y) | x <- [1..16] ] | y <- [1..16] ]

mkRows :: [[(Int,Int)]] -> [TR]mkRows = map $ \cs -> <TR><% mkColums cs %></TR>

mkColumns :: [(Int,Int)] -> [TD]mkColums = map $ \c -> <TD bgcolor=(color c)><% c %></TD>

Haskell Server PagesXHTML Literals

ASP-style embedding

Translated to universal DOM representation

http://radar.oreilly.com/erlanghaskellruby-thumb.png

streams

tuples

Unions

Content classes

XML object literals

Generalized member access+ SQL comprehensions

XML 2003: Growing C

Type System Extensions

T ::= N | T[] | T{} | T(…,T,…) | T|T | T&T | T! | T? | T+ | T* | struct {…, T m,…}

intersection, union

streams

tuples (rows)

(structural)

arrays closures

XQuery data model

String n = "Wolfram";struct{String? Subject}* subjects = select it.Subject from it in inbox where it.From == n Compiler

plugins

C Query Comprehensions

foreach(r in select CustomerID, ContactName from dbo.Customers where City == mycity order by ContactName) { …} Type inference

SQL = data model + query syntax

Select Name, Age From CustomersWhere City = "Seattle"

Table of rows

XQuery/XPath = data model + query syntax

From $C In CustomersWhere $C/City = "Seattle"Return <Cust Name={$C/Name}> { $C/Age } </Cust>

Set of nodes

Foreach C In Customers If C.City = "Seattle" R.Add(New With {C.Name, C.Age}) End IfNext Collection of

objects

Objects = data model + query syntax

0

1

3

4

56

0

1

3

4

56

2 2

Filtering

X Mod 2 = 0

T (T Bool) T

0

1

3

4

56

0

2

6

8

1012

2 4

X * 2

Mapping

T (T S) S

0

1

3

4

56 21

2

Sum

Aggregating

T (S, (S,T) S) S

T ((T,T) T) T

Monads !

ℳ<T> Unit<T>(T src)ℳ<T> SelectMany<S,T> (ℳ<S> src, Sℳ<T> f)

ℳ<T>

ST

A container type

A function type

A constructor

A composer

Monads !

ℳ<T> Unit<T>(T src)ℳ<T> SelectMany<S,T> (ℳ<S> src, Sℳ<T> f)

ℳ<T>

ST

IEnumerable<T> IQueryable<T>

Func<S,T>Expr<Func<S,T>>

Standard Query Pattern(generics not expressive enough)

LINQ Project== monad comprehensions in C# & VB

VB 9 C# 3.0 …

StandardQuery

Operators

DLinq(relational)

XLinq(xml)

LINQ Framework

• Local Type Inference• Object & Collection Initializers• Anonymous Types• Lambda Expressions• Query Comprehensions• Extension Methods• Expression Trees• Simplified Properties• Partial Methods• Deep XML Support (VB)• Nullable Types (VB)

Features

EnablesLanguageExtensionsvia libraries

A better paradigm for programming massive clusters of commodity hardware than Google MapReduce based on LINQ

LINQ 2.0

Map Group By Repartition Aggregate

From W In WordsGroup By WAggregate N = Count()Select W, N

SawzallExample 3

submitsthroughweek: table sum[minute: int] of count: int;

log: P4ChangelistStats = input;

t: time = log.time; # microseconds

minute: int = minuteof(t) +60*(hourof(t) +24*(dayofweek(t)-1));

emit submitsthroughweek[minute] <- 1;

Using C# 3.0Comprehensions

var SubmitsThroughWeek = from s in db.Submits group s by s.SubmitTime.Minute + 60*(s.SubmitTime.Hour + 24*s.SubmitTime.DayOfWeek) into g select new { minute = g.Key , count = g.Count() };

Using Visual Basic 9Comprehensions

Dim SubmitsThroughWeek = From s In db.Submits Group By Minute = s.SubmitTime.Minute + 60*(s.SubmitTime.Hour + 24*s.SubmitTime.DayOfWeek) Into Minute, Count()

UsingStandard Sequence Operators

var SubmitsThroughWeek = db.Submits .GroupBy(s=>s.SubmitTime.Minute + 60*(s.SubmitTime.Hour + 24*s.SubmitTime.DayOfWeek)) .Select(g=>new { minute=g.Key , count=g.Count()} );

“Reduce”

“Map”Repartition

Division By 0 Is The Goal, Not An Error

Functional PL Object-Oriented PLSmalltalk JavaHaskell OCamlXML JSONLaTex MS WordBetamax VHSNouvelle Cuisine FastfoodSemantic Web Search… …

Do you see a pattern?

P(success) = F(10X improvement * Moore’s Law)

P(success) = F(perceived crisis/perceived pain of adoption)

Geeks

Users

Marketing

Cool!Next release is even better!

Just want to get job done

No patience to learn new stuff

Coerce users to believe gadgets will make them

happy

“For Dummies” Version

C

Haskell

Haskell98

Haskell’

10x better

Moore’sLaw

P(success) = F(perceived crisis perceived pain of adoption)

What is the user biggest crisis?

How can we make adoption truly painless?

Change Function to the rescue

P(success) = F(perceived crisis perceived pain of adoption)

Change Function to the rescue

P(success) = F(100% 0)

P(success) =

Silver Bullet

Are “functional” languages such as Erlang and F# the Silver Bullet for the many-core problem?

Shared NothingMessage Passing

Really?

Shared NothingMessage Passing

Really?

Page 165:

There is a subtle error in on_exit and keep_alive … Write your code such that race conditions cannot happen.…Fortunatley, the OTP libraries have code for building servers, supervisor trees, and so on.These libraries have been well tested and should not suffer from any race conditions.

Unsafe and Useless

safeunsafe

useful

uselessHaskell

C++

VBC#

F#Erlang

Nirvana

What is a Functional Language

A language where functions are first-class citizens

ThoseSneakySide Effects

unsafeCast :: a -> bunsafeCast x = unsafePerformIO $ writeIORef castref x >> readIORef castref

castref = unsafePerformIO $ newIORef undefined

new_cell(X) -> spawn(fun() -> cell(X) end).cell(Value) -> receive {set, NewValue} -> cell(NewValue); {get, Pid} -> Pid!{return, Value}, cell(Value); {dispose} -> {} end.set_cell(Cell, NewValue) -> Cell!{set, NewValue}.

get_cell(Cell) -> Cell!{get, self()}, receive {return, Value} -> Value end.dispose_cell(Cell) -> Cell!{dispose}.

4711

c.set_cell(v)

v =c.get_cell()

What is a function

-calculusE ::= EE | …

let x = E1 in E0[x] E0[x:=E1]

(x.E0[x])E1 E0[x:=E1]

What is a function

let t = DateTime.Now.Ticksin (x,x)( DateTime.Now.Ticks, DateTime.Now.Ticks)

Racecondition

Mens sana in corpore sano

Haskell

Purity is the key to success

Mistake

DateTime.Now.Ticks long

Type error!!!!!!!!!!!!!!!

What is a function

let t = ().DateTime.Now.Ticksin (x,x)( ().DateTime.Now.Ticks, ().DateTime.Now.Ticks)

Valuerestriction

Values vs Computation

How to turn something mutable into something immutable?

Time changes, the clock does not

Generalization

Monads

M<A>

A computation that produces a value of type A with side-effects described by M

M IO Exception Animation Collection

Algebra/API

Return A M<A>

Bind M<A>(AM<B>)M<B>

Join M<M<A>>M<A>

UnsafePerformIO M<A>A

LINQ

Monads are the secret sauce behind LINQ

IEnumerable<S> SelectMany<T,S>( IEnumerable<T> src, Func<T, IEnumerable<S>> selector)

Bind

IO

data IO a

putChar :: Char -> IO ()getChar :: IO Char

newIORef :: a -> IO (IORef a)readIORef :: IORef a -> IO awriteIORef :: IORef a -> a -> IO ()

forkIO :: IO a -> IO ThreadID

Side-effecting

computation that yields a value of type

a

IO

main :: IO()main = do{ x <- newIORef “hello” ; c <- getChar ; s <- readIORef x ; writeIORef x (c:s) ; ... }

Does nothing

STMdata STM a

atomic :: STM a -> IO aretry :: STM aorElse :: STM a -> STM a -> STM a

newTVar :: a -> STM (TVar a)readTVar :: TVar a -> STM awriteTVar :: TVar a -> a -> STM ()

STMputR :: TVar Int -> Int -> STM ()putR r i = do { v <- readTVar r ; writeTVar r (v+i) }

main :: IO()main = do{ … ; atomic $ putR 4711 ; … }

STM

getR :: TVar Int -> Int -> STM ()getR r i = do { v <- readTVar r ; if (v < i) then retry else writeTVar r (v-i) }

STMnonBlockGetR :: TVar Int -> Int -> STM BoolnonBlockGetR r i = do { getR r i ; return True }‘orElse‘ do { return False }

retry

STMnonBlockGetR :: TVar Int -> Int -> STM BoolnonBlockGetR r i = do { getR r i ; return True }‘orElse‘ do { return False }

retry

STMAn MVar is a mutable location either empty, or full with a value.

takeMVar function leaves a full MVar empty, blocks on an empty MVar.

putMVar on an empty MVar leaves it full, and blocks on a full MVar.

type MVar a = TVar (Maybe a)

newEmptyMVar :: STM (MVar a)newEmptyMVar = newTVar Nothing

STMRead the contents of the TVar retry until not Nothing:

takeMVar :: MVar a -> STM atakeMVar mv = do { v <- readTVar mv ; case v of Nothing -> retry Just val -> do { writeTVar mv Nothing ; return val } }

STM

Retry until Nothing,Update the underlying TVar

putMVar :: MVar a -> a -> STM ()putMVar mv val = do { v <- readTVar mv ; case v of Nothing -> do{ writeTVar mv (Just val) } Just val -> retry }

C

Haskell

Haskell98

Haskell’

10x better

Moore’sLaw

Is thePerceived Real

Crisis >>>>

Perceived pain of adoption?

Recommended