Zapomniana technika programowania?
Pierwsze słyszę?
Istnieje taki szczególny rodzaj programowania, w którym tworzy się program, wchodząc z nim w interakcję podczas jego działania. Co więcej, istnieją pewne języki i środowiska zaprojektowane od podstaw do obsługi tego rodzaju programowania, zwanego właśnie repl-driven development. Nie nie, przychodzące od razu na myśl Python i Ruby wcale nie są przykładami takich języków. Czym więc są te systemy programowania i czym różnią się od Pythona, Ruby czy innych języków, które przecież oferują repl?
Słowo repl jest akronimem oznaczającym pętlę odczytaj-porównaj-wydrukuj. Termin pochodzi z historii Lispa. Od samego początku, sześćdziesiąt lat temu, standardowym sposobem pracy z Lispem było uruchomienie procesora języka, wpisywanie wyrażeń w jego znaku zachęty i czekanie, aż oceni wyrażenia i wydrukuje wyniki, zanim poprosi o kolejne wyrażenie. Czyli właśnie taka pętla read-eval-print. W dzisiejszych czasach takie działanie jest oczywistością. Każdy język oferuje repl. Ba, istnieje witryna internetowa repl.it, której celem jest dostarczanie takich odpowiedzi. Oczywiście nie zapewnia wszystkich środowisk programistycznych a szczególnie zabawne jest to, że nie zapewnia żadnego z kanonicznych środowisk programistycznych opartych na replikach: Common Lisp i Smalltalk.
No to czym się różnią te „reple”?
Taki Lisp czy Smalltalk, w odróżnieniu od chociażby Pythona, ma język i system wykonawczy, które są zaprojektowane od podstaw z założeniem, że zamierzasz tworzyć programy, uruchamiając silnik języka i rozmawiając sobie z nim, ucząc się go interaktywnie, zmieniając program w trakcie jego wykonywania. Od razu możesz pomyśleć: ale jak to, w Pythonie też możemy wykonywać polecenia „po kawałku” (vide Anaconda)? Możliwość robienia pewnych rzeczy w repl nie powoduje jednak, że silnik staje się środowiskiem programowania opartym na replikacji. To, co wyróżnia staromodne środowiska Lisp i Smalltalk, to fakt, że nie nakładają one nieuzasadnionych ograniczeń na to, co możesz zrobić; jeśli język i środowisko wykonawcze mogą to zrobić, to replika też może to zrobić. Na przykład, możesz poprosić bieżącą wersję Lisp, aby przebudowała się od zera za pomocą polecenia (rebuild-ccl :full t)
. Cały zakres możliwości systemu deweloperskiego jest dostępny dla repl.
Najważniejsza różnica to jednak oczywiście możliwość zmiany programu podczas gdy jest on uruchomiony. Co się stanie, gdy w Pythonie zdefiniujesz funkcję A, która wywołuje jeszcze niezdefiniowaną funkcję B? Oczywiście wywołanie funkcji A zostanie przerwane bo B nie doczekało się póki co zdefiniowania. Większość współcześnie stosowanych środowisk programistycznych przerwie działanie takiego programu i „wróci do prompta” uprzednio wyświetlając komunikat o błędzie.
Breakloop
Tymczasem w takim staromodnym środowisku Lisp lub Smalltalk, przerwa w wykonywaniu funkcji A będzie skutkowało wpadnięciem w breakloopa. Breakloop to w pełni funkcjonalny repl, zawierający wszystkie narzędzia głównego repl, ale istniejąca w dynamicznym środowisku naszej „uszkodzonej” funkcji. Z breakloopa można wędrować w górę i w dół stosu zawieszonych wywołań, badając wszystkie zmienne, które są widoczne leksykalnie z każdej ramki stosu. Możesz więc sprawdzić wszystkie dane na żywo w uruchomionym programie. Co więcej, możesz edytować wszystkie aktualne dane w programie. Jeśli uważasz, że przerwanie zostało spowodowane niewłaściwą wartością w jakiejś określonej zmiennej lub polu, możesz to interaktywnie zmienić i wznowić zawieszoną funkcję. Jeśli teraz działa poprawnie, gratulacje: znalazłeś problem i jego rozwiązanie.
Ponieważ cały język i system programowania są dostępne bez ograniczeń, w replice można zdefiniować brakującą funkcję B, wznowić działanie funkcji A i uzyskać spodziewany wynik. W rzeczywistości istnieje styl programowania, dobrze znany w kręgach Lisp i Smalltalk, w którym definiuje się funkcję najwyższego poziomu za pomocą wywołań innych funkcji, które jeszcze nie istnieją, a następnie definiuje się te funkcje w wynikowych przerwaniach. To szybki sposób na wdrożenie kodu, jeśli wiesz już, jak powinna działać dana funkcja.
Sprawdź oferty pracy na TeamQuest
Dzisiaj
Obecnie nie każdy programista preferuje taki sposób rozwoju. Niektórzy programiści wolą myśleć o rozwoju jako o procesie projektowania, planowania i montażu funkcji niczym części na stole warsztatowym. Nie ma w tym nic złego – na takim podejściu zbudowano międzynarodowy przemysł o niewyobrażalnej wielkości. Ale jeśli wolisz interaktywne programowanie, jeśli jest to dla ciebie bardziej naturalne, może to uczynić cię znacznie bardziej produktywnym. Obecne modele kształcenia i organizacji pracy doprowadziły do sytuacji, że wielu programistów nigdy nawet nie słyszało o repl-driven development – a może akurat w ich pracy byłoby to prawidłowe podejście do tworzenia oprogramowania?
Przeczytaj też o technikach zarządzania swoim czasem.