Czy język programowania mógłby również działać bez instrukcji?

9

Podczas programowania w JavaScript zauważyłem wszystko, co można zrobić za pomocą instrukcji, a bloki można wykonać za pomocą samych wyrażeń. Czy język programowania może działać poprawnie tylko z wyrażeniami? A jeśli tak, dlaczego w ogóle używane są wyciągi?

MaiaVictor
źródło
2
Tak, istnieje wiele języków, w których wszystko jest wyrażeniem, takich jak Ruby i wszystkie dialekty Lisp.
amara,
@sparkleshy Rozumiem, tylko zgaduję: wszystkie mają operator analogiczny do przecinka JavaScript (wykonuje dwie instrukcje i zwraca wartość ostatniego)? Czy ogólnie jest to rozwiązanie do wykonywania dwóch instrukcji po kolei? Myślę, że liczę prognozy CL jako analogu, nawet jeśli działa to dla> 2 wyrażeń.
MaiaVictor,
1
Wszystko-to-wyrażenie nie musi wyglądać inaczej niż zwykły język instrukcji, instrukcje po prostu ... mają wartości. Jeśli wykonasz wyrażenia instrukcji javascript, cały istniejący kod będzie całkowicie poprawny.
amara
1
CoffeeScript jest językiem typu wszystko-jest-wyrażeniem, który kompiluje się w JavaScript.
Spoike,
1
powiązane (być może duplikat): Jaka użyteczna ekspresja będzie niemożliwa w języku, w którym wyrażenie nie jest stwierdzeniem? „Dlaczego tak wiele gramatyk rozróżnia wyrażenia i stmt, skoro jak zaznaczono w odpowiedziach, nie ma to sensu”.
komar

Odpowiedzi:

14

Pewnie. Najprostszym sposobem jest przypisanie wartości wynikowej do każdej konstrukcji, która jest obecnie instrukcją, a tym samym przekształcenie jej w wyrażenie. Jednak niekoniecznie jest to przydatne lub znaczące. Jedynym potencjalnym zyskiem jest odrobina konceptualnej prostoty. Jednak jeśli następnie przystąpisz do usuwania rzeczy takich jak średniki i pętle (wymagające łańcuchowego łączenia przez inne operatory i funkcje), programy intensywnie korzystające z instrukcji stają się brzydkie.

Bardziej radykalnym, ale sensownym sposobem na to jest takie zaprojektowanie języka, aby prawie wszystko miało znaczącą wartość, i użycie go w taki sposób, że prawie zawsze używasz wyrażenia dla tej znaczącej wartości, a nie dla innych efektów. Robią to funkcjonalne języki programowania (do pewnego stopnia; na przykład Haskell ma deklaracje, które nie są wyrażeniami).

Instrukcje są używane, ponieważ w paradygmacie imperatywnym istnieje wiele typowych operacji, które nie mają użytecznej wartości wynikowej, a także dlatego, że pojęcie instrukcji sekwencyjnych (zamiast obliczeń) całkiem dobrze pasuje do tego paradygmatu. Jeśli duży procent twojego programu to mutowanie stanu, a nie obliczanie nowych wartości, nie ma sensu wymagać tworzenia wartości (co jest wynikiem pętli for?). W przeciwieństwie do tego, gdy cały twój paradygmat (FP) opiera się na obliczaniu wartości, wartości odstające, które nie mają wartości wynikowej, nie gwarantują wyjątku: Zamiast tego dajesz im wynik wartownika, który nic nie znaczy.


źródło
-1 to nie jest do końca prawda
amara,
3
@sparkleshy Jaka część nie jest prawdą i jak?
1
akapit pierwszy: wątpisz w pomysł, że instrukcje mają przydatne zwracane wartości (ale wiele z nich ma), zaproponuj brzydką rzecz (dlaczego?). akapit drugi: oświadcza, że ​​wszystkie funkcjonalne języki programowania używają tej brzydkiej koncepcji z marginesami, co jest śmieszne. akapit trzeci: fałsz, mamy już w blokach {} wartość jest ignorowana i nie powoduje żadnych problemów, niepoprawna; już dajesz im brak wartości pustki, w jaki sposób wartość null jest mniej znacząca? ogólnie: to nie jest tak naprawdę prawda
amara,
2
@sparkleshy - Żadne instrukcje nie mają przydatnych wartości zwracanych, dlatego są instrukcjami . Mogą mieć przydatne skutki uboczne (takie jak przydział), ale to nie to samo. To nie jest tak naprawdę marginalna koncepcja. Jest dobrze znany, jeśli nie do końca praktyczny, jeśli jest wzięty do N-tego stopnia. Ta wartość wartownika nie jest zerowa ani nieważna, jest to jednostka, która subtelnie różni się od obu. +1 dla Delnana, aby to nadrobić.
Telastyn
4
@sparkleshy (1) Możesz mylić wyrażenia (które mogą być jedynym składnikiem wyrażenia) z wyrażeniem (które nie są wyrażeniem i nie mają wartości wynikowej). (2) Co? Każdy zwolennik FP to potwierdzi (i argumentuje, że to dobrze). A może jest to tylko „część”, której jesteś przeciwny? (3) Bloki {} są tym, o czym mówię („pojęcie instrukcji sekwencyjnych”). I gdzie mam powiedzieć, że coś powoduje problemy? Różnica między voidi null/ unitpolega na tym, że te ostatnie są wartościami i mogą być przekazywane, podczas gdy voidjest wyjątkowe, ponieważ nie ma wartości tego typu.
5

Zależy od tego, jak zdefiniujesz „wyrażenie” i „wyrażenie”.

Bardzo ścisła definicja rozróżniałaby stwierdzenia jako „rzeczy, które mają skutki uboczne, a być może wartość zwrotną”, a wyrażenia jako „rzeczy, które mają wartości zwracane, ale nie mogą mieć skutków ubocznych”. Przy takiej definicji żaden znaczący program nie może zostać napisany bez co najmniej jednej instrukcji (która musiałaby ocenić wyrażenie i wyprowadzić jego wartość zwrotną) - same czyste wyrażenia nie mogą wchodzić w interakcje ze światem poza programem. Sam język może być nadal całkowicie czysty (tzn. Nie zawierać żadnych instrukcji), jeśli nieczysta część zostanie przeniesiona z języka do ekosystemu wspierającego (dokładnie tak robi Haskell, chociaż język ma zarówno definicje, jak i wyrażenia) .

Jeśli jednak dopuszczasz skutki uboczne w wyrażeniach, wówczas rozróżnienie między wyrażeniami a wyrażeniami staje się arbitralne i znacznie mniej interesujące - oczywiście możesz wymyślić język programowania, który składa się wyłącznie z wyrażeń; większość dialektów Lisp działa w ten sposób. W takiej sytuacji ocena wyrażenia pod kątem skutków ubocznych jest prawie dokładnie taka sama, jak wykonanie instrukcji, i można argumentować, że w takim języku wyrażenia i instrukcje są tym samym. Różnica między wyrażeniem a wyrażeniem jest zatem tylko składniowa.

Wiele języków wciąż czyni to rozróżnienie składniowe, ponieważ jest użyteczne nie ze względów technicznych, ale ze względu na czytelność. Wyrażenie czegoś oznacza, że ​​jesteś zainteresowany jego wartością zwrotną, a tym bardziej jego skutkami ubocznymi; złożenie oświadczenia mówi czytelnikowi, że zamierzasz powodować skutki uboczne, a zwracana wartość może być interesująca lub nie.

tdammers
źródło
+1 za komentarze na temat czytelności ... W końcu ludzie muszą to zrozumieć ...
mattnz
1

ATL i Xtend to języki programowania działające bez instrukcji. Wiele języków funkcjonalnych również nie zawiera instrukcji. Tak, tak, język programowania może działać dobrze bez instrukcji. Myślę, że wypowiedzi w wielu językach są reliktem programowania imperatywnego. Są nadal używane, ponieważ są powszechnie znane, a w niektórych przypadkach sprawiają, że kod jest bardziej czytelny.

SpaceTrucker
źródło
1

Tak.

Języki funkcjonalne (i języki pojedynczego przypisania) wszystko jest wyrażeniem. Przykładami są Haskal (i SISAL). Gdzie zarówno instrukcje if, jak i pętle zwracają wartości.

Istnieją inne klasy języków: Łatwo przychodzi mi na myśl języki deklaratywne (jestem pewien, że istnieje wiele innych języków, które nie zależą od instrukcji). Te języki nawet nie potrzebują wyrażeń (w takim samym znaczeniu, jak normalnie byś pomyślał). Deklarujesz, co jest prawdą i możesz uzyskać wiele zwrotów wyników. Łatwy jest tutaj prolog.

Martin York
źródło
Haskell ma deklaracje, nie są wyrażeniami.
Janus Troelsen