Full Stack Software Engineer
Idea odtwórczości wtórnej
Co się dzieje z tworzeniem oprogramowania, kiedy wykonanie tanieje na tyle, że punktem wyjścia przestaje być problem, a staje się cudze rozwiązanie tego problemu.
Kiedy możliwość tworzenia przestaje być ograniczeniem
Przez dużą część historii oprogramowania sporo pomysłów kończyło się jeszcze przed pierwszą linią kodu. Nie musiały być złe. Wystarczyło, że między pomysłem a działającą wersją stało kilka miesięcy pracy, pieniądze, ludzie i masa rzeczy, o których zwykle nie myśli się w chwili, kiedy pomysł wpada do głowy. Własny edytor, aplikacja do notatek czy narzędzie dla programistów od razu oznaczały więc coś więcej niż „fajnie byłoby to zrobić”. Koszt wymuszał zastanowienie się, czy naprawdę warto w to wejść.
Ten filtr miał oczywiście swoją cenę. Odcinał ludzi bez kapitału, zabijał dobre pomysły i sprawiał, że część z nich nigdy nie wychodziła poza szkic. Dzisiaj jest pod tym względem dużo lepiej. Sam korzystam z tej zmiany praktycznie codziennie. To, do czego kilka lat temu potrzebowałbym kilku osób, jestem w stanie przynajmniej sprawdzić sam, czasem jeszcze tego samego dnia.
Zmieniło się jednak miejsce, w którym pojawia się ograniczenie. Techniczna realizacja coraz rzadziej zabija pomysł na starcie, więc większego znaczenia nabiera decyzja, czy w ogóle powinien zostać zrealizowany.
Mam wrażenie, że kultura wokół software'u trochę za tym nie nadąża. Nadal bardzo mocno premiuje moment pojawienia się czegoś nowego. Demo, screenshot, repozytorium, pierwsze gwiazdki, pierwszy tysiąc użytkowników. „Built this over the weekend” jest dobrą historią i łatwo ją pokazać. Znacznie gorzej wygląda opowieść o czterech latach poprawiania synchronizacji, migracjach danych, dokumentacji albo błędzie występującym tylko na jednej wersji macOS.
A przecież duża część jakości produktu ujawnia się dopiero później, kiedy znika pierwsza ekscytacja i zostaje zwykłe używanie.1
Generatywne AI tylko przyspiesza coś, co zaczęło się wcześniej. Jeszcze niedawno zdanie „napisałem własny system do X” automatycznie sugerowało spory nakład pracy. Dzisiaj sam łapię się na tym, że pierwsze pytanie brzmi raczej: ile to zajęło i jaka część powstała z agentem.
Jeżeli za kilka lat jedna osoba będzie mogła w ciągu dnia przygotować kilka sensownych wariantów tego samego produktu, samo „potrafię to zbudować” zacznie mówić o twórcy coraz mniej. Bardziej interesujące stanie się to, co wybrał: dlaczego akurat ten problem, dlaczego od zera, dlaczego nie rozszerzenie czegoś istniejącego, dlaczego ta funkcja weszła do produktu, a inna nie.
Fred Brooks pisał wiele lat temu o różnicy między złożonością wynikającą z samego problemu a tą, którą dokładamy sobie narzędziami i sposobem implementacji.2 Dzisiejsze narzędzia zdejmują z nas coraz większą część tej drugiej. Pierwsza nadal zostaje i chyba właśnie tam będzie się przesuwać coraz większa część pracy.
Zaczynamy od cudzego rozwiązania, a nie od problemu
W tym miejscu dochodzę do rzeczy, dla której brakowało mi nazwy.
Odtwórczość wtórna.
Brzmi trochę zbyt poważnie jak na obserwację dotyczącą aplikacji, ale dobrze opisuje to, co mam na myśli. Kiedy stworzenie produktu było drogie, częściej trzeba było zacząć od samego problemu. Jak ludzie zapisują informacje? Jak do nich wracają? Co właściwie przeszkadza im w obecnym sposobie pracy?
Dzisiaj bardzo łatwo zacząć o krok później i zamiast zastanawiać się nad notatkami, zastanawiać się nad tym, jak zrobić lepszego Notiona.
Kolejna osoba patrzy już na produkt, który miał być lepszym Notionem. Bierze z niego jedną rzecz, z innego narzędzia drugą, dodaje własny pomysł i tworzy następną wersję. Nie ma w tym nic szczególnie dziwnego, bo cała technologia rozwija się dzięki temu, że ktoś korzysta z rzeczy powstałych wcześniej.
Ciekawy robi się dopiero moment, w którym po kilku takich iteracjach pierwotny problem zaczyna być ledwo widoczny. Zostają wcześniejsze odpowiedzi i to je interpretujemy dalej.
To właśnie nazywam odtwórczością wtórną. Punktem odniesienia dla kolejnego produktu staje się już nie sam problem, ale cudza odpowiedź na ten problem.
Kiedy zacząłem o tym myśleć, wróciłem do Williama Morrisa i Williama Stanleya Jevonsa. Pisali o zupełnie innych rzeczach: Morris o pracy, produkcji i mechanizacji, Jevons o zużyciu węgla.3 Interesuje mnie u nich przede wszystkim sam mechanizm. Wydajność rośnie, koszt pojedynczego działania spada i pojawia się dodatkowa możliwość produkcji.
Morris zwracał uwagę, że maszyny określane jako oszczędzające pracę niekoniecznie prowadzą do tego, że po prostu pracujemy mniej.4 Jevons zauważył podobną zależność przy wykorzystaniu zasobów: większa efektywność może w pewnych warunkach zwiększyć zużycie całkowite.5
Kiedy patrzę na własną pracę, ten odruch widać bez większej teorii. Agent skraca mi zadanie z jednego dnia do godziny. Teoretycznie odzyskałem większość dnia. W praktyce prawie nigdy nie zamykam wtedy komputera.
Robię następną rzecz.
Jeśli prototyp, którego wcześniej nie zacząłbym ze względu na dwa miesiące pracy, mogę sprawdzić w tydzień, pojawia się pokusa, żeby go sprawdzić. Potem kolejny. Koszt eksperymentu spada na tyle, że znacznie mniej pomysłów odpada przed rozpoczęciem.
To jest ogromna zaleta. Łatwo jednak przyzwyczaić się do sytuacji, w której większa liczba wykonanych rzeczy sama zaczyna wyglądać jak postęp.
Sam wpadałem w ten sposób myślenia wiele razy. Korzystam z jakiegoś produktu, czegoś mi brakuje i pojawia się bardzo szybka reakcja: zrobiłbym to inaczej. Jeszcze kilka lat temu następny krok oznaczał policzenie kilku tygodni pracy. Dzisiaj mogę otworzyć repozytorium i godzinę później mieć początek własnej wersji.
To jest trochę niebezpiecznie przyjemne.
Nie każdy brak wymaga jednak nowego produktu. Czasami da się go załatwić małym skryptem, pluginem albo zmianą w istniejącym projekcie. Zdarza mi się też coś jeszcze dziwniejszego: używam narzędzia przez dwa lata i właściwie nic mi w nim nie przeszkadza, a potem przez dwa dni oglądam konkurencję i nagle widzę dziesięć problemów, których wcześniej w ogóle nie zauważałem.
Najprostszy przykład mam z notatkami.
Mam swój system. Wiem, gdzie wrzucam projekty, gdzie luźne pomysły, jak czegoś szukam i jak później do tego wracam.
Potem trafiam na nowe narzędzie i okazuje się, że nie mam grafu wiedzy, semantycznego wyszukiwania, lokalnego modelu znającego wszystkie moje notatki ani automatycznych połączeń między nimi. Każda z tych funkcji może być przydatna. Tyle że jeszcze pół godziny wcześniej mój system działał.
I wtedy zmienia się też sposób, w jaki go oceniam. Zamiast patrzeć na to, czy pomaga mi pracować, zaczynam porównywać go z funkcjami, które właśnie zobaczyłem gdzieś indziej.
Jeśli zdecyduję się przenieść, koszt zmiany też nie kończy się na eksporcie kilku plików. Dane zwykle da się skopiować. Znacznie trudniej przenieść przyzwyczajenia, nazewnictwo, skróty, automatyzacje, linki i wszystkie małe decyzje, które po dwóch latach są już prawie niewidoczne.6
Nowe narzędzie przez jakiś czas jest więc gorsze właśnie dlatego, że jest nowe. Później je oswajam i zwykle mniej więcej wtedy pojawia się następne.
Możemy tworzyć więcej. Co zrobimy z odzyskanym czasem
Nie mam ochoty wracać do świata, w którym stworzenie prostego produktu kosztowało kilka miesięcy. Lubię obecne narzędzia i lubię możliwość sprawdzenia pomysłu bez kompletowania zespołu przed napisaniem pierwszej wersji.
Pytanie zaczyna się później: co właściwie robimy z czasem, który dzięki temu odzyskaliśmy?
Najbardziej oczywista odpowiedź brzmi: produkujemy więcej. Więcej aplikacji, bibliotek, startupów i eksperymentów. Jeśli koszt próby spada, liczba prób rośnie i trudno się temu dziwić.
Nie cały odzyskany czas musi jednak kończyć jako kolejny produkt. Część może zostać w środku tego, który już powstał.
Tu robi się dużo mniej efektownie.
Kompatybilność plików po pięciu latach. Migracje, których użytkownik nawet nie zauważa. Dokumentacja, która faktycznie zgadza się z programem. Dostępność traktowana jak część produktu, a nie coś dopisywanego później.7 Maintainer odpowiadający na issue pół roku po tym, jak projekt przestał być ciekawym weekendowym eksperymentem.
Na premierze trudno się tym pochwalić. Po dwóch latach korzystania z produktu te rzeczy zaczynają znaczyć więcej niż animacja na stronie głównej.
Podobnie patrzę na eksport danych. Jest mało ekscytujący, dopóki naprawdę nie próbujesz odejść z danego narzędzia. Prawo UE częściowo chroni możliwość przenoszenia danych osobowych, choć art. 20 RODO ma konkretny zakres i nie oznacza prawa do skopiowania całego stanu dowolnej aplikacji.8 Dla mnie sama możliwość wyjścia z produktu bez utraty własnych informacji jest po prostu częścią jakości.
I chyba tutaj najbardziej przeszkadza mi odtwórczość wtórna. Nie sam fakt, że ludzie patrzą na cudze rozwiązania, bo bez tego rozwój technologii byłby niemożliwy. Bardziej chodzi o tempo, które prawie usuwa moment pomiędzy zauważeniem niedoskonałości a rozpoczęciem własnego projektu.
Kiedyś ten moment wymuszał koszt. Dzisiaj trzeba stworzyć go sobie samemu.
Nie traktuję tego jako checklisty przed każdym git init. Sam pewnie złamałbym połowę tych zasad przy pierwszym projekcie, który po prostu wydałby mi się ciekawy. Eksperymentowanie jest potrzebne.
Zastanawiam się tylko, czy nie za łatwo zaczęliśmy utożsamiać nowy projekt z nową wartością.
Wolałbym częściej widzieć sytuacje, w których ludzie dochodzący do podobnego pomysłu próbują zrobić coś razem, rozwijają wspólny standard albo dokładają brakujący element do istniejącego projektu.9 Z drugiej strony świat kilku ogromnych produktów bez sensownych alternatyw też nie brzmi dobrze, więc nie mam tu żadnej prostej zasady.
Właściwie właśnie ten brak prostej odpowiedzi jest dla mnie ciekawy.
Generatywne AI jeszcze bardziej namiesza w tych proporcjach. Jeśli dzisiaj jedna osoba potrafi wykonać pracę, do której niedawno potrzebny był mały zespół, za kilka lat część oprogramowania może powstawać właściwie na żądanie. Zamiast wybierać jedną z dziesięciu aplikacji do rozwiązania małego problemu, być może wygeneruję jedenastą dokładnie pod siebie, użyję jej przez miesiąc i później wyrzucę.
Nie wiem, czy tak będzie, ale nie wydaje mi się to już szczególnie odległe.
W takim świecie jakość będzie miała jeszcze mniej wspólnego z liczbą godzin spędzonych nad kodem. Bardziej będzie mnie interesowało, czy ktoś rozumiał problem, wiedział czego nie dodawać i miał jakiś powód, żeby rozwijać produkt również po pierwszym tygodniu zainteresowania.
Kod raczej nam się nie skończy. Pomysły też nie.
Bardziej zastanawia mnie, czy będziemy potrafili poświęcić jednej rzeczy wystarczająco dużo uwagi, żeby miała czas dojrzeć.
Do Morrisa wracam więc już właściwie tylko po jedno. Technologia może oddać nam część czasu, ale nie mówi, co mamy z nim zrobić. Najprościej przeznaczyć go na następną rzecz. Można też zostać trochę dłużej przy poprzedniej.
Im dłużej patrzę na tempo, w jakim powstają dzisiaj nowe narzędzia, tym mniej interesuje mnie to, co jeszcze będziemy potrafili zbudować. Podejrzewam, że bardzo dużo.
Znacznie ciekawsze jest dla mnie to, czy nauczymy się lepiej rozpoznawać moment, w którym naprawdę warto zacząć coś nowego, i taki, w którym sensowniej będzie zostać przy rzeczy już istniejącej.
Gdzie dokładnie przebiega ta granica, nadal nie wiem.
Pewnie dlatego ten tekst w ogóle powstał.
Footnotes
-
M.M. Lehman, Programs, Life Cycles, and Laws of Software Evolution, Proceedings of the IEEE, 1980: PDF. ↩
-
F.P. Brooks, No Silver Bullet: Essence and Accidents of Software Engineering: tekst. ↩
-
William Morris pisał o mechanizacji i produkcji m.in. w Useful Work versus Useless Toil oraz News from Nowhere. William Stanley Jevons opisywał zależność między efektywnością wykorzystania węgla a jego zużyciem w The Coal Question z 1865 roku. ↩
-
William Morris, Useful Work versus Useless Toil (1884): pełny tekst. ↩
-
William Stanley Jevons, The Coal Question. Opisana przez niego zależność stała się później podstawą pojęcia określanego jako paradoks Jevonsa. ↩
-
S. Leroy, Why Is It So Hard to Do My Work? The Challenge of Attention Residue When Switching Between Work Tasks, 2009: DOI. ↩
-
Zjawisko budowania własnego rozwiązania mimo istnienia wystarczającej alternatywy bywa opisywane jako not invented here. Zob. też Dan McKinley, Choose Boring Technology. ↩