Ostatnio na forum Warsztatu wyrosła dyskusja wokół niepozornej instrukcji break
. Zaczęło się od zasłyszanej opinii, że korzystanie z niej jest objawem złego stylu programowania i że jest generalnie niezalecane. Argumentem na rzecz takiego twierdzenia jest to, że break
jest podobny w swoim działaniu do etykiet i “wyklętej” instrukcji goto
:
W sumie wyszła z tego całkiem długa polemika, która ujawniła kilka ciekawych faktów. Po pierwsze: przejrzystość kodu jest w całkiem dużym stopniu kwestią subiektywną i o ile jednemu może przeszkadzać brak (lub niewystarczająca ilość) komentarzy, to dla drugiego o wiele ważniejsze może być używanie lub nieużywanie określonych konstrukcji językowych. Po drugie: oprócz wspomnianego już goto
czy wywołanego we wspomnianym wątku break
a, do instrukcji potencjalnie niepożądanych swobodnie można zaliczyć bardzo wiele innych rozwiązań – zależnie od upodobań, poczucia ‘słuszności’, bieżącej fazy księżyca i pewnie mnóstwa jeszcze innych kryteriów. I tak dostało się chociażby pętlom “nieskończonym” (typu while(true)
lub for(;;)
), wspomniano coś o wyjątkach, a sam napomknąłem o instrukcji continue
lub “przedwczesnym” return
:
Teoretycznie można by wszystkie te konstrukcje usunąć w imię ideologicznej czystości programowania strukturalnego, w którym każdy blok ma dokładnie jedno wejście i wyjście. Ale tu na szczęście wkracza wniosek trzeci: języki programowania używane w praktyce nie są żadnymi doskonałymi modelami, nad którymi należy się zachwycać. To narzędzia i jako takie powinny być przede wszystkim wygodne w użytkowaniu.
Więc nie warto drzeć kotów o sens stosowania break
czy nawet goto
(która to instrukcja też ma swoje zastosowania) i wydawać ogólne sądy na temat ich ‘nieprofesjonalności’. Bo nawet jeśli ta czy inna instrukcja rzekomo jest zła, to korzystający z niej kod nadal może być dobry, czytelny i łatwy do modyfikacji… Łącznie z refaktoringiem, który tego czy innego break
a może przecież usunąć ;P
Zdaje mi się, że główną ideą programowania strukturalnego było, aby czytający kod mógł czytać go łatwo i ze zrozumieniem, bez zbędnego cudowania.
Taki kod w Asm ze skokami w różne miejsca programu nie jest najfajniejszy do czytania ;)
Odnosnie tematu, na podstawie tego co napisalem przed chwila powiem tylko jedno: trzeba zachować rozsądek :)
Jeśli ktoś czyta kod i widzi break to wie dokładnie gdzie ten break skacze. Podobnie z return i continue. Przy goto dowolność jest większa, ale jeśli jest używane to zazwyczaj tak, że widać dokąd idzie ;) (przydaje sie glownie przy wychozeniu z 2 petli)
Takie jest przynajmniej moje zdanie :)
Od kiedy W. Dijkstra napisal “Go To Statement Considered Harmful” nikt juz nie lubi goto. A to przeciez dobra instrukcja jest.
Sabre- z całym szacunkiem, ale Dijkstra chyba dłużej studiował ten temat i uważniej. Ty piszesz, że jest dobrą, bowiem jest wygodna, prawda? On to napisał, bowiem spojrzał na wszystko, włącznie z burdelem jaki się tworzy w związku z forwardingiem i innymi cudami procesora.
Nie ma algorytmu, którego nie możemy zaimplementować bez GOTO. Nie ma algorytmu, w którym zastosowanie GOTO miało jakiekolwiek znaczenie dla złożoności obliczeniowej (pozytywne, lub negatywne).