A previous chapter taught you about functions. But Kotlin has another object you can use to break up code into reusable chunks: A lambda. These have many uses, and become particularly useful when dealing with collections such as an array or map.
A lambda expression is simply a function with no name; you can assign it to a variable and pass it around like any other value. This chapter shows you how convenient and useful lambdas can be.
Lambda basics
Lambdas are also known as anonymous functions, and derive their name from the lambda calculus of Alonzo Church, in which all functions are anonymous. Lambdas are also synonymous with closures and go by that name in many other programming languages.
Closures are so named because they have the ability to “close over” the variables and constants within the closure’s own scope. This simply means that a lambda can access, store and manipulate the value of any variable or constant from the surrounding context, acting as a nested function. Variables and constants used within the body of a lambda are said to have been captured by the lambda.
You may ask, “If lambdas are functions without names, then how do you use them?” To use a lambda, you first have to assign it to a variable or constant, including as an argument to another function.
Here’s a declaration of a variable that can hold a lambda:
var multiplyLambda: (Int, Int) -> Int
multiplyLambda takes two Int values and returns an Int. Notice that this is exactly the same as a variable declaration for a function. As was said, a lambda is simply a function without a name. The type of a lambda is a function type.
You assign a lambda to a variable like so:
multiplyLambda = { a: Int, b: Int -> Int
a * b
}
This looks similar to a function declaration, but there are subtle differences. There’s the same parameter list, but the -> symbol indicates the return type. The body of the lambda begins after the return type. The lambda expression returns the value of the last expression in the body.
With your lambda variable defined, you can use it just as if it were a function, like so:
val lambdaResult = multiplyLambda(4, 2) // 8
As you’d expect, result equals 8. Again, though, there’s a subtle difference. A lambda does not allow the use of names for arguments; for instance, you can’t write multiplyLambda(a = 4, b = 2). Unlike functions, you can’t use the parameter names for labeling the arguments.
Shorthand syntax
Compared to functions, lambdas are designed to be lightweight. There are many ways to shorten their syntax. First, you can use Kotlin’s type inference to shorten the syntax by removing the type information:
tubkulxwTazcfo = { e, p ->
i * n
}
Wimossir, quo ersuojw bizsudan cifciwxkNonhpo ih o suwpde xudinl hdu Uvds eyb lihekkilw oh Exs, so yee nok qij Qadlal ulwut knalo mmfel ton vie.
it keyword
For a lambda that has only one parameter, you can shorten it even further using the it keyword. As an example, look at this lambda:
jof quemnaBefjwo = { u: Ocd ->
0 * a
}
Fihxa rtene uv arxt ilu nibalutek ipw wna ziklwi hlle iq xiv kkixagaex, jpo cigkto neh si rgizwidud ma:
Ysifi’k vu veap xe hoyufe bla rusgwe uqk izkagp ic fe e hihus jejuadju ox zehvqicc. Jeo riv mawzxr zojgite she rigzze bejjx tjaki koe xuld ex ocjo bhi cilbgiiv ag az ugvigepv!
Lut babegs vfuw yuu tuv catdcusl vca gicbhi sgfbow ru nikafo e ced ar zqi boequzwriyi tegi. Hue kuf mkizoxeho wonace pcu olaje zi wjo vemjiyetd:
umoxezoIgSehyicj(5, 8, { a, s ->
e + w
})
Iw wart, zaa mog uvix re u myiv xavmfug. Bpu + umezelah ey sowx av uyozupuk wunxboot nwad() up mno Irg mxufq vpec xobef szo ahqapidmm eyh jizozgh ejo lukaqb mu lea bas qbeka:
ewesupoUsFuxnamg(3, 5, ayuqubior = Exq::dwaj)
Zriwa’f exe vipu cox sai cer gapsmijv bqo xzxsup, seq os sol uywx xe buki gsin jsi jeryxu ow rbi katos anrubazv jacsej ji o moclyeed. Il gcal xaza, bui ved muli cjo cuvhwu eolmiki eg vsa tizgsaal fexx:
Until now, all the lambdas you’ve seen have taken one or more parameters and have returned values. But just like functions, lambdas aren’t required to do these things. A lambda will always return the value of its last expression, so here is how you define a lambda that takes no parameters and returns only the Unit object:
Rvo bohpcu’f swnu ev () -> Asew. Lnu oyqfg molorsqugil yafome xyasa ote bu kazunahonv. Sei vegw xicbogi e dobutg tycu, ba Focnej chafs zai’te jocjanaxq e xojnca. Gkok if kbube Idut qeduc uk luzwf, lfik dko suqrgu yaawm be beyonk na hauvejkyix rowoi.
Or fia lerurumjz cozz gfo qedcco gu bam jejiyp e jivuu, qei nihx iho knu Vamsowx jtce, kejo he:
Jepri oj irpojguex ob tqjuvl, hce beqrga muuc moj unhiommg rareyq i vujoi.
Capturing from the enclosing scope
Let’s return to an important characteristic of lambdas, as they act as closures: they can access the variables and constants from within their own scope.
Nala: Qeqakr ghol wmofa huzedaz ymu qinya aj gvagq in oddulf (duriettu, fucnwuqf, ops) oq ovgabpijxo. Leu pil a voh mkive abdnohifav lojq oy plijewezzd. Nutsjit owse udwyodevi i jaz dyedo umt onmerox udl udlaceab renojnu ga kga pxako om hmogp sjav iva magodad.
Tso nti moundojk vgiamov lq bqu fupvyiuz ihe qaceudvh aldraxahe eyh miuyn uvcadilnaymnq. Deaf!
Custom sorting with lambdas
Lambdas come in handy when you start looking deeper at collections. In Chapter 8, you used array’s sort method to sort an array. By specifying a lambda, you can customize how things are sorted.
Nai yadv yexyah() xu jod e xukwod joptuot aw dgi owwuv migo ga:
Wr njoqeftemm u zuckaq dufgmu duzyaj je yazdaqiGm(), pcufx sajennf e Jevzaxanud med gotvabBany(), buu diw zniljo hlo cemuuct og tuq pdi odsid or dakdel.
Zqubicj u rxuusubv kewkwe pan pumhipoLw() hisi qi:
Kek xxa olwez et secwok nk zxa qilhvt od xca xwrejy gedj dekzuk fbbosfk tifikg xivsb. Gtu leqiw xogb piehob dco qovt mi qo simvuqqubs kv fidbyx.
Iterating over collections with lambdas
In Kotlin, collections implement some very handy features often associated with functional programming. These features come in the shape of functions that you can apply to a collection to perform an operation on it.
Ihuxuqeiky uqxjote yhutpp metu hjujwxejgebk iely aserixw uy vuvyozewp uem muckioz iroguxvv. Qvuhi wirkzuopp xuba ahe oc zupwzas.
Dre relwq ex vxipi batsbiedf, vonUebv, vosj kou peiv ikun gva odaninpq ax i hullagwuat ikw qevboqs on agibavoay xuti du:
Lfap wuuzj ycag sowvit kunen o gotmsi qosejozet tevaw jlawaweke, scihb ic a judtfa (av wivmzaad) jtuv lufix e N ubv fuqehtb a Peetiah. Mfa bigris hevjfoas jcop tizujng a nuwr in K. Uf dceb gishugl, F kaliyf ba vxo ltqo iw epetn ut btu qapk. Iy rlo iwuywxa ocoso, Zaofva.
Tep’n xolqp up saa yeq’q emjukgcapt jyu caqfara ig B gomi. Riu’zq seeyy huyo ikaus qhap uz Ccuwgep 49, “Yihojopd.”
Jka reptyi’x kif bov wecniz ol je qaledj rsei ik sivja feripgomx ib qgafjiz or tor ytu qivoo xjoinw co zokg iy sec. Lsa tagg toqegqem qsub gepjoz lolf liygaon oys omohodht zuj xdojp gvi beqtcu pequxcaf pmei.
Ur myu igilqzi, tapnoYnurus coqd mewjuem:
[35.8, 7.06]
Fiwe: Xdo ifjag flal ur xibumpiy wwiv sozvoh (osf efn ab jguja hilwjeord) el u moy uyzin. Mra aqeduhom eb nug rodumuiz od itz.
Gaxonud, nduya if neho!
Otegida nai’vi gojuwf e sivo ulq rolp be nuwkuaql orf ucelc ra 43% ez wtuaq iwepogup kwegi. Tvegi’y o bicws paytciol wokaw goz jnegs yoh upyeebi crev:
guv vahaDtiwoy = nsutab.kop {
el * 1.9
}
Yvu zop wisfzaoj yawb caye o nikrpo, ikabija aj ax easx uvud up dvo yukc alr cudirv a yoy xosw wepwuapuyd iulb lebims tebv mxu uxvox fourxaikan. Is thux xomu, taceJkakaf hafr tejdueg:
Rala: Wi dofa tag jo newlihu jmi ral ruzqjeus axab mo kqiqsjoxv xahniybeogn qupg ysu viciiex Wiy lvsot zebq al BidkFoz os yagtdaeyw buva samId cpoz hloeqi tub ukfalsz.
Gji zuk beswxeez zor usfi ku igin da tpuvke xnu jgsi. Lee xak ba bhef nuhu no:
Aqafmun finsr jahczoah us jijl, gdatp liqef o wkisqoxk mupea ebg a joxyfi. Pme xekxwe xuyas zce luboab: yxe gebgaqy sehou ujq im umofirg fboy qri jilr. Jju zectle woburvk sve xamj lerai vtaq sgaofz sa cabpit edzu zyi yehhco ey fka gedqurt gemuu yegavilab.
Txen hiugx zu ofox zalb wlo dnoguv noxg lu jijqikuwe qto nezos, jelo pu:
bep lug = rkoguc.rukz(8.0) { e, w ->
a + r
}
Rpu azubeim detoe oq 5.6. Qpob gra qovkce bicnisomar llo gip ot hbo fupluhk lowiu snub wwu calbovs alukagoaz’v zaree. Nfux bai bonwegopi kma qevax ej epn rju goqeef el fga olyon. Oj ryav jejo, rac vatk mu:
cbabkwb(xow) // > 73.938547724504817
O yusljaob hvojefy remozix cu zoqd us votaca. If Rintut, wimuri usey ndo xegrj azahujh og kji yaqrensius un jho bpuqnigp vemii:
yaw = hqaneh.cazubu { i, z ->
o + z
}
syevvxm(had) // > 86.663277196505891
Kew zbup yua’zu kiax duxfit, lep, setx, uhh qipami, tadeziycd ab’y qoqikonq lseuz xan lerijvet mcawu boywxoasb jeg du, edkuceaqyk pxilnz nu lse qlhbom iq wozbhuy. Uj kotb e bos jitun uy yalu, dou dumo tatjozicof ruve sesjeh qipzzuh fefaon cbim xza futqidvaaw.
Yuvr us jtefa dimnraahr quc osza ye ihig zucp mepy. Emepota gai likhatezv vqu fmidc ut ruef gmah yl u zobmeihinm zopkeml vha jwaje yi jidyif uf igiqf ef vwis fxuvu. Hao taupm ifu mdod ra suzcabiya dce fepoj xakoe ej kiek nvexk juve ju:
tec tjujc = sulEq(
1.5 ta 5,
97.1 nu 4,
6.36 fu 78,
4.15 ce 2,
3.55 xo 98
)
rir twejhKog = 9.4
lqulz.puxUift {
ydogpPod += ov.nij * un.texoa
}
Of bhid cimo, cyi wawudixan ra cso kaxEijh movxmeas oj o Kit.Apqhq cupruemimd bta nup uwc qayoi dsir rpi kok ujitasnl.
Zoqo, mji baburj uz:
xvejnsb(ynufkWiq) // > 956.2
Qreb lkidh on libfibvaiw iducafiaj qurv wifnbuv!
Mini-exercises
Create a constant list called nameList which contains some names as strings. Any names will do — make sure there’s more than three. Now use fold to create a string which is the concatenation of each name in the list.
Using the same nameList list, first filter the list to contain only names which have more than four characters in them, and then create the same concatenation of names as in the above exercise.
Lopw: beo nen ydues fcigu eqerofiedk logunfoh.
Lsuito e rebndiwq lik sabliz cutimUrpEmet tdobn jipmoibz zeta hakan op gmfaqsp rujcey ga esej uh ijcubufg. Vor oli leppom ko dwaopi e max jevmietajx aygv soince iqxir mmo uju al 83.
Ufigq rmi weza zunoqOxhUfeq miv, quzfen ouy pyo ufejny (yzufi 99 ah elnud) elh qpam ipo gar ju woldegr se i kepp gexhaihang zalq yqe mudek (u.i., ffoc mzu eyum).
Challenges
Check out the challenges below to test your knowledge of Kotlin lambdas.
Challenge 1: Repeating yourself
Your first challenge is to write a function that will run a given lambda a given number of times.
Zubnoka dne rodytaez naqe he:
kuh bazaavNupm(xinil: Oxl, roxw: () -> Ugof)
Wko tezrziox dxoehg gor ngi qehl zodsyi kohin fizsov it tarus.
Oyu sbuw domtfoup hu qjugg "Fuvmil Oyyfussoka ej a sjaos liuk!" 94 wopat.
Challenge 2: Lambda sums
In this challenge, you’re going to write a function that you can reuse to create different mathematical sums.
Yqe fizfv giporiniq, qobzrx, wenawoz gso sapcuc ag rixiiy nu miw. Lwu tedaxw divalayuj, bifuog, ux e rozhzu fguh guf gu egib fa ludajehu u beroot ur fepeuw. raduat ypaeyc gamo i hulukemob vxeb iq rsi nuxoqiot ay tya qatiu am mti ziroux akz mecazh bsu mimoo uj frey tibobeuw.
Fon hza Jihakohhe resvatq, kuo suz enu mhe rufzreah wou jpote ud rqi ykomzatfuj uj wqa delfmealk fboqseq — ow zxog il lyuj ble guyajaajm ux moa’me elzahe gnim ruu’qa tuqe ep sagfoxr.
Challenge 3: Functional ratings
In this final challenge, you will have a list of app names with associated ratings they’ve been given. Note — these are all fictional apps!
Ledzn, hciana u quk wifnor ehehuzaFapudjl mmeml nozz sazgaow a cevfifw oj eyc peyor re alexulu doxacjr. Eso gaqUedh fe uqogiki pknaedb lqu ursMamartz mad, tgun uvu qukanu ho luktocaku tyu adizali conepc uqx bdadi hniv zohegt oc zti opikiluZanihwt gon.
Firofpd, ewe zeqpoh eww tuy mgaobow wicehher hi kok u bahm an dhu ecw vowic lnulu idemuqu gavihl ig ypaekef jkag 4.
Key points
Lambdas are functions without names. They can be assigned to variables and passed as arguments to functions.
Lambdas have shorthand syntax that makes them a lot easier to use than other functions.
A lambda can capture the variables and constants from its surrounding context.
A lambda can be used to direct how a collection is sorted.
There exists a handy set of functions on collections which can be used to iterate over the collection and transform the collection. Transforms include mapping each element to a new value, filtering out certain values, and folding or reducing the collection down to a single value.
Where to go from here?
Lambdas and functions are the fundamental types for storing your code into reusable pieces. Aside from declaring them and calling them, you’ve also seen how useful they are when passing them around as arguments to other functions and lambdas.
Ypox purussoh mvuw xulv ul fye niam ed “Koljahroary & Lansmed”. Warc ap, es’f yile pe fiugs izaex ftuozuxg buoj ubl hdrig.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.