Funkcja anonimowa (również literał funkcyjny lub lambda-abstrakcja) – definicja funkcji, która sama w sobie nie jest powiązana z identyfikatorem (chociaż może być przypisana do zmiennej).
Funkcje anonimowe mogą być"Higher order functions". learnyouahaskell.com: argumentami przekazywanymi funkcjom wyższego rzędu lub używane do budowania wyniku funkcji wyższego rzędu, która musi zwracać funkcję.
Jeśli funkcja jest używana tylko jeden raz lub ograniczoną liczbę razy, użycie funkcji anonimowej może być syntaktycznie wygodniejsze niż użycie funkcji nazwanej. Funkcje anonimowe są wszechobecne w funkcyjnych językach programowania i innych językach z obecnymi funkcjami pierwszego rzędu, gdzie pełnią taką samą rolę dla typu funkcji jak literały dla innych typów danych.
Funkcje anonimowe biorą początek w pracach Alonzo Churcha nad wynalezieniem rachunku lambda w 1936 roku (przed pojawieniem się komputerów elektronicznych), w którym wszystkie funkcje są anonimoweFernandez, Maribel (2009), Models of Computation: An Introduction to Computability Theory, Undergraduate Topics in Computer Science, Springer Science & Business Media, p. 33, , The Lambda calculus ... was introduced by Alonzo Church in the 1930s as a precise notation for a theory of anonymous functions. Przejawia się to między innymi tym, że w niektórych językach programowania, funkcje anonimowe są tworzone faktycznie przez użycie słowa kluczowego lambda. Ponadto funkcje anonimowe są często nazywane lambdami lub lambda-abstrakcjami. Funkcje anonimowe to jedna z charakterystycznych cech języków programowania od czasu powstania języka Lisp w 1958 roku i coraz większa liczba nowoczesnych języków programowania wspiera funkcje anonimowe.
Funkcje anonimowe są rodzajem funkcji zagnieżdżonych, zapewniając dostęp do zmiennych w zasięgu funkcji zawierającej (zmiennych nielokalnych). Oznacza to, że anonimowe funkcje powinny być implementowane z wykorzystaniem domknięć. W przeciwieństwie do nazwanych funkcji zagnieżdżonych, nie mogą one być rekurencyjne bez zastosowania operatora punktu stałego (również znanego jako anonimowe mocowanie lub anonimowa rekursja) lub przypisywania ich do nazwy"Lecture 29: Fixpoints and Recursion"..
Zastosowanie Funkcje anonimowe mogą być wykorzystane, by zawierać w sobie funkcjonalności, które nie powinny być nazwane oraz, być może mają jedynie krótkotrwały użytek. Niektóre przykłady, o których warto wspomnieć, obejmują domknięcia i currying.
Funkcje anonimowe to kwestia stylu programowania. Ich stosowanie nie jest wymagane. W dowolnym miejscu, w którym można ich użyć, można także zdefiniować specjalną nazwaną funkcję, która działa dokładnie tak samo. Niektórzy programiści wykorzystują funkcje anonimowe dla hermetyzacji niektórych fragmentów kodu, w ten sposób odbierając możliwość ponownego wykorzystania, co zapobiega zaśmiecaniu kodu wieloma małymi jednowierszowymi nazwanymi funkcjami.
W niektórych językach programowania, można określić anonimową funkcję wykonaną dla specjalnego zastosowania, aby dać właśnie to (i tylko), czego chce programista, co jest bardziej wydajne, eleganckie i mniej podatne na błędy pewnych operacji, które korzystają ze stałych wartości.
Cały kod w następujących sekcjach został napisany języku Python 2.x (nie 3.x).
Sortowanie Podczas próby sortowania w niestandardowy sposób może być łatwiej zawrzeć logikę porównania w funkcji anonimowej, niż tworzyć funkcję nazwaną. Większość języków zapewniają generyczną funkcję sortowania, która realizuje algorytm sortowania, który może sortować obiekty dowolnego typu. Funkcja ta zwykle przyjmuje dowolną funkcję porównującą, która przyjmuje dwa argumenty i określa, czy są równe lub czy pierwszy jest „większy” bądź „mniejszy” od drugiego (zwykle zwracając liczbę ujemną, zero lub dodatnią).
Rozważmy sortowanie listy łańcuchów po długości poszczególnych elementów:>>> a = ['dom', 'samochód', 'rower'] >>> a.sort(lambda x,y: cmp(len(x), len(y))) >>> print(a) ['samochód', 'rower', 'dom']
Funkcja anonimowa w tym przykładzie to wyrażenie lambda:lambda x,y: cmp(...)
Anonimowa funkcja przyjmuje dwa argumenty: x i u=y oraz zwraca ich porównanie, korzystając z wbudowanej funkcji cmp().
Inny przykład to sortowanie listy elementów według nazw ich klas (w języku Python, wszystko ma klasę):>>> a = [10, 'liczba', 11.2] >>> a.sort(lambda x,y: cmp(x.__class__.__name__, y.__class__.__name__)) >>> print(a) [11.2, 10, 'liczba']
Należy pamiętać, że nazwa klasy 11.2 to „float”, nazwa klasy 10 to „int”, i nazwa klasy 'liczba' to „str”. W posortowanej kolejności-to „float”, „int”, a potem „str”.
Domknięcia Domknięcia to funkcje ewaluowane w środowisku zawierające zmienne o ustalonych wartościach. Poniższy przykład przypisuje „wartość graniczną ()” zmiennej w funkcji anonimowej, która porównuje wejście do argumentu threshold.def comp(threshold): return lambda x: x < threshold
Może to być używane jako swego rodzaju generator funkcji porównania:>>> 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
Byłoby niepraktyczne tworzenie funkcji nazwanej dla każdej możliwej funkcji porównującej, a zachowywanie wartości granicznej dla przyszłych zastosowań byłoby absolutnie nieeleganckie. Niezależnie od przyczyny zastosowanie domknięcia funkcja anonimowa to jednostka, która zawiera funkcjonalność wykonywania porównania.
Currying Currying to proces modyfikacji funkcji tak, aby przyjmowała mniejszą ilość argumentów (w tym przypadku, transformujemy funkcję, która wykonuje dzielenie przez liczbę całkowitą, w taką która wykonuje dzielenie przez jeden, ustalony dzielnik).>>> def dziel(x, y): ... return x / y
>>> def dzielenie(d): ... return lambda x: dziel(x, d)
>>> naPol = dzielenie(2) >>> naTrzy = dzielenie(3)
>>> print naPol(32), naTrzy(32) 16 10
>>> print naPol(40), naTrzy(40) 20 13
Podczas gdy korzystanie z anonimowych funkcji razem z curryingiem nie jest może zbyt powszechne, to wciąż może być stosowane. W powyższym przykładzie funkcja dzielenie generuje funkcję dzielącą przez określony dzielnik. Funkcje naPol oraz naTrzy tworzą funkcje podziału o stałych dzielnikach.
Funkcja dzielenie tworzy również domknięcie poprzez przypisanie zmiennej „d” wartości.
Funkcje wyższego rzędu Python 2.x zawiera kilka funkcji, które pobierają jako argument anonimowe funkcje. W tej sekcji opisano niektóre z nich.
Map Funkcja Map wykonuje wywołanie funkcji dla każdego elementu listy. W poniższym przykładzie podnosi do kwadratu każdy element tablicy, korzystając z funkcji anonimowej.>>> a = [1, 2, 3, 4, 5, 6] >>> print map(lambda x: x*x, a) [1, 4, 9, 16, 25, 36]
Anonimowa funkcja przyjmuje argument, który mnoży z samym sobą (podnosi go do kwadratu).
Filter Funkcja filter zwraca wszystkie elementy z listy, które przekazane jako argument do określonej wcześniej funkcji wartościują ją na True.>>> a = [1, 2, 3, 4, 5, 6] >>> print filter(lambda x: x % 2 == 0, a) [2, 4, 6]
W powyższym przykładzie anonimowa funkcja sprawdza, czy przekazany mu argument jest parzysty.
Fold Funkcje fold/reduce (składanie/redukowanie) przechodzą po wszystkich elementach na liście (zwykle od lewej do prawej), nagromadzając je, w określony sposób, do pewnej wartości. Powszechne wykorzystywane są, aby zredukować wszystkie elementy listy do jednej wartości, np.:>>> a = [1, 2, 3, 4, 5] >>> print reduce(lambda x,y: x*y, a) 120
Co wykonuje .
Zaprezentowana tutaj funkcja anonimowa mnoży dwie wartości.
Wynikiem funkcji fold nie musi koniecznie być jedna wartość - właściwie rzecz biorąc funkcje map i filter mogą być zaimplementowane z użyciem fold. W przypadku funkcji map, wartość nagromadzona to nowa lista, zawierająca wyniki wywołania funkcji dla każdego elementu listy oryginalnej. W filter, wartość nagromadzona to nowa lista zawierająca tylko te elementy, które spełniają określony warunek.
Lista języków Poniżej znajduje się lista języków programowania, które w pełni obsługują nienazwane funkcje anonimowe, wspierają jakiś wariant funkcji anonimowych lub nie mają wsparcia dla funkcji anonimowych.
Ta tabela pokazuje pewne ogólne trendy. Po pierwsze, języki, które nie obsługują funkcji anonimowych – C, Pascal, Object Pascal – są konwencjonalnymi, statycznie pisanymi językami. To jednak nie oznacza, że statycznie wpisane języki są niezdolne do obsługi funkcji anonimowych. Na przykład, języki z rodziny ML są statycznie typowane, jednak fundamentalnie zawierają funkcje anonimowe, a język Delphi, dialekt Object Pascal, został rozbudowany o wsparcie funkcji anonimowych. Po drugie, języki które traktują funkcje jako funkcje pierwszego rzędu – Dylan, JavaScript, Lisp, Scheme, ML, Haskell, Python, Ruby, Perl – generalnie posiadają wsparcie dla funkcji anonimowych, co oznacza, że funkcje mogą być definiowane i przekazywane z taką samą łatwością jak inne typy danych. Gdyby ktoś nie uznawał powyższych przykładów za wystarczające, to wystarczy wspomnieć, że standard C++11 dodaje funkcje anonimowe do C++, czyli do języka konwencjonalnego, statycznie typowanego.
Język Wsparcie Notki ActionScript Ada Wyrażenia funkcyjne są częścią Ada2012 ALGOL 68 Brainfuck Bash Stworzono bibliotekę w celu dodania wsparcia dla funkcji anonimowych"Bash lambda".. C Wsparcie jest zapewniane w clang, wraz z llvm compiler-rt lib. Wsparcie w GCC jest udostępnione jako implementacja w makrach. Szczegóły zobacz niżej. C# C++ Część standardu C++11 CFML Wraz z Railo 4. / ColdFusion 10 Clojure COBOL Niestandardowy dialekt języka Managed COBOL: Micro Focus wspiera lambdy, nazwane anonimowymi delegatami/metodami"Managed COBOL Reference".. Curl D Dart Delphi Dylan Eiffel Erlang F# Factor Wsparcie przez „Cudzysłowia”"Quotations - Factor Documentation" Fortran Frink Go Gosu Groovy Haskell HaXe Java Wspierane od Java 8. JavaScript Nazywane funkcjami strzałkowymi () ze względu na swoją formę: (a, b) => a * b. Dostępne od ES2015. Julia Lisp Logtalk Lua MUMPS Mathematica Maple MATLAB Maxima OCaml Octave Object Pascal Delphi, dialekt Object Pascal, implementuje natywne wsparcie dla anonimowych funkcji (formalnie metod anonimowych (ang. )) od konferencji Delphi 2009. Dialekt Oxygene również je wspiera. Objective-C (Mac OS X 10.6+) Nazywane blokami; ponadto bloki Objective-C, mogą być wykorzystywane również w C i C++, gdy programujemy na platformie firmy Apple. Pascal Perl PHP Od PHP 5.3.0 prawdziwe funkcje anonimowe są wspierane; wcześniej istniało tylko częściowe wsparcie dla funkcji anonimowych, które działało podobnie do implementacji w C#. PL/I Python Python wspiera funkcje anonimowe poprzez składnie lambda, w którym można używać tylko wyrażeń, nie pełnych instrukcji. R Racket Rexx RPG Ruby Funkcje anonimowe Ruby, sprowadzone z języka Smalltalk, są nazywane blokami. Rust Scala Scheme Smalltalk Funkcje anonimowe są nazywane blokami. Standard ML Swift Są nazywane domknięciami (ang. ). TypeScript Tcl Vala Visual Basic .NET v9 Visual Prolog v 7.2 Wolfram Language
Przykłady Liczne języki obsługują funkcje anonimowe, lub podobną funkcjonalność.
C (niestandardowe rozszerzenia) Anonimowa funkcje nie są obsługiwane przez standardowy język C, ale są obsługiwane przez niektóre z jego dialektów, takie jak gcc i clang.
GCC GCC zapewnia wsparcie dla anonimowych funkcji, mieszanych przez funkcje zagnieżdżone i pewne wyrażenia. Ma postać:( { zwracany_typ nazwa_funkcji_anonimowych (parametry) { cialo funkcji } nazwa_funkcji_anonimowych; } )
Poniższy przykład działa tylko z GCC. Należy również pamiętać, że ze względu na sposób działania makr, jeśli twoje l_body zawiera przecinki poza nawiasami, program się nie skompiluje, jako że GCC używa przecinka jako separatora do następnego argumentu w makro.