Monads, also known as Kleisli triples in Category Theory, are an (endo-)functor together with two natural transformations, which are surprisingly useful in pure languages like Haskell, but this talk will NOT reference monads. Ever. (Well, at least not in this talk.)
Instead what I intend to impress upon an audience of newcomers to Haskell is the wide array of freely available libraries most of which are liberally licensed open source software, intuitive package management, practical build tools, reasonable documentation (when you know how to read it and where to find it), interactive shell (or REPL), mature compiler, stable runtime, testing tools that will blow your mind away, and a small but collaborative and knowledgeable community of developers. Oh, and some special features of Haskell - the language - too!
2. What is Haskell?
Figure: "pure functional, lazy, polymorphic, statically and strongly typed with type inference . . . "
3. How can I drive this thing?
Figure: Photo from "If programming languages were cars" blog post
http://machinegestalt.posterous.com/if-programming-languages-were-cars
4. Can I drive Haskell without all this?
Figure: No need to know Category Theory proofs, just some intuitions!
5. # finger $(whoami)
Login: susan Name: Susan Potter
Directory: /home/susan Shell: /bin/zsh
Practicing since 1997-09-29 21:18 (GMT) on tty1 from :0
Too much unread mail on me@susanpotter.net
Now working at Desk.com! Looking for smart developers!;)
Plan:
github: mbbx6spp
twitter: @SusanPotter
6. Are we "doing it wrong"?
Figure: Maybe! ;)
http://absolutelymadness.tumblr.com/post/17567574522
7. Overview: Choosing a language
Many considerations
political, human, technical
Runtime
performance, reliability, configurability
Knowledge
culture, mindshare, resources, signal to noise ratio
Tooling
development, build/release, configuration, deployment
8. Overview: Choosing a language
Many considerations
political, human, technical
Runtime
performance, reliability, configurability
Knowledge
culture, mindshare, resources, signal to noise ratio
Tooling
development, build/release, configuration, deployment
9. Overview: Choosing a language
Many considerations
political, human, technical
Runtime
performance, reliability, configurability
Knowledge
culture, mindshare, resources, signal to noise ratio
Tooling
development, build/release, configuration, deployment
10. Overview: Choosing a language
Many considerations
political, human, technical
Runtime
performance, reliability, configurability
Knowledge
culture, mindshare, resources, signal to noise ratio
Tooling
development, build/release, configuration, deployment
11. Overview: Agenda
My Claims / Hypotheses
Laziness, Functional, Type System
Toolkit & Runtime
Library Ecosystem
Pitfalls & Hurdles
12. My Claims
Performance is reasonable
on par with Java and C# Mono; 2-3x CPU times of C (approx); BUT always doubt benchmarks
http://shootout.alioth.debian.org/u64q/haskell.php
Productivity with long-term benefits
after initial steep learning curve
Haskell types offer stronger verifiability
strong and meaningful checks applied
Pure functional code is easier to test
probably not controversial
13. My Claims
Performance is reasonable
on par with Java and C# Mono; 2-3x CPU times of C (approx); BUT always doubt benchmarks
http://shootout.alioth.debian.org/u64q/haskell.php
Productivity with long-term benefits
after initial steep learning curve
Haskell types offer stronger verifiability
strong and meaningful checks applied
Pure functional code is easier to test
probably not controversial
14. My Claims
Performance is reasonable
on par with Java and C# Mono; 2-3x CPU times of C (approx); BUT always doubt benchmarks
http://shootout.alioth.debian.org/u64q/haskell.php
Productivity with long-term benefits
after initial steep learning curve
Haskell types offer stronger verifiability
strong and meaningful checks applied
Pure functional code is easier to test
probably not controversial
15. My Claims
Performance is reasonable
on par with Java and C# Mono; 2-3x CPU times of C (approx); BUT always doubt benchmarks
http://shootout.alioth.debian.org/u64q/haskell.php
Productivity with long-term benefits
after initial steep learning curve
Haskell types offer stronger verifiability
strong and meaningful checks applied
Pure functional code is easier to test
probably not controversial
16. Haskell "lazy" by default
Figure: Photo by Mark Fischer
http://www.flickr.com/photos/tom_ruaat/4431626234/
17. Haskell "lazy" by default
Figure: Photo by Mark Fischer
http://www.flickr.com/photos/tom_ruaat/4431626234/
(jarring for mainstream programmers)
29. Laziness in Haskell is . . .
CallByName
+ SharingOptimization
+ PossibleMinorOverhead
30. Laziness: Buyer Beware
filter (λ x → x < 6) [1..]
(never terminates)
takeWhile (λ x → x < 6) [1..]
(does terminate)
dropWhile (λ x → x >= 6) [1..]
(does not terminate)
Need to understand implications
of laziness on functions
Laziness with I/O implications
lazy I/O with handles is problematic, but iteratee idiom solves most of these. There are a number of libraries
available to help with this: enumerator, pipes, . . .
31. Laziness: Buyer Beware
filter (λ x → x < 6) [1..]
(never terminates)
takeWhile (λ x → x < 6) [1..]
(does terminate)
dropWhile (λ x → x >= 6) [1..]
(does not terminate)
Need to understand implications
of laziness on functions
Laziness with I/O implications
lazy I/O with handles is problematic, but iteratee idiom solves most of these. There are a number of libraries
available to help with this: enumerator, pipes, . . .
32. Laziness: Buyer Beware
filter (λ x → x < 6) [1..]
(never terminates)
takeWhile (λ x → x < 6) [1..]
(does terminate)
dropWhile (λ x → x >= 6) [1..]
(does not terminate)
Need to understand implications
of laziness on functions
Laziness with I/O implications
lazy I/O with handles is problematic, but iteratee idiom solves most of these. There are a number of libraries
available to help with this: enumerator, pipes, . . .
33. Laziness: Buyer Beware
filter (λ x → x < 6) [1..]
(never terminates)
takeWhile (λ x → x < 6) [1..]
(does terminate)
dropWhile (λ x → x >= 6) [1..]
(does not terminate)
Need to understand implications
of laziness on functions
Laziness with I/O implications
lazy I/O with handles is problematic, but iteratee idiom solves most of these. There are a number of libraries
available to help with this: enumerator, pipes, . . .
34. Laziness: Buyer Beware
filter (λ x → x < 6) [1..]
(never terminates)
takeWhile (λ x → x < 6) [1..]
(does terminate)
dropWhile (λ x → x >= 6) [1..]
(does not terminate)
Need to understand implications
of laziness on functions
Laziness with I/O implications
lazy I/O with handles is problematic, but iteratee idiom solves most of these. There are a number of libraries
available to help with this: enumerator, pipes, . . .
35. Laziness: Also Pretty Suuweeeet!
Infinite sequences/lists
made possible
Recursive functions
become practical
Recursive types
become simple
Much more as well ...
36. Laziness: Also Pretty Suuweeeet!
Infinite sequences/lists
made possible
Recursive functions
become practical
Recursive types
become simple
Much more as well ...
37. Laziness: Also Pretty Suuweeeet!
Infinite sequences/lists
made possible
Recursive functions
become practical
Recursive types
become simple
Much more as well ...
38. Laziness: Also Pretty Suuweeeet!
Infinite sequences/lists
made possible
Recursive functions
become practical
Recursive types
become simple
Much more as well ...
39. Purity + Laziness=> Reasoning
Equality (referential transparency)
Can replace occurrences of LHS with RHS
Higher Order Functions
encourage exploitation of higher-level patterns
Function Composition
leads to greater reuse
40. Purity + Laziness=> Reasoning
Equality (referential transparency)
Can replace occurrences of LHS with RHS
Higher Order Functions
encourage exploitation of higher-level patterns
Function Composition
leads to greater reuse
41. Purity + Laziness=> Reasoning
Equality (referential transparency)
Can replace occurrences of LHS with RHS
Higher Order Functions
encourage exploitation of higher-level patterns
Function Composition
leads to greater reuse
42. mysum :: Num a => [a] -> a
mysum xs = foldr (+) 0 xs
myproduct :: Num a => [a] -> a
myproduct xs = foldr (*) 1 xs
myany :: (a -> Bool) -> [a] -> Bool
myany pred xs = foldr ( x b -> b || pred x) False xs
myall :: (a -> Bool) -> [a] -> Bool
myall pred xs = foldr ( x b -> b && pred x) True xs
43. mysum :: Num a => [a] -> a
mysum xs = foldr (+) 0 xs
myproduct :: Num a => [a] -> a
myproduct xs = foldr (*) 1 xs
myany :: (a -> Bool) -> [a] -> Bool
myany pred xs = foldr ( x b -> b || pred x) False xs
myall :: (a -> Bool) -> [a] -> Bool
myall pred xs = foldr ( x b -> b && pred x) True xs
44. mysum :: Num a => [a] -> a
mysum xs = foldr (+) 0 xs
myproduct :: Num a => [a] -> a
myproduct xs = foldr (*) 1 xs
myany :: (a -> Bool) -> [a] -> Bool
myany pred xs = foldr ( x b -> b || pred x) False xs
myall :: (a -> Bool) -> [a] -> Bool
myall pred xs = foldr ( x b -> b && pred x) True xs
45. mysum :: Num a => [a] -> a
mysum xs = foldr (+) 0 xs
myproduct :: Num a => [a] -> a
myproduct xs = foldr (*) 1 xs
myany :: (a -> Bool) -> [a] -> Bool
myany pred xs = foldr ( x b -> b || pred x) False xs
myall :: (a -> Bool) -> [a] -> Bool
myall pred xs = foldr ( x b -> b && pred x) True xs
46. mysum :: Num a => [a] -> a
mysum xs = foldr (+) 0 xs
myproduct :: Num a => [a] -> a
myproduct xs = foldr (*) 1 xs
myany :: (a -> Bool) -> [a] -> Bool
myany pred xs = foldr ( x b -> b || pred x) False xs
myall :: (a -> Bool) -> [a] -> Bool
myall pred xs = foldr ( x b -> b && pred x) True xs
47. mysum :: Num a => [a] -> a
mysum xs = foldr (+) 0 xs
myproduct :: Num a => [a] -> a
myproduct xs = foldr (*) 1 xs
myany :: (a -> Bool) -> [a] -> Bool
myany pred xs = foldr ( x b -> b || pred x) False xs
myall :: (a -> Bool) -> [a] -> Bool
myall pred xs = foldr ( x b -> b && pred x) True xs
48. mysum :: Num a => [a] -> a
mysum xs = foldr (+) 0 xs
myproduct :: Num a => [a] -> a
myproduct xs = foldr (*) 1 xs
myany :: (a -> Bool) -> [a] -> Bool
myany pred xs = foldr ( x b -> b || pred x) False xs
myall :: (a -> Bool) -> [a] -> Bool
myall pred xs = foldr ( x b -> b && pred x) True xs
49. class Monoid m where
mappend :: m -> m -> m
mempty :: m
instance Num a => Monoid a where
mappend :: m -> m -> m
mappend x y = (+) x y
mempty :: m
mempty = 0
instance Monoid Bool where
mappend :: m -> m -> m
mappend True _ = True
mappend _ True = True
mappend _ _ = False
mempty :: m
50. class Monoid m where
mappend :: m -> m -> m
mempty :: m
instance Num a => Monoid a where
mappend :: m -> m -> m
mappend x y = (+) x y
mempty :: m
mempty = 0
instance Monoid Bool where
mappend :: m -> m -> m
mappend True _ = True
mappend _ True = True
mappend _ _ = False
mempty :: m
51. class Monoid m where
mappend :: m -> m -> m
mempty :: m
instance Num a => Monoid a where
mappend :: m -> m -> m
mappend x y = (+) x y
mempty :: m
mempty = 0
instance Monoid Bool where
mappend :: m -> m -> m
mappend True _ = True
mappend _ True = True
mappend _ _ = False
mempty :: m
52. Haskell type signatures can . . .
express side effects
e.g. String -> IO Int
declare computational strategies
e.g. Num a => [a] -> Sum a
impose constraints
e.g. Num a => a -> a
question value availability
e.g. String -> Maybe Int
verify client-server protocol dialogs?
an exercise for reader ;)
53. Haskell type signatures can . . .
express side effects
e.g. String -> IO Int
declare computational strategies
e.g. Num a => [a] -> Sum a
impose constraints
e.g. Num a => a -> a
question value availability
e.g. String -> Maybe Int
verify client-server protocol dialogs?
an exercise for reader ;)
54. Haskell type signatures can . . .
express side effects
e.g. String -> IO Int
declare computational strategies
e.g. Num a => [a] -> Sum a
impose constraints
e.g. Num a => a -> a
question value availability
e.g. String -> Maybe Int
verify client-server protocol dialogs?
an exercise for reader ;)
55. Haskell type signatures can . . .
express side effects
e.g. String -> IO Int
declare computational strategies
e.g. Num a => [a] -> Sum a
impose constraints
e.g. Num a => a -> a
question value availability
e.g. String -> Maybe Int
verify client-server protocol dialogs?
an exercise for reader ;)
56. Haskell type signatures can . . .
express side effects
e.g. String -> IO Int
declare computational strategies
e.g. Num a => [a] -> Sum a
impose constraints
e.g. Num a => a -> a
question value availability
e.g. String -> Maybe Int
verify client-server protocol dialogs?
an exercise for reader ;)
57. Interfaces in OO . . .
Figure: Class definitions are married to the interfaces they implement.
58. Interfaces in Haskell: Typeclasses. . .
Decouple type definition from interface
Allow upstream implementations
Extend thirdparty libraries easily
Redefine implementations upstream
No meaningless "any type" functions
Very flexible
59. Interfaces in Haskell: Typeclasses. . .
Decouple type definition from interface
Allow upstream implementations
Extend thirdparty libraries easily
Redefine implementations upstream
No meaningless "any type" functions
Very flexible
60. Interfaces in Haskell: Typeclasses. . .
Decouple type definition from interface
Allow upstream implementations
Extend thirdparty libraries easily
Redefine implementations upstream
No meaningless "any type" functions
Very flexible
61. Interfaces in Haskell: Typeclasses. . .
Decouple type definition from interface
Allow upstream implementations
Extend thirdparty libraries easily
Redefine implementations upstream
No meaningless "any type" functions
Very flexible
62. Interfaces in Haskell: Typeclasses. . .
Decouple type definition from interface
Allow upstream implementations
Extend thirdparty libraries easily
Redefine implementations upstream
No meaningless "any type" functions
Very flexible
63. Interfaces in Haskell: Typeclasses. . .
Decouple type definition from interface
Allow upstream implementations
Extend thirdparty libraries easily
Redefine implementations upstream
No meaningless "any type" functions
Very flexible
64. class (Eq a) => Ord a where
compare :: a -> a -> Ordering
compare x y | x == y = EQ
| x <= y = LT
| otherwise = GT
(<), (>), (>=), (<=) :: a -> a -> Bool
...
max, min :: a -> a -> a
...
65. Typically this just works . . .
data SimpleShape = Square { size :: Double }
| Circle { radius :: Double }
deriving (Eq, Ord, Show)
We explicitly use the default definitions
. . . and when it doesn’t . . .
instance Ord SimpleShape where
...
66. Are you awake?
Figure: http://absolutelymadness.tumblr.com/post/18126913457
67. Haskell Tooling: Libraries
Quite a few
Practical libraries
Often freely available
Permissive OSS licenses
68. Haskell Tooling: Libraries
Quite a few
Practical libraries
Often freely available
Permissive OSS licenses
69. Haskell Tooling: Libraries
Quite a few
Practical libraries
Often freely available
Permissive OSS licenses
70. Haskell Tooling: Libraries
Quite a few
Practical libraries
Often freely available
Permissive OSS licenses
71. Haskell Tooling: Runtime
Reasonably performant
between JVM 7 and C# Mono performance
GC settings easily customized
Numerous other runtime options
72. Haskell Tooling: Runtime
Reasonably performant
between JVM 7 and C# Mono performance
GC settings easily customized
Numerous other runtime options
73. Haskell Tooling: Runtime
Reasonably performant
between JVM 7 and C# Mono performance
GC settings easily customized
Numerous other runtime options
77. Haskell Tooling: Dependency
Management
Hackage
database of freely available Haskell libraries
Cabal
great to get started, BUT . . .
cabal-dev & similar
provides sandboxing, list RVM with gemsets; more important for statically typed environments
cabal-nirvana
think compatible distribution snapshot of Hackage DB
78. Haskell Tooling: Dependency
Management
Hackage
database of freely available Haskell libraries
Cabal
great to get started, BUT . . .
cabal-dev & similar
provides sandboxing, list RVM with gemsets; more important for statically typed environments
cabal-nirvana
think compatible distribution snapshot of Hackage DB
79. Haskell Tooling: Dependency
Management
Hackage
database of freely available Haskell libraries
Cabal
great to get started, BUT . . .
cabal-dev & similar
provides sandboxing, list RVM with gemsets; more important for statically typed environments
cabal-nirvana
think compatible distribution snapshot of Hackage DB
80. Haskell Tooling: Dependency
Management
Hackage
database of freely available Haskell libraries
Cabal
great to get started, BUT . . .
cabal-dev & similar
provides sandboxing, list RVM with gemsets; more important for statically typed environments
cabal-nirvana
think compatible distribution snapshot of Hackage DB
81. Haskell Tooling: Don’ts for Newbies
Use GHC (not HUGS)
Hugs written for educational purposes not industrial usage
Forget what you know (imperative/OO)
relearn programming in a functional-style
return is a function name
it does not mean return in the C/Java/C# way
class does not mean OO-class
think decoupled interface with optional default impelementations and a lot more power
82. Haskell Tooling: Don’ts for Newbies
Use GHC (not HUGS)
Hugs written for educational purposes not industrial usage
Forget what you know (imperative/OO)
relearn programming in a functional-style
return is a function name
it does not mean return in the C/Java/C# way
class does not mean OO-class
think decoupled interface with optional default impelementations and a lot more power
83. Haskell Tooling: Don’ts for Newbies
Use GHC (not HUGS)
Hugs written for educational purposes not industrial usage
Forget what you know (imperative/OO)
relearn programming in a functional-style
return is a function name
it does not mean return in the C/Java/C# way
class does not mean OO-class
think decoupled interface with optional default impelementations and a lot more power
84. Haskell Tooling: Don’ts for Newbies
Use GHC (not HUGS)
Hugs written for educational purposes not industrial usage
Forget what you know (imperative/OO)
relearn programming in a functional-style
return is a function name
it does not mean return in the C/Java/C# way
class does not mean OO-class
think decoupled interface with optional default impelementations and a lot more power
85. Haskell Tooling: Suggestions
Explicit language extensions
Intentionally and explicitly enable per module
Sandbox your builds
with cabal-dev or similar
Think in types and shapes
and use Hoogle to lookup based on types and function "shapes"
86. Haskell Tooling: Suggestions
Explicit language extensions
Intentionally and explicitly enable per module
Sandbox your builds
with cabal-dev or similar
Think in types and shapes
and use Hoogle to lookup based on types and function "shapes"
87. Haskell Tooling: Suggestions
Explicit language extensions
Intentionally and explicitly enable per module
Sandbox your builds
with cabal-dev or similar
Think in types and shapes
and use Hoogle to lookup based on types and function "shapes"
88. Oh, the possibilities!
Parallel / Concurrency Options
threads, dataflow, par, seq
"Cloud" Haskell
A kind of Erlang/OTP clone in Haskell
Data Parallel Haskell
GHC extensions to support nested data parallelism accounting, "Nepal"
Haskell’s Foreign Function Interface (FFI)
Interface with native code from Haskell
GPU Programming in Haskell
Obsidian, Nikola, GpuGen, numerous papers on this too
Much more. . .
Research meeting industrial application
89. Oh, the possibilities!
Parallel / Concurrency Options
threads, dataflow, par, seq
"Cloud" Haskell
A kind of Erlang/OTP clone in Haskell
Data Parallel Haskell
GHC extensions to support nested data parallelism accounting, "Nepal"
Haskell’s Foreign Function Interface (FFI)
Interface with native code from Haskell
GPU Programming in Haskell
Obsidian, Nikola, GpuGen, numerous papers on this too
Much more. . .
Research meeting industrial application
90. Oh, the possibilities!
Parallel / Concurrency Options
threads, dataflow, par, seq
"Cloud" Haskell
A kind of Erlang/OTP clone in Haskell
Data Parallel Haskell
GHC extensions to support nested data parallelism accounting, "Nepal"
Haskell’s Foreign Function Interface (FFI)
Interface with native code from Haskell
GPU Programming in Haskell
Obsidian, Nikola, GpuGen, numerous papers on this too
Much more. . .
Research meeting industrial application
91. Oh, the possibilities!
Parallel / Concurrency Options
threads, dataflow, par, seq
"Cloud" Haskell
A kind of Erlang/OTP clone in Haskell
Data Parallel Haskell
GHC extensions to support nested data parallelism accounting, "Nepal"
Haskell’s Foreign Function Interface (FFI)
Interface with native code from Haskell
GPU Programming in Haskell
Obsidian, Nikola, GpuGen, numerous papers on this too
Much more. . .
Research meeting industrial application
92. Oh, the possibilities!
Parallel / Concurrency Options
threads, dataflow, par, seq
"Cloud" Haskell
A kind of Erlang/OTP clone in Haskell
Data Parallel Haskell
GHC extensions to support nested data parallelism accounting, "Nepal"
Haskell’s Foreign Function Interface (FFI)
Interface with native code from Haskell
GPU Programming in Haskell
Obsidian, Nikola, GpuGen, numerous papers on this too
Much more. . .
Research meeting industrial application
93. Oh, the possibilities!
Parallel / Concurrency Options
threads, dataflow, par, seq
"Cloud" Haskell
A kind of Erlang/OTP clone in Haskell
Data Parallel Haskell
GHC extensions to support nested data parallelism accounting, "Nepal"
Haskell’s Foreign Function Interface (FFI)
Interface with native code from Haskell
GPU Programming in Haskell
Obsidian, Nikola, GpuGen, numerous papers on this too
Much more. . .
Research meeting industrial application
96. Bonus: References / Resources
Channel 9 Lectures (Erik Meijer)
http://channel9.msdn.com/Shows/Going+Deep/
Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1
Learn You A Haskell
http://learnyouahaskell.com
Haskell Reddit
http://www.reddit.com/r/haskell/
Haskell Cafe
http://www.haskell.org/mailman/listinfo/haskell-cafe
Real World Haskell
http://book.realworldhaskell.org/
97. Bonus: References / Resources
Channel 9 Lectures (Erik Meijer)
http://channel9.msdn.com/Shows/Going+Deep/
Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1
Learn You A Haskell
http://learnyouahaskell.com
Haskell Reddit
http://www.reddit.com/r/haskell/
Haskell Cafe
http://www.haskell.org/mailman/listinfo/haskell-cafe
Real World Haskell
http://book.realworldhaskell.org/
98. Bonus: References / Resources
Channel 9 Lectures (Erik Meijer)
http://channel9.msdn.com/Shows/Going+Deep/
Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1
Learn You A Haskell
http://learnyouahaskell.com
Haskell Reddit
http://www.reddit.com/r/haskell/
Haskell Cafe
http://www.haskell.org/mailman/listinfo/haskell-cafe
Real World Haskell
http://book.realworldhaskell.org/
99. Bonus: References / Resources
Channel 9 Lectures (Erik Meijer)
http://channel9.msdn.com/Shows/Going+Deep/
Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1
Learn You A Haskell
http://learnyouahaskell.com
Haskell Reddit
http://www.reddit.com/r/haskell/
Haskell Cafe
http://www.haskell.org/mailman/listinfo/haskell-cafe
Real World Haskell
http://book.realworldhaskell.org/
100. Bonus: References / Resources
Channel 9 Lectures (Erik Meijer)
http://channel9.msdn.com/Shows/Going+Deep/
Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1
Learn You A Haskell
http://learnyouahaskell.com
Haskell Reddit
http://www.reddit.com/r/haskell/
Haskell Cafe
http://www.haskell.org/mailman/listinfo/haskell-cafe
Real World Haskell
http://book.realworldhaskell.org/
101. Bonus: Brief QuickCheck Example
module Tests where
import Test.QuickCheck (quickCheck)
propReverseReverse :: [Char] -> Bool
propReverseReverse s = (reverse . reverse) s == s
excuse the weird syntax form, indenting didn’t show up ;(
main = do {quickCheck propReverseReverse }