Oblíbeným omylem všech OOP nováčků je lpění na „posílání zpráv“. Poukazovat na to, že tamten jazyk posílá zprávy a jiný jazyk zprávy neposílá ale volá metody. A že tamten jazyk jen říká co by měl objekt udělat a ten druhý mu přímo nařizuje, co má udělat. Ale to jsou všechno pitomosti.
Posílání zpráv v OOP terminologii samozřejmě neříká, jak je to implementované. Zprávy lze posílat synchroně a asynchroně, přičemž to první připomíná spíš volání metod. Synchroně znamená, že objekt, který zaslal zprávu nemůže pokračovat ve vykonávání kódu, dokud neobdrží odpověď. Asynchroní zpráva odpověď nevyžaduje. Lze objektu přímo předat „program“, který vykonat, nebo příkaz. Příkaz může objekt pochopit jinak, než program. Voláním metody dáváme objektu „program“ jako zprávu, konkrétně v C++ adresu programu, který má objekt vykonat. Ale u virtuálních metod už tomu tak není, tam dáváme objektu příkaz formou indexu do tabulky vt. Takže i tady platí, že objekt může zprávu pochopit jinak, než bylo zadáno.
Pokud se v souvislosti s OOP mluví o smalltalku a upozorňuje se třeba na to, že OOP obecně nezná typy a že mohu poslat kterémukoliv objektu jakoukoliv zprávu atd, tak i tohle všechno zvládneme v jiných jazycích, akorát prostě ne přímo, ale pomocí prostředníka. V Javě například pomocí interfaců. V C++ kupodivu ještě lépe, i tady máme interfacy, ale můžeme si je vyvolávat pomocí jména (nebo GUID). A interface, pokud obsahuje jednu metody, jedná se vlastně o objekt zprávy. Ale metod může mít víc. Konečně, třeba takové COM+ a jeho metoda QueryInterface. Každému objektu můžete položit otázku, zda neumí nějaký interface a je to ekvivalentní jako když se objektu zeptám, zda zpracuje nějakou zprávu. A stejně jako v OOP jsou objekty netypové (nemají typ), tak i v COM+ vzásadě objekty nemají typ, jen nabízí různé interfacy, libovolného množství a složení.
Uznávám, že například jazyky typu smalltalk řeší tohle všechno jednodušeji a nenutí programátora vymýšlet „systémy“ nebo používat knihovny, aby dosáhl téhož. Ale je to určitá cena za svobodu. V některých jazycích máme víc svobody, ale víc práce. V jiných jazycích zvládneme totéž s desetinou úsilí… ale něco nás to bude stát.
>> Oblíbeným omylem všech OOP nováčků je lpění na „posílání zpráv“. Poukazovat na to, že tamten jazyk posílá zprávy a jiný jazyk zprávy neposílá ale volá metody. A že tamten jazyk jen říká co by měl objekt udělat a ten druhý mu přímo nařizuje, co má udělat. Ale to jsou všechno pitomosti.
V jakých jazycích se dá napsat třída, která má vložený objekt a jedinou metodu, která říká „všechny zprávy, které neumím zpracovat, předej vloženému objektu“?
V jakých jazycích se dá napsat konstruktor, který vrací instanci jiné třídy než které je konstruktorem?
Takové drobné pitomosti :)
Jistě, třeba ta druhá věc se dá obejít tím, že místo konstruktoru voláme metodu třídy, která vrací nově vytvořený objekt. Proč ne? Koneckonců plechovku můžeme taky otevřít buď otvírákem nebo sekerou ;)
Samozřejmě že to co popisujete jde. Třeba QueryInterface vám sice nesmí vrátit interface vnořeného objektu, protože to Microsoft tak chce, ale já mám systém, který tohle pravidlo nemá a tam to jde. Takže já se objektu zeptám, ať mi dá interface, který on neumí, ale který umí jeho vnořený objekt, a on mi předá interface vnořeného objektu. A tomu pak zavolam metodu. Přitom zprávou v tomto případě není volání metody, ale celý protokol včetně dotazu na zadaný interface (a pokud jsou interfaci identifikovány objektem, (typeinfo), pak je to to samé jako jméno zprávy … jméno zprávy == taky objekt)
Konstruktor v OOP? Jestli si myslíte, že v OOP někdo definoval C++ konstruktor, tak jste vedle. V OOP pokud vím jsou továrny. Řeknu jednomu objektu, aby vytvořil jiný objekt. To že v C++ jsou speciální funkcí _TŘÍDY_ konstruktor není nic jiného, než objekt, který je singletonem (třída) má metodu „vytvoř instanci třídy“ (objekt). To nevylučuje, aby měl tento objekt jinou metodu „vytvoř instanci jiné třídy“. Mimochodem, třídy nepatří do OOP. v OOP jsou jen objekty
Asi tak, plechovku otevřu sekerou jako otvírákem, ale otvírákem si nenasekám dříví. Ale sekerou teoreticky mohu ten otvírák vyrobit :-)
Reagoval jsem na „Poukazovat na to, že tamten jazyk posílá zprávy a jiný jazyk zprávy neposílá ale volá metody.“
Přesně takhle to totiž AFAIK je – některé rádobyobjektové jazyky jako třeba C++ volají funkce, přičemž skutečně objektové jazyky posílají zprávy – se kterými potom objekt může dělat, co uzná za vhodné.
První příklad byl na to, že „vnější objekt“ se může chovat jakkoli podle toho, co má za vnořený objekt. Nevím, jak by se tohle dalo v C++ ne-složitě udělat, rád se nechám poučit. Nedovedu si to dost dobře představit ani v Javě a C#, i když tam by to možná přes nějaké ty reflexe atd. nějakým krkolomným způsobem šlo.
Ad konstruktor – ano, skutečně objektové jazyky konstruktory nepotřebují, stačí metody třídy*. Jenže to se netýká ani C++, ani Javy, ani C#.
Jediný „skutečně objektový“ jazyk, který znám, který se docela používá, je Objective C.
Pokud si vytvoříte nad jakýmkoliv jazykem jakýkoliv systém, který je de facto vlastním jazykem s vlastními zákonitostmi, tak už to není původní jazyk. Ano – v C++ určitě jde naprogramovat Smalltalk. To jde i v assembleru, a přesto nikdo soudný nebude považovat assembler za objektový jazyk.
* Pokud se vám slovo „třída“ nelíbí, nahraďte si ji opisem „singleton objekt továrna“, já s dovolením raději budu psát „třída“, je to kratší
Až na to, že já OOP považuji za filozofii, vy to považujete za technické řešení. Zkuste se na to dívat jak na filozofii. Nebo třeba jako na návrhový vzor. Tam vůbec neřešíte, zda volání zprávy vypada jako
obj1 zprava obj2
nebo
obj1.getInterface<zprava>().send(obj2)
Zapisy jsou ekvivalentni (za předpokladu, že getInterface a send jsou nástroje pro zacílení a posílání zprávy).
OOP je filozofie, kterou lze aplikovat na jakýkoliv jazyk. Technické řešení je detail.
Z C++. Zprava je ve skutecnosti deklarovana jako:
class zprava: IInterface {
public:
virtual void send(IObject *) = 0;
};
class IObject {
public:
virtual IInterface *getInterfacePtr(const std::typeinfo &tinfo) {return 0;}
template<class Ifc>
Ifc &getInterface() {
IInterface *ptr = getInterfacePtr(typeid(Ifc));
if (ptr == 0) throw ... nejaka vyjimka ...
return static_cast
(ptr);
}
virtual IObject() {}
};
Hlavní myšlenka je v tom, že všechny objekty podědí IObject a ta obsahuje funkci na hledani rozhrani. Pomoci getInterface se zeptam objektu, zda umi nejake rozhrani a pokud ano, zavolam na rozhrani funkci. Pokud ne, hodi to vyjimku. Virtualni funkce getInterface pak musi byt implementovana ve vsechn objektech, da se tam pouzit i dynamic_cast (v příkladu to nemám, bylo by to složitější) a objekt pak pouze implementuje tu funkci jen tam, kde docházi k předávání kompetencí.
Objekt pak může vypadat takto (pro řešení s dynamic_castem)
class MujObjekt: public IObject,
public zprava1,
public zprava2,
public zprava3,....
{....};
nebo
class MujObjekt {
public:
IInterface *getInterfacePtr(const std::typeinfo &type) {
if (type == typeid(zprava1) return &objektCoUmiZprava1;
...
...
return 0;
}
};
>> Až na to, že já OOP považuji za filozofii, vy to považujete za technické řešení.
V žádném případě. Nepodsouvejte mi prosím něco, co jsem neřekl a co jste si jenom vydedukoval z toho, co jsem napsal.
OOP je samozřejmě „filosofie“ naprosto nezávislá na samotném jazyku. Jenže jazyk jednotlivé myšlenky oné filosofie buď PŘÍMO (!) podporuje, nebo je potřeba v onom jazyku napsat systém, který je de facto samostatným jazykem, ve kterém už ony myšlenky půjdou využít. Mezi námi prostými venkovany se tomu říká drbat se levou rukou za pravým uchem…
Příklad:
myšlenkou je multithreadové programování
Otázka: dá se v assembleru programovat multithreadově? Ano, dá, pokud používám nějaké knihovny. Samotný jazyk pro to ale žádné prostředky nemá. Zkráceně řečeno: assembler multithreadové programování PŘÍMO nepodporuje.
Oproti tomu Java multithreadové programování podporuje víc – už jen např. klíčovým slovem synchronized, které assembler nemá, ať se kdo chce třeba na hlavu staví.
Samozřejmě si v assembleru můžu napsat makra, která budou dělat v principu totéž jako javovské „synchronized“, ale to neznamená, že assembler podporuje multithreadové programování. Jak už jsem řekl: jistě si v assembleru můžu napsat SmallTalk. Stejně tak si ho můžu napsat třeba v C, Javascriptu nebo čemkoli, co je turingovsky úplné.
Jestliže někdo tvrdí, že z hlediska multithreadového programování jsou assembler, C, Java a Erlang totožné jazyky, protože ve všech lze psát v duchu multithreadové filosofie, tak mu na to nelze říct než: netvrdíš nic jiného, než že tyhle jazyky jsou turingovsky úplné.
Váš příklad s nadstavbou nad C++, která umí něco, co C++ neumí, je toho víc než jasným příkladem. Stejně tak např. GObject nedokazuje, že C je OOP jazyk.
Pokud se vám to nelíbí, tak si pojem „objektový jazyk“ úplně vymažte ze slovníku a říkejte jenom „objektové POUŽITÍ turingovsky úplného jazyka“. Ovšem až budete někomu tvrdit, že Brainfuck nebo lambda kalkul jsou objektové jazyky, můžete zůstat …mírně řečeno… nepochopen
Tohle vlákno vzniklo proto, že jsem jen upozorňoval, že velmi častou chybou začátečníků je, že něco považují za pravé OOP a něco za nepravé OOP. Většinou v roli prvního příkladu je smalltalk a v druhem buď C++ nebo JAVA. Nejčastějším argumentem je posílání zpráv. A jedním dechem uvádím, že je to pitomost, protože způsob posílání zpráv nedělá z jazyka pravý OOP jazyk, protože pravé OOP vlastně neexistuje.
Můžete to chápat i jako pokus o flame :-)
V zásadě ale trpíme všichni rozsahem definic. Co už je OOP jazy a co nikoliv? Co už je multithreadový jazyk a co už nikoliv. Předně si myslím, že JAVA není multithreadový jazyk ani proto, že podporuje synchronized. Multithreadový jazyk si představuji něco úplně jiného. A stejně tak OOP jazyk. Javu i C++ považuji za OOP jazyky už proto, že techniky a konstrukce, které se tam používají uznadňují implementovat OOP filozofii. Stejně tak smalltalk to usnadňuje, je objektový jazyk. Ale podobně se lze dívat i na python :-) Programátora nutí myslet objektově. A to je celé. Přesto stejně ve všech těchto jazycích lze programovat procedurálně (po staru). O tom, zda jsou objekty implementované jako místa v paměti, záznamy v tabulkách, a zda se zprávy posílají, volají se metody a jestli objekty mají nebo nemají přístupné atributy (a zda vůbec mají atributy).
Vždycky na jedné straně bude stát náročnost implementace a na druhé straně úplnost (nebo pohodlí) OOP modelu. A tyhle dvě věci jdou prostě proti sobě.
PS: V tomto ohledu mě dost mrzí vývoj některých běžných jazyků. Například v C++0× jsou některé věci dobré, ale chybí dodělání věcí, které souvisí s OOP, například třídní proměnné, základní typy jako objekty, atd. Java vyloženě trpí neexistencí destruktorů, jako přesné vymezení existence objektu (objekt existuje od teď … až do někdy).
PSS: Překvapuje mě, že úpravou jednoho jazyka vzniká jiný jazyk, podle Vašich slov. Jenže opět trpíme rozsahem definic. Co je jazyk a co už není? Patří do jazyku jeho standardní knihovna? Tohle je třeba spor… má být v C++ podpora multithreadingu? Nebo si vystačíme s knihovní funkcí? Já zvládnu z C++ udělat multithreadový jazyk pomocí své knihovny.
Když protlačím svou (výše uvedenou) úpravu jazyka do standardních knihoven, bude z toho jazyk s úlnějším OOP modelem? Jiný příklad. Má být v C++ zaveden GC? Já tvrdím že ne. Já zvládnu napsat GC v současném C++ a nepotřebuju žádnou buildin podporu. A vo tom to je. Potřebujeme jazyk na vyšší úrovni abstrakce, aby jsme ocenili úplný OOP model? Já ho nepotřebuju, ale chápu, že někdo bez toho nemůže v noci spát. Kolik ho to bude stát výkonu. Kolik zbytečného kódu se kvůli tomu napíše a v runtime vykoná?
Omyl. Žádný spor o definici přece mezi námi není. Vaši větu „velmi častou chybou začátečníků je, že něco považují za pravé OOP a něco za nepravé OOP“ si překládám jako „v každém jazyce se dá psát objektově“.
Čili žádnou (užší či širší) definici „OOP jazyka“ nepotřebujeme, protože všechny jazyky jsou turingovsky kompletní, takže co se týče expresivnosti ekvivalentní.
Čili vaše hrdé zvolání „já umím v C++ napsat posílání zpráv“ přebíjím svým zvoláním „já to umím i v Brainfucku!“
Tím je causa finita.
No tak za prvé, já nejsem matfyzák a za druhé, pokud někdo tvrdí, že větu
C++ je míň OOP než Smalltalk
může říct jen „začátečník“, pak jste to Vy, ne já. OOP-ekvivalentnost jazyků tvrdíte Vy, ne já.
Já naopak výše zmíněnou větu klidně vyřknu a chápu ji jako jiné vyjádření teze „SmallTalk PŘÍMO podporuje větší množinu myšlenek OOP než C++“.
No a? Ale o to přece vůbec nejde. Napadlo mne, že nejste matfyzák, protože byste neměl takový zmatek se slovem defince.
Obecně se neříká objektové jazyky, ale objektově ORIENTOVANÉ jazyky. Orientují se na objektové programování. Je mi srdečně jedno, jak moc úplný je OOP model který jazyk používý. Většina současných OOPL (Object Oriented Programming Languages) implementují naprostou většinu z filozofie OOP. Je na Vás, abyste si vybral, co Vám vyhovuje co do výkonu, či rychlosti vývoje.
Jen jsem chtěl podotknout, že způsob komunikace mezi objekty nic neříká o úplnosti modelu OOP. V naprostý většina totiž volání metod vystačuje, a jen puntíčkář bude zkoumat technické pozadí implementace dívat se, zda zápis 100 factorial v nějakém bufferu vytvoří zprávu, kterou pak předá do jiného buffer a následně předá řízení oslovenému objektu, který jí z bufferu vyzvedne a provede … a bude tomu říkat zasílání zpráv.
>> Napadlo mne, že nejste matfyzák, protože byste neměl takový zmatek se slovem defince.
Nemám žádný zmatek se slovem „definice“. Říkám ale, že vy žádnou takovou definici nepotřebujete, protože se snažíte dokázat, že v každém jazyku se dá programovat podle OOP filosofie a že i když C++ nějaký OOP prvek neobsahuje, dá se tam nějak krkolomně nabastlit.
>> Obecně se neříká objektové jazyky, ale objektově ORIENTOVANÉ jazyky.
Toho slovíčkaření už bylo dost se slovem „třída“, ne?
>> Většina současných OOPL (Object Oriented Programming Languages) implementují naprostou většinu z filozofie OOP.
Opakuju: jediný běžně používáný jazyk, který znám a který implementuje přímo, čistě a jednoduše „naprostou většinu z filozofie OOP“, je Objective C. To není žýdný flame, to je konstatování.
Dal jsem vám jasný příklad s konstruktorem – v článku pod kterým diskutujeme, je uvedeno, k čemu je dobré, aby třída vracela instanci jiné třídy. Je to čisté, praktické a elegantní – a v současných OOP jazycích (Java, C#) to (čistě) nejde.
>> Jen jsem chtěl podotknout, že způsob komunikace mezi objekty nic neříká o úplnosti modelu OOP. V naprostý většina totiž volání metod vystačuje
No a s tím právě nesouhlasím – a klidně si mě nazývejte začátečníkem, to je mi celkem fuk.
Jestliže jazyk implementuje komunikaci mezi objekty blbě, naučí se programátor používat blbé postupy, které mají s OOP málo společného. Viz výměna názorů mezi p. Viriusem a p. Čadou.
Tím končím, začínáme se opakovat.
Ale blbost. To je jako byste řekl, že důkazem, že dřevo hoří je pokus, při kterém se prokázalo, že voda nejde zapálit. Si říkejte co chcete, ale jste vedle.
Zaprvé, konstruktor je funkce třídy, jehož jediným úkolem je inicializovat instanci třídy. Lepší by bylo, kdyby se to implementovalo tovární funkcí „createInstance“, na objektu třídy. Jenže z implementačních důvodů tyto jazyky nemají třídy chápány jako objekty, ale spíš jako šablony objektů. Proto konstruktor. Technické řešení vyplývající ze způsobu implementace OOP.
Za druhé, vyplývajícího z funkce konstruktoru je, že konstruktor nemůže a ani není určen k inicializaci jiného objektu, než objektu, který vzniká instanciací třídy. A navíc konstruktor je chápan jako členská funkce instance, ne třídy. Má zvláštní postavení hlavně proto, že je spouštěn na nezkonstruovaný objekt, což může v některých jazycích, ktere objekty mapují přímo do paměti problém, proto se používá konstruktor, aby po vytvoření objektu byl objekt zkonstruován. Prostě když už nic jiného, tak účelem konstruktoru je zvalidovat přidělený paměťový prostor, asi jako bagr, který přijede na rozorané pole, aby tam udělal základy domu.
To vy chcete je tovární funkci, která zkonstruuje jiný objekt. Ale ten objekt se zkonstruuje voláním jeho konstruktoru. Cítíte ten rozdíl? V C++ konkrétně se vytvoření instance skládá ze dvou kroků, neprve přidělení paměti a následně zavoláním konstruktoru na tu paměť. Vůbec netuším, co by mělo znamena, že konstruktor má vytvořit jiný objekt. Asi jako když matka porodí dítě a to se po porodu rozhodne stát psem.
Ukažte mi použití vašeho konstruktoru, abyste mi vyvrátil pocit, že tomu rozumíte jak koza petrželi.
No, je-li tohle pravda (a já nepopírám, že takový výklad dává smysl), je IMO snad lepší OOP nepoužívat, tedy vyjma speciálních domén. Osobně dávám přednost programům, které dělají to, co chce programátor a ne to, co si objekty usmyslí. ;-) Ideální program je snadno verifikovatelný a srozumitelný a to ten OOP přístup v extrémním případě naprosto rozbíjí a představuje neřízenou střelu. Samozřejmě chápu, že OOP přináší určité výhody (zapouzdření, znovupoužitelnost) a užitečné konvence (Demeterův zákon), ale upřímně, nic z těch věcí, které považuju za významné, nevyžaduje posílání zpráv namísto volání metod. Ba co víc, mnohé věci řeší srovnatelně efektivně například funkcionální programování. A po docela obstojných zkušenostech s dynamickými jazyky začínám čím dál tím více uznávat užitečnost kvalitního statického typového systému, který poskytují jazyky z širší rodiny ML (např. Haskell a Scala).
__getattr__ instance = Trida(parametr) self je zbytečnej opruz, to je fakt. Ale na druhou stranu, kdyby self skryli (něco jako „implicitní“ parametr metody), tak by to nebylo nic víc než syntaktický cukr.
Spíš mě fakt štve ta naprostá absence kontroly. Boo je v tomhle daleko příjemnější – když člověk opravdu chce dynamické chování, použije duck typing a v ostatních případech si užívá pohodlí automatické kontroly. Když se k tomu ještě přidá typová inference, je z toho skoro ideální jazyk ;)
Cyklus nekonečný = nekonečný cyklus.
Vážený pane, když nevíte, co znamená svoboda, tak to fakt nemá cenu. Svoboda znamená, že k výchozího stavu se do libovolného konečného stavu dostanete pomocí několika kroku a libovolnou cestou. Nesvoboda znamená, že do některých konečných stavů se buď vůbec nedostanete, nebo vás to bude stát obrovskové úsilí a budete mít velmi omezený výběr cest.
Považuji jazyky automaticky dělající určité věci za programátora za nesvobodné, protože jejich automatické nástroje nelze deaktivovat. Pokud se budu 10× objektu číslo ptát na faktoriál, tak 10× se bude někde v pozadí vyhodnocovat odesílání zprávy a hledat se program, který bude počítat zadanou úlohu, zatímco rychlejší cesta by byloa vyhodnotit to jednou a pak to vyřešit. Jistěže existují optimalizace, cache a buh ví co, ale to je asi jako když evropská unie látá problémy regulací dalšími regulacemi.
Zkuste ve smalltalku napsat program pro kompresi LZW. Určitě to zvládnete, ale porovnejte výslednou výkonnost s nativním řešení(třeba v C). A to je přesně ta nesvobodam protože vy pak už nemáte jinou možnost, než to napsat v nativu a připojit to jako externí modul, jelikož Vám ten jazyk nedává jinou možnost.
Tím neříkám, že svoboda je lepší. I svoboda má svou cenu. Někdo prostě radši má nástroje k dispozici a vybere si cestu, která mu nejlíp vyhovuje. Jiný si řekne, že to nechá na někom jiném a k cíli se nechá vést za ručičku.
Nezapomeňte že cílem všech jazyků je říct lidsky pochopitelnou formou počítači, co má udělat. U některých jazyků to ale znamená, že jednoduché sdělení bude znamenat obrovskou záťež pro celý stroj. V jiných jazycích budete toho muset hodně namluvit, aby počítač pochopil, co chcete udělat. Já osobně považuji to druhé za svobodnější prostředí, než to první.
Od kdy je nativním jazykem počítačů Cčko?
Já bych tedy byl dost opatrný v používání slova svoboda v souvislosti s programovacími jazyky. Co se týká řešení, tak už tady bylo řečeno, že všechny jazyky, o který se tu nejmenovitě bavíme, jsou turingovsky úplné. Tudíž i množstvím cest se neliší.
Liší se tak akorát efektivitou běhu, což je implementační problém, nikoli problém jazyka a případně efektivitou programování či čitelností kódu.
No Cčko je nativní vícéméně od té doby, co C bylo vymyšleno tak, aby převod do strojáku byl víceméně 1:1 Rozhodně pro překlad a běh nepotřebujete virtuální stroj, ani JIT compiler. Tím je myšleno nativní. A já tim ani nemyslel jazyk, ale výsledný kód, který je ve strojáku „as-is“. Proto se v něm do dnes vyvýjejí operační systémy.
Co mi ovsem na nizkourovnosti Cecka zacina dost citelně chybět, je podpora VLIW obecně, konkrétně MMX, SSE a SSE2. Už to, že v céčku nejde pracovat s flagy (asi kvůli přenositelnosti) některé algoritmy neumožňuje čistě napsat (vícebajtová aritmetika například, tj. sekvence ADD, ADC, ADC, ADC, ADC…) ale nějaká možnost použít výše uvedenu instrukční sadu – to by jazyku jako C slušelo :-)
Nějak mi uniká, co tím vlastně chcete říci. C není žádným suprémem v oblasti lidské pochopitelnosti, ani programátorské svobody, ani rychlosti kódu. Smalltalk je rozhodně lidsky pochopitelnější, jednodušší a čistší jazyk, než C. Pokud jde o programátorskou svobodu, tak tady asi konkurenci nemá Forth – můžete si v něm udělat cokoli, jakkoli, za ručičku Vás tu určitě žádný překladač nevede – ovšem se všemi důsledky, jež z toho plynou. A pokud jde o efektivitu kódu, tak – nepočítám-li Assembler – tady (pro někoho možná kupoodivu) vítězí Fortran. Vím, je nesmysl porovnávat v tomto ohledu jazyky, když je to záležitost překladačů, ale filosofie jazyka má na návrh jeho překladače a možnosti optimalisace poměrně velký vliv. No a že Smalltalk podporuje objektový přístup lépe, než C++, to je prostě fakt – C++ = „objektový assembler“. Já jsem žil ovšem vždycky v přesvědčení, že tak to taky bylo myšleno. Flame by IMHO mohl vzniknout na téma „je lépe objektový Smalltalk nebo Lisp (CLOS)“, kde oba jazyky nabízejí luxusní nástroje pro OOP, ale každý to realizuje úplně jinak. Smalltalk je 1. liga v OOP, CLOS je 1. liga v OOP, ale C++ – to určitě první objektová liga není.
Jinými slovy – že dáváte přednost C++ je sice hezké, ale je to věc, jež má tu zajímavou vlastnost, že z ní o Smalltalku a OOP vůbec nic neplyne. :-)
Myslím, že se tady míchá svoboda (volnost) jazyku s jeho účelem. Smalltalk vznikl jako vyšší jazyk pro řešení rozsáhlých abstraktních úloh, čehož je komprese LZW přesným opakem. Komprimovat nikdy nebylo smyslem Smalltalku. Naopak jde o typickou výpočetně a datově jednoduchou úlohu, pro kterou jsou přímo určeny jazyky assembler a C.
Užití nevhodných jazyků pro řešení specifických úloh není v praxi neobvyklou chybou.
Co kdo povazuje za svobodu a upresneni jejiho vykladu v dane situaci muze byt na miste. Dotazujici se muze ujistovat, zde svoboda neni vice zamenovana napriklad za zbozne prani. Zaroven se ujistete, zda Vase svoboda neni jen Vasim zboznym pranim.
Co se tyka implementace LZW, tak jste to trefil – ano, mame ruzne kese, zname a mame JIT pro runtime preklady a dalsi nastroje a metody, ktere dokazi zdanlive neefektivni jazyk ucinit efektivnim a mnohdy efektivnejsim nez v pripade, ze by to programator psal v cecku nebo strojaku. Pokud mam dnes dobry jazyk, tak zitra muzu mit i dobrou implementaci prekladu toho jazyka pro prislusny stroj. Nadcasovost jazyka nepovazujte za chybu, to by byla chyba.
Pro me znamena svobova (kdyz se bavime o vyvoji):
- moznost vybrat si nastroj, ktery mi pro dany ukol nejlepe vyhovuje (pokazde to muze byt neco jineho – BASH, Python, ciste C, assembler, PL/SQL, C++)
- moznost menit si ten jazyk nebo knihovny pod rukama (zkuste vymenit v C nebo Jave defaultni random() za neco lepsiho – opruz)
- samozrejme neco na zpusob LGPL je jen vyhodou
Oblíbeným omylem všech OOP nováčků je lpění na „posílání zpráv“. Poukazovat na to, že tamten jazyk posílá zprávy a jiný jazyk zprávy neposílá ale volá metody. A že tamten jazyk jen říká co by měl objekt udělat a ten druhý mu přímo nařizuje, co má udělat. Ale to jsou všechno pitomosti.
No já ti nevím, když na tom bazíruje největší OOP nováček ze všech. Nic mě nezlepší náladu víc, než když se od srdce po ránu zasměju, děkuji.