bookmark_borderMetoda Copy’ego Paste’a

Swego czasu znajomy programista wystosował do przełożonego nietypową prośbę. Zażyczył sobie pedałów wytnij-kopiuj-wklej. Argumentował, że jego praca bardzo przyspieszy.

Pomysł sam w sobie niegłupi. Szczególnie, gdyby połaczyć go ze skrzynią biegów schowka i zmieniać nią obiekty. Był to oczywiście jego szyderczy żart, ale rzeczywistość już tak śmieszna nie jest, bo wczoraj zmarł Larry Tesler.

Kto?

Twórca metody kopiuj-wklej!

Urodził się w 1945 i studiował na uniwersytecie Stanforda. Podczas pracy w PARC w Xerox w latach 70 pracował nad systemem do obróbki dokumentów – Gypsy. Wtedy i tam właśnie narodziła się idea wytnij-kopiuj-wklej, którą potem zaniósł do Apple, w którym pracował przez kolejne lata.

Nie wiem, jak wy, ale ja od dziś Metodę Copy’ego Paste’a nazywał będę Metodą Teslera.

bookmark_borderDaily na 9

Owocowe czwartki, game roomy, ubezpieczenia medyczne, elastyczne godziny pracy. Wszystko, byle tylko zwabić dewelopera do firmy. Żeby go zatrzymać, tego wybrednego, rozpieszczonego przez rynek pracy programistę.

Software house to nie Żabka na Bałutach i głodni, jak mawiał Himilsbach: bajkowego nastroju, klienci nie ustawiają się w kolejce od rana. Można zatem rozpocząć pracę wcześniej lub później. Ważne, by osoby pracujące razem mogły się porozumieć, spotkać, wymienić myśli. Benefit jest ważny, bo chronotyp jest ponoć jak wzrost – bez łamania kości nie da się go zmienić.

Czymże jest ten chronotyp? Jest byciem nocnym Markiem albo rannym ptaszkiem. Jest preferencją organizmu do wstawania rano lub do późnej, wieczornej aktywności. Podobno w tradycyjnie żyjących plemionach rozkłada się on tak, że około 25% populacji lubi nocny tryb życia, 25% poranny, a reszta coś pomiędzy. Miałoby to służyć przetrwaniu grupy, bo w każdym momencie nocy i dnia jest ktoś kto czuwa

Mamy więc Janusza, który wstaje z kurami i Mariusza, co zasypia z sowami. Teoretycznie obaj mają elastyczne godziny pracy i muszą się spotkać od czasu do czasu na callu.

I tu – cały na biało – wchodzi scrum master i ogłasza daily na 9.

Janusz spoko, przychodzi na 7, zje śniadanie, zrobi kupę, poogląda koty w internecie i jest gotowy i świeży na spowiedź z wczorajszych tasków.

Mariusz natomiast każdego dnia roboczego wstaje niewyspany, bo najchętniej przyszedłby na 12, a spać wcześniej nie może. Rośnie mu frustracja, spada IQ, wysypia się tylko w weekendy i wakacje. Każdy poranek spieszy się zaspany na to przeklęte daily. I w dodatku zespół patrzy na niego krzywo. Leń, spóźnia się, marudny, czarna owca, baran czarny.

Tymczasem badania sugerują, że nocne Marki są bardziej inteligentne, a nie leniwe: https://www.psychologytoday.com/us/blog/the-scientific-fundamentalist/201005/why-night-owls-are-more-intelligent-morning-larks

Ta drobna z pozoru kwestia organizacyjna, czyli daily o 9 rano, czyni z marszu nieefektywnym część zespołu. Jak dużą część to już zależy od szczęścia lub nieszczęścia, ale statystycznie około jednej czwartej. Nic nie stoi na przeszkodzie, by daily odbywać na koniec dnia lub w jego środku. Jest to zwyczajnie nawyk, rytuał, który się rozprzestrzenił i jest w nieprzemyślany sposób powielany.

Reasumując: podczas organizowania zespołu scrumowego warto zwrócić uwagę na preferencję jego członków co do godzin, w jakich spotkania mają się odbywać. Dotyczy to również spotkań w godzinach około-obiadowych, gdy część osób może po prostu umierać z głodu z powodu kilkugodzinnych dyskusji.

Zbyt poranne daily może obniżyć wydajność zespołu, o ile znajdują się w nim nocne Marki. Warto o tym pamiętać.

bookmark_borderProblem nazw w programowaniu

Czytanie kodu źródłowego jest trudniejsze, niż jego pisanie. Przyzna to każdy kto pracował z odziedziczonym repozytorium i próbował zrozumieć jego działanie. Przebijanie się przez tysiące linii kodu, przez setki definicji funkcji i zmiennych, w próbie zrozumienia co autorzy mieli na myśli jest ciężkim, męczącym, okrutnie wyczerpującym zadaniem.

Dlaczego tak jest?

Czy zrozumienie przepisu kuchennego jest trudne?

Czy jest trudniejsze od napisania go?

Czy zrozumienie przepisu kuchennego sprzed trzydziestu lat jest trudniejsze od zrozumienia przepisu sprzed tygodnia?

Nie sądzę.

Czemu więc czytanie kodu źródłowego staje się trudniejsze z każdym kolejnym miesiącem od jego powstania? Dlaczego nowy kod jest czytelny, a stary niezrozumiały? Jaka może być przyczyną “gnicia oprogramowania” i nienawiści do legacy code?

Zastanówmy się nad czynnością czytania kodu źródłowego. Co robimy próbując zrozumieć program, wgryźć się w kod?

Działamy jak komputery, tylko mniej wydajnie. Przeglądamy kod, czytamy go, napotykamy na zmienne i funkcje. Nie będąc maszynami nie jesteśmy w stanie spamiętać każdej wartości oraz ciągu konstrukcji. Próbujemy więc “zrozumieć” kod. Napotykając na nazwę zmiennej staramy się domyślić, co oznacza i w jakim kontekście jest używana. Nazwy funkcji lub procedur również próbujemy zrozumieć, najlepiej bez wnikania w ich treść.

Dokładnie tak samo działamy w świecie rzeczywistym. Gdy w przepisie napotykamy na słowo “marchew” wyobrażamy sobie marchew. Rozumiemy ideę marchewki bez zapoznawania się że szczegółami takimi jak jej masa, kolor, DNA, czy temperatura.

Kod źródłowy jednak – mimo starań obozu oprogramowania zorientowanego obiektowo – nie jest jak świat rzeczywisty. Odstaje od niego znacząco.

W świecie rzeczywistym dysponujemy ogromną, lecz ograniczoną ilością słów w naszych słownikach. Języki naturalne przetwarzane są przez ludzkie mózgi zupełnie inaczej niż kod źródłowy przez kompilatory. Krzesło na przykład to dla człowieka nie tylko konkretne krzesło, ale idea krzesła jako takiego. W większości przypadków zbędne nam są szczegółowe informacje na temat obiektów by przetwarzać i rozumieć język naturalny, w którego zdaniach te obiekty, reprezentowane przez słowa, występują. Tam z kolei gdzie jest nam potrzebna precyzja definicji (jak w prawie na przykład) napotykamy na spore problemy.

Świetnym przykładem ilustrującym, co by było gdybyśmy przetwarzali język naturalny tak jak komputery przetwarzają kod źródłowy jest ten filmik:

Wróćmy do czynności czytania kodu przez programistów. Cóż robi developer? Czyta nazwę zmiennej lub funkcji i próbuje zgadnąć, co ona oznacza. Póki kod jest “czysty” i niezbyt stary instynktowne zrozumienie jest stosunkowo poprawne. Czytanie idzie mu dobrze i praca z kodem jest sprawna.

Kłopot zaczyna się, gdy nie jest w stanie poprawnie domniemać znaczenia nazw.

Problem jest jednak znacznie poważniejszy. Jest to jedna z fundamentalnych trudności w rozwoju oprogramowania. Częściowo oddaje to poniższy cytat:

There are only two hard things in Computer Science: cache invalidation and naming things

Phil Karlton

Chodzi o nazewnictwo.

Nazewnictwo jest punktem styku pomiędzy światem maszyn i ludzi. Jest jednocześnie przepaścią między jednym, a drugim. W świecie rzeczywistym, gdzie język ludzki rozumiany jest przez mózgi, które są w stanie instynktownie zrozumieć klasy obiektów / idee przedmiotów rzadko tworzone są nowe słowa. W kodzie źródłowym nowe słowa tworzone są nieustannie.

Co dzieje się, gdy tworzymy nowe słowo w ludzkiej mowie? Uczymy się go. Powstaje nowe słowo – na przykład „komputer” – i wszyscy ludzie na świecie uczą się, że oznacza ono taką, a nie inną rzecz. Nie ma znaczenia, czy mowa o MacBooku, Dellu XPS, ENIACu, czy PC-cie. Nie tworzymy odrębnych słów opisujących komputery stojące w każdym z departamentów firmy, nie tworzymy innych słów na różne modele MacBooka mające inną wielkość pamięci RAM. Nie ma takiej potrzeby. Nowe słowa tworzymy rzadko. Za nowym słowem kryją się duże grupy obiektów. 

Inaczej jest w przypadku kodu źródłowego. „Użytkownik” znaczy co innego w każdym omal programie, jaki do tej pory napisano. W jednych jest to imię i nazwisko, w innych również data urodzenia, w jeszcze innych płeć. W niektórych imię i nazwisko może się składać tylko z liter łacińskich, w pewnych mieć maksymalnie 20 znaków. I tak dalej, etc.

Mówiąc krótko: w kodzie źródłowym niczego nie da się nazwać poprawnie. Żadna nazwa, jak dobrej byśmy nie wybrali, nie będzie odpowiadała znaczeniu słów wyjętych z języka naturalnego, ze świata ludzi.

Możemy być tylko zbyt precyzyjni („user”) lub zbyt ogólni („userWithNameAndSurnameAndSexAndDateOfBirth). Nigdy omal nie będziemy idealnie precyzyjni w nazywaniu zmiennych, czy funkcji. Nigdy te nazwy nie będą znaczyły tego, co nam się wydaje. Zawsze musimy nawigować się do definicji i czytać implementację. Za każdym razem, gdy dołączamy do istniejącego projektu musimy „nauczyć się jego języka”. Nauka nowego języka jest zawsze trudna, żmudna i męcząca. Dlatego właśnie, ze wszystkich wymienionych powyżej przyczyn, czytanie kodu źródłowego jest trudne.