tło
Strona Wikipedii na temat cukru syntaktycznego zawiera :
W informatyce cukier syntaktyczny jest składnią w języku programowania, który ma na celu ułatwienie czytania lub wyrażania. Dzięki temu język jest „słodszy” dla ludzi: rzeczy można wyrazić jaśniej, bardziej zwięźle lub w alternatywnym stylu, który niektórzy mogą preferować.
Naprawdę nie rozumiem, jaka jest różnica między Syntactic Sugar a Syntax.
Doceniam fakt, że wersja słodka może być jaśniejsza, bardziej zwięzła, być może sprowadzona z jakiegoś bojlera. Ale wydaje mi się, że na pewnym poziomie cała składnia zasadniczo robi to, aby stworzyć abstrakcję tego, do czego kod zostaje skompilowany.
Z tej samej strony w Wikipedii:
Procesory językowe, w tym kompilatory, analizatory statyczne i tym podobne, często przetwarzają konstrukcje cukrowe w bardziej podstawowe konstrukcje przed przetwarzaniem, proces czasami nazywany „desugowaniem”.
Jako ćwiczenie myślowe, jeśli „często” w tym stwierdzeniu oznacza „zawsze”: Jeśli różnica polega tylko na tym, czy kompilator „odsyła” składnię przed przejściem do następnego etapu, w jaki sposób programista, który nie zna wewnętrznych kompilatora wie (lub obchodzi), co to jest Sugar'd Składnia, czy nie?
Bardzo powiązane pytanie na tej stronie „Rygorystyczna definicja cukru syntaktycznego?” ma odpowiedź, która rozpoczyna się:
IMHO Nie wydaje mi się, aby można było zdefiniować cukier syntaktyczny, ponieważ wyrażenie to jest BS i prawdopodobnie będzie używane przez osoby, które mówią o „prawdziwych programistach” używających „prawdziwych narzędzi” w „prawdziwych systemach operacyjnych”
Co może mi wskazywać, że być może programista używający języka nie ma dużej różnicy? Być może różnica jest zauważalna tylko dla autora kompilatora? Chociaż mogą zdarzyć się sytuacje, w których programista korzystający z języka może wiedzieć, co kryje się pod maską cukru syntaktycznego? (Ale może w rzeczywistości w jakimkolwiek dyskursie na ten temat używa się tego terminu jako przynęty na płomienie?)
Sedno pytania
Więc ... krótka wersja pytania:
- Czy istnieje prawdziwa różnica między składnią a cukrem syntaktycznym?
- Dla kogo to ma znaczenie?
Dodatkowe jedzenie do przemyślenia
Premia za sprzeczność tematu:
Na stronie Wikipedii podano przykład:
Na przykład w języku C
a[i]
notacja oznacza cukier składniowy*(a + i)
Podczas gdy inna odpowiedź na powyższe powiązane pytanie mówi o tym samym przykładzie:
Teraz zastanów się
a[i] == *(a + i)
. Pomyśl o dowolnym programie C, który używa tablic w jakikolwiek istotny sposób.
I podsumowuje, że:
[]
Notacja ułatwia tę abstrakcję. To nie jest cukier składniowy.
Przeciwny wniosek dla tego samego przykładu!
źródło
Odpowiedzi:
Główną różnicą jest to, że składnia to gramatyka zdefiniowana w języku, aby umożliwić ujawnienie niektórych funkcji. Gdy tylko uzyskasz dostęp do tej funkcji, każda inna składnia, która pozwala ci robić to samo, jest uważana za cukier. To oczywiście prowadzi do nieparzystych scenariuszy dotyczących tego, która z dwóch składni jest cukrem, zwłaszcza że nie zawsze jest jasne, co było pierwsze.
W praktyce cukier syntaktyczny jest używany tylko do opisania składni dodanej do języka w celu ułatwienia korzystania z niego, na przykład tworzenia
lhs + rhs
mapy infixlhs.Add(rhs)
. Uważam, że indeksowanie tablicy C jest cukrem syntaktycznym.Ma to znaczenie przede wszystkim dlatego, że eleganckie wzory zwykle ograniczają ilość powielania. Potrzebujący (a przynajmniej chcący) cukier składniowy jest przez niektórych postrzegany jako oznaka niepowodzenia projektu.
źródło
if (a) return blah; ...
kontraresult_type res; if (a) res = blah; else {...}; return res;
. Musiałbyś założyć określone języki i uzyskać niezwykle prawnika językowego (często do niewielkiej semantyki operacyjnej), aby znaleźć różnicę między tymi programami.Składnia jest tym, czego używa procesor języka, aby zrozumieć, co oznaczają konstrukcje języka. Konstrukty uważane za cukier syntaktyczny również muszą być interpretowane przez procesor językowy, a zatem są częścią składni językowej.
To, co odróżnia cukier syntaktyczny od reszty składni języka, polega na tym, że możliwe byłoby usunięcie cukru syntaktycznego z języka bez wpływu na programy, które można pisać w tym języku.
Chciałbym powiedzieć, że aby podać bardziej formalistyczną definicję
Nie ma to w żaden sposób na celu oczerniania cukru syntaktycznego ani języków, które go mają, ponieważ użycie cukru syntaktycznego często prowadzi do programów, których intencje są bardziej zrozumiałe.
źródło
->
operator C i nie rozumiem, jak ten operator jest mniej ogólny niż jakikolwiek inny.Inne odpowiedzi nie wspominały o kluczowej koncepcji: abstrakcyjna składnia ; bez niego termin „cukier syntaktyczny” nie ma żadnego sensu.
Składnia abstrakcyjna określa elementy i strukturę języków oraz sposób łączenia fraz tego języka w celu tworzenia większych fraz. Składnia abstrakcyjna jest niezależna od konkretnej. Termin „cukier syntaktyczny”, jak rozumiem, odnosi się do konkretnej składni.
Ogólnie rzecz biorąc, projektując język, będziesz chciał stworzyć konkretną składnię dla każdego terminu składni abstrakcyjnej, aby ludzie mogli pisać kod w twoim języku za pomocą zwykłego tekstu.
Powiedzmy teraz, że tworzysz niezręczną konkretną składnię dla foo . Użytkownicy narzekają, a Ty wdrażasz nową konkretną składnię, która reprezentuje tę samą abstrakcyjną składnię . W rezultacie twoja abstrakcyjna składnia i semantyka się nie zmieniły, ale teraz masz dwie konkretne składnie dla tego samego terminu składni abstrakcyjnej.
Wierzę, że to właśnie ludzie mają na myśli, mówiąc „cukier składniowy” - zmiany, które wpływają tylko na konkretną składnię, ale które nie wpływają na składnię abstrakcyjną ani semantykę.
Różnica między „cukrem syntaktycznym” a „konkretną składnią” jest teraz wyraźna. Dla mnie. :)
Ta interpretacja pomaga również wyjaśnić, co mógł oznaczać Alan Perlis, gdy powiedział: „cukier syntaktyczny powoduje raka średnika”: cały konkretny cukier syntaktyczny na świecie nie może naprawić słabej abstrakcyjnej składni, a cały wysiłek włożony w dodanie cukru wysiłek, którego nie spędzasz, zajmując się prawdziwym problemem - abstrakcyjną składnią.
Powinienem również zauważyć, że to wyłącznie moja opinia; Wierzę w to tylko dlatego, że jest to jedyna taka interpretacja, która ma dla mnie sens.
źródło
p
do struktury zawierającej polax
, czy wyrażenia(*p).x
ip->x
mają taką samą składnię abstrakcyjne? Myślę jednak, że byłoby wspaniale, gdyby wszystko sprowadzało się do abstrakcji kontra konkretnej składni..
rdzeniem. Lewym podwęzłem katalogu głównego jest a*
, a jego dzieckiem jestp
. Prawym podwęzłem katalogu głównego jestx
. W przypadku drugiego wyrażenia abstrakcyjne drzewo składniowe ma->
katalog główny, a katalog główny ma dwoje dziecip
ix
. Próbuję dowiedzieć się, czy sensowne jest parsowanie obu wyrażeń inaczej, aby miały to samo abstrakcyjne drzewo składniowe, ale nie widzę tego w tej chwili.x
)(
lub;
) w celu stworzenia drzewa, które odzwierciedla faktyczną strukturę programu (patrz en.wikipedia.org/wiki/Abstract_syntax_tree ). Jednak w abstrakcyjnej składni nic nie mówi się (jeszcze) o semantyce programu.Cukier syntaktyczny jest podzbiorem składni języków. Podstawową ideą jest to, że istnieje więcej niż jeden sposób, aby powiedzieć to samo.
Co sprawia, że trudno powiedzieć, które elementy są cukier syntaktyczny i które kawałki są „czyste składnia” to stwierdzenia jak „trudno powiedzieć, która forma przyszedł pierwszy” lub „trudno jest wiedzieć, w którą stronę ma autor języka” lub „to nieco arbitralne, aby zdecydować, która forma jest prostsza ".
To, co ułatwia wybór, które utwory są czyste lub słodkie, polega na zadaniu pytania w ramach konkretnego kompilatora lub tłumacza. Czysta składnia to rzeczy, które kompilator konwertuje bezpośrednio na kod maszynowy lub na które interpreter bezpośrednio odpowiada. Cukier jest materiałem, który najpierw zamienia się w kilka innych składni zanim te bezpośrednie rzeczy się zdarzą. W zależności od implementacji może to być lub nie takie samo, jak zamierzenie autora, a nawet to, co twierdzi specyfikacja językowa.
W praktyce decyduje się w ten sposób o rzeczywistości.
źródło
Naprawdę, twój pierwszy cytat z Wikipedii mówi, że wszystko „… ułatwia czytanie…”, „… słodsze dla ludzi w użyciu…”.
Na piśmie skrócone formy, takie jak „nie” lub „nie”, można uznać za cukier składniowy.
źródło
Zwykle cukier składniowy jest częścią języka, którą można wyrazić przez istniejącą część języka (składnię) bez utraty ogólności, ale z możliwą utratą jasności. Czasami kompilatory mają wyraźny krok usuwania, który przekształca AST utworzony przez kod źródłowy i stosują proste kroki, aby usunąć węzły odpowiadające cukrowi.
Na przykład Haskell ma cukier składniowy dla monad z rekurencyjnie stosowanymi zasadami
W tej chwili nie ma znaczenia, co to dokładnie znaczy - jednak można zauważyć, że specjalna składnia w LHS może zostać przekształcona w coś bardziej podstawowego w RHS (mianowicie aplikacje funkcyjne, lambda i
let
s). Te kroki pozwalają zachować najlepsze cechy obu światów:Podobnie w C można sobie wyobrazić wyłączenie reguły przepisywania (z powodu przeciążenia operatora itp. Nie jest to prawdą w przypadku C ++):
Można sobie wyobrazić pisanie wszystkich programów bez użycia
->
lub[]
w C, które używają dziś tej konstrukcji. Jednak programiści byliby trudniej go używać, dlatego podali cukier składniowy (wydaje mi się, że w latach 70. może to uprościć także pracę kompilatorów). Jest to prawdopodobnie mniej jasne, ponieważ można technicznie dodać następującą, całkowicie poprawną regułę przepisywania:Czy cukier składniowy jest zły? Niekoniecznie - istnieje niebezpieczeństwo, że zostanie on wykorzystany jako kult ładunku bez głębszego zrozumienia. Na przykład następujące funkcje są równoważne w Haskell, ale wielu początkujących napisałoby pierwszą formę, nie rozumiejąc, że nadużywają cukru składniowego:
Ponadto cukier składniowy może nadmiernie komplikować język lub być zbyt wąski, aby umożliwić uogólniony kod idiomatyczny. Może to również oznaczać, że język nie jest wystarczająco potężny, aby łatwo wykonywać określone czynności - może być zaprojektowany (nie dawaj programistom ostrych narzędzi lub bardzo specyficznego języka niszowego, że dodanie bardziej rozbudowanej konstrukcji zaszkodziłoby innym celom) lub przez pominięcie - ten drugi forma nadała cukierowi składniemu złą nazwę. Jeśli język jest wystarczająco potężny, aby używać innych konstrukcji bez dodawania cukru składniowego, uważa się, że bardziej eleganckie jest ich stosowanie.
źródło
Myślę, że najbardziej oczywistym przykładem byłaby składnia „+ =” w C.
i
wykonaj dokładnie to samo i skompiluj dokładnie do tego samego zestawu instrukcji maszynowych. Druga forma pozwala zaoszczędzić na wpisywaniu kilku znaków, ale co ważniejsze, bardzo wyraźnie widać, że modyfikujesz wartość na podstawie jej bieżącej wartości.
Jako przykład kanoniczny zamierzałem zacytować operatora post / prefiksu „++”, ale zdałem sobie sprawę, że to coś więcej niż cukier syntaktyczny. Nie ma możliwości wyrażenia różnicy między ++ i i ++ w jednym wyrażeniu przy użyciu
i = i + 1
składni.źródło
a[f(x)] += 1
.Najpierw zajmę się niektórymi innymi odpowiedziami konkretnym przykładem. Oparty na zakresie C ++ 11 for for loop (podobnie jak foreach loop w różnych innych językach)
jest dokładnie równoważny (tj. wersja cukrowa)
Teraz, mimo że nie dodaje żadnej nowej abstrakcyjnej składni ani semantyki do języka, ma on prawdziwą użyteczność.
Pierwsza wersja wyraźnie określa cel (odwiedzenie każdego elementu w kontenerze). Zapobiega to również nietypowym zachowaniom, takim jak modyfikowanie pojemnika podczas przechodzenia, dalsze przemieszczanie się
iterator
w korpusie pętli lub subtelne nieprawidłowe warunki pętli. Pozwala to uniknąć możliwych źródeł błędów, a tym samym zmniejsza trudność czytania i rozumowania na temat kodu.Na przykład błąd jednoznakowy w drugiej wersji:
powoduje błąd „jeden po drugim” i niezdefiniowane zachowanie.
Tak więc wersja słodzona jest przydatna właśnie dlatego, że jest bardziej restrykcyjna, a zatem łatwiejsza do zaufania i zrozumienia.
Po drugie, do pierwotnego pytania:
Nie, „cukier syntaktyczny” to (konkretna) składnia języka, uważana za „cukier”, ponieważ nie rozszerza składni abstrakcyjnej ani podstawowej funkcjonalności języka. Podoba mi się odpowiedź Matta Fenwicka na ten temat.
Ma to znaczenie dla użytkowników tego języka, podobnie jak każdej innej składni, i dlatego cukier zapewnia wsparcie (iw pewnym sensie błogosławi) określonym idiomom.
Wreszcie na pytanie bonusowe
brzmi to bardzo podobnie do definicji cukru syntaktycznego: obsługuje (i zapewnia błogosławieństwo dla autorów języka) za pomocą wskaźników jako tablic.
p[i]
Forma nie jest tak naprawdę bardziej restrykcyjne niż*(p+i)
, więc jedyną różnicą jest jasne przekazywanie intencji (i niewielki przyrost czytelność).źródło
Niezależnie od pierwotnego znaczenia tego wyrażenia, obecnie jest on przede wszystkim pejoratywny, prawie zawsze wyrażony jako „tylko” lub „tylko” cukier składniowy. Ma to znaczenie tylko dla programistów, którzy lubią robić rzeczy w nieczytelny sposób i chcą zwięzłego sposobu na uzasadnienie tego swoim kolegom. Definicja tych, którzy dziś używają tego terminu, z ich punktu widzenia, mogłaby wyglądać następująco:
Dlatego otrzymujesz dwa przeciwne wnioski dla tego samego elementu składniowego. Pierwszym przykładem notacji tablicowej jest użycie oryginalnego pozytywnego znaczenia tego terminu, coś podobnego do odpowiedzi Barta. Drugim przykładem jest obrona notacji tablicowej przed zarzutem bycia cukrem syntaktycznym w sensie pejoratywnym. Innymi słowy, argumentuje, że składnia jest użyteczną abstrakcją, a nie kulą.
źródło