2013-08-09 13 views
6

Nowy standard C++ 11 obsługuje funkcje lambda, co moim zdaniem jest przydatną funkcją. Rozumiem, że standardy C i C++ różnią się od siebie, ale nie rozumiem, dlaczego C11 nie obsługuje funkcji lambda. Myślę, że może mieć wiele zastosowań.Dlaczego C11 nie obsługuje funkcji lambda

Czy istnieje powód, dla którego twórcy standardu C11 nie uwzględniają tej funkcji?

+0

Dobrze dla SO. Ta strona jest przeznaczona do pytań technicznych, więc myślę, że twoje pytanie jest w pewnym sensie pogranicze tutaj. Lepiej zapytaj o to na forum lub w grupie dyskusyjnej. W przeciwnym razie łatwo znajdziesz minuty sesji komitetu normalizacyjnego C online i zobaczysz, o czym rozmawiają. Nie pamiętam tego ostatnio. –

Odpowiedz

3

To jest naprawdę moja opinia, ponieważ nie wiem, co komitet myśli.

Z jednej strony Lisp wspiera wyrażenia lambda od czasu jego narodzin, czyli w 1958 r. Język programowania C narodził się w 1972 r. Tak więc wyrażenie lambda ma dłuższą historię niż C. Więc jeśli pytasz dlaczego C11 nie obsługuje wyrażenia lambda, to samo pytanie można zadać o C89.

Z drugiej strony, wyrażenie lambda jest zawsze funkcjonalną rzeczą programowania i jest stopniowo absorbowane do imperatywnych języków programowania. Niektóre z "wyższych" języków (np. Java, przed planowaną Javą 8) jeszcze jej nie obsługują.

Wreszcie, C i C++ zawsze uczą się od siebie, więc może będzie w następnym standardzie C. Na razie możesz rzucić okiem na Blocks, niestandardowe rozszerzenie dodane przez Apple. To jest przykładowy kod z Wikipedii:

#include <stdio.h> 
#include <Block.h> 
typedef int (^IntBlock)(); 

IntBlock MakeCounter(int start, int increment) { 
     __block int i = start; 

     return Block_copy(^ { 
       int ret = i; 
       i += increment; 
       return ret; 
     }); 

} 

int main(void) { 
     IntBlock mycounter = MakeCounter(5, 2); 
     printf("First call: %d\n", mycounter()); 
     printf("Second call: %d\n", mycounter()); 
     printf("Third call: %d\n", mycounter()); 

     /* because it was copied, it must also be released */ 
     Block_release(mycounter); 

     return 0; 
} 
/* Output: 
     First call: 5 
     Second call: 7 
     Third call: 9 
*/ 
7

2016 aktualizacja: Apple style lambdas z zamknięciami zostały ponownie przedstawione grupie roboczej na spotkaniu Londyn 2016, w new proposal document który stara się rozwiązać kilkoma niedociągnięcia z poprzedniej próby, uporządkowanie terminologii i wyjaśnień oraz bardziej szczegółowe informacje na temat tego, w jaki sposób zamknięcia i lambdy mogą być "podobne do C".

Od the reception was cautiously positive (7-0-9 Tak/Nie/wstrzymywanie się) wygląda na bardzo prawdopodobne, że wkrótce pojawi się coś podobnego do tego języka.


Krótka odpowiedź jest po prostu, że C nie zawiera funkcje lambda bo nikt jeszcze nie dokonał dopuszczalny wniosek grupy roboczej ISO C włączenia funkcji lambda.

Można spojrzeć na listę niektóre z propozycji omawianych przez grupę roboczą tutaj: http://www.open-std.org/jtc1/sc22/wg14/www/documents

Jedyna propozycja lambdas jakiegokolwiek rodzaju, że mogę znaleźć się na tej liście są bloki Apple (jak wykazano w odpowiedzi Yu Hao), w dokumencie N1451. Ta propozycja jest omawiana dalej w N1483, która porównuje ją z lambdami w języku C++ i N1493 i N1542, które są protokołami z posiedzeń, na których przedstawiono te dokumenty.

Było kilka powodów, dla których propozycja w N1451 nie mógł zostać przyjęty, podane w N1542:

  • początkowo komisja miała trudności ze zrozumieniem propozycję
  • to używa nieprawidłowych cytatów i terminologii, która jest sprzeczna z istniejącymi C standardowy
  • jest najwyraźniej niejasny i niekompletny
  • Apple było w trakcie próby opatentowania tej funkcji (nie jest jasne, czy jest to przeszkoda w standaryzacji, czy nie, ale tak bym to zakładała)
  • Zupełnie nowa funkcja zupełnie nowe semantyki proponuje w 2010 miał dokładnie zerową szansę być gotowy na czas do 2011 roku, a byłby podniósł uwalnianie C11
  • bloków jak przedstawione nie są kompatybilne z C++ 11 lambdas

Wygląda również na to, że nie byli przekonani, że obecnie wykazuje wystarczającą użyteczność. Standardyzacja C najwyraźniej stara się być bardzo konserwatywna, a mając tylko jeden główny kompilator implementujący tę funkcję, prawdopodobnie będzie chciał poczekać i zobaczyć, jak konkuruje z lambdami w C++ i czy ktokolwiek inny ją podnosi. Nie jest to funkcja "C" w przeciwieństwie do funkcji "Clang", dopóki nie oferuje jej wiele kompilatorów.

Wszystko, co powiedzieliśmy, głosy komisji najwyraźniej nieznacznie pochyliły się na korzyść tej cechy (6-5-4 Tak/Nie/wstrzymać się), ale nie na tyle, aby osiągnąć niezbędny konsensus.

O ile mi wiadomo, inne duże, lambdy C++ 11, nie zostały zaproponowane do włączenia do C przez kogokolwiek; a jeśli nie pytasz, nie dostaniesz.

Każda propozycja lambda w języku C dodawałaby całą masę nowych reguł dotyczących zmiennych okresów istnienia i lokalizacji oraz kopiowania i alokacji i ... itd. Dla wielu osób może to wyglądać bardzo nie-C, dzięki wartościom przenoszonym za plecami programisty lub nagłym nieoczekiwanym zmianom w ich życiu - unikanie tego typu rzeczy to połowa powód, dla którego ludzie decydują się pisać w C obecnie. Musi więc istnieć propozycja, która faktycznie odpowiada filozofii C, zanim zostanie potraktowana poważnie. Jestem pewien, że można to zrobić, ale obie duże propozycje zostały opracowane z myślą o językach o bardzo odmiennej "filozofii", w których tego typu rzeczy nie stanowią przeszkody i nie muszą koniecznie odzwierciedlać celu C i postać w obecnym stanie.

+0

W jaki sposób proponujemy funkcje grupie roboczej ISO C nie będąc członkami ISO ani ANSI? Chciałbym zasugerować obsługę formatu UTF-8 dla C2x. – MarcusJ

+0

@MarcusJ? Obsługa UTF-8 jest już w C11. – Leushenko

+0

Nie ma postaci użytkowej. – MarcusJ

8

C ma być małym i prostym językiem. Celowo pomija funkcje wysokiego poziomu, gdy te same rzeczy można zrobić w prostszy sposób. Ma na celu zapewnienie tylko podstawowych funkcji, które są absolutnie niezbędne do programowania przenośnego.

C nie ma referencji, ponieważ są po prostu wskaźnikami. C nie ma klas, dziedziczenia i funkcji wirtualnych, ponieważ można po prostu używać struktur i tworzyć własne vtables za pomocą wskaźników funkcji. Nie ma narzędzia do zbierania śmieci, ponieważ programiści mogą samodzielnie śledzić alokację pamięci, nie ma szablonów, ponieważ w rzeczywistości są to tylko makra. Jeśli potrzebujesz wyjątków, możesz użyć longjmp, a zamiast przestrzeni nazw po prostu dodajesz przedrostki do nazw.

Dodanie dowolnego z tych skrótów na wysokim poziomie może sprawić, że programowanie będzie trochę wygodniejsze, ale dzieje się tak kosztem uczynienia języka bardziej skomplikowanym, czego nie należy lekceważyć. Jest to śliskie zbocze, które bezpośrednio prowadzi do bałaganu, jakim stał się C++.

C nie ma funkcji lambda, ponieważ nie są one naprawdę konieczne. Zamiast tego możesz po prostu użyć funkcji statycznej i umieścić kontekst w strukturze.

+0

Nie zgadzam się z ostatnim akapitem. To nie jest "naprawdę konieczne". Wskaźniki funkcji są mniej prawdopodobne, aby były wstawione niż lambdas https://stackoverflow.com/questions/13722426/why-can-lambdas-be-better-optimized-by-compiler-than-plain-functions, które powodują powtarzalne wywołania funkcji przez spowolnienie wskaźnika dla operacji takich jak qsort – texasbruce