C++ bez cholesterolu

Nazewnictwo i terminologia

Wiele różnych rzeczy zainspirowało mnie do napisania tego rozdziału. Z grubsza to głównie wypowiedzi, jakie czytam na grupach dyskusyjnych, z jakimi stykam się w różnych dyskusjach i publikacjach, jak również książki które mają pecha wpaść w moje ręce. :)

W książce, z której jako pierwszej uczyłem się C++ (było to dawno, za czasów popularności Borland C++ 3.1, może niektórzy pamiętają:) znalazłem takie zdanie w jednym z przypisów: "Można spotkać książki pozornie poświęcone programowaniu, a tak naprawdę lansowaniu własnego nazewnictwa". To jest niestety prawda, z tym tylko że kwestia polskiego słownictwa jest dość trudna zwłaszcza dla czegoś, co jest nowe i nie posiada w większości odpowiedników w języku polskim. Wiele z nich nawet ma odpowiedniki leksykalne w języku polskim, a mimo to są często nie do zastosowania z uwagi na dziwaczność brzmienia w danym kontekście.

Tu zamierzam przedstawić kwestie słownictwa związanego z C++ (ale oczywiście nie jest to tylko słownictwo specyficzne dla C++, bo wiele z tych słów jest czymś ogólnym nie tylko dla języków, ale również dla programowania, czy w ogóle informatyki). Postarałem się wybrać najciekawsze, jak również takie z którymi są największe problemy. Nie ukrywam również, że po części będę "lansował własne nazewnictwo", ale postaram się to wyraźnie zaznaczyć, że nie jest to ogólnie przyjęte określenie, lecz moja propozycja.

Jedną z ostatnich inspiracji są polskie tłumaczenia książek Bjarne Stroustrupa. Mogę nawet powiedzieć, że z dużą ostrożnością teraz podchodzę do książek informatycznych tłumaczonych przez kobiety. Może ktoś się postara zmienić ten "stereotyp", ale mam wrażenie że takie książki są wręcz przesycone tłumaczeniami na siłę na język polski, co nie zawsze jest potrzebne, a często wręcz szkodliwe. Przykładowo w "Projektowanie i rozwój języka C++" p. Jowita Koncewicz-Krzemień uparcie używa określenia "odniesienie", podczas gdy określenie "referencja" już zdążyło się zadomowić. To jest jednak mało znaczące; powiedzmy że te określenia są równoważne. Ta książka mimo wszystko dobrze się broni, choć przesadne używanie języka polskiego wszędzie gdzie się da (włącznie z przykładami) jest bardzo szkodliwe. Przykładowo, wielokrotnie używa się tam polskich liter w identyfikatorach w tych przykładach, co jest nie do uzyskania w rzeczywistości. Innym błędem jest podany przez Stroustrupa przykład manglowania nazw pod uniksem: funkcja

sqrt( zespolone )

jest manglowana jako

sqrt__F7zespolone

W oryginale oczywiście było to

sqrt__F7complex

Stroustrup nie napisał, a pani tłumacz nie domyśliła się, że owo "7" w tej nazwie to ilość liter słowa "complex", która nie jest taka sama, jak ilość liter słowa "zespolone". Tłumaczenie na polski wszystkiego na siłę jest o tyle bezsensem, że akurat informatyk nie znający angielskiego w sensownym zakresie jest praktycznie uważany za analfabetę.

Znacznie więcej zastrzeżeń mam do tłumaczenia trzeciego wydania książki "Język C++", tłumaczonego przez p. Janinę Mincer-Daszkiewicz. Powiem wprost: tłumaczenie to jest żałosne, w dodatku pani tłumacz popełniła niemal wszystkie możliwe błędy podczas tłumaczenia specyficznych określeń. Niektóre z nich zostaną tutaj wyszczególnione. Podczas lektury tej książki zastanawiałem się nawet, czy nie lepiej byłoby nabyć angielski oryginał, bo pani tłumacz ma również problemy z polską gramatyką (jak np. pisownia "nie" z imiesłowami, dla której jedyną niekontrowersyjną formą jest pisownia rozdzielna).

Mogę jednak powiedzieć, że tłumacze w Polsce chyba nie uczą się niczego, zwłaszcza jeśli chodzi o książki w których występuje specyficzne słownictwo. Reedycja jakiś czas temu serii książek pt. "Dune", czyli "Diuna" świadczy o tym, że biorą się do tego ludzie zupełnie na bakier z tematem – wręcz można by się zastanawiać, dlaczego tytuł nie brzmi "Wydma". Może i sensownie było używać spolszczonych określeń, tyle że nie na tym etapie, kiedy słownictwo związane z Diuną już od dłuższego czasu w języku polskim funkcjonuje. Tym bardziej więc lepiej wziąć się za książki tłumaczone po raz pierwszy (jak np. książki Pratchett'a), bo przy reedycji tłumaczenia na pewno jakiś twórczy tłumacz wymyśli zupełnie inne. W książkach naukowych jest to dodatkowo o tyle niebezpieczne, że staje się to potem powszechnie używanym słownictwem w różnych publikacjach, dyskusjach i dokumentacjach. Z drugiej strony, o tyle łatwiej tego uniknąć, że te określenia zazwyczaj już funkcjonują w naukowej terminologii, więc trzeba się tylko zdobyć na odrobinę wysiłku i się nimi zainteresować.

Inicjacja, czy inicjalizacja?

To jest właśnie jedno z notorycznie używanych określeń (w szczególności jest używana inna forma - inicjowanie) we wspomnianej książce. Może więc wyjaśnijmy, co oba słowa znaczą i skąd się wzięły. Określenie "inicjacja" (i związane z tym słowo "inicjować" i "inicjowanie") występuje już od dawna w języku polskim. Co ciekawe jednak, jego brzmienie w informatyce jest co najmniej kuriozalne. Wspomniana książka jest takoż jedną z niewielu książek, w których takie określenie jest używane (w szczególności, w ŻADNEJ poza tą książce takiego określenia nie widziałem). Nie wiem np., ile wspólnego może mieć "inicjacja" zmiennej z inicjacją seksualną człowieka, albo z inicjacją członka klanu. Gdyby takiego określenia używac w stosunku do obiektu, to może ono znaczyć tylko i wyłącznie rozpoczęcie życia przez obiekt, a więc również kwestię związaną z przydziałem pamięci (również na stosie). A jak jest w rzeczywistości? Ano w rzeczywistości jest to kwestia lenistwa niektórych Polaków, dla których słowo "inicjalizacja" jest za długie, i którzy go w uproszczeniu tłumaczą w ten sposób.

Wszędzie w literaturze angielskiej owo określenie brzmi "initialization". Wartą podkreślenia rzeczą jest, że język angielski (mimo wszystko) używa dużo więcej słów zapożyczonych z łaciny, niż polski. Jest to jedno z nich. Ponieważ słowa łacińskie z założenia dobrze się adoptują w języku polskim, wiec warto przy takich słowach - jeśli nie ma w języku polskim dobrego określenia - zapożyczyć takie słowo na tej samej zasadzie. Co właściwie znaczy określenie "initialize"? Oznacza dokładnie "set a variable an INITIAL value", czyli ustaw zmiennej wartość INICJALNĄ (czyli początkową). Tu problem polega właśnie na tym, że "initial" brzmi (z powodów podanych wyżej) całkiem naturalnie, podczas gdy w języku polskim jest to łaciński dziwoląg. Dlatego każdy Anglik czy Amerykanin wprost domyśli się, co znaczy "initialize", natomiast Polak pomiędzy "inicjować" i "inicjalizować" nie widzi większej różnicy. Istotą tego słowa jest właśnie określenie "inicjalny" (w słowie "inicjować" cząstka "inicjalny" już nie występuje), a końcówka "-ize" jest typową, zapożyczoną z greki końcówką (w bezokoliczniku "-izein") tworzącą czasownik (jak np. "apologizein", które w angielskim istnieje jako "apologize") i stamtąd zapożyczoną do łaciny. Jest też więcej takich słów, jak np. propertize, czy specialize. A dalej - "initialization" jest rzeczownikiem pochodzącym od "initialize".

Nie warto tworzyć neologizmów znaczeniowych, zwłaszcza jeśli a) jest to wyraz zapożyczony z łaciny, więc należy go przyjmować w poprawnej formie, b) może powodować problemy przy - bardzo prawdopodobnym przecie - tłumaczeniu na angielski (z "variable initiation" już się gdzieś spotkałem!) i c) brzmi dziwacznie w konfrontacji z dotychczasowym znaczeniem. Zatem: nie inicjujmy!

Overloadnig: przeciążanie, czy przeładowanie?

Właściwie to angielskie określenie "overloading" znaczy dosłownie "przeciążanie". Jestem też zwolennikiem tego określenia. Niektórzy autorzy książek jednak używają określenia "przeładowanie", gdyż jedną z cząstek tego słowa jest "loading", co oznacza ładowanie. Ponieważ jednak warto by się zdecydować na jedno określenie, więc trzeba by to jakoś rozsądzić.

Przede wszystkim, co oznacza tak "na codzień" określenie "overload" w języku angielskim, a w szczególności jak się tego używa. No więc można tego słowa używać np. w sytuacji, kiedy ktoś załaduje na ciężarówkę więcej, niż wynosi jej ładowność. Stąd właśnie "loadnig". Po polsku w tych okolicznościach używa się określeń takich jak "zbytnie obciążanie", "obciążanie ponad miarę", czy też krócej "przeciążanie" ("load" tłumaczy się również jako "obciążenie"!) i stąd właśnie taki odpowiednik znaczeniowy. Może i "przeładowanie" byłoby odpowiednikiem leksykalnym (właściwie nie do końca, bo dokładnym odpowiednikiem leksykalnym byłoby "nadładowanie"). Jednak nie jest to argument, bo słowo "przeładowanie" w języku polskim istnieje i z "overload" niczego wspólnego nie ma. Można np. przeładować towar z jednej ciężarówki na drugą lub przeładować (czyli ponownie załadować) kod do pamięci, toteż najbliższym angielskim odpowiednikiem "przeładować" byłoby "reload". Na dodatek słowo to nie posiada żadnej przewagi nad "przeciążaniem", bo jest dłuższe, jest neologizmem (znaczeniowym), brzmi dziwacznie w tym kontekście i nie jest ani trochę bliższe znaczeniowo (w szczególności, żadne z tych słów nie odzwierciedla znaczenia). Wydaje mi się zatem, że używanie określenia "przeciążanie" jest o wiele bardziej poprawne.

Template: szablon, czy wzorzec?

Ok, wyjaśnijmy sobie więc najpierw, czym jest jedno i drugie. Szablonem powszechnie nazywa się kawał papieru (blachy, czy plastiku), który ma wycięte odpowiednie dziury w kształcie jakiegoś napisu, czy rysunku, przez który maluje się farbą. Jest to jedyne znane mi użycie. Nie używa się go nawet w terminologii tłoczenia płyt (nylonowych i kompaktowych), choć można by było to tam na upartego zastosować.

Dobrze, to czym jest wzorzec? I, przede wszystkim, czym się różni od wzoru? W zasadzie jedno i drugie jest czymś, na czym można się "wzorować", ale nie jest to to samo. Wzór jest czymś całkowicie abstrakcyjnym; opisuje jedynie wymagane zależności. Wzorzec natomiast jest czymś już istniejącym, na czym można wzorować się przez podobieństwo. Jednak dokumentacje wzorca nie mówią wszystkiego, a jedynie sam zbiór cech, które należy naśladować, czy też, na których należy się wzorować.

Powiem szczerze: mnie się określenie "wzorzec" bardziej podoba, ale również uważam je za poręczniejsze w przeciwieństwie do "szablonu". I jest jeszcze jedna rzecz. Szablon, to po angielsku "stencil". A nam chodzi o słowo "template".

Rekurencja, czy rekursja?

Ha! Ile już osób się na to złapało. Może więc od początku. Istnieje kilka ciekawych słów, które niby zarówno w angielskim, jak i w polskim są wzięte z łaciny, a jednak do tych samych określeń używa się różnych słów. Np. impose znaczy nakładać, a imponować to impress. Podobnie, konkurencja to po angielsku competition; zaś concurrency oznacza współbieżność. Co zaś ze słowem "recurrency"? Słownik podaje znaczenie "powtarzanie się" (pewnie jeszcze ktoś podpowie, że to po polsku będzie repetycja :). Zaś recursion tłumaczy się na polski jako "rekurencja".

Można by powiedzieć, że to słowo wręcz w szczególności nie dotyczy C++, bo w C++ rekurencję stosuje się dość rzadko (w odróżnieniu od języków funkcjonalnych – a o tym określeniu za chwilę :). Wspomniałem jednak o tym z uwagi na to, że określenie "rekursja" występuje we wspomnianym polskim tłumaczeniu książki pt. "Język C++". Pani Janina Mincer-Daszkiewicz (co jest bardzo dziwne jak na człowieka aspirującego do tłumaczenia książek z dziedziny informatyki) najwyraźniej nie uważała na lekcjach matematyki w liceum ani na studiach (lub nie chodziła na takowe), kiedy mówiono o ciągach, dla których podstawowym i najprostszym wzorem jest tzw. wzór rekurencyjny. Albo kiedy mówiono o równaniach rekurencyjnych liniowych (no ale dobrze, to już powiedzmy że jest wyższa matematyka ;). Jest to właśnie określenie, które jest tłumaczeniem angielskiego "recursive" (jak ktoś nie wierzy, to odsyłam do książek matematycznych w języku angielskim). Zresztą tak się akurat składa, że określenia matematyczne istniejące w języku polskim są w dość dużej części wzięte z języka angielskiego i dlatego mnóstwo określeń istniejących również w informatyce posiada w języku polskim swoje odpowiedniki od dawna. Warto więc z nich skorzystać i nie tworzyć neologizmów, zwłaszcza gdy dane słowo już od dawna w środowisku informatycznym już funkcjonuje.

Funkcyjny, czy funkcjonalny?

Chodzi o określenie języków programowania, w których program definiuje się jako pojedyncze, złożone wyrażenie, jak również o metodologię programowania w której zamiast czynności wykonawczych używa się złożonych wyrażeń. Dane, które posiadam są następujące:

  1. w polskim "żargonie" i w literaturze przeważa "funkcyjny"
  2. ale widywałem też w literaturze i publikacjach określenie "funkcjonalny"
  3. po angielsku używa się tu "functional", co znaczy "funkcjonalny"

Więc chyba jednak przewaga jest po stronie tego drugiego słowa, nie? :). No ale żeby kwestię rozstrzygnąć, to trzeba rozważyć kilka rzeczy. Ponieważ słowa "funkcyjny" i "funkcjonalny" pochodzą od słów odpowiednio "funkcja" i "funkcjonał", więc trzeba rozważyć, co dokładnie ma się na myśli.

Jest tu też pare dość niefortunnych kwestii. Np. słowo "funkcja" istnieje w języku C, a przez to i w C++, jednak jest to totalna pomyłka, bo w C i C++ owa "funkcja" to tak naprawdę procedura. To, że może ona zwracać wartość nic nie znaczy. Jedną z cech właściwych funkcji powinna być deterministyczność (i bezstanowość), a funkcja w C i C++ taka niestety być nie musi. Poza tym, definicja funkcji powinna się składać również z wyrażeń, a nie instrukcji do wykonania, bo takie coś nazywa się procedurą. Z tego powodu określenia "funkcja" w C i C++ używa się nadal, ale stosuje się też zamiennie właściwsze słowo "procedura". Zamieszania tutaj oczywiście narobił nikt inny, jak p. Niklaus Wirth, twórca języka Pascal, dla którego najwyraźniej funkcja to taka procedura, która zwraca wartość (można też podziękować panom K&R za zmałpowanie tego terminu; Bjarne Stroustrup powiedzmy że nie miał specjalnie wyjścia :).

No ale niestety zamieszanie już powstało i nie da się tego odwrócić. Dobrze oczywiście, że programowanie z użyciem tych właśnie "funkcji" nazywane jest programowaniem proceduralnym (a nie funkcyjnym). Ale z drugiej strony, jest określenie "functional programming" i trudno tutaj uniknąć pomyłki w znaczeniu słowa "funkcja". Dlatego właśnie jestem przeciwnikiem określenia "funkcyjny" i konsekwentnie używam "funkcjonalny".

Z drugiej jednak strony przeciwnicy określenia "funkcjonalny" (co ciekawe, zazwyczaj ludzie interesujący się programowaniem funkcjonalnym) też mają swoje argumenty. Jednym z nich jest to, że określenie "funkcjonalny" już istnieje w języku polskim i znaczy mniej więcej "przydatny", czy też "użyteczny". Ci sami ludzie zapominają najwyraźniej, że po pierwsze, takie samo dokładnie znaczenie posiada również jego angielski odpowiednik, "functional", a po drugie, również w języku polskim nie jest to jedyne jego znaczenie. Mówi się np. o czymś takim jak opis funkcjonalny, czy złożoność funkcjonalna programu (w języku angielskim również używa się słowa "functional" w tym kontekście). Języki i metodologia, o których na początku wspomniałem, są właśnie ukierunkowane na opis funkcjonalny programu, w odróżnieniu od języków imperatywnych, które definiują czynności do wykonania.

Nie chcę oczywiście nikogo przekonywać do słowa "funkcjonalny", jedynie wskazuję, że jest ono jedynym poprawnym tłumaczeniem angielskiego określenia "functional" :). Zwłaszcza odradzam używanie tego słowa potencjalnym studentom informatyki, gdzie wykładowcy potrafią za stosowanie słowa "funkcjonalny" nawet uwalić na egzaminie.

Co to znaczy "singular"?

Jednym z wystąpień tego słowa jest teoria gramatyki języków (naturalnych oczywiście, nie programowania), w którym znaczy to "liczba pojedyncza" (w odróżnieniu od liczby mnogiej, czyli plural). Jest to określenie jednak używane w teorii biblioteki STL, w której określa się pewną właściwość wartości iteratora. Iterator posiada "singular value", gdy nie jest związany z żadnym zbiornikiem. Ale możliwości powstania takiej wartości jest kilka. Jedną z nich jest niezainicjalizowanie iteratora żadną wartością, przez co wewnętrzna reprezentacja zawiera "śmieci". Inną zaś jest trwanie iteratora ponad trwanie zbiornika.

Jak się okazało jednak, określenie to równie dobrze może być stosowane do zwykłych zmiennych. Jak to powiedziałem już w części poświęconej zmiennym, to określenie nie jest użyte w standardzie; tam używa się określenia "indeterminate initial value" (oczywiście tylko do pierwszego przypadku). Określenie to zastosowałem w tym przypadku z uwagi na jego trafność nie tylko dla tego pierwszego przypadku, ale również dla innych. Pasuje ono dobrze do wskaźnika, bo wskaźnik jest obarczony właściwie tymi samymi problemami, co iterator - może zarówno zawierać "śmieci", jak też jego wartość może przestać być poprawna w sytuacji gdy obiekt, na który wskazywał, przestaje istnieć. Pasuje to jednak również do zwykłych zmiennych, co opisałem w rozdziale pt. "Właściwości wartości".

O ile pamiętam, w matematyce to określenie jest również używane np. w teorii macierzy. Macierz jest "singular", jeśli jej wyznacznik jest równy zero. I takie określenie tłumaczy się jako "osobliwy". Takie określenie też podają słowniki. To wszystko jednak nie dotyczy określenia, które jest powszechnie używane, tylko określenia, którego użyłem tak "na własną rękę".

Collection i container

Kolejne określenie, którego użyłem na własną rękę, to zbiornik. Wiem, że może się niespecjalnie sensownie kojarzyć, bo będzie się kojarzył z czymś, co ma zawierać płyn. Jednak wydawało mi się najbardziej sensownym z uwagi na kilka rzeczy takich jak długość słowa oraz związki leksykalne. Zbiornik jest bowiem obiektem typu zbiorczego (czyli obiektem zbiorczym, tzn. zawierającym inne obiekty).

Jak widać po tych dwóch angielskich określeniach, w tym temacie nawet w języku angielskim nie ma jednoznaczności. Określenie "collection" jest powszechnie używane w językach obiektowych i to określenie jest też używane w bibliotekach obiektowych, jak np. MFC czy Qt. W C++ jednak (przynajmniej w STL-u) króluje określenie "container" (a gdzie było używane wcześniej, to tego akurat nie wiem).

Ze słowem "collection" jest łatwiej, bo można go po prostu tłumaczyć jako "kolekcja", co pasuje idealnie. Gorzej z "container", bo choć niby można by go tłumaczyć jako "kontener", to jednak zbyt wielu będzie się to kojarzyło z ogromnym blaszanym pudłem wyładowanym towarami. Jest to zresztą identyczny problem specjalizacji znaczeniowej, jak ze słowem "combine" tłumaczonym jako "kombajn" w znaczeniu maszyny rolniczej (choć to określenie, oznaczające program lub urządzenie charakteryzujące się wieloraką funkcjonalnością, zaczyna być coraz powszechniej używane). Wielu upodobało sobie słowo "pojemnik". W sumie pomiędzy słowami "pojemnik" i "zbiornik" w znaczeniu "obiekt zbiorczy" różnica jest niewielka. Jestem zwolennikiem słowa "zbiornik" tylko z uwagi na to, że po pierwsze jest bliski słowu "zbiorczy", a po drugie ma jedną sylabę mniej ;).

Predicate

Właściwie można wykpić się zapożyczaniem z łaciny i stworzyć "predykat". Tyle że – jak powiedziałem – z łaciny należy zapożyczać jeśli nie istnieje polski odpowiednik. Problem jest nadal z tym samym, mianowicie z ilością słów łacińskich w języku angielskim. Słowo "predicate" istnieje już od dawna w języku angielskim, zaś określenie "predykat" w języku polskim jest po prostu przeniesionym na żywca słowem z języka angielskiego w przekonaniu, że skoro słowo jest z łaciny, to tak można.

Tworzenie takiego słowa jest o tyle bez sensu, że słowo "predicate" tłumaczy się (wg słowników) na polski jako "orzecznik". Co ciekawe, słowo to jest po polsku całkowicie zrozumiałe, a na dodatek jego znaczenie w kontekście STL-a dokładnie pasuje. Proponuję zatem używanie określenia "orzecznik", jako że IMHO na pewno takie słowo lepiej się zaadoptuje w języku polskim.

Wiem, oczywiście, że słowo "predykat" było zaciągnięte do języka polskiego już wcześniej (i to jeszcze zanim powstała STL), ale to nie zmienia faktu, że uważam jego istnieje w języku polskim za bezsens (no ale zawsze ktoś powie że są też ziemniaki i kartofle, nie wspominając już o pyrach).

Debugger

Jak na razie nie szykuje się, żeby ktoś wymyślił polski odpowiednik tego słowa. Przydałoby się, owszem, niestety wszelkie próby spaliły na panewce, gdyż brzmiały zbyt dziwacznie (jak "odpluskwiacz") lub były za długie i przez to nieporęczne (jak "program do śledzenia" lub "narzędzie do śledzenia"). Równie fiaskowata jest próba podjęta przez wspomnianą już panią Janinę Mincer-Daszkiewicz, która użyła określeń "program uzdatniający" i "program uruchomieniowy" (nb. bardzo jestem ciekaw, w jakich to środowiskach się takich określeń używa).

Pozostańmy może jednak przy określeniu "debuger", bo jak na razie nikt nie wymyślił nic lepszego. Nie tracę jednak nadziei, że ktoś kiedyś wymyśli.

Generic i general

Właściwie poza znów importowanym z łaciny słowem "generyczny", nie ma w języku polskim to słowo żadnego odpowiednika. Kolejna próba wspomnianej pani tłumacz dołączenia słowa "uogólnione" tworzy słowo, które nikomu nic nie mówi. Pod tym względem zatem nie różni się od "generyczny" poza tym, że to pierwsze brzmi bardziej po polsku.

Czy zatem powiemy, uogólniony, czy ogólny, różnica jest niewielka, a i tak nikt nie wie, o co chodzi. Słowo "general" jest jeszcze w miare zrozumiałe, z tym tylko że jest niejednoznaczne, bo zbyt... ogólne :). Ale dlatego właśnie to słowo jest również w języku angielskim używane z ostrożnością.

Akurat określenie "generyczny" nie ma za wiele wspólnego z tą szeroko pojętą "ogólnością", czy "uogólnianiem" (to ostatnie słowo po angielsku będzie "generalization", czyli znów jest to pochodna słowa "general"). Nie jest to też proste do wyjaśnienia po polsku, bo nie istnieje żaden istniejący wcześniej w języku polskim termin, który mógłby oddać to znaczenie. Najprościej mówiąc, generyzm jest odwrotnością dostosowania, ale to wyjaśnienie jeszcze nie mówi wszystkiego. Generyzm jest trochę czymś więcej. Istnieją np. leki generyczne, czyli takie, które można stosować do różnych terapii. Programowanie generyczne z kolei oznacza tworzenie uniwersalnego kodu możliwego do wykorzystania w szerokiej gamie zastosowań. Tak samo, każda rzecz może być generyczna, jeśli umożliwia wielorakie wykorzystanie; jeśli przydaje się w szerokiej gamie zastosowań. Przykładowo, generyczny może być samochód, jeśli umożliwia ekonomiczną jazdę zarówno po mieście, w trudnych warunkach terenowych, jak i na długich trasach (co prawda nie słyszałem o takowym, ale co za różnica ;).

Wydaje mi się zatem, że w kwestii "generic" można pozostać przy określeniu "generyczny", z tym tylko że dobrze jest jednocześnie starać się wyjaśnić jego znaczenie.

Argument, czy parametr?

Zamieszanie z tymi dwoma słowami jest dość spore i mieszanie ich nawzajem jest wolną amerykanką stosowaną dosłownie wszędzie: począwszy od wypowiedzi na grupach dyskusyjnych, poprzez literaturę, kompilatory, skończywszy na opisie standardu C++. Na domiar złego, nie ma zbyt wiele wspólnego z językiem polskim; jedno i drugie jest tak samo mieszane we wszystkich językach.

Ponieważ nie tylko w językach C i C++, ale także w wielu innych wcześniejszych używano procedur, które mogą dostać coś na wejście, zaczęto to jakoś nazywać. I tak w zależności od okoliczności poczęto nazywać je argumentami lub parametrami. Różnią się w tym również twócy kompilatorów. Przyjrzyjmy się może więc genezie tych słów.

Argument jest słowem, które jest używane w matematyce i dotyczy funkcji. Funkcję w matematyce definiuje się jako przyporządkowanie każdemu elementowi z jednego zbioru elementu z drugiego zbioru. Element z pierwszego zbioru jest zwany argumentem. Ponieważ w C++ operujemy funkcjami, zatem określenie argument wydaje się być całkiem właściwe. Argumentem w ogólności możemy nazywać wszelkie wartości, które są podawane do "czegoś" na wejście.

Parametr z kolei jest słowem używanym przede wszystkim w opisach działających urządzeń. W matematyce stosuje się to jako element wzoru, który ma się zmieniać relatywnie rzadko, w szczególności równanie z parametrem jest jedynie podstawą do stworzenia pełnego równania. Stosowano je rówież w makrodefinicjach różnych makrogeneratorów i (początkowo) makroasemblerów. Z założenia więc jest to coś, co steruje pracą makra, wartość na której operuje wykonawca makra – ale nie samo makro. Parametr, jak sama nazwa wskazuje, służy do parametryzacji, czyli szczegółowego określania, co dana definicja ma oznaczać.

Parametrem może być przede wszystkim jakaś właściwość programu używana podczas jego wykonywania i zmieniana przez użytkownika. Jest to zatem taki element, który siedzi sobie w środku i steruje sposobem wykonywania. A to, że parametr jest podawany na wejście dla tego makra, niczego nie oznacza.

Nic już się chyba nie poradzi na to, że kompilatory firm Borland i Microsoft wciąż używają określenia "parametr" na to, co się przekazuje do funkcji. Szczęściem gcc używa określenia "argument" (aczkolwiek, jak zauważyłem, nie do końca konsekwentnie). O ile w języku takim jak C czy Pascal nie ma to nazewnictwo żadnego istotnego znaczenia, o tyle C++ ich pomylenie może powodować drobne zamieszanie.

A wszystko z powodu wzorców. Właśnie wzorce są typami (lub funkcjami) parametryzowanymi i w związku z tym otrzymują parametry (żeby było wiadomo o co chodzi, używa się też określenia "parametr wzorca"). Co w sytuacji gdy mamy wzorzec funkcji np. taki:

template <class T> T min( const T& t, const T& t1 );

Czym jest tutaj `T'? Jest parametrem. Ok, ale czym jest wtedy `t'? Może więc jednak używajmy konsekwetnie określenia "argument" na to, co funkcja dostaje na wejście. Będzie wtedy mniej nieporozumień.