~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 019A7F9E7AC6582535866563EF35BDCD__1713962220 ✰
Заголовок документа оригинал.:
✰ Anonymous function - Wikipedia ✰
Заголовок документа перевод.:
✰ Анонимная функция — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Anonymous_function ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/01/cd/019a7f9e7ac6582535866563ef35bdcd.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/01/cd/019a7f9e7ac6582535866563ef35bdcd__translat.html ✰
Дата и время сохранения документа:
✰ 16.06.2024 09:47:20 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 24 April 2024, at 15:37 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Анонимная функция — Википедия Jump to content

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

Из Википедии, бесплатной энциклопедии

В компьютерном программировании ( анонимная функция функциональный литерал , лямбда-абстракция , лямбда-функция , лямбда-выражение или блок ) — это определение функции , не привязанное к идентификатору . Анонимные функции часто представляют собой аргументы, передаваемые функциям более высокого порядка или используемые для создания результата функции более высокого порядка, которая должна возвращать функцию. [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]

Примеры [ править ]

Многие языки поддерживают анонимные функции или что-то подобное.

АПЛ [ править ]

Лишь некоторые диалекты поддерживают анонимные функции, например 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.ListConvertAll() метод):

// Инициализируем список: 
 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, выполняется немедленно.

  1. полностью анонимный, называется как созданный
    {  сказать   «Мне позвонили»  };
     
  2. присвоено переменной
    мой   $squarer1  = ->  $x  {  $x  *  $x  };   № 2а.   заостренный блок 
     my   $squarer2  = {  $^x  *  $^x  };   № 2б.   twigil 
     my   $squarer3  = {  my   $x  =  сдвиг   @_  ;  *  };   № 2в.   Стиль Перл 5 
    
  3. карри
    sub   add  (  $m  ,  $n  ) {  $m  +  $n  } 
      мой   $seven  =  добавить  (  3  ,  4  ); 
      мой   $add_one  =  &add  .   предполагая  (  m => 1); 
      мой $eight =   $add_one  (  $seven  ); 
     
  4. Объект WhatWordCode
    мой   $w  = * -  1  ;   # Объект WhatCode 
     my   $b  = {  $_  -  1  };   # та же функциональность, но как блок Callable 
    

Руби [ править ]

Ruby поддерживает анонимные функции, используя синтаксическую структуру, называемую блоком . В Ruby существует два типа данных для блоков. Procs ведут себя аналогично замыканиям , тогда как lambdas ведут себя более похоже на анонимную функцию. [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  .   Начинать  () 

См. также [ править ]

Ссылки [ править ]

  1. ^ «Функции высшего порядка» . Learnyouahaskell.com . Проверено 3 декабря 2014 г.
  2. ^ Фернандес, Марибель (2009), Модели вычислений: введение в теорию вычислимости , Темы бакалавриата по информатике, Springer Science & Business Media, стр. 33, ISBN  9781848824348 , Лямбда-исчисление ... было введено Алонзо Чёрчем в 1930-х годах как точное обозначение теории анонимных функций.
  3. ^ «Выражения стрелочных функций — JavaScript» . МДН . Проверено 21 августа 2019 г.
  4. ^ «Баш лямбда» . Гитхаб . 08.03.2019.
  5. ^ БиллВагнер. «Лямбда-выражения — справочник по C#» . docs.microsoft.com . Проверено 24 ноября 2020 г.
  6. ^ «Поддержка закрытия» . Архивировано из оригинала 6 января 2014 г. Проверено 5 января 2014 г.
  7. ^ «Что нового в ColdFusion 10» . Архивировано из оригинала 6 января 2014 г. Проверено 5 января 2014 г.
  8. ^ «Clojure — функции высшего порядка» . Clojure.org . Проверено 14 января 2022 г.
  9. ^ «Управляемый справочник COBOL» . Документация Микро Фокус . Микро Фокус . Архивировано из оригинала 25 февраля 2014 года . Проверено 25 февраля 2014 г.
  10. ^ «Функции — язык программирования D» . dlang.org . Проверено 14 января 2022 г.
  11. ^ Перейти обратно: а б «Экскурсия по языку дартс» . dart.dev . Проверено 24 ноября 2020 г.
  12. ^ «Анонимные методы в Delphi — RAD Studio» . docwiki.embarcadero.com . Проверено 24 ноября 2020 г.
  13. ^ «Функции — Программирование Дилана» . opendylan.org . Проверено 14 января 2022 г.
  14. ^ «документы/синтаксис» . elm-lang.org . Проверено 14 января 2022 г.
  15. ^ Перейти обратно: а б «Синтаксис Erlang/Elixir: ускоренный курс» . эликсир-lang.github.com . Проверено 24 ноября 2020 г.
  16. ^ Перейти обратно: а б «Эрланг -- Забавы» . erlang.org . Проверено 24 ноября 2020 г.
  17. ^ Перейти обратно: а б Картермп. «Лямбда-выражения: забавное ключевое слово — F#» . docs.microsoft.com . Проверено 24 ноября 2020 г.
  18. ^ «LAMBDA: совершенная функция рабочего листа Excel» . microsoft.com . 25 января 2021 г. Проверено 30 марта 2021 г.
  19. ^ «Котировки – Факторная документация» . Проверено 26 декабря 2015 г. Цитата — это анонимная функция (значение, обозначающее фрагмент кода), которую можно использовать в качестве значения и вызывать с помощью фундаментальных комбинаторов.
  20. ^ «Фринк» . frinklang.org . Проверено 24 ноября 2020 г.
  21. ^ Перейти обратно: а б «Анонимные функции в GoLang» . Документы GoLang . 9 января 2020 г. Проверено 24 ноября 2020 г.
  22. ^ «Документация Госу» (PDF) . Проверено 4 марта 2013 г.
  23. ^ «Отличная документация» . Архивировано из оригинала 22 мая 2012 года . Проверено 29 мая 2012 г.
  24. ^ «Анонимная функция — HaskellWiki» . wiki.haskell.org . Проверено 14 января 2022 г.
  25. ^ «Лямбда» . Haxe — Кроссплатформенный набор инструментов . Проверено 14 января 2022 г.
  26. ^ «Функции — JavaScript | MDN» . http://developer.mozilla.org . Проверено 14 января 2022 г.
  27. ^ «Функции · Язык Джулии» . docs.julialang.org . Проверено 24 ноября 2020 г.
  28. ^ «Функции высшего порядка и лямбды — язык программирования Kotlin» . Котлин . Проверено 24 ноября 2020 г.
  29. ^ «Программирование на Lua: 6» . www.lua.org . Проверено 24 ноября 2020 г.
  30. ^ «Программирование на Maple: 1.6: Анонимные функции и выражения — Центр приложений» . www.maplesoft.com . Проверено 24 ноября 2020 г.
  31. ^ «Анонимные функции — MATLAB и Simulink» . www.mathworks.com . Проверено 14 января 2022 г.
  32. ^ «Руководство Maxima 5.17.1: 39. Определение функций» . maths.cnam.fr . Проверено 24 ноября 2020 г.
  33. ^ Перейти обратно: а б «Руководство Нима» . nim-lang.github.io .
  34. ^ «Примеры кода — OCaml» . ocaml.org . Проверено 24 ноября 2020 г.
  35. ^ «GNU Octave: анонимные функции» . Octave.org . Проверено 24 ноября 2020 г.
  36. ^ «Функциональные литералы» . Руководство пользователя OpenSCAD . Викикниги . Проверено 22 февраля 2021 г.
  37. ^ Перейти обратно: а б «perlsub — Подпрограммы Perl — Браузер Perldoc» . perldoc.perl.org . Проверено 24 ноября 2020 г.
  38. ^ «PHP: Анонимные функции — Руководство» . www.php.net . Проверено 24 ноября 2020 г.
  39. ^ Перейти обратно: а б «6. Выражения — документация Python 3.9.0» . docs.python.org . Проверено 24 ноября 2020 г.
  40. ^ «4.4 Функции: лямбда» . docs.racket-lang.org . Проверено 24 ноября 2020 г.
  41. ^ «Функции» . docs.raku.org . Проверено 14 января 2022 г.
  42. ^ Перейти обратно: а б Сосински, Роберт (21 декабря 2008 г.). «Понимание блоков Ruby, процедур и лямбд» . Реактивный.ИО. Архивировано из оригинала 31 мая 2014 г. Проверено 30 мая 2014 г.
  43. ^ «Замыкания: анонимные функции, которые могут захватывать свое окружение — язык программирования Rust» . doc.rust-lang.org . Проверено 14 января 2022 г.
  44. ^ «Анонимные функции» . Документация Скала . Проверено 14 января 2022 г.
  45. ^ «Декламация 3: Функции высшего порядка» . www.cs.cornell.edu . Проверено 14 января 2022 г.
  46. ^ Перейти обратно: а б «Замыкания — язык программирования Swift (Swift 5.5)» . docs.swift.org .
  47. ^ «Документация — повседневные типы» . www.typescriptlang.org . Проверено 14 января 2022 г.
  48. ^ Перейти обратно: а б «Проекты/Вала/Руководство — GNOME Wiki!» . Wiki.gnome.org . Проверено 24 ноября 2020 г.
  49. ^ Кэтлин Доллард (15 сентября 2021 г.). «Лямбда-выражения — Visual Basic» . docs.microsoft.com . Проверено 14 января 2022 г.
  50. ^ «Справочник по языку/Термины/Анонимные предикаты — wiki.visual-prolog.com» . wiki.visual-prolog.com . Проверено 14 января 2022 г.
  51. ^ «Чистая анонимная функция: элементарное введение в язык Wolfram» . www.wolfram.com . Проверено 14 января 2022 г.
  52. ^ «Лямбды, замыкания и все, что между ними · Проблема № 1048 · зигланг/зиг» . Гитхаб . Проверено 21 августа 2023 г.
  53. ^ «Выражения операторов (с использованием коллекции компиляторов GNU (GCC))» . gcc.gnu.org . Проверено 12 января 2022 г.
  54. ^ «Спецификация языка для блоков — документация Clang 13» . clang.llvm.org . Проверено 14 января 2022 г.
  55. ^ «Лямбда-выражения (начиная с C++11) — cppreference.com» . ru.cppreference.com . Проверено 14 января 2022 г.
  56. ^ Ярви, Яакко; Пауэлл, Гэри (nd). «Глава 16. Boost.Lambda» . Документация по повышению . Способствовать росту . Проверено 22 декабря 2014 г.
  57. ^ Перейти обратно: а б с д Это ж г Скит, Джон (23 марта 2019 г.). C# в глубине . Мэннинг. ISBN  978-1617294532 .
  58. ^ Перейти обратно: а б Альбахари, Джозеф (2022). C# 10 в двух словах О'Рейли. ISBN  978-1-098-12195-2 .
  59. ^ «Спецификация языка C# 5.0» . Центр загрузки Microsoft .
  60. ^ «Что нового в JDK 8» .
  61. ^ Перейти обратно: а б Учебные пособия по Java: лямбда-выражения , docs.oracle.com
  62. ^ «Глава 15. Выражения» . docs.oracle.com .
  63. ^ "jdk/LambdaMethod.java" . Гитхаб .
  64. ^ «Программирование на Lua — еще о функциях» . Архивировано из оригинала 14 мая 2008 года . Проверено 25 апреля 2008 г.
  65. ^ «2.7. Анонимные функции · GitBook» . www.cs.cornell.edu .
  66. ^ http://php.net/create_function в верхней части страницы это указано как «(PHP 4 >= 4.0.1, PHP 5)»
  67. ^ «PHP: rfc:closures» . wiki.php.net .
  68. ^ «Анонимные предикаты» . в справочнике по языку Visual Prolog
  69. ^ «Замыкания — пример ржавчины» . doc.rust-lang.org .
  70. ^ Перейти обратно: а б «В качестве входных параметров — пример Rust» . doc.rust-lang.org .
  71. ^ «Время жизни — ржавчина на примере» . doc.rust-lang.org .
  72. ^ «Синтаксис анонимной функции — документация Scala» . Архивировано из оригинала 23 июля 2013 г. Проверено 31 декабря 2010 г.
  73. ^ применить страницу руководства , получено 6 сентября 2012 г.
  74. ^ Справочное руководство Vala , получено 9 июня 2021 г.

Внешние ссылки [ править ]

Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 019A7F9E7AC6582535866563EF35BDCD__1713962220
URL1:https://en.wikipedia.org/wiki/Anonymous_function
Заголовок, (Title) документа по адресу, URL1:
Anonymous function - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)