Анонімна функція

В комп'ютерному програмуванні, анонімною функцією (інші назви функціональний літерал або лямбда-вираз, лямбда-функція) називається така функція, яка визначена без вказання пов'язаного з нею ідентифікатора. Анонімні функція зазвичай:

  1. передаються у вигляді аргументу у функції вищого порядку, або
  2. використовуються для побудови результату функції вищого порядку, яка має повертати функцію.

Якщо функція використовується в програмі лише раз, або обмежену визначену кількість раз, використання анонімної функції може бути більш синтаксично простішим ніж використання іменованої функції. Анонімні функції широко застосовуються у функціональних мовах програмування і інших мовах програмування з функціями першого класу, де вони виконують ту саму роль для функціонального типу, що і літерали для інших типів даних.

Анонімні функції були представлені в роботі Алонзо Черча як винайдене ним лямбда числення у 1936 (до появи електронно-обчислюваних машин), в якому всі функції анонімні. В деяких мовах програмування, анонімні функції оголошуються з використанням ключового слова lambda, а самі анонімні функції часто називаються лямбда абстракціями або лямбда виразами. Анонімні функції почали використовуватись в мовах програмування починаючи з мови Lisp в 1958 і тепер дедалі більше сучасних мов програмування підтримують анонімні функції.

Анонімні функції є формою вкладених функцій, в тому плані, що вони дозволяють доступ до змінних в зоні видимості функції, в яку вони вкладені (не локальні змінні). Це означає, що анонімні функції повинні визначатися з використанням замикань. На відміну від іменованих вкладених функцій, вони не можуть бути рекурсивними без використання оператору фіксованої точки (також називається анонімною фіксованою точкою або анонімною рекурсією).

Приклади[ред. | ред. код]

Багато мов програмування мають підтримку анонімних функцій, або чогось подібного.

C (не стандартне розширення)[ред. | ред. код]

Анонімні функції не підтримуються стандартним C, але підтримуються деякими його діалектами, такими як gcc і clang.

GCC[ред. | ред. код]

GCC має підтримку анонімних функцій, що є поєднанням вкладених функцій і операторних виразів. Вони мають таку форму:

( { return_type anonymous_functions_name (parameters) { function_body } anonymous_functions_name; } ) 

Даний приклад працює лише в проєктах, що компілюються GCC. Слід відмітити, що завдяки роботі макроса, якщо ваша 'l_body' матиме коми за межами дужок, тоді цей код не скомпілюється оскільки gcc використовує кому як роздільник для наступного аргументу макроса. Аргумент 'l_ret_type' можна прибрати, якщо доступне використання '__typeof__'; в наведеному прикладі використання __typeof__ для масиву поверне 'testtype *', який можна розіменувати для отримання фактичного значення, якщо це необхідно.

#include <stdio.h>  //* це є визначення анонімної функції */ #define lambda(l_ret_type, l_arguments, l_body)       \   ({                                                  \    l_ret_type l_anonymous_functions_name l_arguments  \    l_body                                             \    &l_anonymous_functions_name;                       \    })  #define forEachInArray(fe_arrType, fe_arr, fe_fn_body)                                    \ {                                                                                         \   int i=0;                                                                                \   for(;i<sizeof(fe_arr)/sizeof(fe_arrType);i++) {  fe_arr[i] = fe_fn_body(&fe_arr[i]); }  \ }  typedef struct __test {   int a;   int b; } testtype;  void printout(const testtype * array) {   int i;   for ( i = 0; i < 3; ++ i )     printf("%d %d\n", array[i].a, array[i].b);   printf("\n"); }  int main(void) {   testtype array[] = { {0,1}, {2,3}, {4,5} };    printout(array);   /* анонімна функція задається як функція для foreach */   forEachInArray(testtype, array,     lambda (testtype, (void *item),     {       int temp = (*( testtype *) item).a;       (*( testtype *) item).a = (*( testtype *) item).b;       (*( testtype *) item).b = temp;       return (*( testtype *) item);     }));   printout(array);   return 0; } 

Див. також[ред. | ред. код]