data pipelines in swift
TRANSCRIPT
"Hello" |> println
• Meet%the%Forward%Pipe%Operator%|>
• Popular%in%languages%such%as%F#%and%Elixir.
• Simply%applies%le>%hand%side%of%expression%as%first%argument%of%funcAon%on%the%right
Data$Pipelines
// the result of each step becomes first arg in the next1...5|> (filter, isEven) // [2, 4]|> (map, {$0 * 3}) // [6, 12]|> (reduce, 0, +) // 18
Data$Pipelines
students// filter to students with last name L*|> (filter, { $0.lastName.hasPrefix("L") }// get list of all their first names|> (map, Student.firstName)// make all the names uppercase|> (map, String.uppercaseString)
Op#onal<T>+Method+Chaininglet animalNoiseMap = ["cow":"moo", "dog":"woof", "cat":"meow"]
animalNoiseMap["dog"]?.uppercaseString // .Some("WOOF")animalNoiseMap["fox"]?.uppercaseString // .None
Op#onal<T>+Func%on+Chaininglet animalNoiseMap = ["cow":"moo", "dog":"woof", "cat":"meow"]
map(animalNoiseMap["dog"]) { count(filter($0, isVowel)) } // .Some(2)map(animalNoiseMap["fox"]) { count(filter($0, isVowel)) } // .None
Op#onal<T>+Pipeline
animalNoiseMap["dog"] // .Some("woof")|> (filter, isVowel) // .Some(["o", "o"])|> count // .Some(2)
Op#onal<T>+Pipeline
[2, 4, 6, 8, 10]|> (map, increment) // [3, 5, 7, 9, 11]|> (find, 7) // .Some(2)|> isEven // .Some(true)
Op#onal<T>+Pipeline
[2, 4, 6, 8, 10]|> (map, increment) // [3, 5, 7, 9, 11]|> (find, 6) // .None|> isEven // .None
Result<T>*Pipeline!// uses https://github.com/antitypical/Result
func escapeInput(string: String) -> String { ... }
func readFile(fileName: String) -> Result<String> { ... }
func processText(string: String) -> String { ... }
let processedText = inputFileName |> escapeInput |> readFile |> processText
Experimental,Forward,Pipes
|>> // apply as second argument|>>> // apply as third argument|< // apply as last argument
Benefits
• pipelines(are(about(composi'on,(encouraging(small,(pure,(reusable(func3ons
• fewer("temporary"(variables(intended(for(use(on(next(line
• data(pipeline(reads(like(a(nice(list
• code(for(handling(values,(Optional<T>(and(Result<T>(is(the(same:(avoid(if-lets(and(switches(and(without(knowledge(of(monad(kung>fu
Non$Muta)ng+Helpers
Pure%versions%of%everything%in:
• ExtensibleCollectionType
• RangeReplaceableCollectionType
• MutableCollectionType
• Mutable)dic-onary)stuff
Currying// curry the first argument at the endfunc map<S: SequenceType, T>(f: S.Generator.Element->T)(seq: S) -> [T] {...}
1...5|> filter(isEven) // [2, 4]|> map({$0 * 3}) // [6, 12]|> reduce(0, +) // 18
Non$Muta)ng+Helpers
Pipes&contains&curried&versions&of:
• map,#filter,#reduce
• ExtensibleCollectionType
• RangeReplaceableCollectionType
• MutableCollectionType
• Mutable#dic.onary#stuff