it-swarm-eu.dev

Co je to lambda a proč by to bylo užitečné?

Zatím jsem slyšel o:

  • Lambda počet
  • Lambda programování
  • Lambda výrazy
  • Lambda funkce

Zdá se, že vše souvisí s funkčním programováním ...

Očividně to bude integrováno do C++ 1x, takže bych to teď mohl lépe pochopit:

http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions

Může někdo stručně definovat, co jsou to lambdské věci, a dát tam, kde to může být užitečné?

55
jokoon
  • Lambda počet

Lambda kalkul je výpočetní model, který vynalezl Alonzo Church ve 30. letech. Syntaxe a sémantika většiny funkčních programovacích jazyků jsou přímo nebo nepřímo inspirovány lambda kalkulem.

Lambda počet ve své nejzákladnější podobě má dvě operace: Abstrakce (vytvoření (anonymní) funkce) a aplikace (použití funkce). Abstrakce se provádí pomocí operátoru λ, který dává lambda kalkulu své jméno.

  • Lambda výrazy
  • Lambda funkce

Anonymní funkce se často nazývají „lambda“, „lambda funkce“ nebo „lambda výrazy“, protože, jak jsem řekl výše, λ byl symbolem pro vytvoření anonymních funkcí v lambda počtu (a slovo lambda se používá k vytvořit anonymní funkce v mnoha jazycích založených na LISP ze stejného důvodu).

  • Lambda programování

Toto není běžně používaný termín, ale předpokládám, že to znamená programování pomocí anonymních funkcí nebo programování pomocí funkcí vyššího řádu.


Trochu více informací o lambdách v C++ 0x, jejich motivaci a jejich vztahu k funkčním ukazatelům (hodně z toho je pravděpodobně opakováním toho, co už víte, ale doufám, že to pomůže vysvětlit motivaci lambd a jak se liší z ukazatelů funkcí):

Ukazatele funkcí, které již existovaly v C, jsou docela užitečné např. předat porovnávací funkci třídění. Jejich užitečnost je však omezená:

Například pokud chcete seřadit vektory podle elementů ith každého vektoru (kde i je parametr run-time), nemůžete to vyřešit ukazatelem funkce. Funkce, která porovnává dva vektory podle svého prvku ith, by musela vzít tři argumenty (i a dva vektory), ale funkce třídění by vyžadovala funkci, která vezme dva argumenty. To, co bychom potřebovali, je způsob, jak nějak předat argument i funkci před předáním funkci třídění, ale nemůžeme to udělat pomocí obyčejných C funkcí.

Pro vyřešení tohoto problému zavedla C++ koncept „funkčních objektů“ nebo „funktorů“. Funktor je v podstatě objekt, který má metodu operator(). Nyní můžeme definovat třídu CompareByIthElement, která vezme argument i jako argument konstruktoru a poté vezme oba vektory k porovnání jako argumenty k metodě operator(). Pro seřazení vektoru vektorů elementem ith můžeme nyní vytvořit objekt CompareByIthElement s argumentem i a potom tento objekt předat funkci třídění.

Protože funkční objekty jsou pouze objekty a nikoli technicky funkční (i když se mají chovat jako ty), nemůžete vytvořit funkční ukazatel ukazatelem na funkční objekt (samozřejmě můžete mít ukazatel na funkční objekt, ale by měl typ jako CompareByIthElement*, a proto by neměl být ukazatelem funkce).

Většina funkcí ve standardní knihovně C++, které berou funkce jako argumenty, jsou definovány pomocí šablon, takže pracují s ukazateli funkcí a také s funkčními objekty.

Nyní k lambdám:

Definování celé třídy k porovnání elementem ith je poněkud podrobnější, pokud jste ji někdy použili k třídění vektoru pouze jednou. I v případě, že potřebujete pouze ukazatel funkce, je definice pojmenované funkce suboptimální, pokud je použita pouze jednou, protože a) znečišťuje jmenný prostor ab) funkce je obvykle velmi malá a ve skutečnosti není dobrý důvod k tomu, aby se logika rozčlenila na vlastní funkci (kromě toho nemůžete mít funkční ukazatele bez definice funkce).

Takže k opravě byly tyto jehňata zavedeny. Lambdy jsou funkční objekty, nikoli funkční ukazatele. Pokud použijete lambda literál jako [x1, x2](y1,y2){bla}, vygeneruje se kód, který v podstatě provede následující:

  1. Definujte třídu, která má dvě členské proměnné (x1 A x2) A operator() s argumenty (y1 A y2) a tělo bla.
  2. Vytvořte instanci třídy a nastavte členské proměnné x1 A x2 Na hodnoty proměnných x1 A x2 Aktuálně v rozsahu.

Lambda se tedy chovají jako funkční objekty, kromě toho, že se nemůžete dostat ke třídě, která je vygenerována k implementaci lambda jiným způsobem než pomocí lambda. V důsledku toho jakákoli funkce, která přijímá funktory jako argumenty (v podstatě znamená jakoukoli non-C funkci ve standardní knihovně), bude přijímat lambdy, ale žádná funkce přijímající pouze ukazatele funkcí nebude.

43
sepp2k

Funkce lambda jsou v podstatě funkce, které vytvoříte „za běhu“. V C++ 1x mohly být použity ke zlepšení podpory funkčního programování:

std::for_each( begin, end, [](int i){std::cout << i << '\n';} );

Výsledkem bude zhruba kód podobný tomuto:

struct some_functor {
  void operator()(int i) {std::cout << i << '\n';}
};

std::for_each( begin, end, some_functor() );

Pokud potřebujete some_functor Právě pro toto jedno volání funkce std::for_each(), má tato lambda funkce oproti tomu několik výhod:

  • to, co se děje ve smyčce, je určeno přesně tam, kde je vyvolána funkce smyčkování
  • osvobozuje vás od psaní kódu kódu kotle
  • v nějakém oboru jmenného prostoru neleží žádný funktor, díky němuž by se každý díval na kód a přemýšlel, co je potřeba
18
sbi

Funkce lambda je jiné jméno pro anonymní funkci - v podstatě funkce bez jména.

Obvykle to používáte v jazycích, kde budete muset tuto funkci použít pouze jednou. Například místo

def add(a, b)
  return a+b

a pak předání této funkce do jiné podobné funkce

reduce(add, [5,3,2])

S lambdou byste to prostě udělali

reduce(lambda x, y: a+b, [5,3,2])
7
Martin Konecny