Štěpán Škrob: Horkým kandidátem byl WebKit, ale vybrali jsme Gecko

Vyzpovídali jsme Štěpána Škroba ze společnosti Seznam.cz. Zeptali jsme se na několik novinek fulltextového vyhledávače Seznamu. Jak rychlá je nedávno spuštěná nová verze generátoru náhledů? Proč běží právě na Gecku a jak funguje? Proč začal Seznam podporovat mikroformát geo?
Seznam jako jediný český fulltextový vyhledávač obsahuje ve výpisu výsledků náhledy stránek. Kdy jste je nasadili a jak vás ta myšlenka napadla?
Náhledy stránek jsme nasadili poměrně dávno. Už když jsme začali pracovat na vlastní verzi vyhledávání, tak jsme s náhledy počítali. To bylo zhruba v roce 2005. V rané fázi Seznamu největší invenci do služeb vkládal Ivo Lukačovič a myslím, že s tímto nápadem přišel on.
Váš první generátor náhledů jste postavili na Internet Exploreru. Proč jste zvolili právě tohle řešení?
Udělali jsme si průzkum a Internet Explorer z něj vyšel jako nejovladatelnější. Pokud někdo programuje pro Internet Explorer, jistě to potvrdí. Na jádro IE lze navěsit callbacky na velkou množinu akcí, které IE dělá. Pomocí nich se dá jádro ovládat, aby dělalo to, co chceme, a také tím můžeme sledovat jeho činnost.
Zbylé varianty, které jsme zkoušeli, nebyly v dostatečně pokročilé fázi, aby nabídly totéž. Další výhodou IE bylo, že náhled, který z něj generujeme, obsahoval pluginy, např. Flash. Pokud bychom v té době zvolili jiné jádro, museli bychom takové věci doprogramovat, aby byl náhled plnohodnotný.
Štěpán Škrob (1974)
- S Ivem Lukačovičem v letech 1996–97 vytvořil fulltextový vyhledávač Kompas.
- Dnes je produktovým manažerem ve vyhledávacím týmu v Seznamu.
- Rád létá s modely letadel.
- Píše na Seznam Fulltext Blog pod přezdívkou Solamyl.
Vytvořili jste vlastní aplikaci, která embedovala komponentu IE?
Generátor běžel jako služba ve Windows, která využívala komponentu Internet Exploreru. Spustila si asi 20 instancí IE, které načítaly stránky a po jejich načtení snímaly obrázky. Ty byly následně zmenšeny.
Jaký byl výkon tohoto generátoru?
Ve špičce tak 2–3 snímky za vteřinu. Ale to byl celkový výkon několika strojů. Používali jsme tenkrát 2–3 počítače.
Můžete se ptát, proč 20 IE udělá tak málo screenshotů. Má to dva hlavní důvody – za prvé veškeré stahování z IE ve Windows jde (je to tedy jen domněnka, ale všechny indikace k tomu spějí) přes jediný download manager, který omezuje celkový průtok dat, takže přidávání dalších IE od určitého bodu nepomáhá. A ten druhý důvod je, že focení některých stránek prostě trvá dlouho. Pokud stránka obsahovala Flash, tak jsme od okamžiku oznámení načtení celé stránky ještě čekali asi 20 vteřin, aby náhled obsahoval nějakou pěknou část a nikoliv jen bílou stránku „Loading…“.
Dnes bez problému pořídíme asi 20 náhledů za vteřinu.
Takže jste se rozhodovali i podle vlastností dané stránky. Jaké informace vás při tom zajímaly?
Kromě toho, zda stránka obsahuje Flash a jiné dynamické prvky, jsme zjišťovali, jaké má rozměry. Detekce dynamických prvků je důležitá pro určení doby čekání pro vyfocení a rozměry pak pro nastavení šířky okna prohlížeče.
Některé stránky byly optimalizované pro šířku 1024 px, jiné měly centrovaný design a 600 px. Pokud bychom obě snímali na 1024 px, tak by stránka s 600 px byla příliš úzká. Proto jsme podle těchto údajů volili optimální rozlišení pro snímání náhledů.
Nedávno jste spustili novou verzi generátoru. Ta je postavena na jádru Gecko. Proč jste vůbec dělali změnu?
S tím prvním systémem byla řada provozních problémů. Máme u nás spoustu serverů a administrátoři, kteří je spravují, nemůžou tolik času věnovat pouze jedné aplikaci. A první systém byl náročný na údržbu. Po spuštění běžel průměrně asi měsíc, pak byla zapotřebí údržba. Na naše poměry to ale bylo příliš často.
To je jediná věc, ve které je nový generátor lepší?
Je jich víc, zkusím je shrnout:
- větší rychlost
- větší spolehlivost (původnímu generátoru se čas od času některé náhledy nepovedly)
- menší náklady na údržbu
Hodně nám záleželo právě na rychlosti. Před časem jsme zlepšili robota fulltextového vyhledávání, takže dnes stahuje stovky stránek za vteřinu. Vedle toho generátor náhledů zvládal ony 2–3 stránky za vteřinu. Proto byly náhledy někdy zastaralé.
O kolik bude nový generátor výkonnější?
Výkon ještě ladíme, ale už dnes bez problému pořídíme asi 20 náhledů za vteřinu. Tam, kde jeden původní stroj zvládal 1 náhled za vteřinu, jich nový zvládá 10. A budeme ještě zrychlovat.
Je nový generátor architektonicky podobný původnímu systému?
Současná verze je řekněme o generaci dál. Celá aplikace je mnohem rozsáhlejší. Původní verze se starala jen o generování náhledů. Nová verze obstarává také jejich výdej. Jedná se o velké množství malých obrázků, které by nebylo efektivní nabízet jako statické soubory z webserveru, proto jsme tyhle dvě funkce zkombinovali dohromady.
Která jádra prohlížečů jste zvažovali?
Než jsme začali pracovat na nové verzi, udělali jsme si nový průzkum HTML enginů. Horkým kandidátem byl WebKit. To bylo ale již před časem a tehdy neběžel WebKit na Linuxu ještě tak optimálně, jak bychom chtěli. Dokázali jsme přes něj generovat náhledy, ale byl tam problém s Flashem a nedokázali jsme se dostat na DOM stránky. Právě tohle šlo totiž s IE jednoduše, u něj jsme před sejmutím náhledu ze stránky získali potřebné informace a podle nich jsme snímání náhledu uzpůsobili.
WebKit ale vypadá nadějně a pokud se bude někdy dělat třetí generace, tak bude určitě ve hře. My jsme vybrali projekt MozEmbed, což je embedovaná Mozilla. Jednoduše řečeno jádro prohlížeče (Gecko) zabalené do knihovny.
Ovšem co se týče ovladatelnosti, z enginů, které jsme zkoušeli, je na tom asi nejhůř. Má velmi slabé možnost ovládání. Můžeme nabídnout URL a sejmout náhled, ale kupříkladu zjistit rozměr stránky nebo přítomnost Flashe, JavaScriptu apod., to se z rozhraní dost dobře nedá.
Na druhou stranu Gecko řešilo naše problémy. Vytvářelo náhledy pěkné a spolehlivě i včetně Flashe. A to nakonec převážilo. Získání vlastností stránky jsme vyřešili jinak. Stránka se nyní zpracovává dvoufázově. Je tam předřazená aplikace, která stránku načte a zjistí z ní potřebné údaje.
Podle provozu, který nyní máme, bych řekl, že Mozilla funguje spolehlivě.
Náhledy tedy snímáte za stejných podmínek, jak stránky vidí uživatel, tedy včetně JavaScriptu a pluginů?
Ano, ten JavaScript je dobře poznat na mapách. Většina mapových aplikací, jako jsou Mapy.cz, to jsou jen holé stránky. Mapové dlaždice se již nahrávají JavaScriptem. Kdybychom používali jen čistý HTML engine, ve většině takových případů bychom viděli jen prázdnou stránku.
Určitě bychom chtěli generovat náhledy i pro URL, které vedou do světa.
Jak jste v tom případě připraveni na bezpečnostní problémy prohlížečů?
Vše běží na oddělených virtuálních serverech. Není tam přímý přístup k železu a síť je nastavená tak, aby se z nich dalo dostat jenom tam, kam se mají dostat. Takže to je určité bezpečnostní opatření pro tuhle aplikaci.
Ale i kdyby. Tím, že jsme použili Mozillu a máme řešení na Linuxu, to pro nás znamenalo extrémní zvýšení bezpečnosti proti Windows. Původní systém běžel na Windows Serveru. Když si člověk představí, že tam běžel puštěný Internet Explorer a za každý den navštívil necelých 100 tisíc náhodných stránek z internetu. Na těch strojích běžel antivirus, ale i přesto…
…se občas zavirovaly?
Antivirové programy umí spolehlivě odstranit pouze známé viry. U zcela nových virů používají heuristiky a snaží se rozpoznat podezřelé chování. I když je to velmi účinné, není to nikdy 100 %.
Ovšem, pokud bych měl první systém postavený na Internet Exploreru zhodnotit, tak abych pravdu řekl, ještě dnes jsem v šoku z toho, že dokázal běžet tak dlouhou dobu sám bez dozoru, aniž by se o něj někdo musel starat. Když tedy pominu onu údržbu přibližně jednou za měsíc.
Nedovedu si představit, že bych na svém notebooku denně otevřel desítky tisíc stránek a tak to dělal po celý měsíc bez restartu.
Setkali jste se už s tím, že by se někdo snažil „optimalizovat“ svůj web pro co nejlepší náhled v Seznamu? A třeba i podváděl, např. zobrazil generátoru náhledů místo webu obrovskou fotografii spoře oděné slečny a snažil se tak zvýšit proklikovost na svůj odkaz v Seznamu?
Ano přesně s tím jsme se setkali, ale bylo to v počátcích v roce 2005. Náhledy se objevily jako novinka a našli se i vtipálci.
Když na něco takového přijdete, co s takovým podvodníkem provedete? Vyřadíte ho z indexu?
Řešíme to individuálně, jelikož to není standardní případ. Rozhodně se smazal ten náhled.
Nedávno Seznam oznámil, že nahradí u vyhledávání ve světě Google za technologii Live Search od Microsoftu. Mezi důvody padla i možnost vkládání náhledů do výsledků od Live Search. Takže uvažujete o tom, že budete mít náhledy pro celý Web? Nebo jen nějaké vybrané stránky?
Existuje plugin do Firefoxu, který do vyhledávačů přidává náhledy. U všech odkazů zobrazuje náhled homepage. A to nám nepřipadá technologicky složité. Ve stejné kvalitě to zvládneme také. Takže určitě bychom chtěli generovat náhledy i pro URL, které vedou do světa a uvidíme, jak to půjde.
V původním generátoru byly náhledy identifikované skrze ID stránky, kterou máme v databázi. To prakticky znamenalo, že jsme nemohli mít náhled pro URL, kterou nemáme v databázi. S tím by nám screenshotování ve světě nešlo, protože to nejsou URL z naší databáze. V novém systému je náhled identifikovaný přes URL, a proto jsme schopni vytvářet náhledy pro libovolné adresy. Není to již úzce svázané s fulltextovým vyhledávačem.
Zkoumali jsme situaci, která kolem mikroformátů panuje. Je to takový začarovaný kruh.
Navíc v původním systému se zasílal požadavek např. na náhled s id=3. Věděli jsme, zda jej máme nebo ne, ale nemohli jsme ovšem dělat nic dalšího. V novém systému dostaneme URL, a když náhled pro danou URL nemáme, snažíme se URL zkracovat, dokud nějaký náhled nenajdeme. V nejhorším případě to skončí u náhledu homepage toho webu. Tím bychom měli eliminovat chybějící náhledy ve vyhledávání. To se totiž ukázalo jako problém. Uživatelé na takové výsledky méně klikají.
Řekněme, že jsem redesignoval svůj web a Seznam stále zobrazuje moje původní náhledy. Jak dlouho mám čekat, nebo můžu celý proces nějak urychlit?
Záleží, o jak navštěvovaný web se jedná. U webů typu Root.cz se náhled hlavní stránky aktualizuje v řádu dvou týdnů. Pokud web není tolik navštěvovaný, je možné si jednoduše nechat nové náhledy vygenerovat. Pro všechny stránky, které vložíte do přidávacího formuláře – a je jedno, že ty stránky již vyhledávač zná – se vygenerují náhledy zhruba do čtvrt hodiny.
Vyhledávač Seznamu začal před několika týdny podporovat mikroformát geo. V čem podpora spočívá?
Tak o mikroformátech obecně jsme již nějaký čas věděli a konkrétně mikroformát geo se nám líbil nejvíc. Pokud jej někdo použije na své stránce, objeví se u stránky ve výsledcích hledání navíc odkaz „Zobrazit na mapě“.
Zkoumali jsme situaci, která kolem mikroformátů panuje. Je to takový začarovaný kruh. Lidé ve stránkách mikroformáty moc nepoužívají, protože je vyhledávače nepodporují. A vyhledávače je nepodporují, protože mikroformáty nikdo moc nepoužívá.
Vy tedy ten kruh chcete v ČR prolomit?
Ano, aby se ten kruh dal prolomit, řekli jsme si, že uděláme podporu do našeho vyhledávače.
Uvažujete do budoucna o podpoře některých dalších mikroformátů?
Dívali jsme se i na další mikroformáty. Jsme schopni je rozpoznat na stránkách a přečíst z nich informace. Ale je otázka, jak je je jednoduše prezentovat, aby to ve výsledcích hledání bylo přínosné a nerušivé.
Plánujete používat mikroformáty i přímo na webech Seznamu? Čili sami psát HTML pomocí mikroformátů?
Zatím jsme do katalogu Firmy.cz všude doplnili mikroformát geo. Ale ty stránky obsahují i kontaktní informace, tam bychom mohli využít i mikroformát hCard.
Blíží se příchod IE8. Ten obsahuje vylepšené integrované vyhledávání s našeptávačem a podporou náhledů. Budete tuto novinku využívat? Uvidíme např. náhledy Seznamu přímo v našeptávači IE8?
Náhledy ve fulltextovém vyhledávání jsou poměrně velké a nejsem si jistý, zda by byl našeptávač IE8 stále tak ergonomický, kdybychom je do něj přidali. Naopak u Zboží.cz jsou fotky produktů o řád menší. Proto myslím, že na Zboží.cz toho můžeme využít.
Zabrousím trochu do historie. Vy jste současně také autorem původního fulltextu Kompas.
Ano, zrovna nedávno jsem doma náhodou našel jeho zdrojáky. (smích)
To byl pokud vím první český fulltextový vyhledávač.
Jsem si jistý, že přede mnou určitě v ČR fulltextové vyhledávání psala řada lidí, ale Kompas byl asi první vyhledávač na zdejším internetu, který fungoval jako websearch. Vytvářel jsem ho na vánoce 1996 a běžel od jara 1997.
V jakém jazyce byl naprogramován a jak dlouho jeho vývoj trval?
Byl napsán v céčku. Já jsem vytvářel čistě vyhledávač. A největší implementační část jsem měl hotovu během vánočních prázdnin. Robota potom vytvářel Ivo Lukačovič, a ten byl v Perlu.
Vyhledávač má vždy dvě části, které lze zcela nezávisle oddělit. Tou první je robot. Jeho funkce je dodávat stránky, které mají být zaindexované. Druhou částí je vlastní vyhledávač. Ten bere od robota HTML stránky – v té době byly předávané přes STDIN – a vytváří z nich index. Já vytvářel tu druhou část.
Vychází stávající vyhledávač Seznamu nějak z původního Kompasu nebo byl kompletně napsán znova na zelené louce?
Nemají spolu nic společného. Mezi Kompasem a současným vyhledávačem byla několik let propast, kdy Seznam používal Jyxo a další vyhledávače. Teprve po tom se začal vyvíjet nový vyhledávač.
Kompas jste vytvořil sám s Ivo Lukačovičem. Kolik lidí se podílí na vývoji fulltextu dnes?
Když spočítám celý fulltextový tým, což zahrnuje i správce databáze, administrátory a vývojáře, tak je to okolo 30 lidí dohromady.
Je dnešní vyhledávač taky napsán v céčku?
Je napsán v C++. Některé části jsou v Pythonu, ale ty hodně výkonné části jsou v C++.
Dnes je v „módě“ tzv. test driven development. Máte k vyhledávači napsány nějaké testy, abyste hlídali jeho kvalitu?
Tohle je těžká otázka. Máme automatické testy, které dokáží kontrolovat funkčnost komponent. Týká se to ale jen těch komponent, které ze vstupů generují jasné výstupy, tam to jde kontrolovat.
Jenže testovat tímhle způsobem, zda ve vyhledávání někde není chyba, by bylo myslím nedostatečné, protože výsledek vyhledávání je závislý na spoustě faktorů, které se mění – internet se pořád vyvíjí.
Máme aplikaci pro kontrolu kvality vyhledávání. To je ale jiný nástroj a nesouvisí s progresivními metodami programování. Jsou lidé, kteří hodnotí dotazy, a tato aplikace na základě ručního hodnocení měří kvalitu vyhledávání. Tím ji můžeme sledovat.
První byl Kompas, nyní máte nový vyhledávač. Plánujete někdy do budoucna vytvořit třetí generaci vyhledávače znova na zelené louce? Nebo vám v boji s konkurencí postačí zlepšovat a vyvíjet dále stávající vyhledávač?
Abychom začali psát celou aplikaci úplně znovu, k tomu by musela nastat nějaká velká pauza, podobná jako nastala mezi Kompasem a současným vyhledávačem, kdy nemělo smysl navazovat.
Budeme vyvíjet verzi, jakou máme. To ale neznamená, že neděláme i velké změny. Náš vyhledávač se skládá z řady komponent. Pokud je potřeba něco zgruntu předesignovat nebo posunout technologicky dál, tak se nějaká část vyhledávače kompletně přepíše.
Nikdy se nestává, že by bylo třeba přepsal všechny komponenty. Ale když něco dosluhuje, přepíše se např. jedna komponenta, ale vztahy na ostatní komponenty zůstanou zachované. Jako když na autě měníte letní gumy za zimní. Nejsou třeba dvě auta, kde by jedno vždy půl roku stálo v garáži. Jde to realizovat na jednom autě.
Děkuji za rozhovor.
Otázky za Zdroják kladl Martin Hassman, fotografie pořídila Ivana Dvorská.
Pekny clanek!
Zajimavy interview, jen bych strasne rad videl ty zdrojove kody spidera i indexera "Kompas" a dozvedel se proc se to z C cele prepsalo do C++. V nespoledni rade bych rad zjistil priblizny pocet radku stareho search enginu a noveho search enginu (kolik maji zdrojove kody radku?). Pravidelna mesicni udrzba win32 = format + kompletni reinstall, ze? :)
c++ kod je viac maintainable a je aj o nejake percento rychlejsi ak vies c++.
????
Možná, ka nevies C. Ale vzhledem k tomu, že v C lze napsat totéž co v C++ (až na to,že někdy napíšeš víc řádků kódu) – první kompilátory C++ fungovaly jako překladač z C++ do C – tak neni důvod, proč by kód v C měl bejt pomalejší.
Pravda je jen to maintable – v c++ se prostě líp píše, líp se hledaj chyby atd…
K teto diskusi jsem si vzpomnel na zajimavy clanek, kde je presne opacny nazor, fakt stoji za to ho precist:
http://lwn.net/Articles/249460/
Ja bych taky C++ zahodil a psal v C. Podle me se naopak v C++ pise daleko hur a hur se hledaji chyby, protoze C++ nuti cloveka delat taaaakhle tluste mezivrstvy, a kdyz si spatne rozvrhnete tridy, tak jste pozdeji ztraceni. V C je daleko jednodussi refaktorizace, a kdyz neignorujete warningy, tak uroven odhaleni chyb uz v compile-time je docela dobra.
-Yenya, http://www.fi.muni.cz/~kas/blog/
C++ může za špatné počasí a napůl nefunkční KDE :-) Jaké tlusté mezivrstvy máte na mysli? Třeba tlustá vrsta výjimek nebo špatně rozvrhnout třídy může být v C dost problém :-), ale vážně – jaké mezivrstvy je nutné vytvářet a v čem je v C snadnější refaktorizovat? Záleží na stylu než na použitém jazyce.
Na druhou stranu, C++ knihovna bez správných úprav asi moc přenositelná nebude – např. na jinou verzi překladače, STL… Ale zatracovat kvůli tomu C++ úplně a za všech situací…
K tomu co napsal Linus (pro mnohé ekvivalent toho, jako by to napsal sám Bůh, ale věřím, že to nebude případ zdejších čtenářů) – v podstatě to, že když někdo moc chce, aby byl projekt v C++ místo v C, asi by ten někdo neměl být k projektu vůbec pouštěn. Hm, Linus si tohle myslí o C++, já si tohle myslím o PHP :-) Možná že já neprogramuji kernel a Linus neprogramuje webové aplikace. K té části o gitu – existují i VCS implementované v Pythonu. Jazyk C++ nevylučuje páchání chyb, asi jako žádný jiný.
Mimochodem, k rychlosti C++ – C++ asi bude o něco pomalejší, než C, ale ne výrazně. Záleží na tom, jakým stylem je projekt naprogramován – pokud se přeužívá STL, pak na vyšší rychlost mají šanci i interpretované jazyky :-)
Přesně. C++ je hlavně objektový a generický jazyk, C je imperativní a markoidní. Pokud chcete v C++ programovat imperativně a makroidně (jako by to dělal Linus), tak jste se spletl s výběrem jazyka.
Přenositelná je celkem v pohodě, dneska už všechny hlavní překladače standard dodržují. Problém může nastat, pokud se používají různá nestandardní rozšíření, ale jinak se dá přecházet tak stejně jako v C.
Dobře napsané C++ je stejně rychlé jako dobře napsané C :)
Zrovna STL je extrémně rychlé, právě protože to jsou všechno šablony, které se inlineují a výborně optimalizují při překladu. Samozřejmě ale jen v případě, že zapnete optimalizace.
Tluste mezivrstvy: je toho vic, ale napriklad: pokud neco delate objektove, pak k vetsine "verejnych" atributu objektu pisete accessor a mutator funkci, ruzne konstruktory, operatory pretypovani a prirazeni a podobne, aby to "vypadalo kompletne", a v tom vsem kodu je jen hodne malo radku toho, co skutecne dela neco netrivialniho. Java je na tom jeste hur, tam se ktem vsem generovanym acessorum a mutatorum pridavaji ty javadoc komentare, takze zdrojak pak nejen ze nejde v normalnim textovem editoru napsat, ale on nejde ani normalnim lidskym okem precist, protoze tech mist kde se "skutecne neco deje" je fakt malo. Tohle je proste fakt, ze objektove jazyky v podstate nuti cloveka psat tak, ze se vsechno obaluje do mezivrstev.
Jinak Linus tam uvadel i racionalni duvody proc ne C++ (treba tu refaktorizaci).
-Yenya
Ale tohle je základ C++. Mimochodem Linus je jeden z těch, kteří prosazují, že jedna procedura (metoda) smí být dlouhá maximálně 25 řádků, takže většinou nemůže dělat něco hodně netriviálního (teda pokud se nevyužije macro hell).
A taky bych dodal, že pokud nepatláte objekty stylem Copy&Paste, jako dělá většina začínajících programátorů C++ (jo, dělal jsem to taky), ale member objekty obalíte do vhodných šablon, případně z nich uděláte objekty, které se starají o svůj obsah nebo je rovnou uvedete jako public, tak žádné accessory a mutátory psát nemusíte a kód je tak daleko přehlednější.
25 radku kodu ktery neco dela je ovsem neco jineho nez accessor/mutator, ktery vypada nejak takhle:
/**
* get_atribut(void)
*
* ziska hodnotu atributu
*/
int get_atribut(void)
{
return this->atribut;
}
Coz je 9 radku kodu ktery nedela vubec nic. Navic kdyz si prectete linux/Documentation/CodingStyle, tak tam neni striktni omezeni na 25 radku, ale spis neco o tom, ze cim hloubeji zanorene struktury ta funkce ma, tim by mela byt kratsi. A ze neni nic spatne na funkci obsahujici jediny prikaz switch, ktery se kvuli mnozstvi variant tahne pres nekolik obrazovek.
-Yenya
Takle píšu accessor já.
Není to sice podle všech doporučení, ale vypadá to celkem přehledně, člověk hned vidí o co jde. (doxygen to sežere) Navíc, když to člověk v deklaraci hodí někam k sobě (accessory a mutatory zvlášť), pak i zdroják vypádá přehledně… Výhoda accessorů je v tom, že pokud se práce s atributem v budoucnu změní, není třeba měnit rozhraní.
Už jsem se takovým případem setkal. Několikrát by změna rozhraní znamenala obrovské náklady a čas.
psát dokumentaci je špatné, áno?
…tak nějak jste to s tou javou myslel? ;)
naopak tohle by se dalo chápat jako výhoda javy, že standardizuje dokumentovaní přímo v kódu, což je potom ve spolupráci s patřičným ide příjemné, pokud na projektu pracuje víc jak jeden člověk (a mnohdy je za předchozí dokumentaci rád i když píše něco sám).
btw, z čeho vycházíte, že se nedá javovský kód psát v obyčejném textovém editoru? já to už párkrát dělal a musím říct, že mi to docela šlo (i když je to pruda).
co se týče čitelnosti, to je asi věc zvyku, protože pro mě je javovský kód čitelný nádherně, za to špagety ála php nebo asp mi dělají problémy a nad nějakým masitějším kódem v perlu či dokonce lispu musím sedět trošku dýl abych vůbec tušil odkud vítr vane…
Kdyz to reknu velmi volne, tak ano, psat dokumentaci je _casto_ spatne. Zvlast _povinna_ dokumentace a zvlast k trivialitam. Treba v jiz zminenem linux/Documentation/CodingStyle se pise:
[vyraz „neda se psat v obycejnem textovem editoru“ u me znamena presne to vase „je to pruda“; PostScriptovy soubor lze taky napsat v obycejnem textovem editoru, ale temer nikdy to nema vyznam]
-Yenya
přiznám se, že s odkazovaného textu jsem nepochopil, proč by mělo být psaní dokumentace "_často_ špatné". to že někdo píše dokumentaci špatně je chyba dotyčného programátora-prasete, za což by měl dostat přes prsty a ne chyba dokumentace jako takové.
pořádná dokumentace (alespoň veřejného api) prostě musí být a musí obsahovat popis toho, co daná metoda (funce, procedura, whatever) bere, co a za jakých podmínek vrací, jaké výjimky a za jakých podmínek můžou nastat atp. myšlenka, že nejlpší dokumentací je přehledně napsaný kód a jako takový nepotřebuje dokumentovat, protože "to je z něj jasné" je naprostý nesmysl. a to i v případě "trivialit" (teď ovšem nemyslím nějaké gettery-settery). jako vývojář chci nějaké api používat a pokud možno okamžitě vědět co dělá. ne se vrtat v cizím kódu a zjišťovat k čemu to vlastně je.
ad textové editory – ano v obyčejném textovém editoru to je nepohodlné, ale jde to. ale takhle je to s většinou jazyků. když se objevilo barvení syntaxe, tak se nikomu nechtělo psát "černobíle", když si někdo zvykne na automatické doplňování/šablony/generování kódu/kontrolu syntaxe/automatizovaný refactoring/hypertextové procházení kódu atd atd tak je samozřejmě psaní v obyčejném textovém editoru otrava. ale stejně jako když přesednete z bmw do trabantu, na dané místo taky nejspíš dojedete, ale o potěšení nebo pohodlí řeč být moc nemůže.
Jenze v C++ je problem, ze tou objektovosti je toho verejneho API (funkci/metod/cehokoli co je verejne pristupne k volani odjinud) je nekolikanasobne vic. A je ho vic o triviality, ne o realnou funkcnost.
Podle me z nazvu funkce by uz melo byt jasne co funkce dela. Dokumentace „API“ je potreba jen v pripade, ze _nad to_ ta funkce ma nejake speciality (mozna ty vyjimky, ja bych treba rekl pozadavky na externi zamykani, atd.).
K velikosti „API“ v C++ jeste prispiva to, ze pokud chcete mit neco naprogramovane „ciste“ (pekne), tak je neco jineho aby „objekt mel ciste (zejmena ortogonalne) navrzene rozhrani“ a je neco jineho, co realne potrebuje uzivatel toho objektu. Coz je to co jsem psal driv – ze proste v C++ k te tride dopisete „kompletni“ rozhrani (pekne ciste navrzene, o tom zadna), akorat je ho mnohokrat vic a casto ne presne takove, jako potrebuji uzivatele toho objektu.
-Yenya
A teď mi řekněte, jaký je rozdíl v tom, že v C i C++ napíšete objektu do knihovny jen základní funkčnost a zbytek necháte implementovat programátora v C novými funkcemi, v C++ dědičností?
V zásadě komentuji algoritmy, pokud vlastní zdrojový kód je těžší analyzovat. Osvědčilo se mi prokládané komentování, tedy jeden komentář, a jeden řádek kódu
Ukázka je samozřejmě primitivní. Používám spíš u náročnějších úkolů, třeba různé ne zrovna na první pohled viditelné optimalizace. Další důvod pro komentáře u vícevláknových algoritmech, kde komentář zpravidla obsahuje očekávaný stav dalších vláken v tom daném míste (případně upozornění na problémové místo, možný race condition a podobně)
Komentování algoritmu zjednodušuje pochopení principu fungovaní později a hlavně odhalování chyb. Komentáře jsou často v implementační části, takže (aspoň v C++) skryté běžnému uživateli.
Java je na tom jeste hur, tam se ktem vsem generovanym acessorum a mutatorum pridavaji ty javadoc komentare, takze zdrojak pak nejen ze nejde v normalnim textovem editoru napsat, ale on nejde ani normalnim lidskym okem precist, protoze tech mist kde se „skutecne neco deje“ je fakt malo.
Tak tohle jsem nepochopil. Tam ty javadoc komentare snad psat nemusite, ne? A kdyz mate IDE, tak jsou dost uzitecne, ne? Takze nechapu…
Nemusite, ale vsichni to pisou. Cili kod v Jave je bez IDE necitelny, protoze tezko hledate, kde v tom vsem je skryta ta cast, ktera opravdu neco dela.
-Yenya
No vidíte a mě Javadoc (resp. Doxygen) u prototypu funkce v hlavičkovém souboru vyhovuje daleko víc, než procházet tisíce řádků zdrojového kódu (který v mnoha případech ani nechci stahovat – proč taky, když to kompilátor slinkuje s hotovým sočkem?) a hledat, co ta která funkce vlastně dělá. A to píšu v Kate a žádné IDE nepoužívám.
Kdo dnes tvrdí, že v C++ se píše mnohem hůř než v C, ať zůstává u C, C++ prostě zatím nepochopil. A nebo ať se C++ začne pořádně věnovat, něco si o tom přečte a zkusí programovat podle všech doporučení C++ programátora. Třeba chytí slinu.
Já bych třeba v C dneska neprogramoval. Přitom jsem v C napsal celou hru (kdysi legendární český dungeon "Brány Skeldalu"). Ale když se dnes kouknu na zdrojáky a vidím tam ty křeče snažící se nahradit v C neexistující objektu, musím se smát. Dnes programuju v C++. Kód, který píšu je výhradně objektový. Mnohem víc používám generika a snažím se do kódu dodad mnoho abstrakce. Člověk se musí naučit myslet komponentně. Stejně tak jako velké systémy se skládají z mnoha komponent, i na úrovni zdrojáků máme komponenty, komponetíky a mikrokomponenty. Vše jsou to objekty, které spolu spolupracují, navzájem se oslovují, komunikují, posílají si zprávy (opět objekty) a starají se o svůj životní prostor. Vznikaji a zanikají, transformují se, žijí a dýchají. Každý má přitom své hřiště, sám si definuje protokol, jak komunikuje s ostatními. Všechno tohle funguje, aniž by řešilo chyby a výjimečné situace. Od toho jsou výjimky. Pokud komponenta (objekt) selže, vyhodí výjimku a o řešení chyby se postará nadřízený. Máte to jako v dobře fungující firmě, kde se problém, který nelze řešit na úrovni podřízených vyhazuje do vyšších pater. Občas se stává, že výjimka byla záměrná, jako když vám nadřízený dá úkol něco provést, vy mu ohlásíte, že jste selhal a on vám za to zvedne prémie (protože nadřízený potřeboval zjistit, že to nejde).
Tyhle všechny možnosti a výhody jsou podmíněny dobrým knihovním zázemím. Právě v tom je C++ nejslabší. STL bohužel (přes svojí rychlost) zdaleka nenabízí to co by člověk potřeboval. Naproti tomu Boost například je obrovský moloch, stejně tak jako QT a jiné systémy, snažící se tohle řešit. Java je v tomhle 100x lepší, stejně jako C# (zazlívám microsoftu, že místo aby podporoval C++, vymýšlí kraviny v podobě .NET frameworku a pak nám to cpe přes svůj marketing a kdejakého začátečníka tím zblbne).
V tomhle směru se i já snažím situaci zlepšit aspoň tím, že kolektuji po různu sesbírané objekty z různých projektů do knihovny "LightSpeed". Ani já však nemám patent na rozum. Vice na mém webu
http://bredy.novacisko.cz
http://bredy.novacisko.cz/?g=main&kat=17 (sekce C++)
Zkusim odpovedet na trochu vyssi urovni abstrakce:
Podle me slabost C++ v oblasti knihoven (kterou sam pripoustite) neni pricina toho, ze se v C++ mnohdy spatne pise, naopak je to dusledkem toho, ze C++ je striktne objektovy jazyk[*]. Vec se ma tak: navrhnout knihovnu (zejmena jeji rozhrani) je tezke (ve vsech jazycich). Jenze v objektovych jazycich je jednak tezsi refaktorizace (jakmile se vam vsude vecpe jisty objektovy model, tezko se prechazi na jiny), a jednak jeste navic je zde vetsi pervasivnost (jak se to rekne cesky – vlezlost?) knihoven – kdyz uz se rozhodnete pouzivat nejakou knihovnu, je temer nutnost prebrat i jeji model hlaseni chyb, alokace/dealokace objektu, atd. Coz obvykle znamena, ze na knihovne (i spatne navrzene, coz se holt stava ve vsech jazycich) je vas projekt daleko vice zavisly. Temer nejde „pouzit jen cast z knihovny“. Toto vnimam jako podstatny rozdil proceduralniho programovani (klidne i s objektovymi rysy) a striktne objektove orientovaneho programovani.
Dale: zapouzdrenim do objektu v podstate delate i lokalni „knihovny“ uvnitr sveho projektu. Opet – navrhnout spravne rozhrani je tezke, ne-li dopredu nemozne. Takze se dela to, ze si reknete „tak treba tohle bude trida/objekt, a radeji k nemu napiseme vsechny metody, ktere by nekdo mohl potrebovat. Nakonec to ale dopadne tak, ze z te tridy se ve velke vetsine pripadu pouzije akorat jeden konkretni konstruktor, jedna nebo dve metody volane presne tim stejnym zpusobem ze vsech mist kodu, a pak destruktor. V proceduralnim jazyce (nejlepe s nejakou agilni metodou programovani), byste tento kod psal az tehdy, az ho skutecne nejaka dalsi vrstva bude potrebovat.
Dalsi vec je (coz ale souvisi s fungovanim knihoven v OO jazycich), ze OO jazyky (a C++ zvlast) jsou daleko mene portabilni. Treba tady http://www.fi.muni.cz/~kas/blog/index.cgi/computers/cplusplus-woes.html pisu o tom, jak je tezke vzit i jen par mesicu stary program v C++ a zkompilovat ho ani ne na jine platforme, ale na novejsim systemu s novejsi verzi libstdc++ a hlavickovych souboru. Muzete namitnout „zbastleny program“, ale podle me je toto temer nevyhnutelny dusledek toho, ze ten program je v C++.
-Yenya
[*] Coz je do jiste miry eufemismus – striktne objektovy jazyk je treba ObjectiveC, ne C++.
Dovolte abych Vám vyvrátil nesmysly, které jste napsal… I když uznávám, že vycházejí ze zavedené praxe.
Jenze v objektovych jazycich je jednak tezsi refaktorizace (jakmile se vam vsude vecpe jisty objektovy model, tezko se prechazi na jiny)
Právě že objektový model je jen jeden a to ten nejzákladnější. Kdyby každý tvůrce kdejaké knihovny dodržoval to nejzákladnější, totiž aby samy objekty (třídy) vystupovali jako samostatné entity, v podstatě vám eliminuje Vámi uváděné problémy. Tohle vyplývá z toho, že valná většina programátorů neumí objekty používat, natož vytvářet.
kdyz uz se rozhodnete pouzivat nejakou knihovnu, je temer nutnost prebrat i jeji model hlaseni chyb, alokace/dealokace objektu
Tohle není problém C++, ale obecně všeho v C. Podívejte se ale třeba na Javu, ta má modely alokace, a hlášení chyb jednotné a dané jazykovou normou. Ale i v C++ máme tuhle možnost. Na svůj blog třeba teď dlouhou dobu chystám článek o strukturovaném výjimkové systému, mnohem lépe navrženém, než je std::exception. Jak už jsem psal, problém je právě v těch knihovnách… nejsou… Kdyby byly, všichni by je používali a uvedené problémy by se redukovali.
Co se alokačního modelu týče, tak C++ striktně nařizuje používat new a delete. Navíc by každý objekt měl být alokovatelný i automaticky (staticky). Že si různí programátoři dobrovolně tuhle možnost omezují, to už je jiná věc. Pokud už technické, či jiné důvody toto znemožňují (továrny na objekty), přesto není problém zařídit, aby uživatel objektů nemusel přejímat alokační model. Objekty zaalokuje knihovna, o uvolnění se postará virtuální destruktor.
. Temer nejde „pouzit jen cast z knihovny“. Toto vnimam jako podstatny rozdil proceduralniho programovani (klidne i s objektovymi rysy) a striktne objektove orientovaneho programovani.
Opět je to to co jsem kritizoval. V současné době BOOSTu, QT, MFC, ALT a jiných projektů opravdu nejde používat jen části knihoven, vina ale neleží na C++ ani na objektech, ale na tvůrcích. Z různých důvodů prostě tvůrci potřebují, aby jejich knihovna vystupovala jako černá skříňka. Může to být neschopnost, ale i marketingový tah. Tohle ale pokud vím je i problém C obecně, neomezuje se jen na C++. Já sám se snažím objekty navrhovat buď jako samostatně fungující objekty, nebo se stromovou závislostí.
Takze se dela to, ze si reknete „tak treba tohle bude trida/objekt, a radeji k nemu napiseme vsechny metody, ktere by nekdo mohl potrebovat. Nakonec to ale dopadne tak, ze z te tridy se ve velke vetsine pripadu pouzije akorat jeden konkretni konstruktor, jedna nebo dve metody volane presne tim stejnym zpusobem ze vsech mist kodu, a pak destruktor.
V tom bych ale neviděl problém, mnohem větším problémem je, že do tříd se časem dopisují metody, které tam nepatří. Programátoři si objekt pletou s knihovnou. Neumí si představit jednoduché relační vztahy. Napíšou objekt obsahující 10 kontejnerů a pro každý kontejner mají samostatnou sadu funkcí na rozhraníl. A neuvědomují si, že správnější přístup je mít metody spřístupňující kontejnery se stejným rozhraním. Objekty nejsou knihovny. objekty jsou malé částice programu, atomy. Mají základní rozhraní: vznikni, zanikni, udelej kopii, zjisti stav, nastav stav, případně něco spočítej. Cokoliv většiho už není objekt, ale bastl.
sou daleko mene portabilni.
Tohle považuji za JPP (Jedna paní povídala). Sám vyvíjím současně na dvou platformách … Linux a Windows a s portabilitou nejsou problémy. Určité odchylky lze najít až na úrovni šablon, občas některý překladač něco pochopí jinak, ale garantuji vám, že se jedná o extrabuřty, špeky a vychytávky. Furt je situace lepší, než třeba na poli kompatibility mezi www prohlížeči. Pokud mluvíme o OS platformách, tak to je jiná záležitost, tady si musí udělat jasno linuxáři. Windows je na tom s kompatibilitou o 100% lépe.
ale podle me je toto temer nevyhnutelny dusledek toho, ze ten program je v C++.
Nesuďte podle linuxu, navíc zaměňujete jazyk a OS platformu. Navíc popisované problémy bývají hlavně na úrovni C. Samotné C++ vč. STL mi přijde celkem dobře kompatibilní. Programy napsané v GCC 3.3 jdou dobře přeložit i v poslední verzi GCC, pokud to jsou programy komplet v C++ a nepoužívají třeba unistd. a další hlavičkové soubory.
U Boost i Qt lze používat jen část knihovny. Boost je na tom dokonce založen (je to kolekce knihoven, ne jedna knihovna) a Qt s tím dělením přišel poté, co přestal být jen GUI framework.
"In other words, the only way to do good, efficient, and system-level and
portable C++ ends up to limit yourself to all the things that are
basically available in C."
Důležité slovíčko, které jste zřejmě přehlédl :)
C++ není striktně obejktový jazyk a ani nechce být. C++ je multiparadigmický jazyk, převážně objektový a generický. Striktně objektový z něj dělají neznalí programátoři. Mimochodem generický (šablonový) program se daleko daleko jednodušeji refaktoruje než procedurální, daleko snáz se tam dělají unit testy (test driven development) a daleko méně duplicitního kódu je třeba napsat. To, že většina programátorů v C++ zná šablony jen jako STL, není chyba jazyka, ale příslušných programátorů.
Tohle zní skoro jako kdyby v objektovém jazyce nešlo programovat agilně a metody nešly přidělávat do objektů teprve ve chvíli, kdy je někdo opravdu potřebuje. To doufám nemyslíte vážně.
Ten program nebyl C++, ale bastl. memcpy není C++ konstrukce, C++ má std::copy, případně kopírovací konstruktor std::string. INT_MAX není C++ makro, C++ má std::numeric_limits<int>::max. A ano, ten program byl neuvěřitelně zbastlený, když předpokládal, že jeden hlavičkový soubor includuje jiné, což nezaručuje ani vámi vychvalované C (mimochodem všechny funkce, které vám nefungovaly, byly Céčkové, nic o problémech s STL tam není). Takže pokud chcete něco kritizovat, tak toho, kdo v C++ používá takové funkce a makra, která do C++ neptaří.
Ja bych to zkratil. C99/GNU99 jsou nejlepsi a C++ je jejich rozsireni, ktere vetsina lidi uziva jinak, nez bylo zamysleno, tudiz produkuji mess a proto se vraceji zpet k C bez rozsireni. Otazkou je, jak bylo puvodne C++ zamysleno, protoze jsem v nem nikdy nevidel tak cisty program, jako v cistem C.
proto se vraceji zpet k C bez rozsireni
To je nějaký výzkum?
Otazkou je, jak bylo puvodne C++ zamysleno, protoze jsem v nem nikdy nevidel tak cisty program, jako v cistem C.
Myslím, že po tomhle prohlášení není třeba v diskuzi pokračovat.
jeste si prisadim: neobjektovy kod v C je v drtive vetsine pripadu lepsi, nez objektovy kod v C++ a kod v PHP4 je stejnym zpusobem temer vzdy lepsi, nez kod v PHP5. Objekty jsou potreba mozna jen pro ty, kteri nedokazi programovat bez nich a to tak, jako je X server s Desktop Environment a kedit potreba pro ty, co nejsou schopni uzivat SHELL / vim a umi pouze klikat mysi a volit z nabidek. :-D
Jestli jste se nikdy nenaučil programovat objektově, tak zkuste hledat vinu jinde než v objektových jazycích. Mimochodem opravdoví programátoři písou programy v catu a Céčkařům se smějí :)
Ja jsem se naucil programovat objektove a venoval se tomu tolik let, az jsem dospel k tomu, ze uz ty objekty (= berlicky) vlastne ani nepotrebuji, protoze jsem zmenil svuj zpusob uvazovani nad zdrojovym kodem a teprve tim zacal psat bez objektu a lepe. Nejsem sam :)
"And limiting your project to C means that people
don't screw that up, and also means that you get a lot of programmers that
do actually understand low-level issues and don't screw things up with any
idiotic "object model" crap." Linus Torvalds
Linus není žádný bůh. Nezapomeň, že to je systémář a pohybuje se někde na úrovni assembleru. Jeho postoj chápu. Člověk, který napsal operační systém zřejmě bude nějak profesně deformovaný. Zároveň si ale nemyslím, že by jeho názor musel být rozhodujícím. Už kvůli tomu, že trend spíš jde ve směru objektového programování. Musíme si uvědomit, že OOP je relativně nová věc, praktické nasazení OOP je záležitost posledních 10 let, tedy lidi, co programovali před rokem 2000 výborně v C už nikdy pravděpodobně nepříjdou na chuť objektům.
Jinak OS se dá napsat i v objektovém programovacím jazyce… Už kvůli tomu, že ty výkonné systémové části se dají skrýt do objektů, postup při analýze je stejný, jako při návrhu objektů v jiných oborech (ať již jde o databáze, nebo řízení zalejvání kytiček).
C++ není nic jiného, než vylepšený C, kde spoustu věci za tebe udělá překladač sám, právě takové ty věci, které v C úděsně zdržují, komplikovaně řeší, nebo způsobují problémy s údržbou a chybovosti. Například díky používání std::string namísto const char * se Seznamu víceméně vyhnul problem s Buffer Overrun. Ten prostě v C++ nastat nemůže.
Linus se rozhodne nepohybuje na urovni assembleru. Jeho nazor na C++ je skutecne vysledkem letitych zkusenosti a neni sam. Obdobny postoj ma vetsina prispevatelu projektu GNU ci Linux Kernel. Nicmene onu citaci jsem vytahl z emailu o git – http://lwn.net/Articles/249460/
OOP nic noveho neni. Tak napr. 70. leta jazyk SmallTalk.
Namisto string::append uzivam str_append(), ktery pracuje se strukturou tak, jako to provadi STL. Obcas uziji treba i stringy z glib, protoze ta je pritomna na vetsine UNIX-like systemech. V C nejsou se stringy opravdu zadne problemy, jen zacatecnici si stezuji dokud je nenapadne zacit uzivat urcitou sadu funkci pro bezpecne programovani – vizte OpenBSD, aneb. nejbezpecnejsi system planety je cely napsan v C a ma 10 let pouze 2 zranitelnosti exploitovatelne pres remote. http://openbsd.org
… a ma *za* 10 let …
str_append(), ktery pracuje se strukturou tak, jako to provadi STL
Tak mi řekněte, jaký je rozdíl mezi vaší strukturou a objektem. Kromě jiného zápisu (a.append(…) vs str_append(a,…)) fakt, že se musíte postarat o inicializaci a deinicializaci struktury. C++ zařídí samo. Jak budete řešit wstring::append() a obecne basic_string<T>::append()?
Tak napr. 70. leta jazyk SmallTalk.
Bylo mi jasné, že mě budete chytat za slovo. Proto jsem mluvil o praktickém nasazení. Experimentování s objekty je prováděno už od Simuly, ale praktický význam… word wide nasazení, (k modelování objektů být zaveden mimo jiné jazyk UML… rok cca 1995…, tedy já jej používám jen okrajově), má teprve v posledních několika málo let (10-15).
Rozdil je v prehlednosti, vykonu a vrstvami pod tim. Ja pracuji s transparentni strukturou pomoci transparentnich funkci, nicmene v C++ malokdo vi, co STL vlastne provadi a je velmi slozite to vubec pochopit, protoze je to hack za hackem. K tomu pridejme pretizene operatory v kazde tride dle uvazeni konkretniho programatora rozsahleho skupinoveho projektu a jsme doma :) Sebelepsi dokumentace vysokou chybovost a spatnou portabilitu nesnizi :)
Append unicode znaku resim pres GString* g_string_append_unichar(GString *string, gunichar wc);
SmallTalk nema world-wide nasazeni? The language was first generally released as Smalltalk-80 and has been widely used since. ( http://en.wikipedia.org/wiki/Smalltalk http://www.smalltalk.org/main/ ) – napr. Xerox v nem tvoril jedno z prvnich GUI.
ORM pochazi z poloviny 70. let – http://en.wikipedia.org/wiki/Object_Role_Modeling a pak zde mame jeste podobne stare ER diagramy (prime predchudce UML).
Na zaklade uvedeneho jazyku Simula (resp. verze z 60. let) je objektum cca 50 let. 10-15 let zni spise jako reklama na Windows, kterym dle teto reklamy zacal cely pocitacovy svet, ale tim mne neoklamete :), zacatek meho sveta jsou prvni time-sharing operacni systemy, jako je UNIX.
Je to asi tak složité na pochopení jako strcat nebo printf. Žádné hacky tam nejsou (až na COW v std::string v GNU stdc++). Pokud šablony nechápete, obraťte se na dokumentaci od SGI, je tam detailně popsáno, co se tam děje.
To je potom prase ten programátor, že jeho třídy dělají neočekávané. Asi jako kdyby funkce strdup příslušný string dumpla do souboru na disk a v kopii toho stringu náhodně prohodila dva znaky.
A teď se schválně zkuste zeptat lidí, co programují KDE, ať máte pohled i ze strany lidí, co si C++ vybrali.
Nekorektni argumentace. Lidi od KDE si vybrali Qt, volba C++ pak uz byla logickym dusledkem – a kdyz se podivate jak se v Qt programuje (MOC a podobne), tak je jasne, ze volba nebyla kvuli objektovemu modelu C++, ale kvuli tomu, ze Qt z C++ diky MOC a souvisejicimu "macro hell" (abych pouzil neci termin z teto diskuse) dela docela pouzitelne programovaci prostredi.
-Yenya
V Qt je nějaké macro hell? Máš na mysli to jedno makro QT_CLASS, které slouží pro MOC? Mimochodem MOC vzniklo proto, že v době vzniku Qt nebyl žádný překladač, který by pořádně implementoval šablony. A do dneška se MOC drží už vlastně jen ze zvyku. V naprosté většině případů MOC vůbec není potřeba používat, je zahrabané někde dole a kdyby se všechna signálová volání přepsala do Boost Signals (a qt_cast na dynamic_cast apod.), fungovalo by to úplně stejně dobře a psalo by se v tom úplně stejně.
Cili jinymi slovy – mam pravdu v tom, ze Vase argumentace tim co a proc si vybrali vyvojari KDE je v tomto pripade irelevantni.
-Yenya
No není. Už v té době existovalo Motif, CDE a další a klidně si mohli vybrat to a vyhnout se C++. Což oni neudělali, zatímco vývojáři GNOME ano (a raději si vyvinuli vlastní toolkit). C++ skutečně byl jeden z důležitých důvodů, proč si vybrali Qt (viz zakládací zpráva):
A já si myslím, že je to přesně naopak, v C se toho dá pokazit daleko víc a hrozně blbě se takové chyby hledají:
Proc pouzivas memcpy() pro praci se stringy? :) :) :)
K tomu je urcen strncpy(), nicmene po nacerpani zkusenosti programatori preferuji napr.:
v C++ to vypada pro zmenu:
Tyto priklady jsou prilis trivialni – nelze z nich posoudit nic. Co se treba podivat jake nechutne hacky jsou ve wrapperech C socketu pro C++? Nebo spinavosti v GTK2 -> Gtkmm ? Linus ma pravdu a vi o cem mluvi.
V rozsahlem projektu jsou objekty pritezi a proto treba takovy Mozilla Firefox / Mozilla XUL / GIMP / OpenGL / Xorg X11 Server / Gnome / Linux jsou vsechny v C.
Implicitne predpokladam, ze C++ je oblibenejsi mezi uzivateli Windows, Objekty jsou skutecne jen ty berlicky, ktere maji pomoci programovat i lidem, nemajicim na to bunky, asi jako M$ chce, aby si uzivatel predstavil „Muj pocitac“ misto hard disku, dvd-vypalovacky, usb disku, etc. protoze by tomu nerozumel. Pokud se k tomu dostane uzivatel, ktery ale znalosti ma, pouze bude zmaten a iritovan kvuli nadmerne abstrakci.
Objekty usiluji o totez, je to myslenka vedouci M$ napr. k typedefum pro veskere standardni datove typy, kvuli kterym je programovani pro Windows hruza. Kdyz ji nekdo pretrpi, uz nechce zazit neco podobneho NIKDY vice a proto radeji zustava kvuli WinAPI u Windows.
A pak prisla jeste vetsi hruza – .NET :) Misto aby M$ C++ podporoval, chysta se od WinAPI *zcela* upustit a vsude mit jen .NET. Budoucnost C++ ve Windows neni svetla, budoucnost C v UNIX-like OS naopak je a vice zmrsene interfaces, nez v C++ vidime u M$ jen tak nenalezneme. Tam bych prave srovnaval kod, ne u trivialit pro praci se stringy, kde ji jeden jazyk ma built-in a druhy ji includuje z glib.
A co je tohle? Vždyť to jsou objekty (akorát tomu říkáte jinak). Konstruktor, nějaký výpis do proudu a destruktor. Navíc ten destruktor musíte volat explicitně (a myslet na to), což asi bude důvod, proč X.org Server neustále leakuje :)
Jakých wrapperech C soketů? Já několik wrapperů znám a ani jeden nemá žádné hacky, je to skutečně jen velmi tenký obal kolem POSIX socketů (konstruktor = open, read, write, select, destruktor = close) a není nejmenší problém takový program portovat třeba na Windows, protože stačí jen přepsat ten obal úplně vespod.
GTK je špinavé samo o sobě, je to objektově orientované programování v procedurálním jazyce a příšené macro hell (Qt ale neustálou alokací na haldě a úplně debilním garbage collectorem není o moc lepší).
A co třeba KDE, Sauerbraten (Cube), Skype nebo Google Earth, všechno v C++?
Jinak co se týče té vychvalované refaktorizace: chtěl jsem upravil aptitude, aby uměl pracovat s více než 65 535 balíčky, tak jsem změnil jeden typedef, který definoval typ pro ID balíčku. Víte, co se potom stalo? Vše se krásně zkompilovalo a aptitude po spuštění umřel na SIGSEGV. Prostě někde někdo nepočítal s tím, že by ten typedef mohl definovat něco jiného než 16-bitové číslo. Jó, to je ta perfektní refaktorizace. Zlaté objekty.
Jinak tím memcpy jsem chtěl ukázat krásný problém Céčka. Schválně jestli sis všiml, který to je (a který se v C++ – opravdovém C++, ne C++ s Céčkovým kódem – nevyskytuje).
To co jste teď ukázal, to jsou objekty. Opravdu, beze srandy. Objekty implementované technicky jinak, než v C++. Vy jste totiž do dnes nepochopil, co je to programování objektově. To není technická záležitost typu konstruktor a destruktor, nebo způsob syntaxtického zápisu. To je o myšlení. Uvádíte, jak jsou si příklady podobné. Asi vás možná překvapí, že výsledný překlad bude v obou případech velice podobný. Ano, i tady máte konstruktor „g_string_new“, volani metody „puts a str“ a destruktor „g_string_free“. Rozdil je v tom, ze zatimco, vy si musite hlidat zanik objektů ručně, C++ to udělá za vás samo. Dokonce bych si dokázal představit obalení GString jako C++ objekt.
No a teď mi napište, co shledáváte na tomhle objektu špatného, třeba oproti klasickému C. Kde je ta berlička, to co dělá nepřehledné. Naopak zde vidíte, že jako uživatel takového objektu nemusíte řešit jak spravovat paměť objektu. Vše je v režii objektu, ten si hlídá alokace a dealokace sám.
A to neuvažujeme třeba jako výhodu má nyní dědičnost, právě v možnosti přidat další funkcionalitu bez zásahu do originálního objektu. Neuvažuji už ani polymofizmus, který budete v C dělat velice obtížně.Ale jde to OOP pouze v C jsem viděl. C++ pouze usnadňuje psaní objektově. Řešení zániku objektu je pouze jedna z jeho automatických činností. Překladač za vás vyřeší často mnohem obtížnější věci, třeba inicializaci objektů při vícenásobné, nebo virtuální dědičnosti, volání virtuální funkcí přes ukazatel na funkci, virtuální destruktoru. Tyhle všechny automatické činnosti jsou už optimalizované s ohledem na cílovou platformu. Garantuji Vám, že ruční správa těchto činností v C v nejlepším případě vygeneruje stejně optimalizovaný výsledek (výjma nějakých extrabuřtů, težící z toho, že programátor má víc informací, než překladač)
Implicitne predpokladam, ze C++ je oblibenejsi mezi uzivateli Windows, Objekty jsou skutecne jen ty berlicky, ktere maji pomoci programovat i lidem, nemajicim na to bunky, asi jako M$ chce,…
Co takhle mi poslat kontakt na toho dealera, který vám prodal to pěkné zboží. Bejt takhle zhulenej se mi snad ještě nepovedlo.
***
C++ is a horrible language. It’s made more horrible by the fact that a lot
of substandard programmers use it, to the point where it’s much much
easier to generate total and utter crap with it. Quite frankly, even if
the choice of C were to do *nothing* but keep the C++ programmers out,
that in itself would be a huge reason to use C.
In other words: the choice of C is the only sane choice. I know Miles
Bader jokingly said „to piss you off“, but it’s actually true. I’ve come
to the conclusion that any programmer that would prefer the project to be
in C++ over C is likely a programmer that I really *would* prefer to piss
off, so that he doesn’t come and screw up any project I’m involved with.
————————————————————————-
Takove nesmysly jsem dlouho nevidel. Ovladam C i C++ – velke casti STL jsem narozdil od vas cetl a byl to jeden z duvodu, proc jsem zacal preferovat C. Zadny tenky kontejner v STL neni, je to hack za hackem a je to dobre videt i pri zkompmilovani STL s debug info a debuggingu vlastnich programu. Objekty zvladam jiz nejmene 10 let a narozdil od vas vim, co musi splnovat, aby se jim tak mohlo rikat. Funkce nejsou objekty. g_string_new() neni konstruktor ale funkce. g_string_free() neni destruktor, ale funkce. buf.str neni zadny proud (stream), ale struktura se clenem str, coz je pointer na znakove pole.
V C++ se pracuje se streamy, proto je MyGString pekne spinava pitomost, puts() je v C++ taktez prasarna, mel tam byt cout. Patlal co uzil chybne memcpy() samozrejme zapomnel v prvni rade, ze memcpy() slouzi k necemu jinemu, v druhe rade mel si vzpomenout na strncpy() – pokud by tomu rozumel – a terminovat retezec pres NUL char ‚