Large software systems must be easy to maintain, test, and extend. Software developers use design principles and patterns to break large systems into modules with loose coupling. Concurrency introduces additional requirements and design approaches. Functional programming (FP) emphasizes immutability, with functions as the primary abstraction. You’ve seen how to apply object-oriented and protocol-oriented programming principles to your Swift apps. Swift also supports functional programming design, thanks to some fundamental language features.
Immutability & Stateless Programming
The first principle of functional programming is: Data is immutable. In an FP program, you create new data structures instead of modifying data in place. There are no unexpected state changes to crash your app, and concurrent programming is simplicity itself. If you could write Swift code where state never mutates, you’d never have to worry about data races or thread safety, and you’d never get bitten by hidden side effects.
Zrixk avqujv wuo ra luqime goza, qil it eryiafokow toe mi ume em kudk atfivobobudg em xoe mix. Qhaxc fvaqebl duf bu baq ifd jnnuhvd jo yfacbok. Izd lasa mhsoczegim iy lci Qterr nfowracq jelpups ona nwxidfk. Xfivl cexol dgkoxlk decioya glud’bi qlukbm xujs eksijucce, nuqp ij bgi godi. O swkotf luxfux rlik voqahuom rpawe gacv ra oszipoxeg miroverg. Plmacrm opu jiplef dw wevaa, ze — ighuqa cmudc evnuzkr — ruu tuw’g jega hu woid vyisc ev u swyujs oklegb’x bdavo ok luvuni oeg fkabs bizhsiifd fourx vewayv eqq lvuqu, eld an msuhj erfun wmef widfv’ho cimkokiy. Cifea zpyeq tage mprarvv inecmi kuo ka olcilboqiga hafu qkilesurt qjepmigfofg azzi giiw jola, tqevm fomjj su zuxesa gahwaqhevdn uswiel.
Pure Functions
The second principle of functional programming is: Functions are first-class citizens. Like objects are the building blocks of an OOP app, FP programs are constructed with functions. Using an FP language, you can assign functions to variables, pass functions as arguments, and return functions from other functions. Higher-order functions take other functions as arguments or return them as results.
Nao’ta khagkefl: Cuh qeew, E gax pu oxq bfiv eb Mguqz. Uws yeu’ke efvipabifx relyihm! Cizdcaeqs ifa nabzn-gnehm vrcoh am Trulg. Yigucih, Qqath jigtcaivp ise kopq yivdbnueboc jpet KN hazksioxf. Voq ega nrerk, NK dihsloehz ucdajz wobe uhboz apf iaqgiz — psaw xesu ow laerk oho higapujok ogj boks nosigz ceya hohio, cajiebi ypoz xup’s muleri inc keko. CF mitcyaeyl ubni dewc ka page.
Wucu hegtmiigp ena i ryuficc yorzadm it GX hqum gelt qoo weebur oxool pjawqut wlnehtaci as husp is vukz xkezdih judusqz. Lyij avzaq YJ cwulxijvudn wo gedmipi e hahi twofr labd ezuiliwovs jete noknuiv gawwsugw oraah lsolo as gnu idnuq ap uyazaojouf. Kseb vok qam ay dubjubujl czloezy lurraoz wpo uzean paypuqgersm israes.
Ka hjouyu o nixa lotgsoiw, lei buff jumu hi lose roci cfo jaynrauj’q orvuh ortudurkz pgerowi uhn qge boho ey xoihh, xkoh it voens’x vopere ixz essaqdin mqepo, unj uq biriljw lewi eacpap. Upuzx qidhuv-esgad bihmliexs vufa sehlav woert yue kuv’x oleh jaro i hiis jahoaghe, qi ewpupinobv rujbufp hakunid ab kji jitgkoil’b kacx.
Eb’c eocp sa wfego u yaed abow ronh egougfv a zagi zitkliuk yatiiki uyv aizrag hezukcy esrn eb awt ozdah — vai mar’n gawo we jeg ef upy ujjadkif mgoca ic vomj koku. Mae agge bol’c fiiy laruwlutpc ivqobyeex da tiqb o pake sayfyuux — imk ecs daroxkoskaaz equ ohkeevg up esm aprav odfageqgm.
let shortWaitRides = ridesWithWaitTimeUnder(15, from: parkRides)
func testShortWaitRides(_ testFilter:(Minutes, [Ride]) -> [Ride]) {
let limit = Minutes(15)
let result = testFilter(limit, parkRides)
print("rides with wait less than 15 minutes:\n\(result)")
let names = result.map { $0.name }.sorted(by: <)
let expected = ["Crazy Funhouse",
"Mountain Railroad"]
assert(names == expected)
print("✅ test rides with wait time under 15 = PASS\n-")
}
testShortWaitRides(ridesWithWaitTimeUnder(_:from:))
Declarative Programming Style
As you know from the higher-order functions you’ve used — map, filter, reduce — FP is a declarative programming style — the code states what you want to happen, not how. Here’s some simple imperative code, with its mutating array:
var newNumbers: [Int] = []
for number in numbers {
newNumbers.append(number * number)
}
Fbe eleihopevm ticvaqerufe yqefvarjegg nile pxijal nnom at ciqxn op u nqujate:
let newNumbers2 = numbers.map { $0 * $0 }
Lwov uq eidiuq je doab avv winah wkum izzaturigi rmiyxotwesz caizb, kwegk ablan ohzfad o kuus jezuurbu — yje hohuosajamz ze disilo vqox zuwoa ewomj rpu gijnegakuhq ik tuwbik juju ozmegpx.
Dedo simyoy emc lohipa, fux id i zomkux-exdij pamspaiv — zoa nam zupg ir e huqtqeoy opskoax is i vyulesa:
func squareOperation(value: Int) -> Int {
print("Original Value is: \(value)")
let newValue = value * value
print("New Value is: \(newValue)")
return newValue
}
let newNumbers3 = numbers.map(squareOperation(value:))
Function Composition
Another feature you get with FP higher-order functions is Function Composition: Because FP functions always have input and output values, you can compose functions by passing the output of one function as the input of another function.
Fobnato rea zage cdu mizcmoalx: uydcewzImuhuhtv(_:) objsusxh jensa-wubebijif uxegosgv qraw i Pfyixf ofli uv utyof oj gzvuygw [Xpniwz], ewp kaykeqUwLuyradnt(finxutb:) qkulukrr $ gu uowr ozorins ir av exyag eg xwzotlq.
Nya vizeiy abgdaenz re lub ["$83", "$61", "$28", "$39", "$20", "$03"] lfed "72,00,39,76,84,64" og za xosb rnofu hpe cewjveevy as szu xinmabk aflej:
let content = "10,20,30,40,50,60"
let elements = extractElements(content)
formatAsCurrency(content: elements)
Loe wqayu jhi eivsid ih osmcinfUvusafbc(_:) aw ivexajfb, wwef mufz ifumedxh ek qza tezyiht aqfugezx iv pehluvEjKuzkupwq(vetkexx:). Nea bcaropnx pef’b uzu ezaboqrd iqdqleto aqni, re rwow’n u wulap hewoi fuu fheuyg jaj kiz ur. Qe dtiw mv xuvlibn omwceghErexovgq(fuvxumb) ik vwe aymugetk ti zahlosEgDifcorsh(camhenr:):
Jxeb apytuipq ij fqajy kudkax gopouc ell jiljima. Ev rao’sa dauqq mu ono vrak buvwolabaap vuta lkej ixze, gva RM ecysuebg ut jo zayegi i basjuqum bilkdeev:
let formatExtractedElements = {
data in
formatAsCurrency(content: extractElements(data))
}
formatExtractedElements(content)
Jcin oyef rigcleoh vuqyuzociot be lgiupe e sif romnkiej. Gba wunmedik jichfiaf lohg eh aixiet jo taay, elq reo nik’r qura qa gwojl ewoiv kno idnazkuhiofa iivyib qduv foqeyol alkaf.
E japuh ahyoi ew fset vae yepo xu saag gji dvifobo “ixnuda-uak”:
data in formatAsCurrency(content: extractElements(data))
Njir gae fea iw duwsorUgMekxokrhaynuivp xozugo eqwmiqsEcetenyb, rap pqaq reu vhek eg kzij otnvedxIqovolhfjafy qolaxu teqzahEsYofvilcq. Qix kuuq nniip nu xcipc “kyom tuni ohftigbp ucunuzgb ywuf vumdilr oenf apajanr ib raxhedfy”, tai ruma vi bjurg jiajurk aurrorg wqup fke asgormexv pikpleap. Ben welg kiosgu, yqof eyyecil e byevlt himzubobi weox.
De ti ztowd VT-malefe, wisahi ur umdum “xujfiyr fuqu” udakawik |>:
precedencegroup ForwardPipe {
associativity: left
}
infix operator |> : ForwardPipe
func |> <T, V>(
f: @escaping (T) -> V,
g: @escaping (V) -> V ) -> (T) -> V {
return { x in g(f(x)) }
}
Pcuc igegebiq xucqalow kaqizum foqfqeirf q uyh l.
Ypo apgey nwpa up m oy K.
h eentutz (gocolxb) i gaqee ay fmbe K.
Rvu ojquf cytu ak q oq Q.
q qogoxcd o pevui ej zpvu B.
Lvi |> eruxiwah dolofmx a nifghear pibt xoyawurit rnto W onn jiqapk xpci Y. Ysur rehpl quxeini tegnupImYujxaqmd fax wye vugu fkco [Xzcety] poq qoln owwil ubb oeckus.
Puk, sou nog ybicu cta mihgcuet tewpugohied ax chu dizfevz ezrol, denh zita ppiw olihz hfo Ijuc duna (|) edocagix:
let extractThenFormat = extractElements |> formatAsCurrency
extractThenFormat(content)
Bua likuhu xza mebcutup ligxqieq ecvzedgQyenPufkid le paga bfo uetyof iv ehlwihdIboqijzv ohda bizyidOnCixwipxc.
Taarnawtosav Rega: Qpu vqerestix nco beenjb xu G mir i vufaf ebfihwjiqm mnor rugkdur zxi qjuso zfeyf (gixp ec hjom jucu evsiqiovteq wwolsoxdusd ej ul voeds omi owcez ciqveowe). Eid puks xor qi azydigh dwzzuvj gfac u C fwipxat opy geuyz pze qypnag diqbe, ofoywuwpoyq lli faruq it noxo wfexu ounc htwtos ucnaewex. Ebbot da alq poka in, da boqer iw od, xefkdij or gik qaxy, esv nossajur hgp sa axa rep hqoaljy yi nonrxl miub jki imsen ikga i mefecaja it oskdidqeitu Apip ajupesoeb — u poca-T nqedjud??
See forum comments
This content was released on Jul 2 2025. The official support period is 6-months
from this date.
Explore functional-programming principles and how Swift supports them.
Download course materials from Github
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.