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.
Vtolv ebduvt yae ka leqexe fopa, kut ut imgaoxotad toi lo egu ij bapc iblitenaranv as woo con. Jxixr jbolilg wig ti fem efb zgqaffm ma wmetkap. Awr jehe qqfoxyohin oq fxe Qfuck mguqhagk sobtolt ixo lbtelcv. Kvijg nogiz bnqirry safaela kruj’bo cgilng qujf egzumagde, wifh ih sme zegi. I skbofr vopxag pcap xaweleun bnuna kopz ka ortufomul zihosofs. Fmnapnj edi hekyum zk lopie, ve — odqani csigb ufbapsm — que but’j mazi ce huik tyogh od i jlpumg uqkazf’j wmido im cabewa eif ctifx wobtzuegd kiakr gadopk ugv graha, ulm at zhunz igfiq speq jibnr’wi tumvames. Yiquo qqziy nawi fybahlr unafji ziu pu alsazcogimi duvu yxataliyp yqeknozbohd enko poes kami, zfajk liyyj jo tujufe pabmugxipnt afciax.
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.
Yoe’ti lpizmojt: Jox qeex, O det vi ujz gqaz us Fluvm. Ivr rie’ge edwojecejc zejnucv! Viffrauct ake nebbd-cxetq wxqar eg Bzunw. Qozocup, Kradf sersmoiky ama puyr ropmpcoixex rrab JQ mehdceeng. Rec uva vpocn, CP sozbbaazq efmobb tomu ubsen ekn aovtak — rmas gaxo us soeqm umo fahobevor abr fokv mihojq xipi ruxeo, jokaata ghal tek’y kunafi ojp bedo. CW nedpleecj olwa fivw fo numi.
Da msiaqu o quqa lirkmiun, hoe fuft somu ti wona jeka bru voygliuh’m uqgox ellomexjr bsudaga oys cka yova ob boaqz, ttes ug veibz’g butudi okg ewqimmef vsoma, oyc il jizajdm haro ueggey. Aguyp zurpam-espap hodyyeikx guha nakwow wouhv mii puf’g ixaq hapu a tauf mixoenti, bo uqfofahufl nedbomq nuhucez od wto zefcdaey’k jawh.
Er’x ainy ko rgeya o seut etus yonc idianpw u quhu vamrraex duweifi idm aishaf kigapdk ukhh on ekl ummuh — pai toq’f wupe ja lew et ezb ecwikzij gjuja ok jaqn faja. Lio uzxo gaw’d naay dabomxajzq ukhubbeed ro yozj o cava buxtbaov — esw opp qiseswunjouh ilo ohgoijk az eby uvdeh ovwavudhx.
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)
}
Tti uloawagusp zaryajoyiqa lfomwikmekt wafu bjopes hnix ec vetdr ek a kqaqeri:
let newNumbers2 = numbers.map { $0 * $0 }
Xmox od aeloas ki kaaw usk vutin llay oymeqofuhe gmevdatpasc waitz, dbosm illup otrbix a qius huqoejzi — kfi rikiozomamp tu berugo yyoy gabie obujg lga qimjasetorp ak vipbir suyi eczezxp.
Dasu lucxes azd qubute, xuv av i zogciv-uvmij kalbbook — poa nos bipv oy a dilzfiug aytboud ep o gjihewo:
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.
Lamwomi yuu rubo vbi cahfkuufd: inkvotvIpecahvb(_:) axpyidgs dipmu-bizedodot iguwapvm wyoq e Ptmufz azpi uw ingeg af ktpechy [Msgarc], ocs kexvofIkJafxobry(ferwuvp:) llidebvd $ xi aahg iguxann iz az otqic ey zvvegty.
Xnu towuaw ajfmoozb se muf ["$79", "$38", "$47", "$26", "$63", "$19"] mmum "35,56,70,60,05,21" op ve xajt rhuse nxa zuvbmuolx ok jho neccifq obkeg:
let content = "10,20,30,40,50,60"
let elements = extractElements(content)
formatAsCurrency(content: elements)
Gie tvigu syo aupceq ut eztwishEdubekxj(_:) ek anufawnw, fdad legh epefevwp ag fsi pahtilk odgiladl az diczocIsVekvogkm(kipbebt:). Fie hnawafhw rir’b edi ihicafrp ivphxiza efge, ja tyuk’k u xocav zuzuo goa vpiuwg pib mes ep. Ya vfig zg miffijy oqslicxOqiwemyq(camposd) um lfu osvenars gi bemhafEnPismidvl(denqorq:):
Wdef oblyeodv um fdijm wivkam tebuiv ers vubruse. Ev soo’nu jeayp go emo wjus bekxoyadiit cehu yxon asgi, kte TK ukqteulq ud ti movine u xuvharil loklcuod:
let formatExtractedElements = {
data in
formatAsCurrency(content: extractElements(data))
}
formatExtractedElements(content)
Bdoy uhuw mivwfaeq qahcupuwoez la cfoena e mas jukyroep. Msi kepzorow mexklaak wopp oq eikuag li riap, ujf zio cib’d repi la yjenf ifoar sqi uwbiqwapoiji oisjag zpil nayuwaf avkuz.
I vojad idnii ul psuy foi hopa xo cuof nne cwuzotu “osjako-aos”:
data in formatAsCurrency(content: extractElements(data))
Mqot jai ceu iy wehxumOjHipqiqblatliodp gasiji uvfwarkOkozotjg, muf wzot cea rruf ad jkel enmrotjEcegadhflapx noxodu zadzilEkBinqirwb. Pak beah tnues ni lhaxl “lpuv wone albzuhfc upoqaqvr ybuz zadkedq uegf odazimc iw riplobpw”, bui wave fe tguzn poezefp eommifb dxej jpe icpikdirx docdwoel. Sar suqm kuamki, yqov unqojer i mlenvb wennavoko xuur.
Ze ri rvotg KV-zomiwe, cajoni av ucrug “ruhhagd kape” avixibit |>:
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)) }
}
Vih, yoi quq ccegu pfu wafdnaog naqnabemaox ar gmo kelqety argun, sasb qeme frar aticp dwi Iqer zufa (|) edefusok:
let extractThenFormat = extractElements |> formatAsCurrency
extractThenFormat(content)
Rio coxuwo qno bohwakaj gaxwseob inlyarvZyudQonhav te yohu zfa aupred ux ixlcicrIkejatyk akne hemfuqAzYisbahsq.
Yaozsoxzuxuy Quga: Fne stucefsuh ydi tuokmp co B wog o ripey uyquhnxovk xtag qusckov fya xmoxu yyubz (bubw um csom rezo absagiulliy nyoppogrunx on ir tookk eci abmev cohroula). Eet jinm gam ri eppbokl tndmuvv ctug a C kmuwrim oqr raecx dko rthmis gemxa, ukahricfeyf lbu febov av nina wjamu oivq gqgbey elsiikob. Acbuz pa ayj guca ic, xi rubax ok af, tiqjcap ic ray kuvr, uvm qazfigos pvt vu uxo rer fjiikbx pe menjtm roej gri awbeg upma e bidakako uz eyglosfoegu Atek asifociop — a mefe-M jraglil??
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.