Анонимна функција

С Википедије, слободне енциклопедије

У програмирању, анонимна функција је функција дефинисана тако да није везана за идентификатор. Анонимне функције су често:[1]

  1. аргументи прослеђени функцијама вишег реда, или
  2. се користе за конструисање резултата функције вишег реда која треба да врати функцију.

Ако се функција користи једном, или ограничен број пута, анонимна функција може бити синтаксички "лакша" од коришћења именоване функције. Анонимне функције су честе у језицима функционалног програмирања и језицима који подржавају функције прве класе (first-class funkcije), где испуњавају улогу типа функције као што литерали раде за типове података.

Анонимне функције је увео Алонзо Черч када је открио ламбда рачун 1936. године, пре настанка електронских рачунара, када су све функције биле анонимне.[2] У неколико програмских језика, анонимне функције су представљене кључном речју ламбда, и анонимне функције се често називају ламбдама или ламбда апстракцијама. Анонимне функције су део програмских језика још од настанка програмског језика Lisp 1958. и све већи број модерних програмских језика подржава анонимне функције. Такође анонимне функције се могу посматрати као форма угњеждених функција.

Употреба[уреди | уреди извор]

Анонимне функције могу бити коришћене за функционалност која не треба бити именована и за краткотрајну употребу. Неки битнији примери су у коришћењу closure и currying функција.

Коришћење анонимних функција је питање стила. Њихово коришћење никада није једини начин за решавање проблема; Свака анонимна функција може бити дефинисана именованом функцијом и бити позивана именом. Неки програмери користе анонимне функције за писање кодова који се неће извршавати више пута, а у себи садржи велики број једнолинијских функција.

У неким програмским језицима, анонимне функције се често имплементирају за веома специфичне потребе као што је коришћење у облику callback функција, или инстанцирање функције за конкретне вредности, које могу бити ефикасније, читљивије и мање склоне грешкама него именоване функције.

Код у следећим примерима је написан у језику Python 2.x .

Сортирање[уреди | уреди извор]

Кад покушавамо да сортирамо нестандардним начином, коришћење анонимне функције у компарационе сврхе може бити једноставније од коришћења именованих функција. Већина језика нуди генеричку функцију која имплементира алгоритам за сортирање који ће сортирати произвољне објекте. Ове функције обично примају произвољу функцију поређења која прима два произвољна објекта и враћа вредности мање од 0, 0 или веће од 0 у односу на то да ли је други прослеђен објекат већи, једнак или мањи од првог прослеђеног.

Сортирање листе стрингова по њиховој дужини:

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

Анонимна функција у овом примеру је ламбда израз:

lambda x,y: cmp(...)

Анонимна функција прима два аргумента, x и y, и враћа поређење између њих користећи уграђену функцију 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[уреди | уреди извор]

Closure функције су функције које имају вредност у окружењу које садржи 'bound' променљиве.

Следећи пример повезује променљиву "threshold" са анонимном функцијом која пореди улаз са њом.

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

Ово може служити као генератор функција поређења.

>>> 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

Било би непрактично креирати функцију за сваку функцију поређења и може бити непрактично чувати вредност по којој се пореди за даљу употребу. I поред разлога зашто се closure функције користе, анонимне функције су ентитет који садржи функционалност која врши поређење.

Currying[уреди | уреди извор]

Currying је процес промене функције да би било потребно мање улазних вредности (у овом случају трансформација функције која изводи дељење било ког целог броја у ону функцију која врши дељење са скупом целих бројева).

>>> 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

Коришћење анонимних функција није честа код currying технике, али се може користити у те сврхе.У примеру изнад, функција divisor генерише функцију са конкретним делитељем.Функција half и third изводи функцију divide са фиксираним делитељем.

Функција divisor такође примењује clousure технику тако што везује променљиву "d".

Функције вишег реда[уреди | уреди извор]

Python 2.x садржи неколико функција које примају анонимне функције као аргумент.Овај одељак описује њих.

Map[уреди | уреди извор]

Map функција врши позив функције над сваким елементом листе. Следећи пример квадрира сваки елемент у низу анонимном функцијом.

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

Анонимна функција прима аргумент и множи га собом (квадрира га). По мишљењу креатора језика, форма изнад није препоручљива, вец предлажу следећу форму са истим значењем а боље се уклапа са наменом језика:

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

Filter[уреди | уреди извор]

Filter функција враћа све елементе листе које имају вредност True кад их проследимо одређеној функцији.

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

Анонимна функција проверава да ли је прослеђени аргумент паран. Исто као у случају са мапом, код испод је препоручљивији.

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

Fold[уреди | уреди извор]

Fold/reduce функција пролази кроз све елементе листе (обично с лева на десно), и нагомилава вредност при том проласку. Честа употреба овога је комбиновање елемената листе у једну вредност. На пример:

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

Ово извршава следеће:

Анонимна функција овде је множење два аргумента.

Резултат fold функције мора бити једна вредност. Уместо тога, и map и filter могу бити креирани коришћењем fold функције.У мапи, вредност која је нагомилана је заправо нова листа која садржи резултате примене функције на сваки елемент оригиналне листе. У filter функцији, вредност која је нагомилана је нова листа која садржи само оне елементе који испуњавају одређен услов.

Списак језика[уреди | уреди извор]

Следећа листа програмских језика неименоване анонимне функције подрзава у потпуности, делом, или не подржава.

Ова табела указује не неке опште трендове. Језици који не подржавају анонимне функције(C, Pascal, Object Pascal) су конвенцијални строго типизирани језици. Медјутим, строго типизирани језици могу подржавати анонимне функције.На пример, ML језици су строго типизирани и садрже анонимне функције, и Delphi, као дијалект објектног Pascal-а је надограђен тако да подржава анонимне функције.Такође, језици који третирају функције као 'функције првог реда'(Dylan, Haskell, JavaScript,Lisp,ML, Perl,Python, Ruby,Scheme) садрже анонимне функције тако да могу бити дефинисане и прослеђене једноставно као и типови података. Међутим, нови C++11 стандард их додаје C++-у иако је конвенцијалан, строго типизиран језик.


Лангуаге Суппорт Нотес
ActionScript Зелена квачицаД
Ada Ред XН 'Expression' функције су део језика Ada2012
ALGOL 68 Зелена квачицаД
Brainfuck Ред XН
Bash Зелена квачицаД Библиотека је направљена тако да садржи анонимне функције у језику Bash.
C Ред XН Подршка је омогућена у Clang-у заједно са LLVM comiler-rt библиотеком. GCC подршка је дата за макро имплементацију која омогућава употребу. Детаље видети испод.
C#] Зелена квачицаД
C++ Зелена квачицаД Подршка постоји од C++11 стандарда.
CFML Зелена квачицаД Подршка постоји од Railo 4 ColdFusion 10.
Clojure Зелена квачицаД
COBOL Ред XН Micro Focus-ов нестандардни Managed COBOL дијалект подржава ламбде, које се називају анонимним методама.
Curl Зелена квачицаД
D Зелена квачицаД
Dart Зелена квачицаД
Delphi Зелена квачицаД
Dylan Зелена квачицаД
Eiffel Зелена квачицаД
Elixir Зелена квачицаД
Erlang Зелена квачицаД
F# Зелена квачицаД
Factor Зелена квачицаД "Quotations" подржава ово.
Fortran Ред XН
Frink Зелена квачицаД
Go Зелена квачицаД
Gosu Зелена квачицаД[3]
Groovy Зелена квачицаД[4]
Haskell Зелена квачицаД
Haxe Зелена квачицаД
Java Зелена квачицаД Подржано у Java 8. видети Java ограничења испод за детаље.
JavaScript Зелена квачицаД
Julia Зелена квачицаД
Lisp Зелена квачицаД
Logtalk Зелена квачицаД
Lua Зелена квачицаД
MUMPS Ред XН
Mathematica Зелена квачицаД
Maple Зелена квачицаД
MATLAB Зелена квачицаД
Maxima Зелена квачицаД
OCaml Зелена квачицаД
Octave Зелена квачицаД
Object Pascal Зелена квачицаД Делфи, дијалект Објектног паскала подржава анонимне функције још од Delphi-ја 2009. Oxygene Object Pascal дијалект их такође подржава.
Objective-C (Mac OS X 10.6+) Зелена квачицаД
Pascal Ред XН
Perl Зелена квачицаД
PHP Зелена квачицаД Od verzije PHP 5.3.0 праве анонимне функције су подржане. Пре тога, биле су подржане само делом, који је радио слично као C#-ова импрементација.
PL/I Ред XН
Python Зелена квачицаД Python подржава анонимне функције кроз ламбда синтаксу, која подржава само изразе, не наредбе.
R Зелена квачицаД
Racket Зелена квачицаД
Rexx Ред XН
RPG Ред XН
Ruby Зелена квачицаД Ruby-јеве анонимне функције су наслеђене од Smalltalk-а, називају се 'блокови'.
Rust Зелена квачицаД
Scala Зелена квачицаД
Scheme Зелена квачицаД
Smalltalk Зелена квачицаД Smalltalk-ове анонимне функције називају се 'блокови'.
Standard ML Зелена квачицаД
Swift Зелена квачицаД Swift-ове анонимне функције се називају 'Closures'.
TypeScript Зелена квачицаД
Tcl Зелена квачицаД
Vala Зелена квачицаД
Visual Basic .NET v9 Зелена квачицаД
Visual Prolog v 7.2 Зелена квачицаД
Wolfram Language Зелена квачицаД

Референце[уреди | уреди извор]

  1. ^ "Higher order functions". learnyouahaskell.com. Retrieved 3 December 2014.
  2. ^ Fernandez 2009, стр. 33.
  3. ^ „Gosu Documentation” (PDF). Архивирано из оригинала (PDF) 01. 05. 2013. г. Приступљено 4. 3. 2013. 
  4. ^ „Groovy Documentation”. Архивирано из оригинала 22. 05. 2012. г. Приступљено 29. 5. 2012. 

Литература[уреди | уреди извор]