Анонимная функция
В компьютерном программировании ( анонимная функция функциональный литерал , лямбда-абстракция , лямбда-функция , лямбда-выражение или блок ) — это определение функции , не привязанное к идентификатору . Анонимные функции часто представляют собой аргументы, передаваемые функциям более высокого порядка или используемые для создания результата функции более высокого порядка, которая должна возвращать функцию. [1] Если функция используется только один раз или ограниченное количество раз, анонимная функция может быть синтаксически проще, чем использование именованной функции. Анонимные функции повсеместно встречаются в языках функционального программирования и других языках с первоклассными функциями , где они выполняют ту же роль для типа функции , что и литералы для других типов данных .
Анонимные функции берут свое начало в работе Алонзо Чёрча, когда он изобрел лямбда -исчисление , в котором все функции анонимны, в 1936 году, до появления электронных компьютеров. [2] В некоторых языках программирования анонимные функции вводятся с помощью ключевого слова лямбда , а анонимные функции часто называют лямбда-выражениями или лямбда-абстракциями. Анонимные функции были особенностью языков программирования со времен Лиспа в 1958 году, и все большее число современных языков программирования поддерживают анонимные функции.
Имена [ править ]
Названия «лямбда-абстракция», «лямбда-функция» и «лямбда-выражение» относятся к обозначениям абстракции функции в лямбда-исчислении, где обычная функция f ( x ) = M будет записана (λ x . M ) , и где M — это выражение, которое использует x . Сравните с синтаксисом Python lambda x: M
.
Название «стрелочная функция» относится к математическому « сопоставлению » символа x ↦ M . Сравните с синтаксисом JavaScript x => M
. [3]
Использует [ править ]
Анонимные функции могут использоваться для хранения функций, которым не нужно давать имя, и, возможно, для краткосрочного использования. Некоторые известные примеры включают замыкания и каррирование .
Использование анонимных функций — это вопрос стиля. Их использование никогда не является единственным способом решения проблемы; вместо этого каждая анонимная функция может быть определена как именованная функция и вызываться по имени. Некоторые программисты используют анонимные функции для инкапсуляции конкретного, непереиспользуемого кода, не засоряя его множеством маленьких однострочных обычных функций.
В некоторых языках программирования анонимные функции обычно реализуются для очень конкретных целей, таких как привязка событий к обратным вызовам или создание экземпляра функции для определенных значений, что может быть более эффективным, более читаемым и менее подверженным ошибкам, чем вызов более общей именованной функции. .
Следующие примеры написаны на Python 3.
Сортировка [ править ]
При попытке сортировки нестандартным способом может оказаться проще сохранить логику сортировки в виде анонимной функции вместо создания именованной функции. Большинство языков предоставляют общую функцию сортировки, реализующую алгоритм сортировки произвольных объектов. Эта функция обычно принимает произвольную функцию, которая определяет, как сравнивать, равны ли два элемента или один из них больше или меньше другого.
Рассмотрим этот код Python, сортирующий список строк по длине строки:
>>> a = [ 'дом' , 'машина' , 'велосипед' ]
>>> a . sort ( key = лямбда x : len ( x ))
>>> a
[ 'машина' , 'велосипед' , 'дом' ]
Анонимной функцией в этом примере является лямбда-выражение:
лямбда х : лен ( х )
Анонимная функция принимает один аргумент: x
и возвращает длину своего аргумента, который затем используется sort()
метод как критерий сортировки.
Основной синтаксис лямбда-функции в Python:
лямбда arg1 , arg2 , arg3 , ... : < операция над аргументами , возвращающими значение >
Выражение, возвращаемое лямбда-функцией, можно присвоить переменной и использовать в коде в нескольких местах.
>>> добавить = лямбда а : а + а
>>> добавить ( 20 )
40
Другим примером может быть сортировка элементов в списке по имени их класса (в Python все имеет класс):
>>> а = [ 10 , 'число' , 11,2 ]
>>> а . сортировка ( ключ = лямбда x : x . __class__ . __name__ )
>>> a
[ 11.2 , 10 , 'число' ]
Обратите внимание, что 11.2
имеет имя класса " float
", 10
имеет имя класса " int
", и 'number'
имеет имя класса " str
". Отсортированный порядок: " float
", " int
", затем " str
".
Замыкания [ править ]
Замыкания — это функции, вычисляемые в среде, содержащей связанные переменные . В следующем примере переменная «порог» привязывается к анонимной функции, которая сравнивает входные данные с порогом.
def comp ( порог ):
вернуть лямбда x : x < порог
Это можно использовать как своего рода генератор функций сравнения:
>>> 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
Было бы непрактично создавать функцию для каждой возможной функции сравнения, и может быть слишком неудобно сохранять пороговое значение для дальнейшего использования. Независимо от причины использования замыкания, анонимная функция — это сущность, содержащая функциональность, выполняющую сравнение.
Каррирование [ править ]
Каррирование — это процесс изменения функции, при котором вместо нескольких входных данных она принимает один входной сигнал и возвращает функцию, которая принимает второй входной сигнал, и так далее. В этом примере функция, выполняющая деление на любое целое число, преобразуется в функцию, выполняющую деление на заданное целое число.
>>> def разделить ( x , y ):
... вернуть x / y
>>> def divisor ( d ):
... вернуть лямбда x : разделить ( x , d )
>>> половина = делитель ( 2 )
> >> третий = делитель ( 3 )
>>> распечатать ( половина ( 32 ), третий ( 32 ))
16,0 10,666666666666666
>>> распечатать ( половина ( 40 ), третий ( 40 ))
20,0 13,333333333333334
Хотя использование анонимных функций, возможно, не является обычным явлением при каррировании, его все же можно использовать. В приведенном выше примере функция divisor генерирует функции с указанным делителем. Функции half и Third каррируют функцию деления с фиксированным делителем.
Функция делителя также формирует замыкание, связывая переменную d
.
Функции высшего порядка [ править ]
Функция высшего порядка — это функция, которая принимает функцию в качестве аргумента или возвращает ее в качестве результата. Обычно это используется для настройки поведения обобщенно определенной функции, часто это конструкция цикла или схема рекурсии. Анонимные функции — удобный способ указать аргументы таких функций. Следующие примеры относятся к Python 3.
Карта [ править ]
Функция карты выполняет вызов функции для каждого элемента списка. В следующем примере возводится каждый элемент массива в квадрат с помощью анонимной функции.
>>> a = [ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> список ( карта ( лямбда x : x * x , a ))
[ 1 , 4 , 9 , 16 , 25 , 36 ]
Анонимная функция принимает аргумент и умножает его на себя (возводит в квадрат). Вышеуказанная форма не одобряется создателями языка, которые утверждают, что форма, представленная ниже, имеет то же значение и больше соответствует философии языка:
>>> a = [ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> [ x * x для x в a ]
[ 1 , 4 , 9 , 16 , 25 , 36 ]
Фильтровать [ править ]
Функция фильтра возвращает все элементы из списка, которые оценивают True при передаче определенной функции.
>>> a = [ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> список ( фильтр ( лямбда x : x % 2 == 0 , a ))
[ 2 , 4 , 6 ]
Анонимная функция проверяет, является ли переданный ей аргумент четным. Как и в случае с картой, более подходящей считается форма ниже:
>>> a = [ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> [ x для x в a , если x % 2 == 0 ]
[ 2 , 4 , 6 ]
Сложить [ править ]
Функция сгиба выполняется по всем элементам структуры (для списков обычно слева направо, «свертывание влево», называемое reduce
в Python), накапливая значение по ходу дела. Это можно использовать для объединения всех элементов структуры в одно значение, например:
>>> из functools import уменьшить
>>> a = [ 1 , 2 , 3 , 4 , 5 ]
>>> уменьшить ( лямбда x , y : x * y , a )
120
Это выполняет
Анонимная функция здесь — это умножение двух аргументов.
Результат свертки не обязательно должен быть одним значением. Вместо этого и карту, и фильтр можно создать с помощью сгиба. В карте накапливаемое значение представляет собой новый список, содержащий результаты применения функции к каждому элементу исходного списка. В фильтре накапливаемое значение представляет собой новый список, содержащий только те элементы, которые соответствуют заданному условию.
Список языков [ править ]
Ниже приводится список языков программирования , которые поддерживают безымянные анонимные функции полностью или частично в каком-либо варианте или не поддерживают вообще.
В этой таблице показаны некоторые общие тенденции. Во-первых, все языки, которые не поддерживают анонимные функции ( C , Pascal , Object Pascal ), являются статически типизированными языками. Однако статически типизированные языки могут поддерживать анонимные функции. Например, языки ML статически типизированы и в основном включают анонимные функции, а Delphi , диалект Object Pascal , был расширен для поддержки анонимных функций, как и C++ (по стандарту C++11 ). Во-вторых, языки, которые рассматривают функции как функции первого класса ( Dylan , Haskell , JavaScript , Lisp , ML , Perl , Python , Ruby , Scheme ), обычно имеют поддержку анонимных функций, поэтому функции можно определять и передавать так же легко, как и другие данные. типы.
![]() |
Язык | Поддерживать | Примечания |
---|---|---|
ActionScript | ![]() |
|
Есть | ![]() |
Функции выражения являются частью Ada2012. |
АЛГОЛ 68 | ![]() |
|
АПЛ | ![]() |
Dyalog, ngn и dzaima APL полностью поддерживают как dfns, так и неявные функции. GNU APL имеет довольно ограниченную поддержку dfns. |
Языки ассемблера | ![]() |
|
АХК | ![]() |
Поскольку анонимные функции AutoHotkey V2 поддерживаются с синтаксисом, аналогичным JavaScript. |
Баш | ![]() |
Создана библиотека для поддержки анонимных функций в Bash. [4] |
С | ![]() |
Поддержка предоставляется в Clang , а также в LLVM библиотеке компилятора . Поддержка GCC предоставляется для реализации макроса, которая обеспечивает возможность использования. Подробности смотрите ниже. |
С# | ![]() |
[5] |
С++ | ![]() |
По C++11 стандарту |
CFML | ![]() |
Начиная с Райло 4, [6] КолдФьюжн 10 [7] |
Кложур | ![]() |
[8] |
КОБОЛ | ![]() |
Micro Focus поддерживает лямбда-выражения, которые называются анонимными делегатами/методами. Нестандартный диалект Managed COBOL [9] |
Завиток | ![]() |
|
Д | ![]() |
[10] |
Дарт | ![]() |
[11] |
Дельфи | ![]() |
[12] |
Дилан | ![]() |
[13] |
Эйфелева | ![]() |
|
Вяз | ![]() |
[14] |
Эликсир | ![]() |
[15] |
Эрланг | ![]() |
[16] |
Ф# | ![]() |
[17] |
Эксель | ![]() |
Функция листа Excel, бета-версия 2021 г. [18] |
Фактор | ![]() |
«Цитаты» подтверждают это [19] |
Фортран | ![]() |
|
Фринк | ![]() |
[20] |
Идти | ![]() |
[21] |
Гоша | ![]() |
[22] |
классный | ![]() |
[23] |
Хаскелл | ![]() |
[24] |
Смешанный | ![]() |
[25] |
Джава | ![]() |
Поддерживается в Java 8 . см. в разделе «Ограничения Java» Подробности ниже. |
JavaScript | ![]() |
[26] |
Юлия | ![]() |
[27] |
Котлин | ![]() |
[28] |
Лисп | ![]() |
|
Логток | ![]() |
|
Два | ![]() |
[29] |
Свинка | ![]() |
|
Клен | ![]() |
[30] |
МАТЛАБ | ![]() |
[31] |
Максима | ![]() |
[32] |
Nim | ![]() |
[33] |
OCaml | ![]() |
[34] |
Октава | ![]() |
[35] |
Объектный Паскаль | ![]() |
Delphi, диалект Object Pascal, изначально поддерживает анонимные функции (формально анонимные методы ) начиная с Delphi 2009. Диалект Oxygene Object Pascal также поддерживает их. |
Objective-C (Mac OS X 10.6+) | ![]() |
Называемые блоки ; Помимо Objective-C, блоки также можно использовать на C и C++ при программировании на платформе Apple. |
OpenSCAD | ![]() |
Поддержка Function Literal была представлена в версии 2021.01. [36] |
Паскаль | ![]() |
|
Перл | ![]() |
[37] |
PHP | ![]() |
Начиная с PHP 5.3.0 поддерживаются настоящие анонимные функции. [38] Раньше поддерживались только частично анонимные функции, которые работали очень похоже на реализацию C#. |
ПЛ/И | ![]() |
|
Питон | ![]() |
Python поддерживает анонимные функции через синтаксис лямбда. [39] который поддерживает только выражения, а не операторы. |
р | ![]() |
|
Ракетка | ![]() |
[40] |
Раку | ![]() |
[41] |
Рекс | ![]() |
|
РПГ | ![]() |
|
Рубин | ![]() |
Анонимные функции Ruby, унаследованные от Smalltalk , называются блоками . [42] |
Ржавчина | ![]() |
[43] |
Скала | ![]() |
[44] |
Схема | ![]() |
|
Болтовня | ![]() |
Анонимные функции Smalltalk называются блоками . |
Стандартный ML | ![]() |
[45] |
Быстрый | ![]() |
Анонимные функции Swift называются замыканиями. [46] |
Машинопись | ![]() |
[47] |
Ткл | ![]() |
[48] |
Налить | ![]() |
[48] |
Visual Basic .NET v9 | ![]() |
[49] |
Визуальный Пролог версии 7.2 | ![]() |
[50] |
Вольфрам Язык | ![]() |
[51] |
Зиг | ![]() |
[52] |
Примеры [ править ]
![]() | Этот раздел содержит инструкции, советы и инструкции . ( декабрь 2018 г. ) |
Многие языки поддерживают анонимные функции или что-то подобное.
АПЛ [ править ]
Лишь некоторые диалекты поддерживают анонимные функции, например dfns , в неявном стиле или их комбинацию.
f ← { ⍵ × ⍵ } Как dfn 4
f 1 2 3
1 4 9
g ← ⊢ Как неявный - 3 поезд вилка ( ⊢ )
g 1 2 3
1 9 производная
h ← × ⍨ Как функция неявная ×
h 1 2 3
1 4 9
C (нестандартное расширение) [ править ]
Анонимная функция не поддерживается стандартным языком программирования C, но поддерживается некоторыми диалектами C, такими как GCC. [53] и Кланг .
GCC [ править ]
Коллекция компиляторов GNU (GCC) поддерживает анонимные функции, смешанные с вложенными функциями и выражениями операторов. Он имеет форму:
( { return_type имя_анонимной_функции ( параметры ) { тело_функции } имя анонимной_функции ; } )
Следующий пример работает только с GCC. Из-за того, как макросы расширяются, l_body
не может содержать запятых вне круглых скобок; GCC рассматривает запятую как разделитель между аргументами макроса.
Аргумент l_ret_type
можно удалить, если __typeof__
доступен; в примере ниже, используя __typeof__
в массиве вернется testtype *
, который при необходимости можно разыменовать для получения фактического значения.
#include <stdio.h>
//* это определение анонимной функции */
#define лямбда(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
{
int a ;
интервал б ;
} Тип теста ;
недействительная распечатка ( const testtype * array )
{
int i ;
for ( i = 0 ; i < 3 ; ++ i )
printf ( «%d %d \n » , массив [ i ].a , массив [ i ] .b ) ;
printf ( " \n " );
}
int main ( void )
{
testtype массив [] = { { 0 , 1 }, { 2 , 3 }, { 4 , 5 } };
распечатка ( массив );
/* анонимная функция задается как функция foreach */
forEachInArray ( тип теста , массив ,
лямбда ( тип теста , ( void * элемент ),
{
int temp = ( * ( тип теста * ) элемент ). a ;
( * ( тип теста * ) элемент ). a = ( * ( тип теста * ) элемент ). b ;
( * ( тип теста * ) элемент ). b = temp ;
return ( * ( тип теста * ) элемент } )
);
распечатка ( массив );
вернуть 0 ;
}
Clang (C, C++, Objective-C, Objective-C++) [ править ]
Clang поддерживает анонимные функции, называемые блоками . [54] которые имеют вид:
^ тип_возврата ( параметры ) { тело_функции }
Тип вышеперечисленных блоков: return_type (^)(parameters)
.
Используя вышеупомянутое расширение блоков и Grand Central Dispatch (libdispatch), код мог бы выглядеть проще:
#include <stdio.h>
#include <dispatch/dispatch.h>
int main ( void ) {
void ( ^ count_loop )() = ^ {
for ( int i = 0 ; i < 100 ; i ++ )
printf ( " %d \n " , я );
printf ( "ах ах ах \n " );
};
/* Передача в качестве параметра в другую функцию */
send_async ( dispatch_get_global_queue ( DISPATCH_QUEUE_PRIORITY_DEFAULT , 0 ), count_loop );
/* Непосредственный вызов */
count_loop ();
вернуть 0 ;
}
Код с блоками должен быть скомпилирован с помощью -fblocks
и связан с -lBlocksRuntime
C++ (начиная с C++11) [ править ]
C++11 поддерживает анонимные функции (технически функциональные объекты ), называемые лямбда-выражениями . [55] которые имеют вид:
[ захватывает ] ( параметры ) спецификации требуются ( необязательно ) { тело }
где " specs
"имеет форму" specifiers exception attr trailing-return-type
в этой последовательности; каждый из этих компонентов является необязательным». Если он отсутствует, тип возвращаемого значения выводится из return
операторы, как если бы это была функция с объявленным типом возвращаемого значения auto
.
Это пример лямбда-выражения:
[]( int x , int y ) { return x + y ; }
C++11 также поддерживает замыкания , называемые здесь захватами. Захваты определяются в квадратных скобках [
и ]
в объявлении лямбда-выражения. Механизм позволяет захватывать эти переменные по значению или по ссылке. Следующая таблица демонстрирует это:
[] // Никаких захватов, лямбда неявно конвертируется в указатель на функцию.
[ x , & y ] // x фиксируется по значению, а y фиксируется по ссылке.
[ & ] // Любая внешняя переменная неявно фиксируется по ссылке, если она используется.
[ = ] // Любая внешняя переменная неявно фиксируется по значению, если она используется.
[ & , x ] // x захватывается по значению. Другие переменные будут захватываться по ссылке.
[ = , & z ] // z захватывается по ссылке. Другие переменные будут фиксироваться по значению.
Переменные, захватываемые по значению, по умолчанию являются постоянными. Добавление mutable
после того, как список параметров сделает их непостоянными.
C++14 и более новые версии поддерживают init-capture, например:
std :: unique_ptr < int > ptr = std :: make_unique < int > ( 42 );
[ ptr ]{ /* ... */ }; // назначение копирования удаляется для уникального указателя
[ ptr = std :: move ( ptr )]{ /* ... */ }; // ок
auto counter = [ i = 0 ]() mutable { return i ++ ; }; // для изменения счетчика 'i' требуется изменяемый
объект (); // 0
счетчик (); // 1
счетчик (); // 2
Следующие два примера демонстрируют использование лямбда-выражения:
std :: vector <int> some_list ; { 1 , 2 , 3 , 4 , 5 }
целое число = 0 ;
std :: for_each ( begin ( some_list ), end ( some_list ),
[ & total ]( int x ) { total += x ; });
// Обратите внимание, что std::accumulate здесь будет лучшей альтернативой...
При этом вычисляется общее количество всех элементов в списке. Переменная total
сохраняется как часть замыкания лямбда-функции. Поскольку это ссылка на переменную стека total
, он может изменить свое значение.
std :: vector <int> some_list ; { 1 , 2 , 3 , 4 , 5 }
целое число = 0 ;
целое значение = 5 ;
std :: for_each ( begin ( some_list ), end ( some_list ),
[ & total , value , this ]( int x ) { total += x * value * this -> some_func (); });
Это вызовет total
храниться как ссылка, но value
будет сохранен как копия.
Захват this
особенный. Его можно захватить только по значению, а не по ссылке. Однако в C++17 текущий объект можно захватить по значению (обозначаемому *this
), или может быть получено по ссылке (обозначается this
). this
может быть захвачен только в том случае, если ближайшая охватывающая функция является нестатической функцией-членом. Лямбда будет иметь тот же доступ, что и член, создавший ее, с точки зрения защищенных/частных членов.
Если this
фиксируется явно или неявно, затем также проверяется область видимости вложенных членов класса. Доступ к членам this
не требует явного использования this->
синтаксис.
Конкретная внутренняя реализация может различаться, но ожидается, что лямбда-функция, которая захватывает все по ссылке, будет хранить фактический указатель стека функции, в которой она создана, а не отдельные ссылки на переменные стека. Однако, поскольку большинство лямбда-функций небольшие по размеру и локальны, они, скорее всего, являются кандидатами на встраивание и, следовательно, не требуют дополнительного хранилища для ссылок.
Если объект замыкания, содержащий ссылки на локальные переменные, вызывается после самой внутренней области блока его создания, поведение не определено .
Лямбда-функции — это функциональные объекты типа, зависящего от реализации; имя этого типа доступно только компилятору. Если пользователь хочет использовать лямбда-функцию в качестве параметра, тип параметра должен быть типом шаблона, или он должен создать std::function
или аналогичный объект для захвата значения лямбда. Использование auto
Ключевое слово может помочь сохранить лямбда-функцию,
auto my_lambda_func = [ & ]( int x ) { /*...*/ };
auto my_onheap_lambda_func = new auto ([ = ]( int x ) { /*...*/ });
Вот пример хранения анонимных функций в переменных, векторах и массивах; и передавая их как именованные параметры:
#include <functional>
#include <iostream>
#include <vector>
double eval ( std :: function < double ( double ) > f , double x = 2.0 ) {
return f ( x );
}
int main () {
std :: function < double ( double ) > f0 = []( double x ) { return 1 ; };
auto f1 = []( двойной x ) { return x ; };
decltype ( f0 ) fa [ 3 ] = { f0 , f1 , [] ( double x ) { return x * x ; }};
std :: vector < decltype ( f0 ) > fv = { f0 , f1 };
фв . push_back ([]( double x ) { return x * x ; });
for ( size_t i = 0 ; i < fv . size (); i ++ ) {
std :: cout << fv [ i ]( 2.0 ) << std :: endl ;
}
for ( size_t i = 0 ; i < 3 ; i ++ ) {
std :: cout << fa [ i ]( 2.0 ) << std :: endl ;
}
for ( auto & f : fv ) {
std :: cout << f ( 2.0 ) << std :: endl ;
}
for ( auto & f : fa ) {
std :: cout << f ( 2.0 ) << std :: endl ;
}
std :: cout << eval ( f0 ) << std :: endl ;
std :: cout << eval ( f1 ) << std :: endl ;
std :: cout << eval ([]( double x ) { return x * x ; }) << std :: endl ;
}
Лямбда-выражение с пустой спецификацией захвата ( []
) можно неявно преобразовать в указатель на функцию того же типа, что и лямбда-выражение. Итак, это законно:
auto a_lambda_func = []( int x ) -> void { /*...*/ };
void ( * func_ptr ) ( int ) = a_lambda_func ;
func_ptr ( 4 ); //вызывает лямбду.
Начиная с C++17 , можно объявить лямбду. constexpr
, а поскольку C++20 , consteval
с обычной семантикой. Эти спецификаторы идут после списка параметров, например mutable
. Начиная с C++23 , лямбда также может быть static
если у него нет захватов. static
и mutable
спецификаторы не могут быть объединены.
Кроме того, начиная с C++23, лямбда-выражение может быть рекурсивным посредством явного this
в качестве первого параметра:
auto fibonacci = []( this auto self , int n ) { return n <= 1 ? n : сам ( n - 1 ) + сам ( n - 2 ); };
Фибоначчи ( 7 ); // 13
В дополнение к этому, C++23 изменил синтаксис так, что круглые скобки можно было опустить в случае лямбды, которая не принимает аргументов, даже если лямбда имеет спецификатор. Также сделано так, что последовательность спецификаторов атрибутов, которая появляется перед списком параметров, лямбда-спецификаторами или спецификатором noException (один из них должен быть), применяется к оператору вызова функции или шаблону оператора типа замыкания. В противном случае это относится к типу оператора вызова функции или шаблону оператора. Ранее такая последовательность всегда применялась к типу оператора вызова функции или шаблону оператора типа замыкания, создавая, например, [[noreturn]]
атрибут невозможно использовать с лямбдами.
Библиотека Boost также предоставляет собственный синтаксис для лямбда-функций, используя следующий синтаксис: [56]
for_each ( a.begin ( a.end ), ( :: ) , std ' cout << _1 << ' );
Начиная с C++14 , параметры функции лямбды могут быть объявлены с помощью auto
. Полученная лямбда называется общей лямбдой и, по сути, представляет собой шаблон анонимной функции, поскольку правила вывода типа автоматических параметров являются правилами вывода аргументов шаблона. Начиная с C++20 , параметры шаблона также могут быть объявлены явно с помощью следующего синтаксиса:
[ захватывает ] <tparams> требует ( необязательно ) ( параметры ) спецификации требует ( необязательно ) { тело }
С# [ править ]
В C# поддержка анонимных функций расширилась благодаря различным версиям компилятора языка. Язык версии 3.0, выпущенный в ноябре 2007 года вместе с .NET Framework версии 3.5, имеет полную поддержку анонимных функций. [57] : 7–8 [58] : 26 В C# они называются лямбда-выражениями , следуя исходной версии анонимных функций — лямбда-исчислению . [59] [57] : 7–8, 91 [58] : 91
// первое int — это тип x' // второе int — возвращаемый тип // <see href=" http://msdn.microsoft.com/en-us/library/bb549151.aspx " />Func<int,int> foo = x => x * x;
Console.WriteLine(foo(7));
Хотя функция анонимна, ее нельзя присвоить неявно типизированной переменной, поскольку синтаксис лямбда может использоваться для обозначения анонимной функции или дерева выражений, и компилятор не может автоматически определить выбор. [57] : 101–103 Например, это не работает:
// НЕ скомпилируется!
вар foo = ( int x ) => x * x ;
Однако лямбда-выражение может участвовать в выводе типа и может использоваться в качестве аргумента метода , например, для использования анонимных функций с возможностью Map, доступной с помощью System.Collections.Generic.List
(в ConvertAll()
метод):
// Инициализируем список:
var Values = new List < int > () { 7 , 13 , 4 , 9 , 3 };
// Сопоставляем анонимную функцию со всеми элементами списка, возвращаем новый список
var foo = values . ConvertAll ( d => d * d ) ;
// результат переменной foo имеет тип System.Collections.Generic.List<Int32>
Предыдущие версии C# имели более ограниченную поддержку анонимных функций. C# v1.0, представленный в феврале 2002 года вместе с .NET Framework v1.0, обеспечивал частичную поддержку анонимных функций за счет использования делегатов . [57] : 6 В C# они называются лямбда-выражениями , следуя исходной версии анонимных функций — лямбда-исчислению . [57] : 91 Эта конструкция чем-то похожа на делегаты PHP. В C# 1.0 делегаты подобны указателям на функции, которые ссылаются на явно названный метод внутри класса. (Но в отличие от PHP, имя не требуется во время использования делегата.) C# v2.0, выпущенный в ноябре 2005 года вместе с .NET Framework v2.0, представил концепцию анонимных методов как способа написания безымянных встроенных операторов. блоки, которые могут быть выполнены при вызове делегата. [57] : 6–7 C# 3.0 продолжает поддерживать эти конструкции, но также поддерживает конструкцию лямбда-выражения.
Этот пример компилируется в C# 3.0 и демонстрирует три формы:
общественный класс TestDriver
{
делегат int SquareDelegate ( int d );
static int Square ( int d )
{
return d * d ;
}
static void Main ( string [] args )
{
// C# 1.0: необходим исходный синтаксис делегата
// инициализация именованным методом.
SquareDelegate A = новый SquareDelegate ( Square );
Система . Консоль . WriteLine ( A ( 3 ));
// C# 2.0: Делегат можно инициализировать с помощью
// встроенного кода, называемого «анонимным методом». Этот
// метод принимает int в качестве входного параметра.
SquareDelegate B = делегат ( int d ) { return d * d ; };
Система . Консоль . WriteLine ( B ( 5 ));
// С# 3.0. Делегат можно инициализировать
// с помощью лямбда-выражения. Лямбда принимает целое число и возвращает целое число.
// Тип x определяется компилятором.
SquareDelegate C = x => x * x ;
Система . Консоль . WriteLine ( C ( 7 ));
// С# 3.0. Делегат, который принимает один ввод и
// возвращает один вывод, также может быть неявно объявлен с типом Func<>.
Система . Func < int , int > D = x => x * x ;
Система . Консоль . WriteLine ( D ( 9 ));
}
}
В случае версии C# 2.0 компилятор C# берет блок кода анонимной функции и создает статическую закрытую функцию. Внутри функция, конечно, получает сгенерированное имя; это сгенерированное имя основано на имени метода, в котором объявлен делегат. Но это имя не раскрывается коду приложения, за исключением использования отражения . [57] : 103 В случае версии C# 3.0 применяется тот же механизм.
Язык разметки ColdFusion (CFML) [ править ]
Используя функция ключевое слово:
fn = function (){
// операторы
};
Или используя функцию стрелки:
fn = () => {
// операторы
};
fn = () => SingleExpression // SingleExpression возвращается неявно. Нет необходимости в фигурных скобках или ключевом слове return
fn = singleParam => { // если стрелочная функция имеет только один параметр, нет необходимости в скобках
// операторы
}
fn = ( x , y ) => { // if стрелочная функция имеет ноль или несколько параметров, необходимо использовать скобки
// операторы
}
CFML поддерживает любые операторы в определении функции, а не просто выражения.
CFML поддерживает рекурсивные анонимные функции:
факториал = функция ( n ) {
return n > 1 ? n * факториал ( n - 1 ) : 1 ;
};
Анонимные функции CFML реализуют замыкание.
Д [ править ]
D использует встроенные делегаты для реализации анонимных функций. Полный синтаксис встроенного делегата:
return_type делегат ( аргументы ){ /*body*/ }
Если однозначно, тип возвращаемого значения и ключевое слово делегат можно опустить.
( x ){ return x * x ;}
Deleate ( x ){ return x * x ;} // если требуется больше подробностей
( int x ) { return x * x ;} // если тип параметра не может быть выведен
делегатом ( int x ){ return x * x ;} // то же самое
делегат double ( int x ){ return x * x ;} // если тип возвращаемого значения необходимо принудительно указать вручную
Начиная с версии 2.0, D размещает замыкания в куче, если только компилятор не докажет, что в этом нет необходимости; тот scope
Ключевое слово можно использовать для принудительного выделения стека.
Начиная с версии 2.058 можно использовать сокращенную запись:
х => х * х ;
( int x ) => x * x ;
( Икс , y ) => Икс * y ;
( int x , int y ) => x * y ;
Анонимную функцию можно присвоить переменной и использовать следующим образом:
auto sqr = ( double x ) { return x * x ;};
двойной у = sqr ( 4 );
Дарт [ править ]
Dart поддерживает анонимные функции. [11]
вар sqr = ( x ) => x * x ;
печать ( sqr ( 5 ));
или
print ((( x ) => x * x )( 5 ));
Делфи [ править ]
Delphi представила анонимные функции в версии 2009.
программы демо-версия ;
введите
TSimpleProcedure = ссылка на процедуру ;
TSimpleFunction = ссылка на функцию ( const x : string ) : Integer ;
вар
x1 : TSimpleProcedure ;
y1 : TSimpleFunction ;
Begin
x1 := процедура
Begin
Writeln ( 'Hello World' ) ;
конец ;
х1 ; //вызов только что определенного анонимного метода
y1 := function ( const x : string ) : Integer
Begin
Result := Длина ( x ) ;
конец ;
Writeln ( y1 ( 'бар' )) ;
конец .
PascalABC.NET [ править ]
PascalABC.NET поддерживает анонимные функции, используя синтаксис лямбда.
начать
вар n := 10000000 ;
вар пп := ( 1 .. n )
. Выберите ( x -> ( Случайный , Случайный ))
. Где ( p -> Sqr ( p [ 0 ]) + Sqr ( p [ 1 ]) < 1 )
. Граф / n * 4 ;
Печать ( стр .) ;
конец .
Elixir[editЭликсир
Эликсир использует замыкание fn
для анонимных функций. [15]
сумма = fn ( a , b ) -> a + b конечная
сумма . ( 4 , 3 )
#=> 7
квадрат = fn ( x ) -> x * x end
Enum . карта [ 1 , 2 , 3 , 4 ], квадрат
#=> [1, 4, 9, 16]
Эрланг [ править ]
Erlang использует синтаксис анонимных функций, аналогичный синтаксису именованных функций. [16]
% Анонимная функция, привязанная к переменной Square
Square = fun ( X ) -> X * X end .
% Именованная функция с той же функциональностью
Square ( X ) - X * X. >
Иди [ править ]
Go поддерживает анонимные функции. [21]
foo := func ( x int ) int {
return x * x
}
fmt . println ( фу ( 10 ))
Хаскелл [ править ]
Haskell использует краткий синтаксис для анонимных функций (лямбда-выражений). Обратная косая черта должна напоминать λ.
\ х -> х * х
Лямбда-выражения полностью интегрированы с механизмом вывода типов и поддерживают весь синтаксис и функции «обычных» функций (за исключением использования нескольких определений для сопоставления с образцом, поскольку список аргументов указывается только один раз).
map ( \ x -> x * x ) [ 1 .. 5 ] — возвращает [1, 4, 9, 16, 25]
Все следующие эквивалентны:
f x y = x + y
f x = \ y -> x + y
f = \ x y -> x + y
Хаксе [ править ]
В Haxe анонимные функции называются лямбда и используют синтаксис function(argument-list) expression;
.
var f = функция ( x ) return x * x ;
ж ( 8 ); // 64
( функция ( x , y ) возвращает x + y )( 5 , 6 ); // 11
Ява [ править ]
Java поддерживает анонимные функции, называемые Lambda Expressions , начиная с JDK 8 . [60]
Лямбда-выражение состоит из разделенного запятыми списка формальных параметров, заключенных в круглые скобки, токена со стрелкой ( ->
) и тело. Типы данных параметров всегда можно опустить, как и круглые скобки, если имеется только один параметр. Тело может состоять из одного оператора или блока операторов. [61]
// без параметра
() -> System . вне . println ( "Привет, мир." )
// с одним параметром (этот пример — идентификационная функция).
a -> a
// с одним выражением
( a , b ) -> a + b
// с явной информацией о типе
( длинный идентификатор , строки имя ) -> "id: " + id + ", name:" + name
// с блоком кода
( a , b ) -> { return a + b ; }
// с несколькими операторами в теле лямбды. Ему нужен блок кода.
// Этот пример также включает два вложенных лямбда-выражения (первое из них также является замыканием).
( id , defaultPrice ) -> {
Необязательно < Продукт > Product = ProductList . транслировать (). фильтр ( p -> p . getId () == id ). НайтиПервый ();
возврат товара . карта ( p -> p . getPrice ()). илиЕльсе ( Цена по умолчанию );
}
Лямбда-выражения преобразуются в «функциональные интерфейсы» (определяемые как интерфейсы, которые содержат только один абстрактный метод в дополнение к одному или нескольким методам по умолчанию или статическим методам). [61] как в следующем примере:
общественного класса Калькулятор {
интерфейс IntegerMath {
int операция ( int a , int b );
по умолчанию IntegerMath swap () {
return ( a , b ) -> операция ( b , a );
}
}
Private static int apply ( int a , int b , IntegerMath op ) {
return op . операция ( а , б );
}
Public static void main ( String ... args ) {
IntegerMath дополнение = ( a , b ) -> a + b ;
IntegerMath Вычитание = ( a , b ) -> a - b ;
Система . вне . println ( "40 + 2 = " + применить ( 40 , 2 , сложение ));
Система . вне . println ( "20 - 10 =" + применить ( 20 , 10 , вычитание ));
Система . вне . println ( "10 - 20 = " + применить ( 20 , 10 , вычитание . поменять местами ()));
}
}
В этом примере функциональный интерфейс под названием IntegerMath
объявлено. Лямбда-выражения, реализующие IntegerMath
передаются в apply()
метод, который будет выполнен. Методы по умолчанию, такие как swap
определить методы для функций.
В Java 8 появился еще один механизм, названный ссылкой на метод (метод ::
оператор) для создания лямбда-выражения для существующего метода. Ссылка на метод не указывает количество или типы аргументов, поскольку они извлекаются из абстрактного метода функционального интерфейса.
IntBinaryOperator sum = Integer :: sum ;
В приведенном выше примере функциональный интерфейс IntBinaryOperator
объявляет абстрактный метод int applyAsInt(int, int)
, поэтому компилятор ищет метод int sum(int, int)
в классе java.lang.Integer
.
Отличия от анонимных классов [ править ]
Анонимные классы лямбда-совместимых интерфейсов похожи, но не совсем эквивалентны лямбда-выражениям.
Для иллюстрации на следующем примере: anonymousClass
и lambdaExpression
оба являются экземплярами IntegerMath
которые добавляют два параметра:
IntegerMathonymousClass ; = new IntegerMath ( {
@Override
public int Operation ( int a , int b ) {
return a + b )
}
};
IntegerMath лямбда-выражение = ( a , b ) -> a + b ;
Основное отличие здесь заключается в том, что лямбда-выражению не обязательно нужно выделять новый экземпляр для IntegerMath
и может возвращать один и тот же экземпляр каждый раз при запуске этого кода. [62]
Кроме того, по крайней мере, в реализации OpenJDK лямбды компилируются в вызывать динамические инструкции, в которых тело лямбда-выражения вставлено как статический метод в окружающий класс, [63] вместо того, чтобы полностью создавать новый файл класса.
Ограничения Java [ править ]
Лямбды Java 8 имеют следующие ограничения:
- Лямбды могут генерировать проверенные исключения, но такие лямбды не будут работать с интерфейсами, используемыми API коллекции.
- Переменные, находящиеся в области, в которой объявлена лямбда, могут быть доступны внутри лямбды только в том случае, если они фактически являются окончательными, т. е. если переменная не мутируется внутри или за пределами области лямбда.
JavaScript [ править ]
JavaScript / ECMAScript поддерживает анонимные функции.
предупреждение (( функция ( x ) {
return x * x ;
}) ( 10 ));
ES6 поддерживает синтаксис «стрелочной функции», где символ => отделяет список параметров анонимной функции от тела:
оповещение (( x => x * x )( 10 ));
Эта конструкция часто используется в Букмарклетах . Например, чтобы изменить заголовок текущего документа (видимый в строке заголовка его окна ) на его URL-адрес , может показаться, что работает следующий букмарклет.
документ . заголовок = местоположение . href ;
Однако, поскольку оператор присваивания возвращает значение (сам URL-адрес), многие браузеры фактически создают новую страницу для отображения этого значения.
Вместо этого можно использовать анонимную функцию, которая не возвращает значение:
( функция () { document . title = location . href ;})();
Оператор функции в первой (внешней) паре круглых скобок объявляет анонимную функцию, которая затем выполняется при использовании с последней парой круглых скобок. Это почти эквивалентно следующему, которое заполняет среду f
в отличие от анонимной функции.
вар f = функция () { документ . заголовок = местоположение . href ;}; е ();
Используйте void() , чтобы избежать появления новых страниц для произвольных анонимных функций:
void ( function () { return document . title = location . href ;}());
или просто:
void ( document.title location.href = ) ;
В JavaScript есть синтаксические тонкости определения, вызова и оценки анонимных функций. Эти подсознательные нюансы являются прямым следствием оценки выражений в скобках. следующие конструкции, которые называются выражением немедленно вызываемой функции Это иллюстрируют :
( функция (){ ... }())
и
( функция (){ ... })()
Представляя " function(){ ... }
" к f
, форма конструкций
скобка внутри скобки (f())
и скобка применяется к скобке (f)()
.
Обратите внимание на общую синтаксическую неоднозначность выражения в скобках, аргументов функции в скобках и круглых скобок вокруг формальных параметров в определении функции. В частности, JavaScript определяет ,
(запятая) в контексте выражения в скобках. То, что синтаксические формы выражения и аргументов функции совпадают (без учета синтаксиса формальных параметров функции) – не простое совпадение! Если f
не идентифицируется в приведенных выше конструкциях, они становятся (())
и ()()
. Первый не дает синтаксического намека на какую-либо резидентную функцию, но второй ДОЛЖЕН оценить первую скобку как функцию, чтобы быть законным JavaScript. (Кроме того: например, ()
может быть ([],{},42,"abc",function(){}), если выражение оценивается как функция.)
Кроме того, функция является экземпляром объекта (аналогично объекты являются экземплярами функции), а скобки для обозначения литерала объекта: {}
для кода со скобками используются при таком определении функции (в отличие от использования new Function(...)
). В очень широком, нестрогом смысле (особенно учитывая, что глобальные привязки скомпрометированы), произвольная последовательность операторов JavaScript в фигурных скобках, {stuff}
, можно считать фиксированной точкой
( функция (){( функция (){( ... {( функция (){ материал }() )} ... )}() )}() )
Правильнее, но с оговорками,
( функция () { материал }() ) ~=
A_Fixed_Point_of (
функция () { возврата функция () { возврат ... { возврата функция () { материал }() } ... }() }()
)
Обратите внимание на значение анонимной функции в следующих фрагментах JavaScript:
function(){ ... }()
без окружения()
это вообще не законно(f=function(){ ... })
не «забывает»f
глобально непохожий(function f(){ ... })
- производительности Метрики для анализа пространственных и временных сложностей вызовов функций, стека вызовов и т. д. в интерпретатора механизме JavaScript легко реализуются с помощью этих последних анонимных функциональных конструкций. Из последствий результатов можно сделать вывод о некоторых деталях рекурсивной и итеративной реализации движка, особенно о хвостовой рекурсии .
Julia[editДжулия
В Julia анонимные функции определяются с использованием синтаксиса (arguments)->(expression)
,
Юлия> ж = х -> х * х ; ж ( 8 )
64
Юлия> (( x , y ) -> x + y )( 5 , 6 )
11
Котлин [ править ]
Котлин поддерживает анонимные функции с синтаксисом {arguments -> expression}
,
val sum = { x : Int , y : Int -> x + y }
sum ( 5 , 6 ) // возвращает 11
val Even = { x : Int -> x % 2 == 0 }
Even ( 4 ) // возвращает истинный
Лисп [ править ]
Lisp и Scheme поддерживают анонимные функции с использованием конструкции «лямбда», которая является ссылкой на лямбда-исчисление . Clojure поддерживает анонимные функции со специальной формой «fn» и синтаксисом чтения #().
( лямбда ( аргумент ) ( * аргумент аргумент ))
Общий Лисп [ править ]
В Common Lisp есть концепция лямбда-выражений. Лямбда-выражение записывается в виде списка с символом «лямбда» в качестве первого элемента. Затем список содержит список аргументов, документацию или объявления и тело функции. Лямбда-выражения можно использовать внутри лямбда-форм и со специальным оператором «функция».
( функция ( лямбда ( arg ) ( сделать что-нибудь arg )))
«функция» может быть сокращена до #'. Кроме того, существует лямбда -макрос , который расширяется до функциональной формы:
; использование резкой кавычки
#' ( лямбда ( arg ) ( сделай что-нибудь arg ))
; используя лямбда-макрос:
( лямбда ( arg ) ( сделать что-нибудь arg ))
Одним из типичных применений анонимных функций в Common Lisp является передача их функциям более высокого порядка, таким как Mapcar , который применяет функцию к каждому элементу списка и возвращает список результатов.
( mapcar #' ( лямбда ( x ) ( * x x ))
' ( 1 2 3 4 ) )
; -> (1 4 9 16)
Лямбда -форма в Common Lisp позволяет лямбда-выражение записать при вызове функции:
(( лямбда ( x y )
( + ( sqrt x ) ( sqrt y )))
10,0
12,0 )
Анонимным функциям в Common Lisp позже можно будет дать глобальные имена:
( setf ( символ-функция 'sqr )
( лямбда ( x ) ( * x x )))
; что позволяет нам вызывать его, используя имя SQR:
( sqr 10.0 )
Схема [ править ]
Scheme Именованные функции — это просто синтаксический сахар для анонимных функций, привязанных к именам:
( определить ( некое имя arg )
( сделать что-нибудь arg ))
расширяется (и эквивалентно) до
( определить какое-нибудь имя
( лямбда ( arg )
( сделать что-нибудь arg )))
Кложур [ править ]
Clojure поддерживает анонимные функции через специальную форму «fn»:
( фн [х] ( + х 3 ))
Существует также синтаксис чтения для определения лямбды:
#( + % %2%3 ) ; Определяет анонимную функцию, которая принимает три аргумента и суммирует их.
Как и Scheme, «именованные функции» Clojure — это просто синтаксический сахар для лямбда-выражений, привязанных к именам:
( defn func [arg] ( + 3 arg ))
расширяется до:
( def func ( fn [arg] ( + 3 arg )))
Возьмите [ править ]
В Lua (как и в Scheme) все функции анонимны. Именованная функция в Lua — это просто переменная, содержащая ссылку на объект функции. [64]
Таким образом, в Луа
функция foo ( x ) возвращает 2 * x конец
это просто синтаксический сахар для
foo = функция ( x ) возвращает 2 * x конец
Пример использования анонимных функций для сортировки в обратном порядке:
table.sort ( сеть , функция ( a , b )
возвращает a . name > b . name
end )
Язык Wolfram, Mathematica [ править ]
Wolfram Language — это язык программирования Mathematica . Анонимные функции важны при программировании последних. Есть несколько способов их создания. Ниже приведены несколько анонимных функций, которые увеличивают число. Первый является наиболее распространенным. #1
относится к первому аргументу и &
отмечает конец анонимной функции.
#1 + 1 &
Функция [ x , x + 1 ]
x \ [ Функция ] x + 1
Так, например:
ж := #1 ^ 2 & ; ж [ 8 ]
64
#1 + #2 и [ 5 , 6 ]
11
Кроме того, в Mathematica есть добавленная конструкция для создания рекурсивных анонимных функций. Символ «#0» относится ко всей функции. Следующая функция вычисляет факториал входных данных:
Если [ #1 == 1 , 1 , #1 * #0 [ #1 -1 ]] &
Например, 6-факториал будет выглядеть так:
Если [ #1 == 1 , 1 , #1 * #0 [ #1 -1 ]] & [ 6 ]
720
MATLAB, Октава [ править ]
Анонимные функции в MATLAB или Octave определяются с использованием синтаксиса @(argument-list)expression
. Любые переменные, которые не найдены в списке аргументов, наследуются из окружающей области и фиксируются по значению.
>> е = @( х ) х * х ; f ( 8 )
ans = 64
>> (@( x , y ) x + y )( 5 , 6 ) % Работает только в октаве
ans = 11
Максима [ править ]
В Maxima анонимные функции определяются с использованием синтаксиса lambda(argument-list,expression)
,
f : лямбда ([ x ], x * x ); ж ( 8 );
64
лямбда ([ x , y ], x + y )( 5 , 6 );
11
МЛ [ править ]
Различные диалекты ML поддерживают анонимные функции.
OCaml [ править ]
Анонимные функции в OCaml — это функции без объявленного имени. Вот пример анонимной функции, которая умножает свои входные данные на два:
весело х -> х * 2
В этом примере fun — это ключевое слово, указывающее, что функция является анонимной. Мы передаем аргумент x и ->, чтобы отделить аргумент от тела. [65]
Ф# [ править ]
F# поддерживает анонимные функции, [17] следующее:
( весело x -> x * x ) 20 // 400
Стандартный ML [ править ]
Стандартное машинное обучение поддерживает следующие анонимные функции:
fn злой => злой * злой
Nim [ edit ]
Nim поддерживает многострочные анонимные функции с несколькими выражениями. [33]
var anon = proc ( var1 , var2 : int ): int = var1 + var2
утверждать anon ( 1 , 2 ) == 3
Многострочный пример:
var anon = func ( x : int ): bool =
if x > 0 :
result = true
else :
result = false
утверждать anon ( 9 )
Анонимные функции могут передаваться в качестве входных параметров других функций:
var города = @[ "Франкфурт" , "Токио" , "Нью-Йорк" ]
города . сортировка (
proc ( x , y : строка ): int = cmp ( x . len , y . len )
)
Анонимная функция — это, по сути, функция без имени.
Перл [ править ]
Перл 5 [ править ]
Perl 5 поддерживает анонимные функции, [37] следующее:
( sub { print "Мне позвонили\n" }) -> (); # 1. полностью анонимный, вызывается как созданный
my $squarer = sub { my $x = shift ; $х * $х }; # 2. присвоено переменной
sub curry {
my ( $sub , @args ) = @_ ;
return sub { $sub -> ( @args , @_ ) }; # 3. как возвращаемое значение другой функции
}
# пример каррирования в программировании на Perl
sub sum { my $tot = 0 ; $tot += $_ для @_ ; $tot } # возвращает сумму своих аргументов
my $curried = curry \& sum , 5 , 7 , 9 ;
напечатайте $curried -> ( 1 , 2 , 3 ), "\n" ; # печатает 27 (= 5 + 7 + 9 + 1 + 2 + 3)
Другие конструкции принимают в качестве аргументов голые блоки , которые выполняют функцию, аналогичную лямбда-функциям с одним параметром, но не имеют того же соглашения о передаче параметров, что и функции — @_ не установлен.
мои @squares = map { $_ * $_ } 1 .. 10 ; # карты и grep не используют ключевое слово sub
my @square2 = map $_ * $_ , 1 .. 10 ; # скобки не нужны для одного выражения
my @bad_example = map { print for @_ } 1 .. 10 ; # значения не передаются, как обычная функция Perl
PHP [ править ]
До версии 4.0.1 в PHP не было поддержки анонимных функций. [66]
PHP с 4.0.1 по 5.3 [ править ]
PHP 4.0.1 представил create_function
это была первоначальная поддержка анонимных функций. Этот вызов функции создает новую функцию со случайным именем и возвращает ее имя (в виде строки).
$foo = create_function ( '$x' , 'return $x*$x;' );
$bar = create_function ( " \$ x" , "return \$ x* \$ x;" );
эхо $foo ( 10 );
Список аргументов и тело функции должны быть заключены в одинарные кавычки или знаки доллара должны быть экранированы.
В противном случае PHP предполагает " $x
" означает переменную $x
и заменит его в строку (несмотря на то, что он, возможно, не существует) вместо того, чтобы оставить " $x
"в строке.
Для функций с кавычками или функций со многими переменными может оказаться довольно утомительным проверять, соответствует ли тело предполагаемой функции тому, что интерпретирует PHP.
Каждый вызов create_function
создает новую функцию, которая существует для остальной части программы и не может быть удалена сборщиком мусора , необратимо используя память в программе. Если это используется для создания анонимных функций много раз, например, в цикле, это может вызвать такие проблемы, как раздувание памяти.
PHP 5.3 [ править ]
В PHP 5.3 добавлен новый класс под названием Closure
и волшебный метод __invoke()
это делает экземпляр класса вызываемым. [67]
$х = 3 ;
$func = функция ( $z ) { возвращение $z * 2 ; };
эхо $func ( $x ); // печатает 6
В этом примере $func
является примером Closure
и echo $func($x)
эквивалентно echo $func->__invoke($x)
.
PHP 5.3 имитирует анонимные функции, но не поддерживает настоящие анонимные функции, поскольку функции PHP по-прежнему не являются объектами первого класса.
PHP 5.3 поддерживает замыкания, но переменные должны быть явно указаны как таковые:
$х = 3 ;
$func = function () use ( & $x ) { $x *= 2 ; };
$функ ();
эхо $х ; // печатает 6
Переменная $x
связан ссылкой, поэтому вызов $func
изменяет его, и изменения видны вне функции.
PHP 7.4 [ править ]
Функции стрелок были представлены в PHP 7.4.
$х = 3 ;
$func = fn ( $z ) => $z * 2 ;
эхо $func ( $x ); // печатает 6
Диалекты Пролога [ править ]
ЛогТок [ править ]
Logtalk использует следующий синтаксис для анонимных предикатов (лямбда-выражений):
{ FreeVar1 , FreeVar2 , ... } / [ LambdaParameter1 , LambdaParameter2 , ...] >> Цель
Простой пример без свободных переменных и с использованием предиката сопоставления списка:
| ?- мета :: map([ X , Y ] >> ( Y равно 2 * X ), [ 1 , 2 , 3 ], Ys ).
Ys = [ 2 , 4 , 6 ]
да
Также поддерживается каррирование. Приведенный выше пример можно записать так:
| ?- мета :: map([ X ] >> ([ Y ] >> ( Y равно 2 * X )), [ 1 , 2 , 3 ], Ys ).
Ys = [ 2 , 4 , 6 ]
да
Визуальный Пролог [ править ]
Анонимные функции (в общем анонимные предикаты ) были введены в Visual Prolog в версии 7.2. [68] Анонимные предикаты могут захватывать значения из контекста. Если он создан в члене объекта, он также может получить доступ к состоянию объекта (путем захвата This
).
mkAdder
возвращает анонимную функцию, которая захватила аргумент X
в закрытии. Возвращаемая функция — это функция, которая добавляет X
на его аргумент:
предложения
mkAdder ( X ) = { ( Y ) = X + Y }.
Питон [ править ]
Python поддерживает простые анонимные функции через лямбда-форму. [39] Исполняемое тело лямбды должно быть выражением и не может быть инструкцией, что является ограничением, ограничивающим ее полезность. Значение, возвращаемое лямбда-выражением, является значением содержащегося выражения. Лямбда-формы можно использовать везде, где можно использовать обычные функции. Однако эти ограничения делают его очень ограниченной версией обычной функции. Вот пример:
>>> foo = лямбда x : x * x
>>> foo ( 10 )
100
В целом, соглашение Python поощряет использование именованных функций, определенных в той же области, что и анонимные функции в других языках. Это приемлемо, поскольку локально определенные функции реализуют всю мощь замыканий и почти так же эффективны, как использование лямбда-выражений в Python. В этом примере можно сказать, что встроенная степенная функция была каррирована :
>>> def make_pow ( n ):
... def фиксированная_экспонента_pow ( x ):
... return pow ( x , n )
... return фиксированная_экспонента_pow
...
>>> sqr = make_pow ( 2 )
>>> sqr ( 10 )
100
>>> куб = make_pow ( 3 )
>>> куб ( 10 )
1000
Р [ править ]
В R анонимные функции определяются с использованием синтаксиса function(argument-list)expression
, который имеет сокращение начиная с версии 4.1.0 \
, аналог Хаскеля.
> f <- функция ( x ) x * x ; f ( 8 )
[1] 64
> ( функция ( x , y ) x + y )( 5 , 6 )
[1] 11
> # Поскольку R 4.1.0
> ( \ ( x , y ) x + y )( 5 , 6 )
[1] 11
Раку [ править ]
В Raku все блоки (даже связанные с if, while и т.п.) являются анонимными функциями. Блок, который не используется в качестве значения r, выполняется немедленно.
- полностью анонимный, называется как созданный
{ сказать «Мне позвонили» };
- присвоено переменной
мой $squarer1 = -> $x { $x * $x }; № 2а. заостренный блок my $squarer2 = { $^x * $^x }; № 2б. twigil my $squarer3 = { my $x = сдвиг @_ ; $х * $х }; № 2в. Стиль Перл 5
- карри
sub add ( $m , $n ) { $m + $n } мой $seven = добавить ( 3 , 4 ); мой $add_one = &add . предполагая ( m => 1); мой $eight = $add_one ( $seven );
- Объект WhatWordCode
мой $w = * - 1 ; # Объект WhatCode my $b = { $_ - 1 }; # та же функциональность, но как блок Callable
Руби [ править ]
Ruby поддерживает анонимные функции, используя синтаксическую структуру, называемую блоком . В Ruby существует два типа данных для блоков. Proc
s ведут себя аналогично замыканиям , тогда как lambda
s ведут себя более похоже на анонимную функцию. [42] При передаче методу блок в некоторых случаях преобразуется в Proc.
# Пример 1:
# Чисто анонимные функции, использующие блоки.
бывший = [ 16 . 2 , 24 . 1 , 48 . 3 , 32 . 4 , 8 . 5 ]
=> [ 16 . 2 , 24 . 1 , 48 . 3 , 32 . 4 , 8 . 5 ]
пр . сортировка_по { | х | х - х . to_i } # Сортировка по дробной части, игнорируя целую часть.
=> [ 24 . 1 , 16 . 2 , 48 . 3 , 32 . 4 , 8 . 5 ]
# Пример 2:
# Функции первого класса как явный объект Proc -
ex = Proc . new { помещает "Привет, мир!" }
=> #<Proc:0x007ff4598705a0@(irb):7>
ex . звонок
Привет , мир!
=> nil
# Пример 3:
# Функция, которая возвращает объект лямбда-функции с параметрами
def Multiple_of? ( п )
лямбда { | х | x % n == 0 }
end
=> ноль
Multiple_four = Multiple_of? ( 4 )
=> #<Proc:0x007ff458b45f88@(irb):12 (лямбда)>
Multiple_four . вызов ( 16 )
=> true
Multiple_four [ 15 ]
=> false
Ржавчина [ править ]
В Rust анонимные функции называются замыканиями. [69] Они определяются с использованием следующего синтаксиса:
|< параметр - имя > : < тип >| -> < возврат - тип > { < тело > };
Например:
пусть ж = | х : i32 | -> i32 { х * 2 };
Однако с помощью вывода типа компилятор может определить тип каждого параметра и тип возвращаемого значения, поэтому приведенную выше форму можно записать как:
пусть ж = | х | { х * 2 };
При замыканиях с одним выражением (т. е. телом с одной строкой) и неявным возвращаемым типом фигурные скобки можно опустить:
пусть ж = | х | х * 2 ;
Замыкания без входного параметра записываются так:
пусть f = || распечататьлн! ( "Привет, мир!" );
Замыкания могут передаваться в качестве входных параметров функций, которые ожидают указатель на функцию:
// Функция, которая принимает указатель функции в качестве аргумента и вызывает ее
// со значением `5`.
fn apply ( f : fn ( i32 ) -> i32 ) -> i32 {
// Нет точки с запятой, чтобы указать неявный возврат
f ( 5 )
}
fn main () {
// Определение замыкания
let f = | х | х * 2 ;
распечататьлн! ( "{}" , применить ( f )); // 10
println! ( "{}" , f ( 5 )); // 10
}
Однако для описания того, как фиксируются значения в теле замыкания, могут потребоваться сложные правила. Они реализуются с помощью Fn
, FnMut
, и FnOnce
черты: [70]
Fn
: замыкание фиксируется по ссылке (&T
). Они используются для функций, которые все еще можно вызывать, если у них есть только ссылочный доступ (с&
) к окружающей среде.FnMut
: замыкание фиксируется по изменяемой ссылке (&mut T
). Они используются для функций, которые можно вызывать, если у них есть доступ к изменяемым ссылкам (с&mut
) к окружающей среде.FnOnce
: замыкание захватывает по значению (T
). Они используются для функций, которые вызываются только один раз.
Благодаря этим особенностям компилятор будет захватывать переменные наименее ограничительным образом. [70] Они помогают управлять тем, как значения перемещаются между областями действия, что очень важно, поскольку Rust следует конструкции жизненного цикла, чтобы гарантировать, что значения «заимствованы» и перемещены предсказуемым и явным образом. [71]
Ниже показано, как можно передать замыкание в качестве входного параметра, используя метод Fn
черта:
// Функция, которая принимает значение типа F (который определяется как
// универсальный тип, реализующий признак `Fn`, например замыкание)
// и вызывает его со значением `5`.
fn apply_by_ref < F > ( f : F ) -> i32
где F : Fn ( i32 ) -> i32
{
f ( 5 )
}
fn main () {
let f = | х | {
печать! ( «Я получил значение: {}» , x );
х * 2
};
// Применяет функцию перед печатью возвращаемого значения
println! ( "5 * 2 = {}" , apply_by_ref ( f ));
}
// ~~ Вывод программы ~~
// Я получил значение: 5
// 5 * 2 = 10
Предыдущее определение функции также можно для удобства сократить следующим образом:
fn apply_by_ref ( f : impl Fn ( i32 ) -> i32 ) -> i32 {
f ( 5 )
}
Скала [ править ]
В Scala анонимные функции используют следующий синтаксис: [72]
( x : Int , y : Int ) => x + y
В определенных контекстах, например, когда анонимная функция является параметром, передаваемым другой функции, компилятор может определить типы параметров анонимной функции, и они могут быть опущены в синтаксисе. В таких контекстах также можно использовать сокращение анонимных функций, используя символ подчеркивания для введения безымянных параметров.
значений список = Список ( 1 , 2 , 3 , 4 )
список . уменьшитьLeft ( ( x , y ) => x + y )
// Здесь компилятор может сделать вывод, что оба типа x и y — Int.
// Таким образом, аннотации типов для параметров анонимной функции не требуются.
список . уменьшитьLeft ( _ + _ )
// Каждое подчеркивание обозначает новый безымянный параметр в анонимной функции.
// Это приводит к еще более короткому эквиваленту анонимной функции, указанной выше.
Смолток [ править ]
В Smalltalk анонимные функции называются блоками и вызываются (вызываются) путем отправки им сообщения «значение». Если необходимо передать несколько аргументов, необходимо использовать сообщение «value:...value:» с соответствующим количеством аргументов-значений.
Например, в GNU Smalltalk
ст > ж := [ : х | х * х ] . значение f : 8 .
64
ст> [ : x : y | x + y ] значение: 5 значение: 6 .
11
Блоки Smalltalk технически являются замыканиями, что позволяет им выйти за рамки своей определяющей области и по-прежнему ссылаться на объявленные в них переменные.
ст > ж := [ : а | [ : н | a + n ]] значение: 100 .
BlockClosure a
«возвращает внутренний блок, который добавляет 100 (захваченных в переменной « » ) к своему аргументу».
st> f значение : 1 .
101
ст> f значение : 2 .
102
Свифт [ править ]
В Swift анонимные функции называются замыканиями. [46] Синтаксис имеет следующую форму:
{ ( параметры ) -> returnType в
операторе
}
Например:
{ ( s1 : String , s2 : String ) -> Bool в
ответ s1 > s2
}
Для краткости и выразительности типы параметров и тип возвращаемого значения можно опустить, если их можно вывести:
{ s1 , s2 взамен s1 > s2 }
Аналогичным образом, Swift также поддерживает неявные операторы возврата для замыканий с одним оператором:
{ s1 , s2 в s1 > s2 }
Наконец, имена параметров также можно опустить; если они опущены, ссылки на параметры используются с использованием сокращенных имен аргументов, состоящих из символа $, за которым следует их позиция (например, $0, $1, $2 и т. д.):
{ $0 > $1 }
ТКЛ [ править ]
В Tcl применение анонимной функции возведения в квадрат к 2 выглядит следующим образом: [73]
apply { x {expr { $x * $x }}} 2
# возвращает 4
В этом примере участвуют два кандидата на роль функции в Tcl. Самый общий вариант обычно называется префиксом команды , и если переменная f содержит такую функцию, то способ выполнения приложения функции f ( x ) будет следующим:
{ * } $f $x
где {*}
— префикс расширения (новый в Tcl 8.5). Префикс команды в приведенном выше примере:
применять {x {expr {$x*$x}}}
Имена команд могут быть привязаны к префиксам команд с помощью interp alias
команда. Префиксы команд поддерживают каррирование . Префиксы команд очень распространены в API Tcl .
Другой кандидат на роль «функции» в Tcl обычно называется лямбда и выглядит как {x {expr {$x*$x}}}
часть приведенного выше примера. Это часть, которая кэширует скомпилированную форму анонимной функции, но ее можно вызвать только путем передачи в функцию. apply
команда. Лямбды не поддерживают каррирование, если только они не объединены с apply
для формирования префикса команды. Лямбды редко встречаются в API Tcl.
Вала [ править ]
В Vala анонимные функции поддерживаются как лямбда-выражения. [74]
делегат int IntOp ( int x , int y );
void main () {
IntOp foo = ( x , y ) => x * y ;
стандартный вывод . printf ( "%d \n " , foo ( 10 , 5 ));
}
Visual Basic .NET [ править ]
Visual Basic .NET 2008 представил анонимные функции через лямбда-форму. В сочетании с неявной типизацией VB обеспечивает экономичный синтаксис для анонимных функций. Как и в Python, в VB.NET анонимные функции должны быть определены в одной строке; они не могут быть составными утверждениями. Более того, анонимная функция в VB.NET должна действительно быть функцией VB.NET. Function
- он должен возвращать значение.
Dim foo = Функция ( x ) x * x
Консоль . WriteLine ( фу ( 10 ))
В Visual Basic.NET 2010 добавлена поддержка многострочных лямбда-выражений и анонимных функций без возвращаемого значения. Например, функция для использования в потоке.
Dim t As New System . Резьба . Thread ( Sub ()
For n As Integer = 0 до 10 'Считаем до 10
Console.WriteLine от ' Распечатываем ( n ) каждое число
Next
End Sub
)
t . Начинать ()
См. также [ править ]
Ссылки [ править ]
- ^ «Функции высшего порядка» . Learnyouahaskell.com . Проверено 3 декабря 2014 г.
- ^ Фернандес, Марибель (2009), Модели вычислений: введение в теорию вычислимости , Темы бакалавриата по информатике, Springer Science & Business Media, стр. 33, ISBN 9781848824348 ,
Лямбда-исчисление ... было введено Алонзо Чёрчем в 1930-х годах как точное обозначение теории анонимных функций.
- ^ «Выражения стрелочных функций — JavaScript» . МДН . Проверено 21 августа 2019 г.
- ^ «Баш лямбда» . Гитхаб . 08.03.2019.
- ^ БиллВагнер. «Лямбда-выражения — справочник по C#» . docs.microsoft.com . Проверено 24 ноября 2020 г.
- ^ «Поддержка закрытия» . Архивировано из оригинала 6 января 2014 г. Проверено 5 января 2014 г.
- ^ «Что нового в ColdFusion 10» . Архивировано из оригинала 6 января 2014 г. Проверено 5 января 2014 г.
- ^ «Clojure — функции высшего порядка» . Clojure.org . Проверено 14 января 2022 г.
- ^ «Управляемый справочник COBOL» . Документация Микро Фокус . Микро Фокус . Архивировано из оригинала 25 февраля 2014 года . Проверено 25 февраля 2014 г.
- ^ «Функции — язык программирования D» . dlang.org . Проверено 14 января 2022 г.
- ^ Перейти обратно: а б «Экскурсия по языку дартс» . dart.dev . Проверено 24 ноября 2020 г.
- ^ «Анонимные методы в Delphi — RAD Studio» . docwiki.embarcadero.com . Проверено 24 ноября 2020 г.
- ^ «Функции — Программирование Дилана» . opendylan.org . Проверено 14 января 2022 г.
- ^ «документы/синтаксис» . elm-lang.org . Проверено 14 января 2022 г.
- ^ Перейти обратно: а б «Синтаксис Erlang/Elixir: ускоренный курс» . эликсир-lang.github.com . Проверено 24 ноября 2020 г.
- ^ Перейти обратно: а б «Эрланг -- Забавы» . erlang.org . Проверено 24 ноября 2020 г.
- ^ Перейти обратно: а б Картермп. «Лямбда-выражения: забавное ключевое слово — F#» . docs.microsoft.com . Проверено 24 ноября 2020 г.
- ^ «LAMBDA: совершенная функция рабочего листа Excel» . microsoft.com . 25 января 2021 г. Проверено 30 марта 2021 г.
- ^ «Котировки – Факторная документация» . Проверено 26 декабря 2015 г.
Цитата — это анонимная функция (значение, обозначающее фрагмент кода), которую можно использовать в качестве значения и вызывать с помощью фундаментальных комбинаторов.
- ^ «Фринк» . frinklang.org . Проверено 24 ноября 2020 г.
- ^ Перейти обратно: а б «Анонимные функции в GoLang» . Документы GoLang . 9 января 2020 г. Проверено 24 ноября 2020 г.
- ^ «Документация Госу» (PDF) . Проверено 4 марта 2013 г.
- ^ «Отличная документация» . Архивировано из оригинала 22 мая 2012 года . Проверено 29 мая 2012 г.
- ^ «Анонимная функция — HaskellWiki» . wiki.haskell.org . Проверено 14 января 2022 г.
- ^ «Лямбда» . Haxe — Кроссплатформенный набор инструментов . Проверено 14 января 2022 г.
- ^ «Функции — JavaScript | MDN» . http://developer.mozilla.org . Проверено 14 января 2022 г.
- ^ «Функции · Язык Джулии» . docs.julialang.org . Проверено 24 ноября 2020 г.
- ^ «Функции высшего порядка и лямбды — язык программирования Kotlin» . Котлин . Проверено 24 ноября 2020 г.
- ^ «Программирование на Lua: 6» . www.lua.org . Проверено 24 ноября 2020 г.
- ^ «Программирование на Maple: 1.6: Анонимные функции и выражения — Центр приложений» . www.maplesoft.com . Проверено 24 ноября 2020 г.
- ^ «Анонимные функции — MATLAB и Simulink» . www.mathworks.com . Проверено 14 января 2022 г.
- ^ «Руководство Maxima 5.17.1: 39. Определение функций» . maths.cnam.fr . Проверено 24 ноября 2020 г.
- ^ Перейти обратно: а б «Руководство Нима» . nim-lang.github.io .
- ^ «Примеры кода — OCaml» . ocaml.org . Проверено 24 ноября 2020 г.
- ^ «GNU Octave: анонимные функции» . Octave.org . Проверено 24 ноября 2020 г.
- ^ «Функциональные литералы» . Руководство пользователя OpenSCAD . Викикниги . Проверено 22 февраля 2021 г.
- ^ Перейти обратно: а б «perlsub — Подпрограммы Perl — Браузер Perldoc» . perldoc.perl.org . Проверено 24 ноября 2020 г.
- ^ «PHP: Анонимные функции — Руководство» . www.php.net . Проверено 24 ноября 2020 г.
- ^ Перейти обратно: а б «6. Выражения — документация Python 3.9.0» . docs.python.org . Проверено 24 ноября 2020 г.
- ^ «4.4 Функции: лямбда» . docs.racket-lang.org . Проверено 24 ноября 2020 г.
- ^ «Функции» . docs.raku.org . Проверено 14 января 2022 г.
- ^ Перейти обратно: а б Сосински, Роберт (21 декабря 2008 г.). «Понимание блоков Ruby, процедур и лямбд» . Реактивный.ИО. Архивировано из оригинала 31 мая 2014 г. Проверено 30 мая 2014 г.
- ^ «Замыкания: анонимные функции, которые могут захватывать свое окружение — язык программирования Rust» . doc.rust-lang.org . Проверено 14 января 2022 г.
- ^ «Анонимные функции» . Документация Скала . Проверено 14 января 2022 г.
- ^ «Декламация 3: Функции высшего порядка» . www.cs.cornell.edu . Проверено 14 января 2022 г.
- ^ Перейти обратно: а б «Замыкания — язык программирования Swift (Swift 5.5)» . docs.swift.org .
- ^ «Документация — повседневные типы» . www.typescriptlang.org . Проверено 14 января 2022 г.
- ^ Перейти обратно: а б «Проекты/Вала/Руководство — GNOME Wiki!» . Wiki.gnome.org . Проверено 24 ноября 2020 г.
- ^ Кэтлин Доллард (15 сентября 2021 г.). «Лямбда-выражения — Visual Basic» . docs.microsoft.com . Проверено 14 января 2022 г.
- ^ «Справочник по языку/Термины/Анонимные предикаты — wiki.visual-prolog.com» . wiki.visual-prolog.com . Проверено 14 января 2022 г.
- ^ «Чистая анонимная функция: элементарное введение в язык Wolfram» . www.wolfram.com . Проверено 14 января 2022 г.
- ^ «Лямбды, замыкания и все, что между ними · Проблема № 1048 · зигланг/зиг» . Гитхаб . Проверено 21 августа 2023 г.
- ^ «Выражения операторов (с использованием коллекции компиляторов GNU (GCC))» . gcc.gnu.org . Проверено 12 января 2022 г.
- ^ «Спецификация языка для блоков — документация Clang 13» . clang.llvm.org . Проверено 14 января 2022 г.
- ^ «Лямбда-выражения (начиная с C++11) — cppreference.com» . ru.cppreference.com . Проверено 14 января 2022 г.
- ^ Ярви, Яакко; Пауэлл, Гэри (nd). «Глава 16. Boost.Lambda» . Документация по повышению . Способствовать росту . Проверено 22 декабря 2014 г.
- ^ Перейти обратно: а б с д Это ж г Скит, Джон (23 марта 2019 г.). C# в глубине . Мэннинг. ISBN 978-1617294532 .
- ^ Перейти обратно: а б Альбахари, Джозеф (2022). C# 10 в двух словах О'Рейли. ISBN 978-1-098-12195-2 .
- ^ «Спецификация языка C# 5.0» . Центр загрузки Microsoft .
- ^ «Что нового в JDK 8» .
- ^ Перейти обратно: а б Учебные пособия по Java: лямбда-выражения , docs.oracle.com
- ^ «Глава 15. Выражения» . docs.oracle.com .
- ^ "jdk/LambdaMethod.java" . Гитхаб .
- ^ «Программирование на Lua — еще о функциях» . Архивировано из оригинала 14 мая 2008 года . Проверено 25 апреля 2008 г.
- ^ «2.7. Анонимные функции · GitBook» . www.cs.cornell.edu .
- ^ http://php.net/create_function в верхней части страницы это указано как «(PHP 4 >= 4.0.1, PHP 5)»
- ^ «PHP: rfc:closures» . wiki.php.net .
- ^ «Анонимные предикаты» . в справочнике по языку Visual Prolog
- ^ «Замыкания — пример ржавчины» . doc.rust-lang.org .
- ^ Перейти обратно: а б «В качестве входных параметров — пример Rust» . doc.rust-lang.org .
- ^ «Время жизни — ржавчина на примере» . doc.rust-lang.org .
- ^ «Синтаксис анонимной функции — документация Scala» . Архивировано из оригинала 23 июля 2013 г. Проверено 31 декабря 2010 г.
- ^ применить страницу руководства , получено 6 сентября 2012 г.
- ^ Справочное руководство Vala , получено 9 июня 2021 г.
Внешние ссылки [ править ]
- Anonymous Methods - When Should They Be Used? (blog about anonymous function in Delphi)
- Compiling Lambda Expressions: Scala vs. Java 8
- php anonymous functions php anonymous functions
- Lambda functions in various programming languages
- Functions in Go