Анонимная функция в программировании — особый вид функций, которые объявляются в месте использования и не получают уникального идентификатора для доступа к себе. Поддерживаются во многих языках программирования.

Обычно при создании анонимные функции либо вызываются напрямую, либо ссылка на функцию присваивается переменной, с помощью которой затем можно косвенно вызывать данную функцию. Но в последнем случае анонимная функция получает имя и уже перестаёт быть анонимной. Если анонимная функция ссылается на переменные, не содержащиеся в своём теле (захват), то такая функция называется замыканием. Лямбда-выражение — типичная для многих языков синтаксическая конструкция для определения анонимной функции.

Синтаксис Синтаксис записи анонимных функций для различных языков программирования в большинстве случаев сильно различается. Язык Пример записи сложения AS3 function(x:int, y:int):int{return x + y;} AutoLISP (lambda (x y) (+ x y))

'((x y) (+ x y))

(quote ((x y) (+ x y))) C# (x,y) => x+y C++ Введены в C++11. Обязательно должны присутствовать захват и тело. Полная форма: [захват](параметры)mutable исключения атрибуты->возвращаемый_тип{тело} Пример: [](int x, int y){ return x + y; } В C++14 была добавлена возможность использовать лямбда-функции с auto: auto lambda = [](auto x, auto y) {return x + y;}; Анонимная функция может захватывать как отдельные переменные, например:int a; auto f = [a](){return a;} так и все внешние переменные: по ссылке [&] или с помощью копии [=]. Также можно комбинировать эти подходы: например, все переменные захватить по ссылке, а определённые параметры по копии. Чтобы иметь возможность модифицировать переменные, захваченные по значению, нужно указать ключевое слово mutable при объявлении функции. В C++14 добавлена возможность инициализации переменных лямбды в захвате. Например: [a = std::string{}](){return a;} CoffeeScript (x, y) -> x + y D // короткая форма записи с автовыводом типов auto a = ((x, y) => x + y)(2, 3);

// длинная форма записи (блок с фигурными скобками) с автовыводом типов auto aa = (x, y) { return x + y; }(2, 3);

// автоопределение компилятором типа анонимной функции: функция или делегат auto b = (int x, int y) => x + y; auto bb = (int x, int y) { return x + y; };

// функции не имеют доступа к внешним переменным auto c = function(int x, int y) => x + y; auto cc = function(int x, int y) { return x + y; };

// делегаты имеют доступ к внешним переменным auto d = delegate(int x, int y) => x + y; auto dd = delegate(int x, int y) { return x + y; };

// делегат, принимающий переменную типа int и возвращающий значение типа double auto f = delegate double(int x) { return 5.0 / x; }; Delphi (c 2009 версии) function(x, y: integer): integer begin result := x+y; end; Erlang fun(X,Y)->X+Y end GNU Octave @(x,y)x+y Go Z := func() int { return X + Y }() Groovy {x, y -> x + y} Haskell \x y -> x + y Java (с версии 8) // with no parameter () -> System.out.println("Hello, world.");

// with a single parameter (This example is an identity function). a -> a

//with a single expression (a, b) -> a + b

// with explicit type information (Long id, String name) -> "id: " + id + ", name:" + name

// with a code block (a, b) -> {return a + b;}

// with multiple statements in the lambda body. It requires a code block. // This example also includes a nested lambda expression as well as a closure. (id, newPrice) -> { Optional<Product> mayBeProduct = findProduct(id); mayBeProduct.ifPresent(product -> product.setPrice(newPrice)); return mayBeProduct.get(); } JavaScript Стрелочная функция (arrow function expression) всегда объявляется без имени. Стрелочные функции добавлены в стандарт ECMAScript 6 (также известный как ECMAScript 2015). // Стрелочная функция. ES6+ (ES2015+) (x, y) => x + y;Объявление функции через выражение функции (function expression) без указания имени. Впервые такой способ описан в спецификации стандарта ECMAScript 3. // Выражение функции. ES3+ function(x, y) { return x + y } Динамическое создание функции конструктором объекта Function (Function constructor) всегда объявляется без имени. Более короткая запись динамического создания функции — вызов функции Function, который автоматически вызывает конструктор Function с теми же параметрами. Эти способы создания функций существуют с самых ранних спецификаций, начиная с ECMAScript первой редакции. // Динамическое создание функции конструктором Function. ES1+ new Function('x', 'y', 'return x + y')

// Более короткая запись. ES1+ Function('x', 'y', 'return x + y') Lua function(x,y) return x+y end Maple (x, y) -> x + y Mathematica #1+#2& или Function[#1+#2] или Function[{x,y},x+y]Mathematica Documentation: Function (&) MATLAB f=@(x,y) x+y Maxima lambda([x,y], x+y)Nimproc(x,y: int): int = x*y PascalABC.NET (x, y) -> x + y Perl sub { return $_ + $_ }perldoc perlref PHP // PHP 7.4+ fn($x, $y) => $x + $y; Стрелочные функции (Arrow Functions) добавлены в PHP 7.4. // PHP 5.3+ function($x, $y) use ($a, &$b) { return $x + $y; } Здесь $a, $b — захваченные переменные, при этом переменная $b ещё и замкнутаяM. Zandstra, “PHP Objects, Patterns, and Practice”, second edition, Ed. Apress, 2008..

// PHP 4.0.1+ create_function('$x, $y', 'return $x + $y;') Создание анонимной функции с помощью функции create_function. Такой способ объявлен устаревшим, начиная с PHP 7.2.0.PowerShell{ param($x, $y) $x + $y } Python lambda х, у: х+уРаздел учебника «Освой Python за 24 часа самостоятельно» R function(x,y) x+y Ruby lambda { |x, y| x + y }Описание в книге «Programming Ruby» Rust | x: i32, y: i32 | x + y Scala Без указания контекста надо указывать тип переменных: (x: Int, y: Int) => x + y Но в местах, где тип может быть выведен, можно использовать сокращенные формы: (1 to 100) reduce ((a, b) => a+b) Или ещё короче, с использованием автоподстановок '_': (1 to 100) reduce (_ + _) Scheme, Common Lisp (lambda (x y) (+ x y)) SML fn (x, y) => x + ySwift // 1 вариант let f: (Int, Int) -> Int = { x, y in return x + y }

// 2 вариант let f: (Int, Int) -> Int = { x, y in x + y }

/* С сокращенными именами параметров */ // 1 вариант let f: (Int, Int) -> Int = { return $0 + $1 }

// 2 вариант let f: (Int, Int) -> Int = { $0 + $1 }TypeScript// Стрелочная функция (arrow function expression) всегда объявляется без имени (x, y) => x + y

// Выражение функции (function expression) без имени function(x, y) { return x + y }

// Динамическое создание функции // конструктором объекта Function (Function constructor) // всегда объявляется без имени new Function('x', 'y', 'return x + y')

// Более короткая запись динамического создания функции. // Вызов функции Function автоматически вызывает // конструктор Function с теми же параметрами Function('x', 'y', 'return x + y') Visual Prolog {(X,Y)=X+Y}

См. также Замыкание (программирование) Callback (программирование)

Примечания

Категория:Концепции языков программирования Категория:Статьи с примерами кода Erlang Категория:Статьи с примерами кода Python Категория:Статьи с примерами кода Ruby