Upload
sharleen-hensley
View
215
Download
0
Embed Size (px)
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?