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
170
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
Facilitating Awesome Meetings
lara
50
6.1k
KATA
mclloyd
29
14k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.4k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
810
Embracing the Ebb and Flow
colly
84
4.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Designing Experiences People Love
moore
138
23k
How to Ace a Technical Interview
jacobian
276
23k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
YesSQL, Process and Tooling at Scale
rocio
169
14k
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