Oglądałem wywiad z Herbem Sutterem na Channel9 i wspomniał na końcu filmu, że składnia od lewej do prawej będzie na szczycie listy życzeń przyszłego standardu C ++ (chociaż przyznaje, że modyfikuje C ++ w ten sposób stworzyłoby zupełnie inną bestię).
Oprócz:
bardziej zrozumiałe dla ludzi, wyraźniejsze gołym okiem; np
//C syntax /*pointer to function taking a pointer to function(which takes 2 integers as arguments and returns an int), and an int as arguments and returning an int*/ int (*fp)(int (*ff)(int x, int y), int b) //Go analogous syntax which is left to write f func(func(int,int) int, int) int
łatwiejsze do przeanalizowania (prowadzi do lepszego wsparcia narzędzia, jak wspomniano w filmie - np. refaktoryzacja kodu)
jakie są inne zalety składni „od lewej do prawej” w języku programowania. Wiem tylko, że Pascal i Go stosują taką składnię (i Go nawet nie idzie na całość, jak rozumiem z tego postu na blogu, z którego wziąłem również przykłady) Czy byłoby możliwe posiadanie systemowego języka programowania z tego rodzaju składni?
źródło
f :: (Int -> Int -> Int) -> Int -> Int
function strlen(s:String):int {...}
. Również wpisany rachunek lambda (stąd Haskell).Odpowiedzi:
Podstawową zaletą jest to, że parsowanie jest prostsze i unikalne. Zauważ, że po przeanalizowaniu wiersza kompilator będzie wiedział, jaki jest dokładnie typ, więc odtąd sposób zdefiniowania typu nie ma znaczenia.
Obecnie trudno odczytać dowolną funkcję, która zwraca argument typu tablicowego lub typu wskaźnika funkcji:
I byłoby mniej szans na nieporozumienie (jako najbardziej dokuczliwa analiza ):
Zastosowanie podobnego podejścia do jednolitej inicjalizacji w C ++ 0x (tj.
{}
Do identyfikacji inicjalizacji). Zauważ, że przy podejściu od lewej do prawej jest znacznie wyraźniejsze to, co definiujemy. Wiele osób (na pewno mnie) ugryzło w dowolnym momencie ten błąd analizowania w przeszłości (więcej niż jeden raz) i nie byłoby tak w przypadku składni od lewej do prawej.źródło
new
operatorowi dwie semantyki ,struct
lubclass
, co nie ma zastosowania do C ++, ponieważ w C ++ nie ma rozróżnienia na typy wartości / odniesienia.Jak się tu dostaliśmy
Składnia C do deklarowania punktów funkcyjnych miała na celu odzwierciedlenie użycia. Rozważ taką deklarację funkcji jak ta
<math.h>
:Aby mieć zmienną punktową, możesz przypisać ją do typu bezpieczeństwa za pomocą
należałoby zadeklarować tę
fp
zmienną punktową w ten sposób:Wystarczy więc spojrzeć na sposób użycia funkcji i zastąpić nazwę tej funkcji odwołaniem do wskaźnika, przekształcając się
round
w*fp
. Potrzebny jest jednak dodatkowy zestaw parenów, co według niektórych sprawia, że jest nieco bardziej chaotyczny.Prawdopodobnie było to łatwiejsze w oryginalnym C, który nawet nie miał podpisu funkcji, ale nie wracajmy tam, ok?
Miejsce, w którym staje się szczególnie nieprzyjemne, zastanawia się, jak zadeklarować funkcję, która albo bierze jako argument, albo zwraca wskaźnik do funkcji, albo jedno i drugie.
Jeśli miałeś funkcję:
możesz przekazać go do funkcji sygnału (3) w ten sposób:
lub jeśli chcesz zachować stary moduł obsługi, to
co jest dość łatwe. To, co jest dość łatwe - ani ładne, ani łatwe - to prawidłowe wypełnianie deklaracji.
Cóż, po prostu wróć do deklaracji funkcji i zamień nazwę na odniesienie do punktu:
Ponieważ nie deklarujesz
gotsig
, możesz łatwiej przeczytać, jeśli pominiesz:Albo może nie. :(
Tyle że nie jest to wystarczająco dobre, ponieważ signal (3) zwraca również stary moduł obsługi, jak w:
Więc teraz musisz dowiedzieć się, jak je wszystkie zadeklarować.
wystarczy dla zmiennej, do której zamierzasz przypisać. Pamiętaj, że tak naprawdę nie deklarujesz
gotsig
tutajold_handler
. To naprawdę wystarczy:To prowadzi nas do poprawnej definicji sygnału (3):
Typedefs na ratunek
Myślę, że do tego czasu wszyscy zgodzą się, że to bałagan. Czasami lepiej nazwać swoje abstrakcje; często naprawdę. Dzięki prawu
typedef
staje się to znacznie łatwiejsze do zrozumienia:Teraz twoja własna zmienna modułu obsługi staje się
a twoja deklaracja sygnału (3) staje się słuszna
co jest nagle zrozumiałe. Pozbycie się znaku * pozbywa się także mylących nawiasów (i mówią, że pareny zawsze ułatwiają zrozumienie - hah!). Twoje użycie jest nadal takie samo:
ale teraz masz szansę zrozumienia dla deklaracji
old_handler
,new_handler
a nawetsignal
kiedy po raz pierwszy je lub potrzebę spotkać je pisać.Wniosek
Okazuje się, że bardzo niewielu programistów C jest w stanie samodzielnie opracować prawidłowe deklaracje dla tych rzeczy bez konsultacji z materiałami referencyjnymi.
Wiem, ponieważ kiedyś mieliśmy to pytanie w naszych rozmowach kwalifikacyjnych dla osób wykonujących pracę jądra i sterownika urządzenia. :) Jasne, w ten sposób straciliśmy wielu kandydatów, którzy rozbili się i spalili na tablicy. Ale unikaliśmy również zatrudniania osób, które twierdziły, że mają wcześniejsze doświadczenie w tej dziedzinie, ale nie mogły właściwie wykonać pracy.
Ze względu na tę powszechną trudność, prawdopodobnie nie jest rozsądne, ale wręcz rozsądne, aby mieć sposób na spełnienie wszystkich tych deklaracji, które nie wymagają już od ciebie bycia programistą potrójnego alfy, siedzącym trzy sigmy powyżej średniej tylko po to, aby tego użyć. coś w rodzaju komfortu.
źródło
Myślę, że nieco straciłeś punkt, kiedy skupiłeś się na bitach od lewej do prawej.
Problemami w C i C ++ są horrendalna gramatyka, którą mają, która jest trudna zarówno do odczytania (ludzie), jak i do analizy (narzędzia).
Bardziej spójna (lub regularna ) gramatyka ułatwia obie te rzeczy. A łatwiejsze parsowanie oznacza łatwiejsze oprzyrządowanie: większość obecnych narzędzi nie ma poprawnego C ++, nawet najnowszej wtyczki Eclipse, gdy próbowali odkryć koło ... i zawiodły, i prawdopodobnie mają więcej osób niż przeciętny projekt systemu operacyjnego.
Prawdopodobnie więc przybiłeś ją, koncentrując się na czytaniu i analizie ... i to wielka sprawa :)
źródło
gcc
?