Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
What Python can learn from Haskell
Search
Gideon de Kok
May 11, 2013
4
160
What Python can learn from Haskell
Or basically, what makes Haskell cool in the modern era ;)
Gideon de Kok
May 11, 2013
Tweet
Share
More Decks by Gideon de Kok
See All by Gideon de Kok
Building a Reactive e-commerce platform - Sting
gideondk
0
300
Functional Reactive Processing
gideondk
3
130
Riak and Akka at SpotDog
gideondk
3
360
Featured
See All Featured
Visualization
eitanlees
145
15k
Faster Mobile Websites
deanohume
305
30k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
Building Applications with DynamoDB
mza
90
6.1k
Designing on Purpose - Digital PM Summit 2013
jponch
115
7k
Testing 201, or: Great Expectations
jmmastey
38
7.1k
Ruby is Unlike a Banana
tanoku
97
11k
Six Lessons from altMBA
skipperchong
27
3.5k
Producing Creativity
orderedlist
PRO
341
39k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.4k
Transcript
What Python can learn from Haskell Saturday, May 11, 13
Daniël @danieldekok Developer Lan ua e Technolo y at Gridline
Workin on NLP based technolo y on a day to day basis (Java, C++, Haskell) Saturday, May 11, 13
Gideon @ ideondk Tech-lead at SpotDo Focusin on functional and
actor based pro rammin throu h Scala and native application development Saturday, May 11, 13
Saturday, May 11, 13
MapReduce wasn’t invented by Goo le Saturday, May 11, 13
Fundamentals based on the principles of functional pro rammin Saturday,
May 11, 13
So why bother about functional pro rammin ? Saturday, May
11, 13
New challen es in computin Saturday, May 11, 13
Bi data Saturday, May 11, 13
Bi data applyin filterin , transformations, and reductions to hu
e streams of data Saturday, May 11, 13
The real-time web Saturday, May 11, 13
The real-time web constant exchan e of data, both in
lar e and small packa es Saturday, May 11, 13
Bi data implications Saturday, May 11, 13
OO isn’t that well suited transformations are not inherent properties
of objects Saturday, May 11, 13
A flat imperative model neither imperative functions are not easily
composable Saturday, May 11, 13
Real-time web implications Saturday, May 11, 13
Traditional stacks aren’t suited Saturday, May 11, 13
Modern stacks neither ;-) Saturday, May 11, 13
Callback hell anyone? fs.readdir(source, function(err, files) { if (err) {
console.log('Error finding files: ' + err) } else { files.forEach(function(filename, fileIndex) { console.log(filename) gm(source + filename).size(function(err, values) { if (err) { console.log('Error identifying file size: ' + err) } else { console.log(filename + ' : ' + values) aspect = (values.width / values.height) widths.forEach(function(width, widthIndex) { height = Math.round(width / aspect) console.log('resizing ' + filename + 'to ' + height + 'x' + height) this.resize(width, height).write(destination + 'w' + width + '_' + filename, function(err) { if (err) console.log('Error writing file: ' + err) }) }.bind(this)) } }) }) } }) Saturday, May 11, 13
Bi data & real-time requirements process lots of data, with
as few resources as possible Saturday, May 11, 13
Developer requirements composable transformations, to work on lar e streams
of data as easily as possible ( while keepin yourself DRY ) Saturday, May 11, 13
Goin functional! Saturday, May 11, 13
Stream processin was born in functional lan ua es Saturday,
May 11, 13
Mappin map :: (a -> b) -> [a] -> [b]
map f xs = [f x | x <- xs] Saturday, May 11, 13
Mappin example Prelude> map (\x -> x + 4) [1,2,3,4,5]
[5,6,7,8,9] Saturday, May 11, 13
A Haskell example obtainKeywords :: [HTMLPage] -> [KeywordSet] obtainKeywords =
map extractPlainText . map tokenize . map toTokenSet Saturday, May 11, 13
Desirable properties obtainKeywords = map extractPlainText . map tokenize .
map toTokenSet Saturday, May 11, 13
More transformations obtainImportantKeywords :: [HTMLPage] -> KeywordSet obtainImportantKeywords = filter
importantDocument . map extractPlainText . map tokenize . map toTokenSet . foldl' Set.union Set.empty Saturday, May 11, 13
Downsides of list-based streams Saturday, May 11, 13
Lazy I/O is ross :-( Saturday, May 11, 13
Like in fancy restaurants no do y ba s allowed!
Saturday, May 11, 13
Not so fancy error handlin ‘either’ Saturday, May 11, 13
Not so fancy error handlin ‘either’ obtainImportantKeywords :: [HTMLPage] ->
KeywordSet obtainImportantKeywords = filter importantDocument . map extractPlainText . map tokenize . map toTokenSet . foldl' Set.union Set.empty Saturday, May 11, 13
Iteratee-based pipelines Saturday, May 11, 13
Packa es: one too many enumerator, conduit, pipes, io-streams Saturday,
May 11, 13
Teachin an old fold new tricks obtainImportantKeywords :: Iteratee KeywordSet
m KeywordSet obtainImportantKeywords = getPages $= EL.filter importantDocument $= EL.map extractPlainText $= EL.map tokenize $= EL.map toTokenSet $$ EL.fold Set.union Set.empty Saturday, May 11, 13
Enumerator obtainImportantKeywords :: Iteratee KeywordSet m KeywordSet obtainImportantKeywords = getPages
$= EL.filter importantDocument $= EL.map extractPlainText $= EL.map tokenize $= EL.map toTokenSet $$ EL.fold Set.union Set.empty getPages Saturday, May 11, 13
Iteratee obtainImportantKeywords :: Iteratee KeywordSet m KeywordSet obtainImportantKeywords = getPages
$= EL.filter importantDocument $= EL.map extractPlainText $= EL.map tokenize $= EL.map toTokenSet $$ EL.fold Set.union Set.empty EL.fold Set.union Set.empty Saturday, May 11, 13
Enumeratees obtainImportantKeywords :: Iteratee KeywordSet m KeywordSet obtainImportantKeywords = getPages
$= EL.filter importantDocument $= EL.map extractPlainText $= EL.map tokenize $= EL.map toTokenSet $$ EL.fold Set.union Set.empty $= EL.filter importantDocument $= EL.map extractPlainText $= EL.map tokenize $= EL.map toTokenSet Saturday, May 11, 13
Operators obtainImportantKeywords :: Iteratee KeywordSet m KeywordSet obtainImportantKeywords = getPages
$= EL.filter importantDocument $= EL.map extractPlainText $= EL.map tokenize $= EL.map toTokenSet $$ EL.fold Set.union Set.empty $= $= $= $= $$ Saturday, May 11, 13
Lettin the stream flow run obtainImportantKeywords Saturday, May 11, 13
Concatenatin concatEnums [enum1, enum2, enum3] Saturday, May 11, 13
Zippin Iteratees EL.zip iteratee1 iteratee2 Saturday, May 11, 13
Combinin Iteratees combinedIteratee = do a <- EL.take 3 b
<- EL.take 3 return (a,b) Saturday, May 11, 13
Iteratee internals Saturday, May 11, 13
Chunks Yield Left overs Saturday, May 11, 13
Continue Yield Error Saturday, May 11, 13
Internals in code data Stream i = Chunks [i] |
EOF deriving (Show, Eq) data Step i m o = Continue (Stream i -> Iteratee i m o) | Yield b (Stream o) | Error Exc.SomeException Saturday, May 11, 13
Constructin an Iteratee consume :: Monad m => Iteratee a
m [a] consume = liftI $ step id where step acc chunk = case chunk of Chunks [] -> Continue $ returnI . step acc Chunks xs -> Continue $ returnI . (step $ acc . (xs ++)) EOF -> Yield (acc []) EOF Saturday, May 11, 13
Stream processin is ettin hip in other lan ua es
as well! Saturday, May 11, 13
Iteratees are available in Scala (more on that later) Saturday,
May 11, 13
Java 8 introduces a new stream API (althou h limited
in comparison) Saturday, May 11, 13
Clojure has reducers Saturday, May 11, 13
case class LogMessage(ip: String, code: Int, message: String) val (enum,
channels) = Concurrent.Broadcast[Array[Byte]] val converter = Enumeratee.map[Array[Byte]](ba => JsValue(ba)) val reader = Enumeratee.map[JsValue](evt => LogMessage(evt("id"), evt("code"), evt("message"))) val filterErrors = Enumeratee.filter(e => e.code == 500) def streamErrors = Action { request => enum &> converter &> reader &> filterErrors &> Comet(callback = "parent.message")) } Showin off Iteratees in Scala Saturday, May 11, 13
The state of the art in Python Saturday, May 11,
13
Generators available throu h yield Saturday, May 11, 13
Built-in map/filter in Python 3 return an iterable (this is
ood!) Saturday, May 11, 13
streams.py import re from stream import filter, map, cut result
= open('file') \ >> filter(re.compile(regex).search) \ >> map(re.compile(' |:|\.').split) \ >> cut[3] \ >> list Saturday, May 11, 13
If you are lookin to continue a interestin project, this
may be it! Saturday, May 11, 13
Mutablility leads to non-determinism root of all evil Saturday, May
11, 13
Saturday, May 11, 13
First meetup in two weeks contact either of us for
more info! http://www.meetup.com/Functional-Gronin en/ Saturday, May 11, 13