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

У програмирању, анонимна функција је функција дефинисана тако да није везана за идентификатор. Анонимне функције су често:[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 функције су функције које имају вредност у окружењу које садржи '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 функција врши позив функције над сваким елементом листе. Следећи пример квадрира сваки елемент у низу анонимном функцијом.

>>> 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 функција враћа све елементе листе које имају вредност 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/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  Н 'Expression' функције су део језика Ada2012
ALGOL 68  Д
Brainfuck  Н
Bash  Д Библиотека је направљена тако да садржи анонимне функције у језику Bash.
C  Н Подршка је омогућена у Clang-у заједно са LLVM comiler-rt библиотеком. GCC подршка је дата за макро имплементацију која омогућава употребу. Детаље видети испод.
C#]  Д
C++  Д Подршка постоји од C++11 стандарда.
CFML  Д Подршка постоји од Railo 4 ColdFusion 10.
Clojure  Д
COBOL  Н Micro Focus-ов нестандардни Managed COBOL дијалект подржава ламбде, које се називају анонимним методама.
Curl  Д
D  Д
Dart  Д
Delphi  Д
Dylan  Д
Eiffel  Д
Elixir  Д
Erlang  Д
F#  Д
Factor  Д "Quotations" подржава ово.
Fortran  Н
Frink  Д
Go  Д
Gosu  Д[3]
Groovy  Д[4]
Haskell  Д
Haxe  Д
Java  Д Подржано у Java 8. видети Java ограничења испод за детаље.
JavaScript  Д
Julia  Д
Lisp  Д
Logtalk  Д
Lua  Д
MUMPS  Н
Mathematica  Д
Maple  Д
MATLAB  Д
Maxima  Д
OCaml  Д
Octave  Д
Object Pascal  Д Делфи, дијалект Објектног паскала подржава анонимне функције још од Delphi-ја 2009. Oxygene Object Pascal дијалект их такође подржава.
Objective-C (Mac OS X 10.6+)  Д
Pascal  Н
Perl  Д
PHP  Д Od verzije PHP 5.3.0 праве анонимне функције су подржане. Пре тога, биле су подржане само делом, који је радио слично као C#-ова импрементација.
PL/I  Н
Python  Д Python подржава анонимне функције кроз ламбда синтаксу, која подржава само изразе, не наредбе.
R  Д
Racket  Д
Rexx  Н
RPG  Н
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. 

Литература

уреди