[PL] Dlaczego C++ to zła opcja? Podsumowanie przygód

Na zakończenie mojego urlopowania i zabaw z C++ pokuszę się o małe podsumowanie.
Zapewne niezbyt odkrywcze, aczkolwiek po raz kolejny powiem - never again.

Mam sentyment do języka, do linii kodu, które kiedyś w nim nasmarowałem, ale teraz po różnych doświadczeniach uważam, że to strata czasu.

Dlaczego?

Po pierwsze, od razu przypomina mi się moja droga rozwoju w fachu programistycznym.
Na początku z studenckim zapałem uwielbiałem programować, ponieważ po prostu mogłem sobie poprogramować. Kropka. Gdy dostawałem jakieś zadanie, to frajdę mi sprawiało nie to co w zadaniu zostało sprecyzowane, lecz droga jaką musiałem odbyć aby do celu dojść.
Przy brakach w doskonałości platformy, języka i środowiska człowiek "marnował" żeby nie skłamać może i ponad 50% czasu wykonania na to, aby poukładać platformę, ujarzmić niuanse języka i łącząć N narzędzi aby w kontekście zadania drogę do celu sobie ułatwić.

Sam cel naogól nie był już tak istotny, zrozumiały i godny zapamiętania. Często sformułowany banalnie i obco więc i niby po co miałby być ważny. W końcu co na tym etapie życia programisty może być atrakcyjnego w zadaniu pt. "Zrób korektę do faktury".

Oj.. trzeba:
1) wystawić fakturę (2) wyliczyć różnice w kwotach pomiędzy dokumentami (3) stworzyć odpowiedni dekret finansowy, (4) uwzględnić rejestry podatków na których też wszystko musi się zgadzać, (5) połączyć ze sobą dokumenty, (5) dodać odpowiednie informacje do zlecenia sprzedaży, itd, itd.

Nuda nie? Niech mi ktoś da dokładną specyfikację tego co tam się ma dziać i fajniej już to przełożyć na rzeczywistą problematykę: (1) tutaj muszę dodać nową klasę, (2) zmodyfikować tamtą metodę, (3) tam mam nieobsłużony wyjątek, (4) kurcze, znowu te wskaźniki (5) a static_cast zwrócił mi bad_ptr.
Takie walki są super, a nie jakieś nie wiadomo co znaczące dekrety.

Jak ten etap minął i zaczęło mnie interesować, co ja tak naprawde w tym oprogramowaniu dodaję. Jaką wartość ma z tego użytkownik. Czy funkcjonalność, którą napisałem ma jakikolwiek sens merytoryczny?

Kaliber się przestawił i w zasadzie to samo ciało poszczególnych funkcji, metod, kod, cała algorytmika implementacji poszła w cień.
Zaczęło się myślenie raczej na poziomie logicznego zaprojektowania całości tak, aby miało ręce i nogi. To co z czystego programowania z poprzedniego etapu zostało to coraz bardziej dojrzewająca świadomość powagi architektury.

Ewolucja poszła dalej, ale właśnie tak jak patrzę na to, jak wygląda .NET Framework i C++ w kontekście aplikacji biznesowych to doskonale ilustruje te dwie charakterystyki.

W projekcie w C++ nie dość, że niuanse języka samego w sobie mogą przy nieuważnym i niedoświadczonym programiście stworzyć błąd, którego później nawet ekspert będzie się chwilkę doszukiwał, to jeszcze w zasadzie (tak jak się przez ten tydzień pobawiłem) brakuje mi jednej ustabilizowanej platformy.

Z jednej strony może i atut, ale potem co tu się dziwić, że na rozmowę kwalifikacyjną może przyjść programista C++ chwaląc swój główny i może i jedyny atut, czyli doskonałe opanowanie składni. Do tej pory mu to wystarczyło: przemęczył kiedyś tam żółte, wielkie, grube i niewygodne w czytaniu "Sekrety C++" Jana Bieleckiego. Po tej lekturze klasa jako byt boży śni mu się po nocach i jest w stanie na ten temat śpiewać jak się go obudzi o 3 nad ranem. Postanowił sobie, że nie ma szacunku do STL, Boost, MFC czy innych bibliotek, które moglibyśmy tutaj wymieniać. Tak śpiewa tym językiem, że do tej pory sobie wszystko sam pisał i dobrze mu z tym było.

Może i super, ale jaki z takiego kandydata jest pożytek, gdy przychodzi do firmy, która używa języka jako primo, ale i paru wydawało by się znanych i popularnych API, które przez popularność są jakby jego (tegoż języka) częścią.

Jak już o tych API tych bibliotek mówimy, to właśnie one mogły by być rozwiązaniem.
Jak tu traktować je jak platformę jak każde co bardziej rozbudowane API zamiast połączyć siły tych podstawowych i fundamentalnych wymyśla koło od nowa.
Ścierpię, że jeśli chodzi o biblioteki do GUI.
C++ jest wieloplatformowe, każdy popularny teraz system okienkowy raczej ma swoje API do GUI i te co bardziej wieloplatformowe biblioteki jak wxWidgets czy Qt po prostu semantykę systemu okraszają swoim wrapperem. Czy są czy nie są wieloplatformowe (jak MFC) to po prostu mają z założenia ułatwić życie w określonych typach projektów, które potrzebują mieć interfejs użytkownika.
Banalne i oczywiste, tylko dlaczego te biblioteki nie korzystają z tych bardziej fundamentalnych? Dlaczego w Qt widze ich własne Qlist, a w MFC widzę CList?
Chyba wszyscy się zgodzimy, że w dzisiejszych czasach takie elementy języka jak lista czy string to dokładnie traktuje się jako element platformy a nie coś co trzeba sobie napisać.
Jedną jedyną na platformę i jak myślę stworzę sobię listę, to w głowie mam taką samą linijkę kodu jak każdy inny programista z takim marzeniem, z którym mam jedną cechę wspólną, wybraliśmy tę samą platformę. Trudno przy tylko opcjach nie zgodzić się, że "platforma C++" ta wspólna dla wszystkich to właśnie składnia języka.

Minimalistyczne podejście, ale w tych kategoriach .NET Framework przez który rozumiem:
1) coraz bardziej dojrzały język (a nawet swoboda wyboru języków)
2) Stała, stabilna i tylko rozwijająca się platforma,
3) Różne środowiska (mając na myśli Mono i open source'owe IDE)

To ciągle bardzo szeroki fundament mamy wspólny. W C++ na poziomie IDE i dostawcy takiej wspólnoty na jednym systemie operacyjnym nie ma (vide Borland i Visual Studio).

Dopiero tak naprawde środowiska zarządzane pokazują prawdziwą moc platformy.
Dopiero Java czy .NET pokazują coś czego podejrzewam w C++ nigdy nie zobaczę i nie uznam za godziwej platformy dającej radę dzisiejszym czasom.

Od razu na myśl przychodzi mi argument kosztu.
Kosztu znalezienia i zatrudnienia odpowiedniego pracownika.
Wyszkolenia go i przygotowania do roli pełnowartościowego członka zespołu.
Potem.. dostarczenie rozwiązania o określonych wymaganiach.

Porównując C++ i alternatywy widzę tutaj z jednej strony parowanie 1:1 (w przypadku .NET) i wiele:wiele w przypadku C++. Jak tu założyć wysoką jakość rekrutacji w rozsądnym czasie gdy mówiąc o tej samej platformie moje oczekiwania wobec kandydata mogą być o galaktykę odmienne od oczekiwania codziennej rzeczywistości po stronie programisty.

W przypadku .NET Framework nagle okazuje się, że sprawa się wyjaśnia.
Jak chcę pisać bazodanowe aplikacje okienkowe w architekturze trójwarstwowej to wiem czego potrzebuję się nauczyć i co przećwiczyć. Czuję się też pewnie, wiedząc, że większość innych osób, którzy chcą tego samego co ja mają te same technologie w głowie.
Czuje się tymbardziej pewnie, bo przez ten fakt wiem, że nie wymyślam sobie niewiadomo jak eksperymentalnej, unikalnej i niesprawdzonej konstrukcji, tylko takiej, która jest uznana na rynku. Czuję się tymbardziej pewnie bo jak będę szukał pracy i natrafię na słowo klucz "programista serwera aplikacyjnego na .NET Framework" to jest 90% szansy, że trafiłem w swoje technologie bez zastanawiania się jakich komponentów oni moga używać i jak to mogli ze sobą pożenić. Pracodawca też jest szczęśliwy bo nie drapie się po głowie gdzie i jak szukać kandydatów, którzy akurat zparują się w miarę dokładnie z jego oczekiwaniami.

Ten twardy narzut platformy, która w wielu nawet bardzo grubych sprawach narzuca architekturę jako "standard" coraz bardziej doceniam. Jeśli tylko jest całość ułożona w akceptowalną, logiczną paczkę, która jeszcze coraz bardziej uzyskuje uznanie od rynku to dlaczego nie polegać na tych wzorcach i faktycznie dlaczego nie skupić się na wykonaniu zadania zamiast na budowaniu dziwacznych mostów na drodze do celu i udawania magika.

To że .NET Framework od początku swojego istnienia tak szybko stał się bardzo popularny to kolejny atut, w którym bardzo duża rzesza programistów go wykorzystujących może dać feedback i pomóc w pozytywnym rozwoju jednej, szerokiej, spójnej platformy. W przypadku rozdrobnienia różnych API, aż takiej siły i tempa rozwoju nie da się zagwarantować przez co wracając co C++ miałem straszny niesmak zacofania nie tylko językowego, ale głównie w platformie.

C++ niby daje tą mistyczną iluzję przenaszalności. Taką samą jak Java.. ba taką samą zresztą jak .NET.
W końcu jest Mono, które ostatnio zauważyłem bardzo boli fanatyczną i fundamentalistyczną część braci i sióstr po fachu z obozu Open Source.
Wszędzie tylko zło i patenty, a ciekawe czemu te osoby nie zauważają, że przy tej popularności .NET Framework i aplikacji biznesowych pod tę platformę, dają sobie akurat szansę (przynajmniej teoretyczną), że część z tych aplikacji nagle mogła by się pojawić nie tylko na systemie z stajni Redmond. Cóż.. always look on the dark side of life można by rzec :)

No ale nie o tym miałem marudzić :) Podsumowując C++ dla mnie w kontekście aplikacji biznesowym coraz bardziej jest językiem i platformą bardzo niepraktyczną.

Native w tym momencie dla mnie jest wartością tylko w śledzeniu jak się WinAPI rozwija w kontekście nowych cech systemu, które nie zostały zaimplementowane wyżej (np. API do DWM czy Application Recovery pod Windows Vista).

Temat wymyślania koła na nowo w tak fundamentalnych elementach jak Lista może conajwyżej pozostawiłbym na rozmowę kwalifikacyjną jako pomysł na wredny proces rekrutacji, na której zostawiłbym człowieka na 30minut z komputerem i kazał mu od zera napisać taką listę, wykorzystując tylko podstawową składnię jakiegokolwiek obiektowego języka.

Była by wspaniała zabawa do analizy przydatności kandydata do fachu.
Sprawdziłbym jakie ma podejście do programowania w bardzo szerokim spektrum:
* Dowiedziałbym się wtedy jaki styl pisania, jak prototypuje, czy konsekwentnie używa jakiejkolwiek notacji.
* Jak jest podatny na stres deadline'u. Wiedziałbym to po tym jak konstrukcja wygląda na koniec czasu. Zobaczyłbym jak szeroki zakres funkcjonalny autor przewidział w kodzie i jakiej powiedzmy subiektywnie było by to jakości. Czy przez listę w stresie zrozumiał tylko podstawową funkcjonalność insert/append/remove/clear/count/getitem. Czy może jak się zastanowi to uwzględni jakieś dodatki jak merge/split/sort.
* Dostałbym odpowiedź na pytanie czy to jest summienny rzemieślnik, który jak coś napisze to mogę w ciemno uznać, że działa. Czy może mistrz klawiatury, który każde zadanie odda pierwszy, ale potem część zaoszczędzonego czasu będzie trzeba poświęcić na powtórne testy.
* Sprawdziłbym jak dobrym jest projektantem. Czy jego lista to będzie jeden wielki moloch czy też będzie umiał ją składnie ułożyć. Może nawet nagle wpadnie na pomysł, że chciałby obsłużyć duplikaty poprzez wyspecjalizowaną linkowaną listę z indeksami, która będzie tylko interfejsem bazowała na podstawowej. Kto wie.. :)
* Mógłbym sprawdzić jak priorytetyzuje zadania. Czy zajmie się implementowaniem po kolei każdej metody jaka mu wpadnie do głowy czy też najpierw zrobi intefejs całości (aby mieć szanse chociażby na pozytywne zaskoczenie w paru powyższych punktach). Ciekawe czy przy prototypach metod zostawi im puste ciała czy też pierwszą rzeczą jaką tam wstawi to będzie chociażby proste

throw NotImplementedException("List::Insert");

które później by mu precyzyjnie podpowiedziało, czego zapomniał napisać, jak do takiego kodu wróci za miesiąc.
* Może to maniak Agile'a i za dużo nie napisze, ale pierwsze co zrobi to napisze sobie szybko test, który oprze na szybko skonstruowanych przez siebie pięciu klasach Test, TestCase, Assert, TestException i TestFramework. Wytłumaczy się, że bez tego czuł się sparaliżowany i nie był w stanie wyksztusić linii kodu.

Tak można kontynuować bogactwo informacji do analizy jaką w tym kontekście dała by mi każda poszczególna trochę różna od siebie implementacja listy.

W praktycznej jednak codzienności wolałbym jednak założyć, że jeśli się umawiamy na jedną platformę, to każdy z nas ją rozumie tak samo i 100 innych programistów na całym świecie potencjalnie też by się z nami dogadało od razu. Stanowczo chciałbym uniknąć sytuacji w której próbujemy się dogadać co jest platformą a co elementami groteskowego mostu, który sobie wybudowaliśmy aby nie pływać przez rzekę. Nie chciałbym stwierdzić, że ja znam platformę A i Ty znasz platformę A, a jedyne co w naszej bogatej znajomości i doświadczeniach, jakie mamy wspólnego do składnię języka.

W sumie po tym tygodniu zabaw wcale się nie dziwię tak naprawdę, że Visual Studio rozwinęło się masakrycznie pod kątem .NET Framework, a Native C++ prawie stoi w miejscu. Nie dziwię się też, po co jako pewna dziwna hybryda językowa powstało Managed C++. Odbieram to jako pomocną dłoń w pierwszym kroku ucieczki od męczarni, której wcale być nie musi.

No chyba, że piszemy gry klasy AAA i lub wylądowaliśmy w paru innych wyspecjalizowanych dziedzinach życia programistycznego, na które jeszcze doskonałego panaceum rozwiązujące współczesne problemy inżynierii oprogramowania nie ma.
Ale tutaj w przypadku konsol do grania chociażby cierpią konsumenci.
W odpowiedzi na coraz większe oczekiwania klienta, za 250zlotych dostaję grę, która niby jest śliczna aż dech zapiera, ale da się ją skończyć w 6h zanim w ogóle zauważę, że to rozrywka była. Jeśli tak nie będzie to pojawi się wariant drugi jak w przypadku naszego Wiedzmina, był tworzony tak długo, że nawet najwięksi optymiści przynajmniej raz zwątpili że w Empiku zobaczą pudełko, które kiedykolwiek zarobi na siebie. 

No ale okay.. koniec marudzenia :) Mam nadzieję, że za dużego flame'a nie wywołałem :)
Wracam do .NET Framework, koniec przygody.

Technorati Tagi: Polish Posts,babbling,C++,geeks