Currying er en teknik i matematik og datalogi, hvor man omskriver en funktion, der tager flere argumenter, til en række funktioner, der hver tager ét argument. Formelt omdannes en funktion f af typen A × B → C til en funktion curry(f) af typen A → (B → C). Ideen går tilbage til tanker om funktioner og argumenter hos Gottlob Frege, mens Moses Schönfinkel og senere Haskell Brooks Curry udviklede de formelle metoder (bl.a. i forbindelse med kombinatorik og type- og lambda-kalkulation), og teknikken er derfor opkaldt efter Curry. Currying optræder naturligt i lambda-kalkulationen.
En vigtig sondring er mellem currying og partial application. Currying er en transformering af selve funktionssignaturen (fra en flerargumentfunktion til en kæde af enkelt-argumentfunktioner). Partial application er derimod at give nogle af argumenterne til en funktion og derved få en ny funktion med færre argumenter.
Eksempel i matematiske termer:
- Ucurried funktion: f(x, y) = x + y, med type A × B → C.
- Curried form: f'(x) = (g hvor g(y) = x + y), altså f' : A → (B → C). På denne måde kan man skrive f'(x)(y) = x + y.
Eksempler i programmering:
- Haskell (funktioner er som regel curried som standard):
add :: Int -> Int -> Intadd x y = x + y
Her eradden funktion, der tagerxog returnerer en funktion, som tagery. - JavaScript (ikke curried automatisk, men kan skrives manuelt):
const add = x => y => x + y;
Kalder manadd(2)får man en funktion, der lægger 2 til sit argument.
Hvorfor bruge currying?
- Partial application: Man kan nemt lave specialiserede funktioner ved at give nogle af argumenterne først.
- Komposition: Curried funktioner gør det enklere at bygge nye funktioner ved sammenkædning og punktfri (point-free) stil.
- Teoretisk enkelhed: I type- og lambda-kalkulation er det praktisk at arbejde med enkelt-argumentfunktioner, hvilket gør formelle beviser og transformeringer lettere.
- Genbrug: Mindre og mere fokuserede funktioner er ofte lettere at teste og genbruge.
Begrænsninger og praktiske overvejelser:
- Currying kan medføre ekstra funktionelle slutprodukter (closures), hvilket i nogle miljøer kan have ydeevne- eller hukommelsesomkostninger. Mange sprog optimerer dog almindelige mønstre af currying og partial application.
- I nogle tilfælde er en ucurried (flere-argumenter) funktion mere naturlig eller mere effektiv, især når argumenterne allerede leveres samlet (fx som en tuppel).
Formelt kan man definere to operationer, curry og uncurry, som på passende typer er hinandens inverse (op til isomorfi):
curry : (A × B → C) → (A → (B → C))uncurry : (A → (B → C)) → (A × B → C)
Afslutningsvis er currying både et nyttigt teoretisk værktøj og en praktisk teknik i funktionel programmering. Sprog som ML og Haskell behandler funktioner som om de kun tager ét argument, hvilket betyder, at currying ligger tæt på sprogets grundlæggende funktionsmodel. I andre sprog kan currying emuleres og bruges til at skrive mere modulært og deklarativt kode.