Prijeđi na sadržaj

Anonimne funkcije

Izvor: Wikipedija

U programiranju, anonimna funkcija je funkcija definisana tako da nije vezana za identifikator. Anonimne funkcije su cesto:[1]

  1. argumenti prosledjeni funkcijama viseg reda, ili
  2. se koriste za konstruisanje rezultata funkcije viseg reda koja treba da vrati funkciju.

Ako se funkcija koristi jednom, ili ogranicen broj puta, anonimna funkcija moze biti sintaksicki "laksa" od koriscenja imenovane funkcije. Anonimne funkcije su ceste u jezicima funkcionalnog programiranja i jezicima koji podrzavaju funkcije prve klase (first-class funkcije), gde ispunjavaju ulogu tipa funkcije kao sto literali rade za tipove podataka.

Anonimne funkcije je uveo Alonzo Cerc kada je otkrio lambda racun 1936. godine, pre nastanka elektronskih racunara, kada su sve funkcije bile anonimne.[2] U nekoliko programskih jezika, anonimne funkcije su predstavljene kljucnom recju lambda, i anonimne funkcije se cesto nazivaju lambdama ili lambda apstrakcijama***. Anonimne funkcije su deo programskih jezika jos od nastanka programskog jezika Lisp 1958. i sve veci broj modernih programskih jezika podrzava anonimne funkcije. Takodje anonimne funkcije se mogu posmatrati kao forma ugnjezdenih funkcija.

Upotreba

[uredi | uredi kod]

Anonimne funkcije mogu biti koriscenje za funkcionalnost koja ne treba biti imenovana i za kratkotrajnu upotrebu. Neki bitniji primeri su u koriscenju closure i currying funkcija.

Koriscenje anonimnih funkcija je pitanje stila. Njihovo koriscenje nikada nije jedini nacin za resavanje problema; Svaka anonimna funkcija moze biti definisana imenovanom funkcijom i biti pozivana imenom. Neki programeri koriste anonimne funkcije za pisanje kodova koji se nece izvrsavati vise puta, a u sebi sadrzi veliki broj jednolinijskih funkcija.

U nekim programskim jezicima, anonimne funkcije se cesto implementiraju za veoma specificne potrebe kao sto je koriscenje u obliku callback funkcija, ili instanciranje funkcije za konkretne vrednosti, koje mogu biti efikasnije, citljivije i manje sklone greskama nego imenovane funkcije.

Kod u sledecim primerima je napisan u jeziku Python 2.x .

Sortiranje

[uredi | uredi kod]

Kad pokusavamo da sortiramo nestandardnim nacinom, koriscenje anonimne funkcije u komparacione svrhe moze biti jednostavnije od koriscenja imenovanih funkcija. Vecina jezika nudi genericku funkciju koja implementira algoritam za sortiranje koji ce sortirati proizvoljne objekte. Ove funkcije obicno primaju proizvolju funkciju poredjenja koja prima dva proizvoljna objekta i vraca vrednosti manje od 0, 0 ili vece od 0 u odnosu na to da li je drugi prosledjen objekat veci, jednak ili manji od prvog prosledjenog.

Sortiranje liste stringova po njihovoj duzini:

>>> a = ['house', 'car', 'bike']
>>> a.sort(lambda x,y: cmp(len(x), len(y)))
>>> print(a)
['car', 'bike', 'house']

Anonimna funkcija u ovom primeru je lambda izraz:

lambda x,y: cmp(...)

Anonimna funkcija prima dva argumenta, x i y, i vraca poredjenje izmedju njih koristeci ugradjenu funkciju cmp().

>>> a = [10, 'number', 11.2]
>>> a.sort(lambda x,y: cmp(x.__class__.__name__, y.__class__.__name__))
>>> print(a)
[11.2, 10, 'number']

Closure

[uredi | uredi kod]

Closure funkcije su funkcije koje imaju vrednost u okruzenju koje sadrzi 'bound' promenljive.

Sledeci primer povezuje promenljivu "threshold" sa anonimnom funkcijm koja poredi ulaz sa njom.

def comp(threshold):
    return lambda x: x < threshold

Ovo moze sluziti kao generator funkcija poredjenja.

>>> func_a = comp(10)
>>> func_b = comp(20)

>>> print func_a(5), func_a(8), func_a(13), func_a(21)
True True False False

>>> print func_b(5), func_b(8), func_b(13), func_b(21)
True True True False

Bilo bi neprakticno kreirati funkciju za svaku funkciju poredjenja i moze biti neprakticno cuvati vrednost po kojoj se poredi za dalju upotrebu. I pored razloga zasto se closure funkcije koriste, anonimne funkcije su entitet koji sadrzi funkcionalnost koja vrsi poredjenje.

Currying

[uredi | uredi kod]

Currying je proces promene funkcije da bi bilo potrebno manje ulaznih vrednosti (u ovom slucaju transformacija funkcije koja izvodi deljenje bilo kog celog broja u onu funkciju koja vrsi deljenje sa skupom celih brojeva).

>>> def divide(x, y):
...     return x / y

>>> def divisor(d):
...     return lambda x: divide(x, d)

>>> half = divisor(2)
>>> third = divisor(3)

>>> print half(32), third(32)
16 10

>>> print half(40), third(40)
20 13

Koriscenje anonimnih funkcija nije cesta kod currying tehnike, ali se moze koristiti u te svrhe.U primeru iznad, funkcija divisor generise funkciju sa konkretnim deliteljem.Funkcija half i third izvodi funkciju divide sa fiksiranim deliteljiim.

Funkcija divisor takodje primenjuje clousure tehniku tako sto vezuje promenljivu "d".

Funkcije viseg reda

[uredi | uredi kod]

Python 2.x sadrzi nekoliko funkcija koje primaju anonimne funkcije kao argument.Ovaj odeljak opisuje njih.

Map funkcijavrsi poziv funkcije nad svakim elementom liste. Sledeci primer kvadrira svaki element u nizu anonimnom funkcijom.

>>> a = [1, 2, 3, 4, 5, 6]
>>> print map(lambda x: x*x, a)
[1, 4, 9, 16, 25, 36]

Anonimna funkcija prima argument i mnozi ga sobom (kvadrira ga). Po misljenju kreatora jezika, forma iznad nije preporucljiva, vec predlazu sledecu formu sa istim znacenjem a bolje se uklapa sa namenom jezika:

>>> a = [1, 2, 3, 4, 5, 6]
>>> print [x*x for x in a]
[1, 4, 9, 16, 25, 36]

Filter

[uredi | uredi kod]

Filter funkcija vraca sve elemente liste koje imaju vrednost True kad ih prosledimo odredjenoj funkciji.

>>> a = [1, 2, 3, 4, 5, 6]
>>> print filter(lambda x: x % 2 == 0, a)
[2, 4, 6]

Anonimna funkcija proverava da li je prosledjeni argument paran. Isto kao u slucaju sa mapom, kod ispod je preporucljiviji.

>>> a = [1, 2, 3, 4, 5, 6]
>>> print [x for x in a if x % 2 == 0]
[2, 4, 6]

Fold/reduce funkcija prolazi kroz sve elemente liste (obicno s leva na desno), i nagomilava vrednost pri tom prolasku. Cesta upotreba ovoga je kombinovanje elemenata liste u jednu vrednost. Na primer:

>>> a = [1, 2, 3, 4, 5]
>>> print reduce(lambda x,y: x*y, a)
120

Ovo izvrsava sledece

Anonimna funkcija ovde je mnozenje dva argumenta.

Rezultat fold funkcije mora biti jedna vrednost. Umesto toga, i mapa i filter mogu biti kreirani korisnjenjem fold funkcije.U mapi, vrednost koje je nagomilana je zapravo nova lista koja sadrzi rezultate primene funkcije na svaki element originalne liste. U filter funkciji, vrednost koja je nagomilana je nova lista koja sadrzi samo one elemente koji ispunjavaju odredjen uslov.

Spisak jezika

[uredi | uredi kod]

Sledeca lista programskih jezika neimenovane anonimne funkcije podrzava u potpunosti, delom, ili ne podrzava.

Ova tabela ukazuje ne neke opste trednove. Jezici koji ne podrzavaju anonimne funkcije(C, Pascal, Object Pascal) su konvencijalni strogo tipizirani jezici. Medjutim, strogo tipizirani jezici mogu podrzavati anonimne funkcije.Na primer, ML jezici su strogo tipizirani i sadrze anonimne funkcije, i Delphi, kao dijalekt objektnog Pascal-a je nadogradjen tako da podrzava anonimne funkcije.Takodje, jezici koji tretiraju funkcije kao 'funkcije prvog reda'(Dylan, Haskell, JavaScript,Lisp,ML, Perl,Python, Ruby,Scheme) sadrze anonimne funkcije tako da mogu biti definisane i prosledjene jednostavno kao i tipovi podataka. Medjutim, novi C 11 standard ih dodaje C -u iako je konvencijalan, strogo tipiziran jezik.


Programski jezik Podrska Beleske
ActionScript DA
Ada NE 'Expression' funkcije su deo jezika Ada2012
ALGOL 68 DA
Brainfuck NE
Bash DA Biblioteka je napravljena tako da sadrzi anonimne funkcije u jeziku Bash.
C NE Podrska je omogucena u Clang-u zajedno sa LLVM comiler-rt bibliotekom. GCC podrska je data za makro implementaciju koja omogucava mogucnost upotrebe. Detalje videti ispod.
C# DA
C DA Podrska postoji od C 11 standarda
CFML DA Podrska postoji od Railo 4 ColdFusion 10
Clojure DA
COBOL NE Micro Focus-ov nesandardni Managed COBOL dijalekat podrzava lambde, koje se nazivaju anonimnim metodama
Curl DA
D DA
Dart DA
Delphi DA
Dylan DA
Eiffel DA
Elixir DA
Erlang DA
F# DA
Factor DA "Quotations" podrzava ovo
Fortran NE
Frink DA
Go DA
Gosu DA
Groovy DA
Haskell DA
Haxe DA
Java DA Podrzano u Java 8. videti Java ogranicenja ispod za detalje.
JavaScript DA
Julia DA
Lisp DA
Logtalk DA
Lua DA
MUMPS NE
Mathematica DA
Maple DA
MATLAB DA
Maxima DA
OCaml DA
Octave DA
Object Pascal DA Delfi, dijalekat Objektnog paskala podrzava anonimne funkcije jos od Delphi-ja 2009. Oxygene Object Pascal dijalekat ih takodje podrzava.
Objective-C DA
Pascal NE
Perl DA
PHP DA Od verzije PHP 5.3.0 prave annimne funkcije su podrzane. Pre toga, bile su podrzane samo delom, koji je radio slicno kao C#-ova imprementacija.
PL/I NE
Python DA Python podrzava anonimne funkcije kroz lambda sintaksu, koja podrzava samo izraze, ne naredbe.
R DA
Racket DA
Rexx NE
RPG NE
Ruby DA Ruby-jeve anonimne funkcije su nasledjene od Smalltalk-a, nazivaju se 'blokovi'
Rust DA
Scala DA
Scheme DA
Smalltalk DA Smalltalk-ove anonimne funkcije nazivaju se 'blokovi'
Standard ML DA
Swift DA Swift-ove anonimne funkcije se nazivaju 'Closures'
TypeScript DA
Tcl DA
Vala DA
Visual Basic

.NET v9

DA
Visual Prolog v 7.2 DA
Wolfram Language DA

References

[uredi | uredi kod]
  1. "Higher order functions". learnyouahaskell.com. Retrieved 3 December 2014.
  2. Fernandez, Maribel (2009), Models of Computation: An Introduction to Computability Theory, Undergraduate Topics in Computer Science, Springer Science & Business Media, p. 33, ISBN 9781848824348, "The Lambda calculus ... was introduced by Alonzo Church in the 1930s as a precise notation for a theory of anonymous functions"