Bylo vydáno OpenBSD 7.7. Opět bez písničky.
V Tiraně proběhl letošní Linux App Summit (LAS) (Mastodon). Zatím nesestříhané videozáznamy přednášek jsou k dispozici na YouTube.
Na čem aktuálně pracují vývojáři GNOME a KDE Plasma? Pravidelný přehled novinek v Týden v GNOME a Týden v KDE Plasma.
Berkeley Humanoid Lite (Onshape, GitHub) je open source humanoidní robot. V amerických cenách jej lze sestavit do 5000 dolarů.
Jakub Jelínek oznámil vydání verze 15.1 (15.1.0) kolekce kompilátorů pro různé programovací jazyky GCC (GNU Compiler Collection). Jedná se o první stabilní verzi řady 15. Přehled změn, nových vlastností a oprav a aktualizovaná dokumentace na stránkách projektu. Některé zdrojové kódy, které bylo možné přeložit s předchozími verzemi GCC, bude nutné upravit.
Byly vyhlášeny výsledky letošní volby vedoucího projektu Debian (DPL, Wikipedie). Staronovým vedoucím zůstává Andreas Tille.
Jason Citron končí jako CEO Discordu. Od pondělí 28. dubna nastupuje nový CEO Humam Sakhnini, bývalý CSO Activision Blizzard.
Článek na Libre Arts představuje baskytarový multiefekt Anagram od společnosti Darkglass Electronics. S Linuxem uvnitř (licence, GitHub).
Městský soud v Praze vyhlásil rozsudek, který vyhověl žalobě novináře Jana Cibulky, který s podporou spolku IuRe (Iuridicum Remedium) požadoval omluvu od státu za to, že česká legislativa nařizuje operátorům uchovávat metadata o elektronické komunikaci. To je přitom v rozporu s právem. Stát se musí novináři omluvit a zaplatit náklady řízení. Především je ale součástí přelomové rozhodnutí o nelegálnosti shromažďování dat a o
… více »Americké technologické firmy Apple a Meta Platforms porušily pravidla na ochranu unijního trhu, uvedla včera Evropská komise (EK). Firmám proto vyměřila pokutu – Applu 500 milionů eur (12,5 miliardy Kč) a Metě 200 milionů eur (pět miliard Kč). Komise to oznámila v tiskové zprávě. Jde o první pokuty, které souvisejí s unijním nařízením o digitálních trzích (DMA). „Evropská komise zjistila, že Apple porušil povinnost vyplývající z nařízení
… více »val pozdrav = "nazdar pane"
//java post(new Runnable(... blabla //scala post(v = 1+1)V tomhle prikladu prekladac zkusi zkonvertovat vyraz v zavorkach na Runnable. Pokud se to nepovede, kompilace selze.
Tiskni
Sdílej:
A čo je na tom jazyku zaujímavé, okrem toho, že je to trochu vylepšená Java? Nevidím na ňom nič, čo by už nebolo inde a koncepčne lepšie. Za to na ňom vidím dosť, čo inde je a tu nie. Ale btw, proti vylepšenej Jave nič. Skutočne to nevyzerá zle a ak by sa časom všetka Java nahradila Scalou, ja by som bol len rád.
Na tohle by možná odpověděla série článků Java.Next, nicméně mnohem zajímavější (mně osobně) přijde Clojure.
Dík za článok. LISP nad jvm vyzerá skutočne zaujímavo. Ale btw, keď už sme pri tom, tak pre dynamické jazyky (akým LISP bezosporu je) by bol vhodnejší dynamický a nie statický virtuálny stroj, ktorý to vôbec neberie do úvahy a teda nemôže tak dobre optimalizovať, garbage collectovať, atď. Ale tak zatiaľ aspoň toto a o 10 rokov sa možno dočkáme hotového Parrota
Ona ani Java není neměnná a blýská se na lepší časy. Nalinkoval bych ten link od SUNů, jenže mi to z nějakého důvodu nejede :( Každopádně princip práce s proměnnými a schopnost lépe se vypořádat s paralelizací je asi to, co by mohlo přiklonit dost uživatelů na stranu LISPu nebo funkcionálních jazyků.. Ale kolem toho je celá řada jiných (a taky zajímavých) článků :)
Tiež mi to na prvý pohľad pripadá ako ďalšie C++ s myšlienkami odvšadiaľ možne, ale vlastne neprinášujúceho nič nové. Ale na rozdiel od prechodu C -> C++, kde nie je úplne zrejmé, že sa jedná o správny prechod (aspoň sa na tom ľudia v tej poslednej diskusii nezhodli), tak nahradením Javy v podstate ľubovoľným jazykom sa nedá nič pokaziť
Určite má ale patent na rossum
Lol, tak z teba by bol skvelý interpreter. Možno ťa uprednostním aj pred pythonom
Lenost jednoho bohužel znamená práci navíc pro mnohé.
Kdo se s tím zmrzačeným textem nechce trápit, ať to přožene přes CZACCENT – trochu se to zlepší.
Jinak článek hodnotím kladně – zajímavé čtení.
Na Vás už mysleli ľudia od smalltalku, to Vám musí stačiť
Scala nema closures, ale usporny zpusob zapisu annonymnich tridMimochodem, tohle je blbost. Každá javovská vnitřní třída vytváří téměř plnohodnotný lexikální uzávěr, u těch anonymních s omezením, že volné proměnné z definující metody musí být
final
(což je pouhý implementační detail vzniklý ze strachu (z) Céčkařů, původně tomu tak být nemělo), chybí akorát možnost nelokálního návratu. Kolem uzávěrů je příliš mnoho strachu, protože příliš mnoho lidí vlastně vůbec netuší, o co jde.
Rozumný zápis lambdy se samozřejmě hodí, ale nejsem si jistý, že to Scala se svým podtržítkem nějak vyhrála…
Proto, bohužel, prorokuju Scale růžovou budoucnostČili podle principu "worse is better" by měla uspět. Ale to by platilo za předpokladu, že i přesto tu komplikovanost se v ní dobře programuje. Což ovšem já nemůžu posoudit. Je otázkou, co ta Scala vlastně řeší. Třeba v C++ (jakožto v "C s třídami") se taky dobře programuje, když se to srovná s "objektovým programováním" v čistém C. Monstróznější typový systém Java asi nepotřebuje. Kdyby funkcionální rysy Scaly byly na takové úrovni, že by z toho vypadla automatická paralelizace ala Haskell, tak prosím. Ale tomu zas nevěřím
Ono, pri týchto runtime-enabled jazykoch nie je v podstate dôvod vyvíjať nejaký konkrétny jazyk (zvlášť taký historický bordel ako Java). Dospeli sme do bodu, kedy sa dajú pre vývoj ekvivalentne použiť rozmanité jazyk a môžu čerpať z obrovskej zásoby spoločných knižníc. A práve vďaka tomuto som si takmer istý, že jazyky, ktoré nie sú vhodné na vývoj odumrú a prežiju len tie najlepšie. Ideálna forma evolúcie. Pri tej záplave nových (a často niekoľkonásobné lepších) jazykov (JRuby, Clojure, Groovy, Scala, IronPython, javascript pre jvm) by som sa veľmi čudoval, keby si java udržala nejakú pozíciu
Výhody Javy jako platformy jsou jasné, ale i jako jazyk má Java něco do sebe – jednoduchost a snadnou čitelnost – on totiž fakt, že jí (podle někoho) leccos chybí, je zároveň výhodou – pasivně (číst cizí kód) se ten jazyk dá ovládnout velice rychle, narozdíl od jazyků, které nabízejí „více možností“ – aby člověk začal jazyk aktivně používat, začal nadšeně mastit svoje první prográmky ta široká nabídka možností nevadí, ale ve chvíli, kdy má číst kód po někom jiném, to už problém je.
Ako platformu by som to nevolal Java a tiež sa mi nepači, že stroj, na ktorom môže bežať ľubovoľný jazyk, sa volá Java Virtual Machine (hoci je pravda, že vznikol len pre potreby Javy a ako taký je na úlohu spoločnej základne dosť nevhodný. Chcelo by to nahradiť niečím úplne novým)
Ľahká čiteľnosť? public static void main? Hahaha, človeče, videli ste už aj nejaký iný jazyk okrem Javy? Java je, čo sa čitateľnosti týka, na tom ako jeden z najhorších jazykov. Možno horší už je len FORTRAN
Ovládnuť sa síce dá, ale je to jazyk slabý, nutí programátora písať nechutné množstvo boiler-platu, ktoré je niekoľkonásobne vyššie ako v iných jazykoch (to súvisí s tou čitateľnosťou), hrá sa na objektový jazyk, ale plne objektový nie je, nepodporuje kopu základných praktík, ktoré sú už desiatky rokov inde úplným štandardom (opäť to súvisí s tým písaním balastu).
Celkovo, jediný argument pre Javu bývala práve platforma, inak na nej nevidím ani jedinú pozitívnu vec, ale teraz, keď už je k dispozícií desiatky silných jazykov, ktoré sú pred javou o dve generácie napred, nevidím pre Javu moc nádej
Je to přesně naopak – „ukecanější“ kód neznamená méně srozumitelný kód.
Analogií budiž přirozené jazyky – představ si jazyk jehož slovní zásoba je 5000 slov. Abys rozuměl lidem mluvícím v tomto jazyce, stačí ti naučit se 5000 slov. Některé věci je potřeba popsat více slovy, takže věty jsou delší, ale jazyk jsi se naučil rychle a nezapomínáš ho, protože ta slova používáš často a většinu (všechna) z nich. A představ si jiný jazyk, který má 50 000 slov. Mluvit se s ním naučíš podobně rychle (nacvičíš si pár frází, pár slovíček), ale abys rozuměl ostatním, musíš znát mnohem více slov (50 000 místo 5000), protože člověk mluvící tímto jazykem může použít kterékoli slovo z těch 50 000 (i když ty ho aktivně nepoužíváš). Jasně, v takovém jazyce se dají tvořit „efektivnější“ (nebo spíš efektnější?) věty složené z méně slov. Jelikož většinu té slovní zásoby nepoužíváš aktivně a některá slova jsi viděl jen ve škole (resp. v učebnici programovacího jazyka), nejseš si v tom jazyce moc jistý, některé konstrukce zapomínáš, protože se s nimi téměř nesetkáváš – v důsledku pak průměrný programátor v takovém jazyce bude dělat více chyb a jeho práce bude méně efektivní.
A že nejsi průměrný programátor ale l33t vývojář? Klidně si v nějakém komplikovaném jazyce piš, ale sám, svoje projekty. Až budeš potřebovat pracovat v týmu a dělat skutečný užitečný software (ne jen exhibici svého „umění“), pravděpodobně budeš muset používat jednodušší jazyk, kterému rozumí i ti obyčejní programátoři. Proč? Protože vždycky jde o peníze, resp. o poměr užitku daného SW a nákladů, které je potřeba vynaložit na jeho vývoj a úpravy. Zákazníka zajímá, co mu software přinese a kolik budou stát vývojáři – ne to, jestli ten kód je „krásný“ a jestli je na X řádků místno na 1,5*X řádků.
Říká se, že mírně pokročilý programátor využívá všemožné konstrukce daného jazyka, i ty méně obvyklé a méně užitečné, už jen proto, aby předvedl, že se je právě naučil. Zatímco zkušený programátor píše kód dostatečně výmluvný a jednoduchý, aby mu rozuměli i jeho hloupější kolegové.
public static void main? Co je na tom špatně? To budeme hodnotit jazyky podle toho, na kolik řádků se v nich dá napsat „Hello World!“? Nějaký vstupní bod v programu být musí, nějakým příkazem (procedurou) se ten program musí spustit a pak už tam žijí objekty a volají si svoje metody. Nebo ti vadí příliš mnoho klíčových slov (3 – public, static, void)? Java má klíčových slov možných konstrukcí v kódu relativně málo, proto je srozumitelnější.
S tým súhlasím. Ničmenej je ukecanejší kód na jednej strane a je kód plný zbytočného boiler-platu na strane druhej, ktorý len zneprehľadňuje čitateľnosť
Ak by som chcel použiť Vašu analógiu, tak Java aj ostatné jazyky majú zhruba rovnakú slovnú zásobu, ale Java Vás núti sa vyjadrovať dlhými vetami na miestach, kde by stačilo jedno slovo Namiesto toho, aby som povedal "Áno, chcem to", musím v Jave povedať "môj názor je taký, že potreba toho objektu je mojou osobou vyžadovaná, a teda dospievam k záveru, že s danou myšlienkou súhlasím"
Nesúhlasím s tým, že Java je finálnym slovom v obore jazyku pre "blbých". Podľa mňa je to proste tak, že Java sa rozšírila vďaka reklame a masívnej podpore a na jej mieste by mohol stáť v podstate ľubovoľný iný jazyk. Zopakujem to znova: Java nemá žiadne zaujímavé vlastnosti, ktoré by z nej robili dobrý jazyk pre hociko (nie len pre hackerov, ale ani pre cvičené opice). Lebo cvičené opice jazyk tak či tak nepochopia, takže je prakticky jedno, ako bude daný jazyk vyzerať.
To je samozrejme možné. Ja o kóde pre predvádzanie nehovorím. Ale ešte raz to zopakujem: je rozdiel medzi jednoduchším kódom a kódom plným balastu ako v Jave, ktorí si Java fanatici zvykli (či už z neznalosti iných jazykov, alebo iných dôvodov) obhajovať ako ultimátny nástroj pre výuku jazyka a písanie programov "pre blbých"
Nejde len o Hello World programy. A podobného balastu ako je public static main (mimochodom, úplne nepotrebné kvalifikátory, ktoré v rozumných jazykoch nenájdete a je to objektívne len relikt C++) v Jave strašne veľa, či už je to ručné definovanie accessorov pre triedy (ktoré v rozumných jazykoch opäť nie je vôbec potrebné, je kompletne automatické a obrovsky to zvyšuje čitateľnosť), boxovanie objektov (opäť úplná zbytočnosť kvôli zlému návrhu Javy ako "objektového jazyka", pričom nie je objekt ako objekt), alebo z kopy ďalších dôvodov, ktoré sa mi tu nechce vypisovať, lebo boli rozobraté už miliónkrát a každému znalcovi jazykov bijú do očí pri pohľade na ľubovoľný java kód Ľubovoľný program, ktorý mi v Jave napíšete, Vám napíšem 2x kratší a _zrozumiteľnejší_ (myslieť si, že dlhšiemu programu sa a priori ľahšie rozumie, mi pripadá hodne ujeté
).
Java nie je zrozumiteľný jazyk. Kým si nevyskúšate 10 ďalších jazykov na trhu a objektívne ich neporovnáte, tak sa s Vami nemá zmysel baviť A myslím to skutočne objektívne, ja proti žiadnemu jazyku a priori nič nemám, odpor získam len vďaka tomu, ako dobre/zle sa v danom jazyku programuje. Java je na tom mizerne.
Dobrý bože!
Ja? To snáď ani nie, pokojne ma volajte Marek
A podobného balastu ako je public static main (mimochodom, úplne nepotrebné kvalifikátory, ktoré v rozumných jazykoch nenájdete a je to objektívne len relikt C++) v Jave strašne veľaCo vám na tom pořád vadí? jedna z mála věcí, která vadí na syntaxi Javy mně, je „package protected“ modifikátor, který nemá žádné klíčové slovo. Nikdy pak nevím, jestli programátor jenom zapomněl nějaký modifikátor uvést, nebo myslel opravdu „package protected“.
Java nie je zrozumiteľný jazyk. Kým si nevyskúšate 10 ďalších jazykov na trhu a objektívne ich neporovnáteKterých 10 myslíte? C, C++, Clipper, JavaScript, Groovy, Pascal, Perl, PHP, Python k takovému zjištění evidentně nestačí.
Vadí nie je to správne slovo. Proste som na to len poukázal. Ale ak sa pýtate v čom je problém, tak v tom, že Java vyžaduje veľa balastu tam, kde ho vôbec netreba. Možno Vás baví písať kopu zbytočného kódu len preto, aby ste uspokojili kompilátor, ale ja sa bez toho zaobídem.
Napríklad tie, aspoň niečo. Hoci keby ste prihodili Ruby, Haskell, Forth, Smalltalk, LISP, FORTRAN, Prolog tak by bol ten zoznam trochu úplnejší -- proste pokiaľ možno, tak všetky zaujímavé prístupy k programovaniu, ktoré sú k dispozícii. Ničmenej, aj to, čo ste vymenovali, by Vám malo stačiť, aby ste boli schopný objektívne porovnať, že Java potrebuje kopu boiler-platu.
Vadí nie je to správne slovo. Proste som na to len poukázal. Ale ak sa pýtate v čom je problém, tak v tom, že Java vyžaduje veľa balastu tam, kde ho vôbec netreba. Možno Vás baví písať kopu zbytočného kódu len preto, aby ste uspokojili kompilátor, ale ja sa bez toho zaobídem.Co konkrétně je na
public static void
deklaraci za balast? Modifikátor přístupu nějak vyjádřit musíte (pokud chcete mít objektové zapouzdření), statické metody od instančních také nějak odlišit musíte, návratovou hodnotu void
by teoreticky bylo možné vynechat, ale když programátor ví, že nechce vracet žádnou návratovou hodnotu, je rozumné, když tuhle myšlenku napíše i do kódu. Různé defaulty jsou sice vhodné pro kompilátor, který je doplní snadno, ale pro člověka je lepší explicitně danou věc uvést.
Napríklad tie, aspoň niečo. Hoci keby ste prihodili Ruby, Haskell, Forth, Smalltalk, LISP, FORTRAN, Prolog tak by bol ten zoznam trochu úplnejší -- proste pokiaľ možno, tak všetky zaujímavé prístupy k programovaniu, ktoré sú k dispozícii. Ničmenej, aj to, čo ste vymenovali, by Vám malo stačiť, aby ste boli schopný objektívne porovnať, že Java potrebuje kopu boiler-platu.Nevidím žádný důvod k tomu porovnávat jazyk pro objektové procedurální programování třeba s funkcionálními jazyky. Co z toho vyjde? Akorát zjištění, že Java jako funkcionální programovací jazyk je špatná. Což ale není žádné překvapení… To, co jsem vyjmenoval, jsou všechno jazyky, se kterými se mi pracuje (někdy podstatně) hůř, než s Javou. C bych ještě použil na „nízkoúrovňové“ programování (když mám danou strukturu dat v paměti bajt po bajtu, těžko na to najdu lepší nástroj, než C), ale zbytek – u C++ si nikdy nemůžu být jist tím, co ten kód doopravdy dělá; u Perlu budu s každým novým programem překvapen, že se to dá napsat i takhle; u PHP zjistím, že mnohé pokusy o oddělení HTML a kódu mohou být ještě větší guláš, než kód a HTML naprasené v jednom; u JavaScriptu si můžu být skoro jist, že programátorovi byly jeho funkcionální vlastnosti na obtíž, a že zasviní globální jmenný prostor. Java je sice ukecaná, ale to vede akorát k lepší čitelnosti – člověk dobře vnímá opakující se vzory, takže
public static void main
vnímá jako jeden vzor, rozhodně to čtení a pochopení programu nezesložiťuje.
u JavaScriptu si můžu být skoro jist, že programátorovi byly jeho funkcionální vlastnosti na obtíž, a že zasviní globální jmenný prostor.
A jak by to mělo vypadat „správně“? Osobně mi tenhle jazyk moc nesedí a snažím se jeho použití minimalizovat. Ale možná v tom jde psát i slušný kód.
A jak by to mělo vypadat „správně“? Osobně mi tenhle jazyk moc nesedí a snažím se jeho použití minimalizovat. Ale možná v tom jde psát i slušný kód.Asi to nedokážu moc dobře popsat, protože moc dobře přemýšlet „v JavaScriptu“ taky neumím, takže sice odhadnu, že se mi něco nezdá, ale vymyslet, jak to má být správně, už tak snadné není. Navíc si myslím, že JavaScript jako jazyk pro internetový prohlížeč nebyl zvolen šťastně. Ale co se týká třeba funkcionálních vlastností, typické je, že ovladač události je nějaká funkce, která teprve v okamžiku vyvolání začne zjišťovat, kdo ji vlastně vyvolal a začne si odněkud (často z globálního jmenného prostoru) sbírat data, se kterými bude pracovat. „Správnější“ je podle mne ta data přibalit k funkci rovnou v okamžiku vytvoření, protože pak se ušetří čas při volání té funkce (může začít rovnou pracovat, nemusí nejprve posbírat data). S globálním prostorem je to snad zřejmé, místo ukládání spousty proměnných na top-level úrovni si tam vytvořit jeden objekt, a v něm mít vlastnosti – a to jedině v případě, kdy ten objekt na globální úrovni opravdu potřebuju (což vede zase zpět k přibalení datům přímo k funkci místo jejich odložení někde v globálním jmenném prostoru).
ovladač události je nějaká funkce, která teprve v okamžiku vyvolání začne zjišťovat, kdo ji vlastně vyvolal a začne si odněkud (často z globálního jmenného prostoru) sbírat data, se kterými bude pracovat. „Správnější“ je podle mne ta data přibalit k funkci rovnou v okamžiku vytvořeníTa data v okamžiku vytvoření funkce nemusí vůbec existovat, případně se mezitím mohou změnit. Správně by je měla ta funkce dostat co parametry. Není-li to možné, samozřejmě je musí odněkud získat. Globální jmenný prostor mají snad všechny jazyky, Javu nevyjímaje, některé z nich (napadají mě teď JavaScript nebo Lua) jenom nedefinují jeho strukturování.
Ta data v okamžiku vytvoření funkce nemusí vůbec existovat, případně se mezitím mohou změnit. Správně by je měla ta funkce dostat co parametry.Ta data při vytvoření funkce v drtivé většině případů existují – nezapomínejte, že nemusí jít o konkrétní hodnoty, ale mohou to být reference.
Globální jmenný prostor mají snad všechny jazyky, Javu nevyjímaje, některé z nich (napadají mě teď JavaScript nebo Lua) jenom nedefinují jeho strukturování.Nepsal jsem nic proti globálnímu jmennému prostoru, ale o jeho bezdůvodném zanášení všemožným odpadem, který tam vůbec nepatří.
Ta data při vytvoření funkce v drtivé většině případů existujíJasně, třeba když se získávají asynchronním voláním
nezapomínejte, že nemusí jít o konkrétní hodnoty, ale mohou to být referencePřípadně reference na referenci. Případně funkce, která ta data získá. A tak. Nezapomínejte, že v dynamickém jazyce se kdykoliv cokoliv může změnit
jeho bezdůvodném zanášení všemožným odpademJo, to se bohužel občas stává a je to na hlavu. Holt někteří programátoři v JavaScriptu vlastně nejsou vůbec programátoři. Ale to se stává i v lepších rodinách.
Nezapomínejte, že v dynamickém jazyce se kdykoliv cokoliv může změnit
Proto jsou tak (ne)oblíbené
Správně by je měla ta funkce dostat co parametry.
Jenže ta funkce bývá často volána z onclick
události nějakého elementu – v takovém případě by to znamenalo, nacpat tyto parametry do atributu elementu a ten je použije při volání oné funkce. To vyžaduje, abychom tyto parametry znali v době generování HTML nebo práci s DOMem (když atributy elementů nastavujeme dynamicky javascriptem). Pak je výhodnější, když si funkce bere proměnné z „globálního“ kontextu než když je dostává jako parametry. I když souhlasím, že je asi lepší ty proměnné zabalit do nějakého jednoho objektu, přes který se k nim přistupuje a ne mít desítky proměnných na nejvyšší úrovni globálního kontextu.
Presne tak. To, že sa dá prasiť, ešte neznamená, že sa musí prasiť
Jak? Rád se něčemu přiučím V současnosti používám
onclick
u tlačítek, odkazů a některých dalších elementů. Volají se tím ajaxové akce a následně se mění DOM stránky (zobrazuje se výsledek).
Ten onclick
atribut se v některých případech vytváří už na serveru, většinou se ale dogeneruje až u klienta JavaScriptem.
(přístupnost mě v tomhle případě nezajímá, bez plnohodnotného prohlížeče s JavaScriptem je ta aplikace ze své podstaty nepoužitelná).
addEventListener()
/removeEventListener()
(W3C) resp. attachEvent()
/detachEvent()
(MSIE).
Takže místo třeba:
radky[i].childNodes[1].onclick = function() { zobraz(this.innerHTML, 'vstupniPole'); return true; };
napíšu tohle:
radky[i].childNodes[1].addEventListener("click", function () { zobraz(this.innerHTML, 'vstupniPole'); return true; }, true);
Výhoda je v tom, že těch posluchačů tam můžu nasázet víc, ale jinak mi přijde, že to vypadá stejně a chová se stejně.
Pak tam mám ještě kus kódu, kde generuji HTML na serveru v Javě a onclick
atribut zadávám jako text (resp. org.w3c.dom.Element.setAttribute()
) a tam se toho asi moc vymyslet nedá.
<button id="b1">+1</button> <button id="b2">-1</button> <br/> <span id="result"></span> <script> function createButton(id, number, resultID) { var resultElement = document.getElementById(resultID); var func = function() { createButton.number += number; resultElement.innerHTML = createButton.number; } document.getElementById(id).addEventListener("click", func, true); } createButton.number = 0; createButton("b1", 1, "result"); createButton("b2", -1, "result"); </script>
Odporúčam Vám naštudovať si niečo o uzáveroch a lexical scope (nenapadá ma teraz preklad), kým začnete posudzovať funkcionálny jazyk. A Váš názor na to, čo je správnejšie sa opäť odvíja od toho, že nemáte skúsenosti s rôznymi jazykmi
V Jave sa globálnym premenných snaží dobrý programátor vyhnúť ako čert krížu. Ostatne, ako v každom jazyku. Sú samozrejme výnimky, ako pri každom pravidle, kedy je použitie globálnej úrovne správne.
Odporúčam Vám naštudovať si niečo o uzáveroch a lexical scope (nenapadá ma teraz preklad), kým začnete posudzovať funkcionálny jazyk. A Váš názor na to, čo je správnejšie sa opäť odvíja od toho, že nemáte skúsenosti s rôznymi jazykmiJá neposuzuji funkcionální jazyk jako takový, já posuzuju jeho (ne)vhodnost pro nasazení jako skriptovacího jazyka pro internetové prohlížeče.
Dá sa v tom naozaj písať veľmi slušný kód. Je to plne funkcionálny a OOP jazyk, takže rôzne zapuzdrenia (hlavne funkcionálne pomocou uzáverov) nie sú problémom. Problémom je to, že ten jazyk je považovaný za úbohý skriptovací jazyk. Odporúčam, ak si nájdete čas sa mu trochu pozrieť na zúbok, mnohonásobne sa to vráti (jednak pri samotnej práci s jazykom, jednak pre rozšírenie programátorských obzorov). Minimalizovanie použitia užitočných vecí z neznalosti by bola trochu škoda.
Ta funkcionální část má něco do sebe (i když i bez ní se dá spokojeně žít), ale obávám se, že nepřekonám svůj odpor k jeho slabému dynamickému typování – to podle mého přináší akorát chaos a je potenciálním zdrojem chyb v programu.
Jasně, silné statické typování není všelékem, ale spousta chyb díky němu vůbec nevznikne.
Pořád je na tom líp než C/C++ a je v tomto ohledu přinejmenším vyhovující.
null
, možná ještě něco, co mne teď v rychlosti nenapadá), ale nevidím důvod, proč ho neoznačit za silný.
S tým sa dá súhlasiť a v tejto oblasti mi Java tiež v podstate nevadí. Ničmenej, silný statický jazyk (ako ukazuje moderný vývoj) potrebuje type inference a ďalšie veci, aby bol prakticky použiteľný, takže v tomto zmysle je Java veľmi primitívna.
null
se snad šířit nemusím, Java nerozlišuje nullable a non-nullable typy, takže ti klidně umožní udělat chybu, která se projeví až za běhu (NPE). Přitom tohle lze ošetřit staticky.
Kovariantní pole: String[]
je podtypem Object[]
(kovariantní změna typu prvku zachovává podtyp, i když by neměla), což vede k možnosti udělat tohle:
public class Array { private static void test(Object[] array) { array[0] = new Object(); } public static void main(String[] args) { String[] array = new String[] { "a", "b", "c" }; test(array); for (String str : array) { System.out.println(str.toUpperCase()); } } }Taky lze zachytit při kompilaci. Ternární operátor, to je trošku historie, od Javy 5 to funguje, ale v Javě 1.4 dostaneš při kompilaci zdrojáku
interface A { void a(); } interface B extends A { void b(); } interface C extends A { void c(); } class BI implements B { public void a (){} public void b(){} } class CI implements C { public void a (){} public void c(){} } public class Ternary { public static void main(String[] args) { A a = true ? new BI() : new CI(); } }chybu
Ternary.java:10: incompatible types for ?: neither is a subtype of the other second operand: BI third operand : CI A a = true ? new BI() : new CI();To, pravda, není díra v typovém systému, spíš jeho impotence, ale zvláštní
String[] a = new String[0];vytvářet
Array<String> a = new Array<String>(0, String.class);Jenže kdy vznikla v Javě pole a kdy generiky…
new Array<String>(0, String.class)
by ještě líp mělo být new Array<String>(0)
, typové parametry by měly být zachovány. A mělo by být možné udělat new T()
, jako třeba v C#.
Javovská pole a primitivní typy jsou relikt minulosti, ale taky jsou užitečné pro programy, kde záleží na výkonu. A vztah generiků a polí je vůbec děsivý
Javovská pole a primitivní typy jsou relikt minulosti
Obávám se, že kdyby v Javě pole nebyla, našlo by se mnohem víc lidí, kteří by remcali, jaký je to hloupý jazyk, když nemá tak základní věc, jako jsou pole. Když tu jsou, tak je to pro některé přebytečný balast – ale takových lidí je naštěstí málo Nikdy se nejde zavděčit všem.
Array
na efektivní pole a Integer
na efektivní int
by mohl umět kompilátor (i když by to pak znamenalo, že by bylo ještě víc magických objektů, které potřebují podporu kompilátoru).
Je to balast, ale pozrite sa na poriadny objektový jazyk (Python má ako tak dobré objekty, ale plne objektové jazyky sú Ruby, Smalltalk, javascript, Self, CLOS v niektorých LISPoch), že sa bez toho dá zaobísť
Sú dobré minimálne na to, aby človeku rozšírili obzory. Navyše funkcionálne a OOP programovanie hrajú pekne dokopy (jedna možnosť realizácie objektov je cez uzávery) a ako hovoríte Java je funkcionálne špatná. Čo nie je vskutku žiadne prekvapenie. A navyše, Java je vôbec špatný jazyk (úbohé OOP, opäť Vás odkážem na horemenované jazyky), ale to už mnohých ľudí prekvapuje.
Tým, že vymenujete tie horšie jazyky sa z toho nevysekáte (hoci Perl, podobne ako javascript je často podceňovaný a nikto s nimi nevie poriadne pracovať) Ale písali ste, že poznáte python, takže si to porovnajte s ním, ten má výhod oproti Jave neúrekom.
Javascript nič nesviní, ale je mi jasné, že by ste to zasvinili Vy, lebo zjavne vôbec netušíte, čo je to za jazyk (tipujem, že tak ako 99% programátorov ho máte za úbohý skriptovací jazyk pre DOM). V skutočnosti sa jedná o veľmi silný plne funkcionálny a OOP jazyk.
U mňa to kopa balastu jednak zozložiťuje tým, že je úplne zbytočná (pohľad na to, čo je zbytočné ale silne závisí od obzoru programátora. Je mi jasné, že prakticky výlučne na Javu sa orientujúci toto nepochopí) a navyše ten balast musím pokaždé furt a znova písať a svoj čas si viem naozaj predstaviť aj lepšie ako písať balast
Pripomeniem svoju pätičku, ktorá tu svietila dva roky: "Syntactic sugar causes cancer of the semicolon" Ale inak áno, máš samozrejme pravdu. Na tak extrémne používané veci -- ako sú lambdy vo funkcionálnych jazykoch -- musí existovať pekná syntax; na tom sa určite zhodneme.
Je to balast, ale pozrite sa na poriadny objektový jazyk (Python má ako tak dobré objekty, ale plne objektové jazyky sú Ruby, Smalltalk, javascript, Self, CLOS v niektorých LISPoch), že sa bez toho dá zaobísťZáleží na tom, čemu říkáte „plně objektové“ jazyky. Pokud myslíte to, že je v nich všechno objekt, pak máte pravdu. Ale některé ty zmíněné jazyky nemají třeba zapouzdření nebo třídní dědičnost, což se hodí třeba pro modulární programování.
Navyše funkcionálne a OOP programovanie hrajú pekne dokopyCož ještě neznamená, že to musíme všechno zmatlat do jednoho jazyka jako když pejsek a kočička vařili dort.
Javascript nič nesviní, ale je mi jasné, že by ste to zasvinili Vy, lebo zjavne vôbec netušíte, čo je to za jazyk (tipujem, že tak ako 99% programátorov ho máte za úbohý skriptovací jazyk pre DOM). V skutočnosti sa jedná o veľmi silný plne funkcionálny a OOP jazyk.Kdybych to netušil, tak asi nepíšu o tom, že ho většina programátorů neumí používat.
A navyše, Java je vôbec špatný jazyk (úbohé OOP, opäť Vás odkážem na horemenované jazyky), ale to už mnohých ľudí prekvapuje.Zatím pořád to vypadá, jaký jste odborník, a že stačí házet odkazy a my obyčejní smrtelníci si to máme dostudovat. Co takhle kdybyste se alespoň pro jednou snížil na naši úroveň, a napsal, v čem je lepší prototypová dědičnost než třídní dědičnost, proč je v OOP zbytečné zapouzdření a chráněný přístup nebo proč je dobré kombinovat objketový a funkcionální přístup v jednom jazyce.
U mňa to kopa balastu jednak zozložiťuje tým, že je úplne zbytočná (pohľad na to, čo je zbytočné ale silne závisí od obzoru programátora. Je mi jasné, že prakticky výlučne na Javu sa orientujúci toto nepochopí)Zkuste napsat, jak to může vypadat bez něj. Já se pak zkusím překonat a pochopit to.
navyše ten balast musím pokaždé furt a znova písať a svoj čas si viem naozaj predstaviť aj lepšie ako písať balastPro programátory, kteří kód jednou napíšou a pak už ho nikdy nečtou to je možná dobrý argument, ale to bude v drtivé většině případ pouze programů, které se po napsání zahodí. Ostatní programátoři si pak snad umí nakonfigurovat editor tak, aby jim v něm fungovalo doplňování a šablony.
Záleží na tom, čemu říkáte „plně objektové“ jazyky. Pokud myslíte to, že je v nich všechno objekt, pak máte pravdu. Ale některé ty zmíněné jazyky nemají třeba zapouzdření nebo třídní dědičnost, což se hodí třeba pro modulární programování.
Jako třeba Self? On je dost velký rozdíl mezi tím, jak si běžně představuje zapouzdření javista, a tím, co ve skutečnosti je. Základem objektově orientovaného programování je polymorfismus, zapouzdření a případně nějaká forma sdíleného chování. Objekt je velice mocná abstrakce, protože každný jednotlivý objekt má výpočetní sílu celého počítače. Má svůj stav a jen on sám rohzoduje o tom, jak se bude chovat navenek ke svému okolí. To je zapouzdření. V Selfu jsou objekty zapouzdřeny i samy před sebou (to má v praxi tu výhodu, že když se rozhodnete změnit datovou položku objektu za metodu, nemusíte jinde změnit ani čárku kódu). Polymorfismus znamená, že s různými objekty můžete zacházet stejně a díky sdílenému chování nemusíte psát implementaci pro každý konkrétní objekt zvlášť.
Zatím pořád to vypadá, jaký jste odborník, a že stačí házet odkazy a my obyčejní smrtelníci si to máme dostudovat. Co takhle kdybyste se alespoň pro jednou snížil na naši úroveň, a napsal, v čem je lepší prototypová dědičnost než třídní dědičnost, proč je v OOP zbytečné zapouzdření a chráněný přístup nebo proč je dobré kombinovat objketový a funkcionální přístup v jednom jazyce.
Prototypová dědičnost má řadu nesporných výhod. Ne všechny jsou vidět v JavaScriptu, který ji má poměrně omezenou. S její pomocí dokážete elegantně plně nahradit třídní dědičnost, násobnou dědičnost, rozhraní, jmenné prostory, uzávěry atd. Můžete tak získat velice mocný jazyk a přitom velmi jednoduchý.
V OOP zapouzdření zbytečné není, naopak je to jeho základní koncept. Chráněný přístup je jen berlička a osobně si nevzpomínám na případ, kdy by jeho absence byla na škodu. Ale vzpomínám si na řadu situací, kdy tomu bylo právě naopak.
Objekty leze plně nahradit uzávěry a naopak uzávěry lze plně nahradit objekty. Tyto dva přístupy nejsou v rozporu a dobře navržený jazyk je může využívat oba bez toho, aby výsledek působil nějak křečovitě.
Samozrejme, že všetky uvedené jazyky majú k OOP rôzny prístup (a to je dobré pre rozšírenie obzorov), ničmenej, majú veľa vecí spoločných, ktoré sú nutné pre to, čo OOP skutočne je -- nech je to čokoľvek a bez ohľadu na konkrétnu realizáciu objektu, alebo dokonca to, či nejaké objekty máme. Ale CLOS by niektorí možno ani nevolali OOP ako skôr generické metódy, takže tie objekty by mali byť základ + enkapsulácia (v ľubovoľnej forme, nemusí byť na prvý pohľad vidieť) + posielanie správ + dynamickosť/late-binding (o tomto trochu viac neskôr). Ničmenej, Java v mnohých z týchto ohľadov zaostáva (prípadne ich vôbec nepodporuje). Opäť, nebudem vypisovať všetko, čo už bolo 100x povedané, nemá to cenu. Na internete je toho neúrekom, stačí si zadať niečo ako "Is Java OOP?" a začať sa dovzdelávať.
Btw, ak chcete na rýchlo nejaké podnety na zamyslenie, tak jednou z charakteristík poriadneho OOP jazyka je to, že je dynamický (o tomto sme sa bavili už s Ladíčkom inde a tam som práve zaujímal opačný názor, že OOP by sa mohlo dať robiť aj staticky, ničmenej nie v dnešnej dobe a už rozhodne nie ako Java), lebo to umožňuje meniť triedy za behu a pod. V Jave toto postupne pridali pomocou reflection hackov, ale je to úplne inde ako napríklad Smalltalk, alebo Ruby, kde si s objektom, či triedou (čo je tiež objekt) môžete za behu robiť, čo Vás napadne (to súvisí s tým, že všetko je objekt, viď ďalší odstavec. Inak to musíte len hackovať, nie je inej cesty).
Ďalej Java nie je čistým (skôr by sa mohlo povedať, že je extrémne špinavým) OOP, pretože (zďaleka) nie všetko je objekt. A hoci na prvý pohľad sa môže zdať, že ide len o int, string, a pod., tak v skutočnosti sa jedná ešte o funkcie, triedy a po chvílke premýšľania človek príde na to, že Java je kopa syntaktického bordelu bez jednotnej štruktúry (IMHO opäť relikt C++) a triedy sú na ňu len dopasované (podobne ako sú len dopasované do C++, ale je pravda, že Java je viac OOP ako C++).
No, jak sa to vezme. Na jednu stranu máte pravdu, že Java nespĺňa len nejaké kategórie a apriori to nemusí nič znamenať, jazyk by to mohol byť dobrý. Na stranu druhú, to, že každý vychvaľuje Javu ako úžasný OOP jazyk je dosť choré, lebo Java proste OOP jazykom nie je a obvykle to poukazuje len na to, že daný človek sa s OOP inde ako v Jave (prípadne C++ a podobných pseudo-OOP jazykoch) nestretol. To za prvé. Za druhé, to, že ten jazyk nespĺňa nejaké kategórie a je to len šmejd plný reliktov minulosti bez nejakého jednotného konceptu (ak už nejaký koncept Java má, tak je to OOP a to je v nej práve na veľmi zlej úrovni) aj prakticky znamená, že núti človeka robiť veci neelegantne/nečitateľne/písať balast. Článok s príkladmi som už linkoval, dá sa ich ale vymyslieť ešte oveľa viac.
Opakuješ pořád dokola totéž, že je to balast a že musíš psát spoustu zbytečného kódu…
Na Javě mi trochu vadí ukecanost v případě getterů a setterů. Příklad:
public class Prepravka { private String vlastnost; public String getVlastnost() { return vlastnost; } public void setVlastnost(String vlastnost) { this.vlastnost = vlastnost; } }
Jenže jak tenhle problém s „ukecaností“ jazyka vyřešit, aniž by se člověk vzdal zapouzdření, aniž by si zavřel dveře k případnému budoucímu přidání dalšího kódu ke čtení/zápisu vlastností? C# na to jde jinak, na první pohled chytřejí, používá property, ale výsledek je stejný, ne-li ještě horší:
public class Prepravka { private string _vlastnost; public string vlastnost { get { return _vlastnost; } set { _vlastnost = value; } } }
Jak jsou na tom jiné jazyky? Je možné někde psát tak úsporně, jako kdybychom používali veřejně přístupné proměnné, a přitom si nechali možnost přidat dodatečný kód jako u getterů a setterů (aniž bychom měnili okolní kód, kde se tyto vlastnosti/metody používají)?
V ideálním případě by člověk deklaroval proměnnou jako property, na jednom řádku, jako když deklaruje veřejnou proměnnou. Jako k veřejné proměnné by se k ní dalo i přistupovat (stejně jednouduše). Ale bylo by možné k ní dodatečně navěsit kód, který se má provádět při jejím čtení nebo zápise. Funguje tohle někde?
co eiffel ? Jestli je to to co myslíš.
jj, ta syntaxe je sice taková „divná“, ale takhle nějak bych si to představoval – možnost jednoduše deklarovat proměnnou a později z ní připsáním pár řádků udělat getter.
Jaké zvýrazňování?
em
, strong
, code
a další zobrazovat jako normální text.
.ds_text_userXXXXX em { font-style: normal; }
Accessory som už uvádzal ako jeden z príkladov Javovského balastu hneď na začiatku a uviedol som aj odkaz na článok, kde je rozobraté, ako sa to rieši v iných jazykoch. Ten odkaz je v tejto diskusii už 2x (preto ho nebudem linkovať znova, dajte si tú prácu a nájdite si ho a tie články prečítajte) a je v ňom ukázaných asi 10 námatkovo vybraných výhod nových jvm jazykov (scala, jruby, groovy, clojure) nad javou (a je to z pohľadu javistu, ktorý sa teší, že už ten balast nemusí písať. To by IMHO mal byť prístup všetkých javistov, ktorí nie sú len fanatikmi, ale snažia sa zlepšovať svoje programátorské umenie). Odporúčam poriadne čítať a sledovať, kým začnete reagovať
Tak zrovna accessory sú zrovna syntactic sugar a dajú sa spraviť lepšie a horšie (a zrovna Groovy je IMHO z tých nových jazykov najhorší -- najviac sa drží Javovské balastu. Ostatné jazyky sú trochu revolučnejšie v poradí: Scala, JRuby, Clojure), ale čo je podstatné, tak v poriadnom jazyku nie sú natvrdo zadrátované do špecifikácie, ale používateľ si ich môže modifikovať (to je tiež v tých článkoch ukázané).
Žiadne duplicity? To je zvláštne. Podľa mňa je článok v komentári 3 a 48 presne ten istý. Ale už vidím, že niekto tu má zjavne problém s vnímaním
Žiadne duplicity? To je zvláštne. Podľa mňa je článok v komentári 3 a 48 presne ten istý. Ale už vidím, že niekto tu má zjavne problém s vnímanímNe, to pouze WebDeveloper Toolbar odstraňuje duplicity ze seznamu odkazů sám automaticky
.class
pro metody a fieldy, tedy reflexe vyhodnocovaná už v okamžiku překladu).
A čo tým chcete povedať? To, že ste ten článok nenašli (napriek tomu, že je tu 2x, slovom _dvakrát_) nie je problém žiadneho toolbaru, ale Váš vlastný
Určite to nie je posledné slovo vo vývoji jazykov, to si skutočne nemyslím. Ak chcete orientáciu na statické veci, tak možno niekto napíše aj Jaskell. Myslieť si, že Java je posledný výkrik technológie a ultimátny jazyk pre jvm a všetka konkurencia je horšia je vyslovene _choré_. Ale ten článok veľmi dobre ilustruje, v čom všetkom je Java nepoužiteľná. A to pritom rozhodne nie je vyčerpávajúci. Mať možnosť si poriadne priohnúť jazyk je skvelá vlastnosť, ktorú Java nevidela ani z rýchlika. A nie, neprasí sa tým kód, práve naopak. Pre malú self-sustained knižnicu a vôbec pre rôzne izolované problémy je vhodné vyrobiť si mikrojazyk a vyjadrovať sa v ňom. Kód je potom ešte 10x krajší a čitateľnejší. To je najväčšia sila (nielen) LISPu, ale práve preto nečakám, že to pochopíte. LISPu sa boja aj ľudia, ktorí majú inak pomerne veľký rozhľad. Sám Alan Kay (pre neznalých/l/ otec OOP) povedal (v maile, ktorý tu už citoval Ladíček), že sám LISPu spočiatku nerozumel a neskôr mu to ohromne rozšírilo obzory a pohľad na to, čo je to vlastne OOP.
A čo tým chcete povedať?To, že jsem se pokoušel mezi tou spoustou odkazů najít ten, který vy jste definoval jediným způsobem: že už je tu dvakrát.
Myslieť si, že Java je posledný výkrik technológie a ultimátny jazyk pre jvm a všetka konkurencia je horšia je vyslovene _choré_.A myslet si, že si to myslí někdo jiný, přestože nic takového netvrdí, je choré rovněž.
Ale ten článok veľmi dobre ilustruje, v čom všetkom je Java nepoužiteľná.Ten článek dobře ilustruje, co vše do Javy nepatří.
Mať možnosť si poriadne priohnúť jazyk je skvelá vlastnosť, ktorú Java nevidela ani z rýchlika.Mít jasně daný jazyk, který si nikdo nemůže přiohnout, je zejména pro velké projekty skvělá vlastnost. Zkombinovat oba požadavky do jednoho jazyka jde jen těžko – takže je správně, že jsou tu jazyky, které umožňují to první, a jiné jazyky, které umožňují to druhé.
Pre malú self-sustained knižnicu a vôbec pre rôzne izolované problémy je vhodné vyrobiť si mikrojazyk a vyjadrovať sa v ňom.Váš názor, že je lepší všechno si znovu napsat od začátku na míru, už jsem zaznamenal. Pak se ale poněkud míjíte s pojetím open-source.
To je najväčšia sila (nielen) LISPu, ale práve preto nečakám, že to pochopíte.Já tvrdím, že pro různé věci se mohou hodit různé jazyky, vy tvrdíte, že Java je kvintesence špatného návrhu jediného správného programovacího jazyka. Kdo tu něco nechápe ponechávám laskavému čtenáři za domácí cvičení.
Tak vážený, za prvé, ten odkaz ste si mali prečítať bez toho, aby som Vás na to opakovane upozorňoval To, že som Vás upozornil berte ako bonus. To, že ste už Vy neschopný tú radu využiť je Váš problém
Nie je to choré a myslím si to preto, lebo ste to tvrdili Viď Váš komentár o Java.Next, že všetky tie veci sú desné a Java sa bez nich zaobíde. Povedať na plnú hubu, že 4 (slovom _štyri_) úplne rozdielne jazyky nemajú oproti blbej Jave čo ponúknuť je veľmi silná káva
Samozrejme. Nepatrí tam nič zaujímavé, čo by človeku umožnilo nepísať balast. Absolútna zhoda.
Lenže každý projekt má iné požiadavky a mať možnosť si napísať jazyk vlastný (čo sa často deje od základu), je ešte ďaleko lepšie, než používať nejaký prehistorický jazyk, ktorý na to vôbec nebol určený Je veľmi naivné si myslieť, že Java je vhodný jazyk pre každý veľký projekt
Samozrejme, ide tu aj o trh a o dostatok zamestnancov so skúsenosťami v jazyku. Lenže toto už skutočne nič nevypovedá o jazyku ako takom, ale len o trhu.
To som nikde netvrdil. Ak narážate na frameworky, tak už tam som napíšal, že je potrebné zvážiť výhody/nevýhody písania nového frameworku nad použitím cudzieho (a že to rozhodnutie nie je ľahké ani trochu). V inej diskusii som písal o jQuery, s ktorou by som asi tiež nemal skúsenosť, keby som nepoužíval open source To práve Vy mi pripadáte ako človek, ktorý za každú cenu musí používať niečo cudzie a nie je schopný vytvoriť nič vlastné
Nie, to teda rozhodne netvrdím a netuším, kde ste túto interpretáciu našli. Môžete ma citovať? Ak nie, tak zoberte tie slová láskavo späť (ospravedlnenie od Vás nečakám. Keď ste schopný si vymýšľať a vkladať mi slová do úst, tak je jasné, že nič také by ste nespravili) Java je zlým návrhom akéhokoľvek jazyka, určite nie jediného správneho. Ja naopak tvrdím, podobne ako Vy (resp. ako Vy píšete v tomto odstavci, ale nie je to konzistentné s Vaším fanatickým zastávaním sa Javy), že na každú úlohu je vhodný iný jazyk a občas je dokonca vhodné si vyrobiť jazyk vlastný (či už pomocou možnosti písať domain-specific jazyky priamo v pokročilých jazykoch, alebo si navrhnúť úplne nový vlastný jazyk + napísať kompilátor)
Ale rozhodne nie je pravda, že len kvôli tomu, že na všetko je vhodný iný jazyk, tak že by malo existovať úloha, pre ktorú je Java najlepšou možnosťou zo všetkých. Ja si dovolím tvrdiť, že taká oblasť neexistuje (ak vynecháme požiadavky súčasného trhu na zásobu cvičených opíc, ktoré ovládajú základy jedného jazyka a inak nie sú schopné uvažovať nad ničím).
Povedať na plnú hubu, že 4 (slovom _štyri_) úplne rozdielne jazyky nemajú oproti blbej Jave čo ponúknuť je veľmi silná kávaStále jste to nepochopil. Tak zkusíme příklad: je to jako byste tvrdil, že autobus je špatné vozidlo, protože třeba takový bagr má velkou lžíci, ale autobus ne. A že teprve až bude mít autobus také pořádnou lžíci, bude za něco stát. Takže já stále trvám na tom, že to, že nějaký jazyk má vlastnost XY a jiný jazyk ji nemá nevypovídá o kvalitě obou jazyků vůbec nic.
Lenže každý projekt má iné požiadavky a mať možnosť si napísať jazyk vlastný (čo sa často deje od základu), je ešte ďaleko lepšie, než používať nejaký prehistorický jazyk, ktorý na to vôbec nebol určenýA někdy je to ještě o hodně horší. Stejně jako přidělat velkou lžíci na některý dopravní prostředek může být dobré, ale přidělávat ji na autobus by bylo hodně špatné.
Je veľmi naivné si myslieť, že Java je vhodný jazyk pre každý veľký projektPletete si kvantifikátory, „existuje (projekt)“ neznamená „pro každý (projekt)“.
Nie, to teda rozhodne netvrdím a netuším, kde ste túto interpretáciu našli. Môžete ma citovať?Např. v citátu hned na začátku tohoto komentáře. Plyne to z každého komentáře, kde tvrdíte, že nějaký jazyk něco umí a Java ne, tudíž je Java špatně navržená.
Áno, až na to, že je otázka, či je táto analógia správna Ja tvrdím, že ani omylom. Že Java.Next je pridanie lepšieho motora a nového náteru do toho autobusu a že to ide až tak ďaleko, že teraz môže lietať a plávať pod vodou
Problém s touto analógiou je, že najprv ten homomorfizmus treba dokázať, inak takéto analógie nemajú ani najmenšiu cenu
Samozrejme. Prečo musíte nesprávne negovať každé moje tvrdenie? Píšem tam (alebo niekde ďalej), že niekedy je to lepšie tak a niekedy onak, vždy sa treba rozhodnúť racionálne. Ale rozhodne nie je Java odpoveď na všetko.
Fajn, takže vy hovoríte, že je tam kvantifikátor existuje? V tom prípade ok, to celkom beriem. Jeden projekt z milióna snáď existuje, som ochotný to prežiť. Ale takýto argument v prospech jazyka je skutočne veľmi slabý A navyše ste nedokázali, že ten projekt skutočne existuje
Ja som sa nepýtal, z čoho to plynie, ale či ma môžete konkrétne citovať. Kým tak neurobíte, tak nie som Vaše výpady, reinterpretácie mojich výrokov a vkladanie slov do úst ochotný brať na vedomie
Áno, až na to, že je otázka, či je táto analógia správnaPak to tedy znamená, že to, že má jeden jazyk nějakou vlastnost, ještě neznamená, že ta vlastnost patří i do jiného jazyka. Pak ale neargumentujte tím, že nějakou vlastnost má nějaký jazyk, ale tím, proč ta která vlastnost patří jazyka s takovou koncepcí, jako má Java. U většina věcí z Java.Next zjistíte, že do jazyka s koncepcí, jakou má Java, ty vlastnosti určitě nepatří.Ja tvrdím, že ani omylom.
Ja som sa nepýtal, z čoho to plynie, ale či ma môžete konkrétne citovať.
Mať možnosť si poriadne priohnúť jazyk je skvelá vlastnosť, ktorú Java nevidela ani z rýchlika.
je v ňom ukázaných asi 10 námatkovo vybraných výhod nových jvm jazykov (scala, jruby, groovy, clojure) nad javouTady argumentujete tím, že nějaké jazyky určitou vlastnost mají, a Java ne, což je špatně. Z toho tedy plyne, že existuje nějaká sada vlastností, která je nejlepší, a pak tedy existuje nějaký univerzální jazyk, který má právě tuhle sadu vlastností.
je v ňom ukázaných asi 10 námatkovo vybraných výhod nových jvm jazykov (scala, jruby, groovy, clojure) nad javouA tady přímo píšete, že je něco výhoda jenom proto, že je to jinak, než v Javě.
Mať možnosť si poriadne priohnúť jazyk je skvelá vlastnosť, ktorú Java nevidela ani z rýchlika. A nie, neprasí sa tým kód, práve naopak.
Nemyslím si, že by to bylo tak jednoznačné plus. Je to spíš otázka, jestli takovou Javu chceme nebo ne.
Ono „přiohnutí“ je sice příjemné pro autora kódu a skvěle se hodí pro kód, který se píše jednou a víc se na něj už nesahá. Ale pokud k tomu kódu má přijít někdo cizí (případně tentýž programátor po letech či měsicích), má mu rozumět a zasahovat do něj najednou se objevují nevýhody – nestačí umět jazy, je potřeba i důvěrně rozumět tomu „přiohnutí“, znát styl a myšlení předchozího programátora.
Vzhledem k oblasti, kde se Java často nasazuje (velké podniky, banky, velké týmy, střídající se námezdní programátoři…) by to byl dost nešťastný krok.
No, lenže mať možnosť jazyk ohýbať, Vás nenúti k tomu to robiť. Ak chcete používať tú starú Javu, tak to pokojne robte. Hoci je pravda, že keď už tu máme nové jazyky, tak to nie je tak dôležité. Proste Java zostane tou starou Javou a Java.Next je tými ohybnými jazykmi. Vývoj ukáže, že čo je lepšie.
Samozrejme. Ak sa používa všade, tak to vedie k takému bordelu, akým je Perl. Ale ak to použijete pre knižnice a pod. (do ktorých nemusí nikto iný vidieť, stačí, že exportujú funkcionalitu), tak je IMHO tento spôsob určite reálna možnosť.
To myslenie a štýl, atď, to musíte poznať vždy. Keď človek začína pripsievať do nejakého projektu, musí sa naučiť jeho architektúru, myšlienku za ním, jeho design, bez toho to nejde. To, že je napísaný v domain-specific jazyku je len drobnosť navyše (zvlášť ak sa návrhári krotili a skutočne tú domain-špecifickosť používajú len tam kde treba a sú to rozumné vlastnosti, ktoré sprehľadňujú zápis a zvyšujú robustnosť, a pod.).
Súhlasím, že vzhľadom k tomu, že veľké podniky najímajú cvičené opice, to môže byť nešťastný krok. Ale a priori, prečo by mali byť veľké a zložité aplikácie navrhované v archaickom a rigidnom jazyku ako je Java? Mňa osobne napadá ako dôvod práve len tá veľká zásoba cvičených opíc.
No, lenže mať možnosť jazyk ohýbať, Vás nenúti k tomu to robiť.Pokud na nějakém projektu pracuje víc než jeden člověk pár týdnů (tj. buď více lidí, nebo se k tomu autor bude za několik měsíců či let vracet), může být užitečné ohýbání zakázat. Protože prvního autora sice nic nenutí jazyk ohýbat, ale jakmile to jednou udělá, už tím ostatní nebo sebe v budoucnosti nutí s tím ohnutím minimálně počítat. Proč si myslíte, že má třeba Linuxové jádro tolik pravidel, ať už nějak automaticky kontrolovaných, nebo jen vyžadovaných při přijímání patche? Proč si nemůže při programování jádra každý C ohnout podle svého?
Pletiete teraz hrušká s jablkami. Pri programovaní jadra si C ohnúť môžete a samozrejme, že sa to často robí. V linuxovom jadre je C ohnuté na maximum. Ničmenej to neznamená, že by to mal každý robiť po svojom. Lenže je tam aj spoločná diskusia a spoločná množina pravidiel, ktorá sa dodržiava. Keď máte slušných ľudí, tak nepotrebujete zákony Len keď máte prasatá (hint: cvičené opice v Jave), tak potrebuje asi skutočne uzamknúť jazyk úplne, aby s ním náhodou niekto niečo nespravil. Ničmenej, ak je nejaký schopný senior architect, ktorý kontroluje kvalitu kódu (pre Linux Linus a Andrew), tak zjavne nepotrebujete neohybný jazyk, stačí kontrola prijatého kódu. Ak je nejaký kód zlý, tak sa proste vráti k opraveniu
Ale a priori zakazovať ohýbanie jazyka (čiže používanie kreativity a elegancie), aby náhodou niektorá cvičená opica niečo nepokazila, to mi pripadá veľmi totalistické a nesprávne.
Pri programovaní jadra si C ohnúť môžete a samozrejme, že sa to často robí. V linuxovom jadre je C ohnuté na maximum. Ničmenej to neznamená, že by to mal každý robiť po svojom.Sláva. Takže se shodneme aspoň na tom, že není dobré, když si na jednom projektu každý ohýbá po svém. Snad se shodneme také na tom, že je dobré to případné ohýbání kontrolovat co nejvíce automaticky, resp. automaticky kontrolovat nějaká pravidla. A teď už zbývá jenom krůček – tuhle kontrolu můžete zabudovat rovnou do kompilátoru a do jazyka. Pravda, nemůže si pak každá firma a každá knihovna nadefinovat svůj vlastní způsob ohýbání, ale ono to má i svou výhodu – můžete snadno přecházet z jednoho kódu na jiný, snadno používat různé knihovny, protože to všechno dodržuje stejná pravidla. Když budete sledovat tuto stopu dál, přijdete i na to, proč je tak rozsáhlý ekosystém Java knihoven – protože se všude používají stejná pravidla, takže můžete vzít skoro libovolné dvě knihovny a použít je ve svém kódu. Když tohle budete zkoušet třeba s C, narazíte na to, že každá knihovna je ohnutá trochu jinak, a musíte nejprve vyřešit, jak je ohnout společně do vašeho kódu. Jestli se nepletu, účastnil jste se také diskuse od zaměnitelnosti GUI toolkitů. A to je přesně ono – aplikace se musí přizpůsobit tomu, jak C nebo C++ ohýbá GTK nebo Qt. Pokud by C nebo C++ nebyly tak ohebné, byl by s tím mnohem menší problém. U Javy na tohle narazíte třeba u classloadingu, protože jedna třída (a jí daná specifikace classloaderu) je navržená špatně (z dnešního pohledu), takže si ji větší aplikace ohýbají, a každá různě, a dohromady to pak spíš nefunguje než funguje. Ale to je výjimka, jinak je hodně věcí v Javě navržených dobře, takže nikdo nemá potřebu si je ohýbat. Pravda je, že by se také spousta věcí dala zlepšit, ale onen odpor k ohýbání tomu brání. Ale jak už jsem napsal – ty věci ke zlepšeí jsou úplně jiné, než ty zmiňované v Java.Next.
Čo je na tom sláva? Je to úplne zrejmé Ale už sa nezhodneme v tej sérii implikácií, ktoré Vám padajú z neba
Ale je to bežný štýl demagogickej argumentácie, použiť niekoľko implikácií, pri ktorých nie je zrejmá pravdivostná hodnota a z toho vydedukovať napríklad, že Java je jazyk vhodný pre veľké projekty, s čím ja vôbec nesúhlasím
Môžete ľahko prechádzať medzi kódom? A to si predstavuje ako? Zoberiete 5000 riadkov aplikácie A a vložíte ich do aplikácie B? Takto sa predsa neprogramuje. Keď už niečo tak knižnice. Lenže rôzne knižnice môžete používať vďaka jvm bez ohľadu na jazyk, ich implementácia Vás nemusí zaujímať -- všetko je to jeden bytekód --, takže tento argument neberiem
Nebudem túto stopu sledovať ďalej, lebo ako som povedal, tá stopa je založená na polopravdách, aby ste sa dobrali výsledku o ktorom axiomaticky predpokladáte, že je správny
Nie, Java knižnice ťažia z toho, že jvm. To je obrovská výhoda, ktorú inde len tak nezískate (a ešte oveľa väčšia výhoda pri spolupráci viacerých jazykov).
S tými C knižnicami opäť nemáte pravdu. Je implementácia a je deklarácia. Tá deklarácia je vždy spoločná, proste knižnica exportuje kopu algoritmov a nejaké dáta, ale vždy je to štandardný zápis. To, aké prasačiny a mágiu knižnica robí vo vnútri Vás absolútne nemusí zaujímať. Jediná výhoda knižníc v Jave nad knižnica v C je jvm. Nič iné.
To ale argumentujete znova niečo iné a to API. API majú proste rôzne knižnice rôzne. Ak Vám dodám dve GUI knižnice v Jave, každú s rôznym API, tak prepísať aplikáciu, ktorá používa jednu knižnicu tak, aby používala tú druhú, je presne to isté, čo prechod GTK -> Qt (s rozdielom, že GTK je C a Qt je C++, kdežto Java má o problém menej vďaka jvm. Ale to je otázka virtuálnej mašiny, nie jazyka)
Ok, ukončime túto debatu. Ja Vám dám za pravdu, že existuje skupina ľudí, ktorí nie sú schopní rozumne pracovať s kódom a preto potrebujú jazyk, ktorý im nedovolí vôbec nič. Inak je to pre mňa rovnako nepoužiteľný jazyk, ako to bol pred pár dňami, nepočul som žiadnu argumenty, ktoré by ma presvedčili o opaku.
Java je jazyk vhodný pre veľké projekty, s čím ja vôbec nesúhlasímNesouhlasit s tím klidně můžete, ale velké projekty se píší často právě v Javě, takže to evidentně jde a spousta lidí si myslí, že je to dobrý nápad. Pokud vy s tím nesouhlasíte, je na vás předložit nějaké argumenty.
Lenže rôzne knižnice môžete používať vďaka jvm bez ohľadu na jazyk, ich implementácia Vás nemusí zaujímaťTolik k programování v ráji. Teď se prosím vraťme zpět na zem, kde vás implementace knihovny bohužel často zajímat musí. Jinak by opět open-source byl k ničemu, že…
Inak je to pre mňa rovnako nepoužiteľný jazyk, ako to bol pred pár dňami, nepočul som žiadnu argumenty, ktoré by ma presvedčili o opaku.Že je to použitelný jazyk dokazují tisíce programů, které jsou v něm napsané. Pokud vám připadá, že je nepoužitelný, bylo by potřeba napsat alespoň jeden příklad toho, co je na něm nepoužitelného*) – dozvěděli jsme se akorát to, že Javu prostě nějak nemáte rád, a to není výchozí pozice, ve které by mělo začít přesvědčování. *) Dozvěděli jsem se pár věcí, u kterých je dobře, že je Java nemá, a pár věcí, které jsou bez problémů řešitelné současnými prostředky Javy.
Veľa ľudí používa Windows. Ďalej to rozoberať nejdem.
Samozrejme, ak Vás to zaujíma, tak máte možnosť tú knižnicu vnútorne pochopiť a zmeniť. Ale to už je iný problém.
Že je Windows skvelo použiteľný systém dokazujú milióny používateľov.
A aký iný argument, než to, že Java niečo nemá, mám použiť, aby som Vás presvedčil? Hovoríte "dajte mi argument" a keď Vám ho dám, tak poviete, "to nie je argument". Má cenu sa vôbec snažiť? Nemá. Ďakujem za diskusiu.
Veľa ľudí používa Windows. Ďalej to rozoberať nejdem.Ale jo, rozeberte to. Rád se dozvím, proč „něco jde/nejde používat“ je synonymum k „používá se to dobře/špatně“.
Že je Windows skvelo použiteľný systém dokazujú milióny používateľov.Asi nedopatřením vám přibylo ve větě „skvěle“. A hned to má úplně jiný význam…
A aký iný argument, než to, že Java niečo nemá, mám použiťTřeba argument, proč je špatně, že to Java nemá. Jinak se klidně můžeme bavit o tom, že Python je naprosto katastrofální jazyk, protože nemá šňůru od splachovadla.
Vy ste sa ako argument snažili použiť to, že Javu používa veľa projektov. A ja hovorím, že to nie je žiadny argument. Veľa ľudí používa suboptimálne riešenia, tak to už vo svete chodí. Nechcel tým povedať, že nemôžete mať pravdu. Ale len, že to z toho neplynie.
Aký iný? Bola to irónia. Rovnako tak s Javou. Opäť, len som chcel poukázať na to, že to nie je argument v prospech tvrdenia "Java je vhodný jazyk pre veľké projekty" (bez ohľadu na pravdivosť tohoto tvrdenia).
Ale veď som Vám to už napísal 100x: treba sa vyjadrovať pomocou kopy zbytočného balastu. Jazyk je málo expresívny, zle čitateľný (toto je asi subjektívne), menej robustný, atď. Bežná výhoda vysokoúrovňových jazykov oproti tým nízkoúrovňovým. Netuším, prečo to musím opakovať stále dokolečka. Sám uznávate, že Java ako jazyk je v istom zmysle nízkoúrovňová. Netvrdím, že to musí byť nevhodné na 100% aplikácií, ale nevidím ani jednu oblasť, kde by nebolo vhodnejšie použiť vysokoúrovňový jazyk. Toť vše. Ale táto diskusia prestáva mať zmysel, obaja opakujeme stále to isté, takže asi sa nedarí niekomu z nás niečo prekomunikovať.
Vzhledem k oblasti, kde se Java často nasazuje (velké podniky, banky, velké týmy, střídající se námezdní programátoři…) by to byl dost nešťastný krok.A proto kucí ze SAPu implementují v ABAPu virtuální mašinu pro Ruby
Ale ak nechcete počuť len názorny antijavistu, ale aj zástancu javy, ktorý ničmenej vidí výhody pekných jazykov, prečítajte si tento článok. Zhrnuje v ňom nové jazyky, ktoré vylepšujú javu (je medzi nimi aj scala), a už bol v tejto diskusiu linkovaný. Okrem iného tam porovnáva aj Java kód a jeho konštrukcie s kódom tých jazykov a dúfam, že si spravíte obraz, ako je na tom Java veľmi zle
IMHO je to lepsi pristup nez navrhnout nejaky vseobjimajici programovaci jazyk ve stylu jak pejsek s kocickou varili dortTo se tu snažím vysvětlit celou dobu, zatím marně…
O tomto táto diskusia vôbec nie je. Ak sa skutočne snažíte vysvetliť tento triviálny fakt a napriek tomu, to nikde nie je vidieť (pamätám si jedinú vetu z jediného komentára v celej diskusii), tak asi niečo nie je v poriadku
A btw, ja s tým plne súhlasím. Než navrhovať Javu, ktorá nie je ani ryba ani rak (nie je to OOP, je to klasické C-like jazyk a objekty sú naňho dolepené), tak by sa niekto mal zamyslieť, čo presne od toho jazyka chce (či už čisté OOP, alebo niečo iné) a aj ho tak navrhnúť a nie mixovať dokopy všetko možné aj nemožné Uznávam, že Java sa každou revíziou posúva ďalej a ďalej a revízia 10 (teraz sme na 7?) už by mohol byť nejaký rozumný jazyk
Ak by sme ale brali Javu revízie 4 a staršiu (lebo nie je dôvod brať len tú najnovšiu. V tých starých verziách je totiž práve vidieť ten jazyk tak, jak ho pôvodne navrhli), tak to by už vôbec bolo na inú diskusii (a v oveľa väčší neprospech Javy)
Hm, ak Vám musím po 100 komentároch vysvetľovať, o čom je vôbec reč, napriek tomu, že tu aktívne komentujete, tak by ste sa nad sebou mohli trochu zamyslieť.
Ide tu o to, že Java je zle navrhnutý jazyk (alebo teda, možno bol zámer navrhnúť ho zle, v tom prípade je to dobre navrhnutý zlý jazyk). Čo samozrejme môžete akceptovať, alebo nemusíte. Ale ľudia, ktorí majú skúseností s veľkým množstvom jazykov a prístupov to vidia a dávajú mi (hoci nepriamo) za pravdu a je to v tejto diskusii vidieť. Na druhej strane sú ľudia ako Vy, ktorí nie sú schopní sa odtrhnúť od svojho milovaného jazyka a objektívne sa pozrieť na jeho nedostatky. Nie je bez zaujímavosti, že takíto ľudia obvykle nemajú skúsenosti s viac než pár jazykmi a aj to väčšinou len jazykmi podobného kalibru ako je Java a ak už, ako Vy, uvedú viac jazykov a medzi nimi aj zaujímavé, tak si dovolím tvrdiť, že do tých jazykov a ich pokročilých a zaujímavých vlastností (čo je to, čo ich odlišuje od Javy a robí z nich jazyky pekné a elegantné, čitateľné, atď., proste high-level) neprenikli.
pokročilých a zaujímavých vlastností (čo je to, čo ich odlišuje od Javy a robí z nich jazyky pekné a elegantné, čitateľné, atď.Takže pokročilé a zajímavé techniky programovacích jazyků definujete tak, že jsou odlišné od Javy. Nevím, čím si to Java zasloužila, že podle vás cokoli, co je jiné, je automaticky pokročilé a zajímavé, ale pak má spoustu pokročilých a zajímavých vlastností třeba Basic.
proste high-levelJistě, to že low-level jazyk není high-level, to je opravdu jeho vážný nedostatek.
Nestaviam svoje argumenty na ničom takom. To len Vy mi stále niečo vkladáte do úst (a teraz už aj do hlavy. Ste fakt macher!) Ja tvrdím, že je to úplne chybne navrhnutý jazyk. Ak má nejaký koncept, tak je to OOP, ale aj to OOP je tam úplne úbohé. Je to jazyk, ktorý nemá žiadnu myšlienku, je to len relikt minulosti a zmiešavanie procedurálneho a objektového programovania. Je to len také trochu uhladené C++. Ok, ak teda tvrdíte, že Java bola s touto myšlienkou aj navrhutá, tak sa možno zhodneme. Ale skutočne som mal pocit, že vyvraciate moje tvrdenia, že na Jave je veľa vecí navrhnutých nesprávne a dalo by sa zlepšiť (lebo nič iné som nikde netvrdil). Je pravda, že si myslím, že jazyk by mal mať nejaký jednotný koncept, a aj preto nemám jazyky ako C++ a Java rád (veľa mojich argumentov proti Jave je použiteľných aj proti C++). Ale C++ aspoň bolo s týmto zámerom skutočne navrhnuté (byť kombináciou high-level a low-level). Myslel som si, že Java bola navrhnutá ako OOP jazyk (lebo kvôli tomu ju zastáncovia vynášajú do neba) a teda sa niekde asi stala chyba a to najskôr tam, že pôvodný tvorca poriadne netušil, čo robí. Ale ako hovorím, ak sa dohodneme, že Java bola už navrhnutá takto bez myšlienky a konceptu (rovnako ako C++), tak môžeme túto diskusii ukončiť.
Nie, naopak, Vy ste žiadny môj argument doteraz nevyvrátili (citujte také vyvrátenie, som naňho zvedavý). Ja nie som ničím zaslepený a prečo Javu hájite mi nie je známe. Ste absolútne neochotný uznať, že veľa vecí, ktoré sa v Jave robí nepohodlne, sa dá robiť lepšie (tu nejde o nejaký jediný správny jazyk. Tu ide o obyčajnú kvalitu jazyka ako takého) a mnohé vylepšenia by nestáli ani cent procesorového času navyše (ak by ste chceli argumentovať, že Java ako low-level jazyk má byť rýchla).
Ja tvrdím, že je to úplne chybne navrhnutý jazyk.To jsem si všiml, že to tvrdíte. Ale nezaznamenal jsem zatím žádný argument. Podotýkám, že „má to jazyk XY a Java ne“ není argument.
Ak má nejaký koncept, tak je to OOPKdyž pořád potřebujete nějaké škatulky, říkejme konceptu Javy třeba JJJ, kde JJJ nemusí být OOP.
Je pravda, že si myslím, že jazyk by mal mať nejaký jednotný konceptTo si myslím také. Jenom si nemyslím, že by koncept Pythonu, Ruby, Lispu a Javy byl stejný, takže mi připadá nesmyslné argumentovat čistě jen tím, že nějaký jazyk něco umí a jiný ne.
Myslel som si, že Java bola navrhnutá ako OOP jazykTo jste si myslel špatně.
lebo kvôli tomu ju zastáncovia vynášajú do nebaVšimněte si, že o OOP v této diskusi píšete jenom vy. Obávám se, že je to spíš tak, že vy si myslíte, že pokud by Java měla nějaké horlivé zastánce, ti by ji vynášeli do nebes právě za OOP.
Ale ako hovorím, ak sa dohodneme, že Java bola už navrhnutá takto bez myšlienky a konceptuNe, na tom se neshodneme. Jedna z myšlenek Javy bylo navrhnout jednoduchý a průhledný jazyk, takový, že když si přečtete kus kódu v tom jazyce, nebudete muset dlouho dumat nad tím, co to v tom jazyce vlastně znamená (myslím, že autoři si vzali jako odstrašující příklad šablony v C++ a řekli si „tohle ne“). Ono se to samozřejmě nepodařilo úplně ideálně, i v Javě už jsem narazil na kód, nad kterým jsem musel dumat, co to vlastně s JVM dělá. Tahle jednoduchost se docela výrazně pokazila generikami, ale myslím si, že to stálo za to. Navíc pro uživatele je to pořád ještě jednoduché, špeky se týkají jenom těch, kdo generické třídy navrhují.
Vy ste žiadny môj argument doteraz nevyvrátiliZatím nebylo jaké argumenty vyvracet. „Má to jazyk XY a Java ne“ není argument.
prečo Javu hájite mi nie je známeNehájím Javu, hájím všechny jazyky, které nemají funkce, které má váš ideální univerzální všemocný jediný správný jazyk.
Ste absolútne neochotný uznať, že veľa vecí, ktoré sa v Jave robí nepohodlne, sa dá robiť lepšie (tu nejde o nejaký jediný správny jazyk.Já to uznávám, jenom vy odmítáte uznat, že takové věci se v Javě dělat nemají, a pokud se v ní dělají blbě, není to chyba Javy. Je to jakobyste konstruktérovi autobusu vytýkal, že se v něm blbě vozí hektolitry mléka.
Argumentov tu už bola spústa; že si ich nevšímate, som už tiež zaregistroval. Skutočne ich mám opakovať? Hovoríte, že ste si nevšimol žiadny, tak ja uvediem jeden a tento spor som vyhral, koniec diskusie, ďalej sa o tom nebavím: accessory. A skutočne sa nemusíte namáhať s ospravedlňovaním (či už kvôli nevšímavosti, alebo tomu, že stále klamete -- ťažko posúdiť, čo z toho to je)
To je ale hlúposť. Java vynucuje, aby v každom súbore bola trieda. Nič iné ako triedy v Jave nie je (teda pardón, na prvý pohľad. Na ten druhý už je to bordel). Všetko je založené na objektoch. Čo má byť to JJJ?
Prečo by bolo nesprávne argumentovať tým, že niekto niečo vie a iný nie? Je nesprávne povedať, že Ferrari je lepšie auto ako trabant? Proste sú určité objektívne kvality (ako rýchlosť auta), ktoré sa dajú zmerať (v prípade jazykov, to koľko balastu napíšete. Balast = kód pre ukojenie túžob kompilátoru, ale inak zbytočných).
Tak to ma mrzí, ale Java tým OOP wanna-be jazykom skutočne pôsobí. Aký je teda jej koncept? Vysvetlíte mi to? Alebo žiadny koncept proste nie je?
V tejto diskusii možno, lebo používam argumenty o neúplnosti (ak by niečo bol OOP jazyk, tak je chyba tam nemať posielanie správ a pod., to je objektívne merítko). Ak Java nie je OOP jazyk, tak beriem, hoci už som sa veľakrát s tým označením Java = OOP stretol a na niektorých školách sa používa na výuku OOP. Čo je navskutku s podivom, ak to je jazyk, ktorý toho s OOP nemal mať moc spoločné.
No tak ja Vám neviem. Java sa prakticky nelíši od C++ (až na to, že si autori predsavzali, že niektoré vlastnosti toho jazyka nepoužijú, presne kvôli tej vašej pseudočitateľnosti a nakoniec sa tam tie vlastnosti aj tak dostávajú/dostali). Ale celkovo už si začínam robiť Vašej predstavy jednoduchosti. Vy musíte mať všetko, čo sa dá napísať zložito napísané zložito, tým je to jednoduché. Nejaké uvažovanie ako určité veci zapísať elegantnejšie a krajšie nepatria zjavne do Vášho repertoára.
Ferrari má 8-valcový motor a trabant nie, je celkom solídny argument proti rýchlosti trabantu Vysvetlite mi, prečo absencia dôležitých vlastností nie je argumentom proti jazyku?
Prečo sa dělat nemají? o_O To je nariadenie z nebies? Je zakázané snažiť sa napísať pekný kód, ten kód musí byť za každú cenú odporný a plný balastu? Ale pravda, nie je to chyba Javy. Je to chyba ľudí, ktorí ju používajú, lebo sú to (ako sa už niekto správne zmienil) masochisti. A s takými je ťažká dišputa.
Nie, práveže je to ako keby som vodičovy autobusu, ktorý má defekt, doporučoval, aby to koleso nafúkal a pôjde to lepšie A ešte raz: dementnými analógiami sa nikam nedostaneme, lebo ako vidíte, dajú sa hrať na obe strany. Kým neukážete súvis reality a analógie, tak ta analógia má len taký význam, že sa na nej dajú nájsť chyby
Argumentov tu už bola spústa; že si ich nevšímate, som už tiež zaregistroval. … accessory„Accessory“ není argument. Argument je např. „accessory mají mít délku identifikátoru nejvýš 5 znaků, protože delší název mi nejde v mém editoru napsat“.
Prečo by bolo nesprávne argumentovať tým, že niekto niečo vie a iný nie? Je nesprávne povedať, že Ferrari je lepšie auto ako trabant? Proste sú určité objektívne kvality (ako rýchlosť auta), ktoré sa dajú zmerať.A pak, kdo by si tady potřeboval rozšířit obzory. Opravdu budete porovnávat autobus a bagr podle jejich rychlosti?
Balast = kód pre ukojenie túžob kompilátoru, ale inak zbytočnýchVíte, že mne ani nenapadá, co je tedy v Javě za balast? Java není tak ukecaná pro kompilátor, ten by to samozřejmě zvládl bez spousty věcí, ale pro člověka, který kód čte.
Nejaké uvažovanie ako určité veci zapísať elegantnejšie a krajšie nepatria zjavne do Vášho repertoára.Záleží na tom, podle čeho posuzujete eleganci a krásu. Vy podle počtu znaků zdrojáku, já podle průzračnosti, s jakou to vyjadřuje myšlenku, kterou ten kód implementuje.
Vysvetlite mi, prečo absencia dôležitých vlastností nie je argumentom proti jazyku?Argumentem by to bylo. Kdybyste alespoň u jedné vlastnosti dokázal, proč je důležitá.
Prečo sa dělat nemají?Protože k tomu Java není určená. Příklad byl uveden hned dále. Vy si pořád stěžujete, že se v autobuse blbě vozí mléko, a že je to chyba autobusu. Je se vám pořád snažím naznačit, že je vaše chyba, že si k převozu mléka vyberete autobus a ne cisternu. No ale vzhledem k tomu, že všechna auta porovnáváte objektivním měřítkem rychlosti, mne to už ani tolik nepřekvapuje.
Niekto raz kategorizoval jazyky podľa toho, koľko toho majú spoločného s LISPom. Bolo tam sedem bodov, Perl ich spĺňal tušim 6 a python 5. Musel by som to nájsť, ale Javu tipujem tak na 0-3. Takže tá polcesta je veľmi zlý pohľad na vec. Python je podobne dobrý jazyk ako Perl (len s trochu inou filozofiou), ale obidva sú na hacking super. Java je blbý jazyk pre blbých ľudí
No, tak je fakt, že tie posledné body boli podpora makier a pod., čo predstavuje výrazný kvalitatívny skok, takže v takomto zmysle je Perl úplne inde ako Python, s tým súhlasím.
Nádopotne.
Mňa tiež a skúšam ju nájsť, ale zatiaľ sa nedarí. Ak to nájdem, zlinkujem to sem.
by som sa veľmi čudoval, keby si java udržala nejakú pozíciuZní to asi divně, ale v "komunitě" návrhářů jazyků pro JVM má Java pozici low-level implementačního jazyka, a tu neztratí ještě pěkně dlouho. Ona totiž ve všech jazycích nad JVM funguje dobře jednosměrná integrace s Javou, ale obousměrná už drhne a integrace samotných jazyků mezi sebou je hudba vzdálené budoucnosti. Něco se rýsuje v podobě MOPu Attily Szegediho, ale uvidíme, kdy to vůbec nějaký jazyk začne podporovat.
Súhlas, že z tohoto pohľadu sa asi udrží, plus komunita má veľkú zotrvačnosť. Ale som si takmer istý, že postupom času nové jazyky Javu úplne vytlačia.
Ale pak tu jsou věci jako řízený kód, verifikace při nahrávání, povinné runtime kontroly, které jsou zase dost vysokoúrovňové.To jsou ale vysokoúrovňové věci z pohledu nativního kódu. Java je ale (nízkoúrovňový) jazyk pro JVM, jak správně píšete.
Fajn, na tomto sa zhodneme. To je v podstate všetko, o čo mi išlo: high-level je lepší ako low-level (až na výnimky), pretože má oveľa vyššiu expresívnosť/robustnosť/udržiavateľnosť/čitateľnosť a vymyslite si ľubovoľné iné pozitívne slovo a takmer určite tam bude patriť tiež Takže asi súhlasíte, že Java je pre bežný projekt nad jvm zlým jazykom z podobného hľadiska, ako je pre bežný projekt zlým jazykom C (napriek tomu, že Java ako taká je oveľa vyššie ako C).
Groovy rozhodně nemá horší syntaxi než Java, jak píšete výše, už proto, že většina javovského kódu je zároveň platným kódem v GroovyAno, jenže to, co přidává Groovy, to pak celé pokazí.,
MarkupBuilder je toho skvělým příkladem.Ano, skvělý příklad toho, jak umožnit psát nečitelný kód.
Jestli vám jsou proti srsti iterátorové metody, literály regulárních výrazů nebo uzávěry, tak vám asi není pomociAno, je mi proti srsti že pro každou prkotinu, kterou může implementovat knihovna, musí existovat extra syntaxe, aby se to dalo napsat tzv. zkráceně.![]()
assert "cheesecheese" =~ /cheese/ assert Pattern.matches("cheese", "cheesecheese"); assert Pattern.compile("cheese").matcher("cheesecheese").match(); assert Pattern.compile("cheese").matcher("cheesecheese").lookingAt(); assert Pattern.compile("cheese").matcher("cheesecheese").find();V čem je ten první zápis lepší, než druhý nebo třetí? Kromě toho, že třetí případ můžu snadno změnit na čtvrtý nebo pátý, ale u prvního budu muset stejně hledat v dokumentaci jazyka, kterou z těch tří metod vlastně volá.
def obj = new Object(); Object obj = new Object();V čem je první zápis lepší, kromě toho, že toho musím v IDE napsat víc, a pokud budu chtít změnit deklarovaný typ (klasický případ u kolekcí), musím se stejně vrátit k původnímu javovskému zápisu?
class X { def say() { println "Hello, world!" } } class X { void say() { System.out.println("Hello, world!"); } }Opět, v čem je první zápis lepší, v tom, že jsem v IDE zadal o 1 znak míň? V tom, že když budu chtít přidat modifikátor nebo změnit návratový typ, musím se vrátit k původní javovské syntaxi?
+1
def obj
toho poznám víc, než z Object obj
? To je mi novinka…
Pokud potřebuju generátor, který má spoustu rozsáhlých generovaných částí napevno zadrátováno v kódu, pak dělám něco špatně. Stejně jako když potřebuju v programu inicializovat velký seznam nebo mapu. To se hodí při prototypování, ale ne pro skutečný program. Ten má mít oddělená data a konfiguraci od prováděného kódu – a buildery nebo syntaktický cukr pro konstrukci seznamů nebo map usnadňuje právě zadrátování dat a konfigurace do kódu.
def obj
s typovou inferencí nebo def obj : Object
bez ní (a Scala to myslím dělá velmi podobně), ale to je detail (který by asi některé pravověrné strašlivě rozezlil Moje ideální představa deklarace proměnné je def obj s typovou inferencí nebo def obj : Object bez ní (a Scala to myslím dělá velmi podobně), ale to je detail (který by asi některé pravověrné strašlivě rozezlilTypovou kontrolu v době překladu považuju pro větší projekty než je pár řádek za plus, stejně tak považuju za plus, pokud na první pohled vidím, o jaký typ se jedná. A jiný deklarovaný a jiný skutečný typ objektu se taky občas hodí.).
Program má mít oddělená data a konfiguraci od kódu, heeee… kód je konfigurace.Takže jazyk, ve kterém jde snadno míchat kód, data a konfiguraci je pro vás ideál. Pak doporučuju třeba PHP. Ale prosím netvrďte, že je to jediná správná cesta. Pro mne je míchání kódu, dat a konfigurace přesně to, co by programovací jazyk podporovat neměl.
A upřímně – pro generování exportů fakt nebudu vymýšlet speciální konfigurační jazyk. Namísto toho si pár metaprogramovacími zásahy uzpůsobím Groovy.Ano, další nevýhoda Javy – místo psaní neustále nového kódu se znovu používají existují knihovny a komponenty.
Typovou kontrolu v době překladu považuju pro větší projekty než je pár řádek za plusStatický typový systém je pro mne velmi důležitý. Ale nechci kvůli němu pokaždé zapálit pět hromničních svic, obětovat ovci a zpívat přitom "Java Hallelujah", takže v řadě případů beru Groovy na milost. Hlavně pro skriptovací použití. Navíc IDEA si typy v Groovy odvozuje a upozorňuje mne na případné problémy, ale to je jen třešnička na dortu.
Takže jazyk, ve kterém jde snadno míchat kód, data a konfiguraci je pro vás ideál. Pak doporučuju třeba PHP.Já pro takové účely doporučuju jakýkoli homoikonický jazyk. Třeba Lisp, pro nadšence Ioke
existují knihovny a komponentyExistující knihovny a komponenty mohou být špatné. Nebo mizerné. Nebo ještě horší. Třeba základní práce s XML v Javě typu "vygeneruj jednoduché XMLko z množiny dat" nebo "natáhni ho do paměti a dej mi triviální přístup k jeho struktuře" je s knihovnami typu DOM, JDOM, DOM4J a já nevím jaké ještě jsou, oproti MarkupBuilderu a XmlSlurperu hotovým utrpením.
Statický typový systém je pro mne velmi důležitý. Ale nechci kvůli němu pokaždé zapálit pět hromničních svic, obětovat ovci a zpívat přitom "Java Hallelujah", takže v řadě případů beru Groovy na milost. Hlavně pro skriptovací použití. Navíc IDEA si typy v Groovy odvozuje a upozorňuje mne na případné problémy, ale to je jen třešnička na dortu.Jistě že se někdy hodí dynamické typy. Ale stejně tak se hodí mít možnost vynutit si, že všechny typy budou známy v době překladu a budou se kontrolovat. Osobně mi připadá lepší mít jazyk, který tohle vyžaduje, než mít u
groovyc
přepínač --force-static-dat-types
.
Existující knihovny a komponenty mohou být špatné. Nebo mizerné. Nebo ještě horší.Pak je dobré ty knihovny opravit.
Třeba základní práce s XML v Javě typu "vygeneruj jednoduché XMLko z množiny dat" nebo "natáhni ho do paměti a dej mi triviální přístup k jeho struktuře" je s knihovnami typu DOM, JDOM, DOM4J a já nevím jaké ještě jsou, oproti MarkupBuilderu a XmlSlurperu hotovým utrpením.Ovšem používání Javy není povinné, že. Pokud snad někdo má pocit, že Java je špatná proto, že to není univerzální programovací jazyk na všechno, pak je problém v tom očekávání, ne v tom, že není splněno. Onen triviální přístup ke struktuře XML se někdy může hodit, a jindy se zase hodí vědět, že volání
element("name")
také nemusí dopadnout dobře, protože XML dokument má neočekávanou strukturu. Navíc zrovna triviální přístup k XML dokumentu je jenom takový mezistupeň, na ještě vyšší úrovni je prostá manipulace s objekty, která se někde na pozadí převádí na manipulaci s XML. K tomu ale nepotřebuju nutně plnohodnotný nový jazyk, může klidně stačit i deklarativní jazyk (postavený třeba na XML nebo anotacích nebo čemkoli jiném).
Ovšem používání Javy není povinné, že.Proto říkám, že v řadě případů beru Groovy na milost. V dalších zase ne, když mi víc záleží na "bezpečnosti" než na expresivitě.
list()
či map()
, protože pak je aspoň šance, že se chytne IDE a napoví mi, co do toho psát. Takhle když napíšu {
, nemá IDE šanci poznat, co se bude dít.
[]
(jak pro literál, tak pro přístup), pro blok kódu vždycky {}
, šipka jenom odděluje parametry uzávěru od jeho těla a třeba v následujícím příkladu je perfektně návodná: def mocniny = cisla.collect() { cislo -> cislo * cislo }
. Zato zkratku def mocniny = cisla.collect() { it * it }
pro jednoparametrové uzávěry nepoužívám vůbec.
Pro datové struktury (seznamy, mapy, s přetypováním i pole) je vždycky [] (jak pro literál, tak pro přístup), pro blok kódu vždycky {},Vždycky, ale jen v Groovy. V Pythonu a JS mají seznamy [] a mapy {}, v Perlu seznamy () a mapy (=>)… Veškerý čas ušetřený stručností jazyka pak promrhám hledáním syntaxe v dokumentaci.
Ladíček nehovoril o mapách, ale o blokoch kódu, čiže lexikálnych uzáveroch, ktoré sa pomocou {} realizujú ešte napríklad v Ruby. [] pre pole je prakticky štandard (výnimkou je LISP, kde sú samé zátvorky, a Perl je syntaktický bordel, takže ten sa nepočíta). {} pre mapy nie je moc časté, okrem Pythonu ma momentálne nenapadá ani jeden jazyk. Ostatne, mapy ako také (hoci veľmi užitočná štruktúra) nie sú zďaleka až tak užitočné ako pole/zoznam, ktoré nájdete skutočne všade. Mapy sú len ďalšie z desiatok štruktúr a často je vhodné si ich písať na mieru. V každom prípade, ja by som išiel ešte ďalej a chcel mať možnosť zadefinovať si operátory pre svoje vlastné štruktúry, ktoré by sa v ničom nelíši od tých []/{} built-in. Nemám rád, keď je niečo v jazyku úplne natvrdo a jazyk mi znemožňuje pridávať si doňho ďalšie veci, len kvôli tomu, že návrhár jazyka objavil "jedinú správnu cestu"^{TM}. Toto je presne prípad Javy: aj keď sa po rokoch konečne niečo pohne k lepšiemu, tak zas je to len trochu syntaxe zadrátovanej do jazyka a nič podstatné sa nemení.
Aby som nebol za debila, tak už ma pre tie {} napadol javascript a python. Holt, jazyky, ktoré človek veľmi nepoužíva, čiastočne zabudne. Ale že by som musel pokaždé hľadať dokumentáciu, tak to nie. Proste si sadnem a za pol hodinu som zasa v danom jazyku ako ryba vo vode. A ak ten jazyk potrebujem používať nejaký čas, tak z toho ani nevypadnem a tú syntax si pamätám. Argumentovať proti užitočným vlastnostiam jazykov tým, že máte pamäť na úrovni pásavca, je opäť choré, ale tak, čo už sa s Vami dá robiť
To je špeciálny prípad, nejedná sa o plnohodnotné programovanie. V každom prípade netuším, prečo používate na skriptovanie jazyky, ktoré neovládate. Čo tak sa naučiť aspoň jeden, ktorý budete ovládať? Ja totiž rozhodne netvrdím, že je nutné každý skript písať v inom jazyku, len aby si človek dokázal, že to vie. Ak v tom máte bordel a pamäť na úrovní pásavca, tak sa naučte jeden skriptovací jazyk (python plne dostačuje, pre jvm si vyberte z Java.Next, Jython, alebo čo chcete) a nič iné na tú úlohu nepoužívajte. Ak skriptujete dosť často, tak by sa syntax mala uchovať v neocortexe. V opačnom prípade kontaktujte svojho neurochirurga
To je bez debaty. Ale v tom prípade Vám skutočne nezostáva nič iné ako sa daný jazyk naučiť, s tým sa holt budete musieť zmieriť
Ladíček nehovoril o mapách, ale o blokoch kódu, čiže lexikálnych uzáverochVšiml jsem si, jenže zrovna ohraničení bloků kódu je jedna z mála věcí, ve která panuje největší shoda napříč jazyky. V jazycích s dynamickým typováním a možností přidávat k objektům data nebo funkce za běhu ale může být lexikální uzávěr s mapou totožný.
Nemám rád, keď je niečo v jazyku úplne natvrdo a jazyk mi znemožňuje pridávať si doňho ďalšie veci, len kvôli tomu, že návrhár jazyka objavil "jedinú správnu cestu"^{TM}. Toto je presne prípad JavyA je to tak dobře. Vy tvrdíte, že neexistuje jediná správná cesta, a přitom svoje tvrzení za takovou jedinou správnou cestu považujete.
No, tak o tom by som si dovolil pochybovať. Bloky (ako uzávery) zas tak veľa jazykov nepodporuje. Nie som žiadny odborník na jazyky, ale nič iné ako Ruby a Smalltalk ma teraz nenapadá a zrovna Smalltalk má inú syntax ([i: i*i]). Samozrejme, z nových jazykov Groovy používa {} a JRuby asi nestojí za zmienku. Ale vo funkcionálnych jazykoch napríklad často poriadnu podporu pre bloky nenájdete a píšu sa proste pomocou lambda funkcií (x -> blok kódu).
Nerozumiem tomu o totožnosti uzáveru a mapy. Jedná sa Vám o podobnosť v syntaxi? Že {a,b,c: kód} by bol blok a {a:b, c:d} by bola mapa? To zrejme je možné realizovať nejakou komplexnou analýzou toho výrazu (lebo sémantika tých výrazov je zjavne úplne iná), ale ja osobne nemám rád používanie jedného operátora (obecnejšíe syntaxe) pre dve úplne rôzne veci. Ale toto je už vec vkusu. Alebo ste mysleli realizáciu uzáveru pomocou mapy? Tomu veľmi nerozumiem a budete ma musieť poučiť, momentálne si nič podobné neviem predstaviť.
To sa trochu dostávame do filozofie. Tvrdenie "neexistuje jediná správna cesta" nie je žiadna cesta, je to len názor na povahu ciest. Ak mám na výber 10 možností ako riešiť problém, tak ja tvrdím, že a priori nie je žiadna z nich lepšia ako tie ostatné, na to ich treba analyzovať. Ale to nie je žiadna správna cesta, to je racionálny úsudok, ak už niečo. Naopak, tvorca Javy tú svoju jedinú správnu cestu do Javy zafixoval. Proti tomu nemám nič, ľudia tvoria rôzne jazyky pre svoje potešenie a z ďalších dôvodov. Ale Vy sa mi tu snažíte tvrdiť (alebo aspoň mám ten pocit), že Java je prakticky bezchybný jazyk, na ktorom sa nedá nič vylepšiť a, že je vhodná na riešenie väčšiny problémov a ostatné jazyky tu de-facto odsudzujete z mne neznámych dôvodov.
Ad generování XML: tady se právě hodí oddělení dat/konfigurace od programu. Pomocí DOM knihoven není potřeba generovat celý dokument – vytvořím si šablonu (jako soubor nebo třeba konstantu) a tu si načtu – třeba šablonu pro fakturu, kde je skoro celé to XML (tzn. nemusím ho vytvářet v programu) a v kódu do ní jen na správná místa dogenerují jména, adresy a položky.
A pak tu jsou věci jako JSP(X) nebo FreeMarker, ve kterých se to XML dá generovat celkem bezbolestně.
Výhoda je např. v tom, že takovou šablonu může upravovat i správce nebo neajťák, kterému stačí základní znalosti XML, a nemusí se na to volat hned programátor.
Např. JSPX mi zabrání dělat např. chyby v tom, že bych neuzavřel značku atd., na takovou chybu by se přišlo okamžitě, takže v tom rozdíl oproti vytváření XML v kódu není.
Pokud budu mít šablonu jako soubor/konstantu a načtu si ji jako DOM a pak ji v kódu jen naparametrizuji, opět nemohu udělat více překlepů, než kdybych to měl v kódu všechno. Nevalidní šablona neprojde a chyba se odhalí hned.
Prostě tu otravnou práci kdy musím nějak vytvořit tu vždy stejnou kostru dokumentu nedělám v programově, ale mám ji připravenou jako šablonu. V kódu šablonu jen naparametrizuji, doplním do ní data – a to se dá dělat klidně nad tak primitivním rozhraním jako je org.w3c.dom.Document
.
musím v IDE napsat víc
A sme doma. Častý argument amatérov. Java + IDE = dobrý jazyk takmer platí, pretože Vám umožňuje vyjadrovať sa elegantne, tak ako v ostatných jazykoch. Na druhej strane, to, že Java bez IDE je nepoužiteľný šmejd platí rovnako tak Na rozdiel od poriadnych jazykov, kde IDE síce uľahčuje prácu, ale nie nutným predpokladom toho, aby sa s jazykom vôbec dalo pracovať! Koniec debaty, už vidím, že nie je dôvod pokračovať v diskusii s človekom, ktorého jediný argument v prospech jazyka je ultimátne IDE, ktoré všetky problémy jazyky rieši
Proč bych proboha neměl používat IDE, když můžu??
To je jako kdybych jedl krumáčem a pohrabáčem, když můžu jíst příborem.
BTW: nutným předpokladem IDE není, Java se dá psát i ve VIMu nebo v notepadu, jen to není tak efektivní.
To, že sa v Jave dá bez IDE zaobísť v princípe, ešte neznamená, že je bez IDE použiteľná Vaše "není tak efektivní" zďaleka nevystihuje podstatu. Ja samozrejme proti IDE nič nemám, uľahčujú prácu v každom jazyku. Ale v Jave zakrývajú problémy jazyka, aby sa vôbec dal používať
Automatické vypĺňanie toho balastu, ktorý je nepotrebný a o ktorom som už dávno hovoril, je jedna zo stránok tejto veci. To, že sa ten balast dá vyplniť automaticky pomocou IDE poukazuje na fakt, že ako taký je tam pre počítač (kompilátor jazyka, alebo IDE) úplne zbytočný a len sa ním prasí miesto, aby sa uspokojil archaický Javovský kompilátor (teda kompilátor chudák s tým nič nemá, ten sa len drží archaických Javovských štandardov)
Např. v Netbeans můžu napsat „psvm“ a stisknout tabulátor. Ale klidně si to spublic static void main(String[] args) { }
budu psát ručně. Protože takový kus kódu mám v každém programu maximálně jednou (u webových aplikací ani to ne). To by byl hodně banální a hloupý důvod pro změnu jazyka.
Gettery a settery? Až někdo přijde se slušnou syntaxí, jak tohle řešit, tak budiž – ale např. syntaxe Eiffelu mě nijak nenadchla. A ani tohle není dostatečně závažný důvod ke změně jazyka.
Horší je problém null hodnot
a NPE. Hodilo by se, aby všechny typy byly ve výchozím stavu nenulové a možnost null
by se musela zvlášť deklarovat. Ne že by toho kódu bylo až tolik, ale dá se to označit za balast – kód který ošetřuje, jestli nám někdo jako parametr náhodou nepodstrčil null
.
Ale tie argumenty nepoužívate len raz. Pri každej metóde musíte písať void (alebo iný typ), hocikde static a pod., pritom sa dá zaobísť aj bez toho. A ak chcete silne typovaný statický jazyk, tak v tomto smere je Java tiež na nič, lebo taký jazyk je veľmi zle použiteľný bez type-inference. Na prvé počutie to možno znie ako mágia, ale sú jazyky, kde nemusíte skoro vôbec písať typy návratových hôdnot a argumentov funkcií a napriek tomu si to vie kompilátor zistiť a sú silne typované. Proste ak mám funkciu, ktorá berie int a vracia int a použijem ju v tele wrappera, tak už je jasné, že aj ten wrapper musí byť int -> int a vypisovať to tam je balast navyše (samozrejme, ak je to knižničná funkcia, ktorá sa exportuje, tak je dobré tam ten typ uviesť, aby ste nemiatli používateľa knižnice). To bol elementárny príklad na ilustráciu, ale funguje to aj v oveľa netriviálnejších prípadoch.
Pozreli ste si ten článok, ktorý je tu už 2x linkovaný? Jedná sa o komentáre 3 a 48, ak sa dobre pamätám. Tá syntax sa dá riešiť rôzne (a v ideálnom jazyku si ju môžete napísať po svojom). V každom prípade, je to len implementačný detail -- podstatné je, že to riešenie je úplne inde ako to balastové javovské.
Yup, to je ďalšia z vecí.
Samozrejme, nič z toho balastu v Jave nie je kritické a človek to pokojne napíše. Lenže keď sa nad tým nakoniec zamyslí, koľko času strávil len písaním balastu (v Java.Next článku to volajú ceremony) a koľko je skutočného kódu, ktorý vykonáva nejakú netriviálnu funkcionalitu, tak to je už ako podnet na zmenu jazyka celkom silný motivátor.
Pri každej metóde musíte písať void (alebo iný typ), hocikde static a pod., pritom sa dá zaobísť aj bez toho.Jak kdo se bez toho obejde. Kompilátor třeba ano (i když
static
nevyčaruje ze vzduchu ani kompilátor), ale javovský programátor ne. On se totiž programátor v Javě raději podívá na deklaraci metody a návratový typ si přečte, než by hledal všechna místa ukončující metodu a hledal, jaký je tam použit typ.
Static nie je nič iné ako signalizácia, že daná vec (metóda/premenná) patrí triede a nie objektu. Keby Java bola poriadnym objektovým jazykom, kde aj triedy sú objekty, tak sa to ničím nelíši a nepotrebujete to
To už je len otázkou štýlu, niekto to má radšej tak, niekto onak. Ale v Jave je to riešené "jediným správnym spôsobom", takže nejaký výber si môže programátor nechať pre seba. Lebo napríklad v Haskelli môžete anotovať funkcie, ak sa Vám to skutočne tak silno žiada
f :: Int -> Int
f n = 2*n
Přesně tak.
Metodě předávám nějaké vstupy a očekávám výstup určitého formátu (typu). Co se děje uvnitř mě nezajímá (to je např. práce nějakého kolegy, nebo autora knihovny… nebo moje a ten kód jsem psal už před nějakou dobou), ale potřebuji mít definované rozhraní – vstupy a výstupy (smysl toho, co se děje uvnitř popisuje název metody a komentář).
Moc nechápu, jak si někdo může libovat v chaosu a mít radost z toho, že si nikdy nemůže být jistý, co mu daná funkce/metoda vrátí za typ.
Co se týče static
– tohle slovo by nemuselo existovat, ale pak by muselo existovat slovo, které by nám říkalo, že daná metoda je instanční. Vzhledem k tomu, že instančních metod je většina, jsem rád, že slovo static
v Javě máme. Např. v PHP se dějí někdy hrůzné věci, to jsem takhle viděl programátora, který se divil, co je to za divné varování – varování, že nestatickou metodu nemůže volat bez instance. Prostě spoléhal na to, že při určité konfiguraci se dají i nestatické metody volat bez instance a pokud nepoužívají instanční proměnné, tak ani nespadnou. Resp. ony někdy nespadnou ani když používají instanční proměnné – ty jsou prostě prázdné a za určité konstelace hvězd ten program může fungovat. Ale kde se k tomu dá koupit křišťálová koule?
Moc nechápu, jak si někdo může libovat v chaosu a mít radost z toho, že si nikdy nemůže být jistý, co mu daná funkce/metoda vrátí za typ.Používáte Hibernate?
"Moc nechápu..." -> To ste ale práve vôbec nepochopili. Jedná sa o silne typovaný jazyk, takže tieto chyby Vám oznámi už kompilátor, netreba čakať, kým to spadne za behu. Ale rozdiel oproti Jave je, že nemusíte písať typ, keď netreba. Hovorím, že sa to nemusí zdať na prvé počutie, treba vyskúšať na vlastnej koži. Ale je to sila. Len sa treba odpútať od tých primitívnych predstáv, že silne typovaný jazyk = všade treba uvádzať typy. Ak by toto platilo, tak by som žiadny silne typovaný jazyk nepoužíval, aspoň kým by ma niekto nedonútil
takže tieto chyby Vám oznámi už kompilátor, netreba čakať, kým to spadne za behu.
Takže tyto chyby mi oznámí až kompilátor. Nebo je k tomu nějaké IDE, které by mi to řeklo při psaní kódu? Jak si mám být jistý, že nějaká funkce vrací číslo a ne třeba řetězec, když píšu kód, který ji volá? Mám se dívat do komentáře, nebo do toho kódu, mám si to vždycky zkompilovat?
Pokud má být důvodem úspora času a počtu písmenek, přijde mi tenhle argument absurdní – funkci/metodu deklaruji jen jednou, ale volám ji na mnoha místech. Napsat při deklaraci int/String/cokoli … těch pár písmenek navíc mi opravdu žíly netrhá. Odměnou za to vím, co funkce vrací.
Pokud má být důvodem možnost, vracet různé typy, lze to řešit více způsoby – např.:
O tom vím, zdroják se v IDE kompiluje prakticky neustále, znova a znova. Ale:
String s = objekt.
a IDE mi napovídá metody, které vracejí text. Jak to bude fungovat bez deklarace návratového typu – bude se třída vždycky kompilovat, použije se už zkompilovaná?Asi je to věc vkusu, ale mně takový styl práce nesedí – radši mám, když se předem dohodnou rozhraní (hlavičky metody/funkcí v tomto případě) a pak každý píše ten svůj kód – jeden píše vnitřek metody a druhý píše kód, který ji volá. Kolegův kód mě nemusí ani moc zajímat, nemusím mít ani poslední verzi – stačí, že vím, jaký datový typ vrací a jaké má parametry a ten vnitřek ať asi klidně mění – ale rozhraní je dané předem. A nemusí to být vždy týmová práce – i když programuji sám, tak si rozmyslím, co bude jaká metoda dělat, vstupy a výstupy jsou známé, logiku napíšu do komentáře a implementaci můžu udělat kdykoli později – ale už hned po deklaraci můžu tu (ještě nehotovou) metodu volat z jiných částí kódu…
Ale ještě k mému předchozímu příspěvku – co je tedy důvodem? Úspora pár písmenek nebo možnost vracet různé typy?
radši mám, když se předem dohodnou rozhraní (hlavičky metody/funkcí v tomto případě) a pak každý píše ten svůj kódOno to má ještě jednu souvislost, kterou jsem si uvědomil nedávno v souvislosti s jQuery a Dojo toolkitem. Dojo má metody
dojo.getById()
, dojo.getbyClass()
a dojo.query()
– ve skutečnosti se nejspíš jmenují jinak, ale to je jedno. jQuery má jen $()
, což je obdoba dojo.query()
– a nebo má možná i ty specializované metody, ale v jQuery se evidentně obvykle používá ta obecná funkce. Na první pohled si člověk řekne, že jQuery to má hezky v jednom a Dojo je zbytečně ukecané. jenže pak si uvědomí, že programátor v drtivé většině případů ví, zda hledá podle ID nebo podle třídy. Takže on tu informaci má, pak se informace ztratí a jQuery ji po usilovném parsování zase vynalezne.
Může se zdát, že to se statickým typováním nebo ukecaností Javy nesouvisí, kompilátor má přece času dost, na rozdíl od jQuery, kdy to zdržuje za běhu. Jenže ono nejde jenom o čas. Ona ta informace, kterou programátor má a která se pak ztratí, a kompilátor ji znovu objevuje (ať už je to typ, návratový typ, modifikátor apod.) nemusí znamenat jenom zrychlení kompilace, ale hlavně to znamená kontrolu. Kontrolu toho, že programátor i kompilátor myslí to samé, že dva programátoři myslí to samé, že se někdo nespletl, nedošlo k nějaké chybě. Ostatně proto je třeba v Javě anotace @Override
– Java fungovala a funguje i bez toho, ale použití té anotace dává kompilátoru šanci ověřit, zda programátor nepřekrývá metodu, o které si myslí, že je ve skutečnosti nová, nebo naopak místo překrytí nevytváří novou metodu.
V jQuery Vám nikto nebráni používať objekt jQuery. $ je len užitočný syntaktický cukor. $(huhu) a jQuery(huhu) sú úplne ekvivalentné. Ale na rozdiel od toho Vášho Dojo mám možnosť to používať rozumnejšie, ak chcem O čom to preboha hovoríte človeče? $ je objekt! a $() je metóda, ktorá Vám vráti modifikovaný jQuery objekt (v zmysle javascriptového prototypingu) a ten si môžete niekam uložiť. Nič sa nikde nestratí. Stratil sa len Váš mozog očividne
Bla bla bla. Pozrite si zdrojáky a dokumentáciu jQuery a potom reagujte.
Hm a trochu pochopenia nadsádzky by nebolo tiež?
Schopnosť pochopiť písaný text mám, ale okrem iného je tam napísané, že jQuery má len $(), čo nie je pravda, tak som to vyvrátil, lebo to očividne poukazuje na absolútnu neznalosť tejto knižnice po preštudovaní jedného tutoriálu Ale súhlasím, že som to nepochopil a reagoval som príliš rýchlo, občas to chce nechať hlavu vychladnúť
Ničmenej, rovnako tak ako človek často vie, že hľadá podľa id alebo class, tak často vie, že hľadá podľa iných vecí (detí, atribútov, názvu elementu) a ak tomu rozumiem, pánovi Jirsákovi vadí, že jQuery nemá pre každú z týchto vecí metódu (prečo zostávať len pri id a class, ostatné selectory sa používajú nemenej často?).
Aha a Vy ho chápete dokonale? Musím uznať, že Vám závidím. Ale ja druhým ľuďom do hlavy nevidím, takže môžem pracovať len s tým, čo napíšu a čo pochopím Na mnohých miestach sa mýlil (a nie najmenšou chybou bolo používanie úplne chybných a nikam nevedúcich analógií, polopravdivých implikácií, či úplných lží a to, že na polovicu mojich odstavcov vôbec nereagoval). A netuším, kam mierite Vy zámernou obhajobou len jednej strany. Je pravda, že táto diskusia je viacmenej flame, ale odmietam uznať, že chyba bola len na mojej strane. Chyba je vždy na stranách oboch (nebudem teraz rozoberať na ktorej s väčšou váhou).
Čo máte proti poukázaniu na jeho neznalosť? Je totiž úplne očividná z toho, čo napísal a bola to moja dedukcia. Mám zakázané dedukovať? Absolútna neznalosť nie je nič dehonestujúce, je to proste fakt. Otázka je len to, či vydedukovaný správne, alebo nie, to už nechajme na pánovi Jirsákovi, som si istý, že je schopný sa obhájiť sám, prípadne ako chlap uznať, že je to pravda. Netuším, prečo sa do toho musíte pliesť Vy. A opäť raz, poprosím o trochu odstupu, braniu s humorom, atď. Ľudia reagujú rôzne a to, že Vám poviem, že ste idiot, nemusí ešte nič znamenať, je to len spôsob vyjadrovania. Jeden príklad za všetky: Linus Torvalds. Je to proste rys osobnosti a nepáči sa mi, že ma kritizujete kvôli takým prkotinám (na druhej strane, som na aktivistov za slobodu zvierat ako ste Vy zvyknutý).
To som aj spravil, už som povedal, že som si nechal vychladnúť hlavu. Čo Vám furt vadí človeče? Ste členom jeho fanklubu? Myslíte, že potrebuje ochrancu? Vaše reakcie mi pripadajú veľmi zvláštne.
"Neumíte to uznat" -> Teraz neviem, či klamete, alebo ste len nevšímavý. Prečítajte si znova môj komentár, napísal som, že je to rys mojej osobnosti a spôsob vyjadrovania = uznal som, že sa neviem chovať (v niektorých prípadoch, konkrétnech v nikam nevedúcich flamewaroch). Ale netuším, čo s tým máte spoločné Vy, ani prečo by som sa mal podriaďovať nejakým Vaším etickým zásadám.
Ale netuším, čo s tým máte spoločné Vy, ani prečo by som sa mal podriaďovať nejakým Vaším etickým zásadám.Co s tím mám společného? Jen to, že jsem mohl mít šanci dozvědět se z diskuse něco nového a místo toho se tu rozběhl naprosto zbytečný flamewar včetně ještě zbytečnějšího osobního napadání. Každopádně na úroveň vašich další příspěvků měla moje reakce očividně vliv, takže považuji svoji misi za úspěšnou...
To, že sa tu rozbehol flamewar nebol môj zámer. Tiež som chcel hlavne diskutovať o nových jazykoch a o ich výhodách oproti Jave, ale holt, zvrhlo sa to.
Môj spôsob vyjadrovania závisí silne od počasia, takže na Vašom mieste by som si veľmi nefandil
Tady šlo spíš o to zda volám metodu pro hledání podle třídy případně metodu pro hledání podle id, nebo jestli je to jedna společná metoda pro oboje. V takovém případě se tu ztrácí informace, zda hledáme podle třídy nebo podle id a pak se asi hledá nejdřív podle id a když se nenajde, tak potom podle třídy.
Ok, nepochopil som ten komentár. Ale pre upresnenie, funguje to tak, že sa najprv testuje najprv na html kód a id (jedným regexom) a ak to nefunguje, tak sa aplikuje celý pomerne pokročilý jQuery selector mechanizmus kombinujúci CSS selectory a Xpath. Takže sa rozhodne nejedná o pracné parsovanie a po pol hodine sa zistí, že hurá, dostali sme id. Tak to rozhodne nefunguje. Ten overhead oproti priamej metóde je minimálny a IMHO je oveľa systémovejšie mať ten selekčný mechanizmus pekne pokope. Ale ak niekto zistí, že bottleneck jeho aplikácie je v selectovaní podľa ID, tak prosím, nech veselo používa niečo iné ako jQuery. Nič proti.
getByPrimaryKey()
často máte, pokud dává v kontextu smysl. Záleží totiž na tom, na jaké úrovni abstrakce jste. V programu máte třeba různé zboží, takže chcete vypsat seznam veškerého zboží, vypsat zboží z nějaké kategorie, získat detaily o konkrétním zboží. Funkce vyhledej_v_databazi
do tohoto kontextu vůbec nepatří, protože to zboží ani nemusí v žádné databázi mít. V relační databázi už nemáte žádné zboží, tam máte jen tabulky, sloupce, vztahy. A s tím zase pracují SQL dotazy. Kdyby se databáze chovala podobně jako objekt jQuery
, byl by tam třeba jeden příkaz pro přidání i smazání záznamu. A podle toho, zda primární klíč v tabulce už existuje, by se databáze rozhodla, zda se záznam přidá, nebo smaže (ponechme teď stranou, že pro přidání záznamu potřebujete vědět také ještě údaje, které chcete přidat).
To srovnání jQuery a Dojo toolkitu neměl být útok na jQuery. Jenom jsem popisoval, že v dokumentaci nebo příkladech sice vypadá jedna funkce pro dotazy hezky a Dojo vypadá ukecaně (má 3 funkce na to, co jQuery zvládne s jednou), ale když si člověk uvědomí, jak danou funkci doopravdy používá, zjistí, že Dojo víc odpovídá realitě (pro koncového programátora).
IMHO máte pravdu obaja, lebo je to veľmi subjektívna záležitosť a hlavne vec vkusu.
V tom prípade Vám ale nerozumiem už vôbec. Chcete teda aj metódy getByAttribute a getByChild a getByElementName a ďalších 10 podobných a ďalších 100 ich kombinácií? Netuším prečo/načo/začo. Ladíčkovo SQL bol dobrý príklad, tu je to podobné. Prečo chcete obmedzovať silný selectorový jazyk kvôli dvom špeciálnym podprípadom? A ďalej, ako ste hovorili o vytvorení getByPrimaryKey v programe, tak to už nie je špeciálna metóda, ale metóda využívajúca plnohodnotnú funkcionalitu SQL. Ak to potrebujete, tak nie je problém si v javascripte vyrobiť: jQuery.getById(id) = function (id) {jQuery('#' + id)}. Alebo kde je problém?
Pre mňa to nie sú dve naprosto odlišné operácie. To je ako povedať, že v SQL je naprosto odlišné podľa ktorého stĺpca selectujem a preto budem pre každý stĺpec písať špeciálnu metódu. Veľmi podivné. Nehovorím, že to tak nemôžete robiť, ale ja rozhodne týmto spôsobom neuvažujem. Pre mňa je to celé mechanizmus selectorov, ktorý hrá pekne dokopy (už preto, že tie id, class a ďalšie môžete kombinovať).
Prečo píšete "pracne", keď aj tak tvrdíte, že výkon je podružný? Buď Vám o ten výkon skutočne nejde a potom takéto veci vôbec nepíšte, alebo Vám oň ide, ale potom mi nedoporučujte lepšie čítať, lebo o tom výkone ste sa zmienili nepriamo už veľakrát, takže mi nemôžete mať za zlé, že som to pochopil tak, ako som to pochopil
To je ale opak toho, ako naozaj diskutujete. Namiesto toho, aby ste priamo napísali, o čo presne Vám tu ide, stále píšete do uvodzoviek o výkone a podstatná časť informácie sa stráca. Poslucháč si ju potom musí (bohužiaľ aj nesprávne) domýšľať.
Áno, lenže čo ak pôjdu veci podľa plánu v 99% prípadov, ale Vy vyrábate dvojnásobný overhead pokaždé? Takéto veci tiež treba brať do úvahy. Ak je to mission-critical aplikácia, tak to môže stáť za zváženie, ale ak to 1% chýb nevadí a skôr ide o dvojnásobne vyššiu rýchlosť produkcie kódu (čo IMHO ide takmer vždy). Nehovoriac o tom, že do programu môžete zaniesť ďalšie chyby tým, že píšete tie anotácie a tie potom zasa treba opravovať.
Prečo chcete obmedzovať silný selectorový jazyk kvôli dvom špeciálnym podprípadom?
Rozdíl u těch dvou metod je přinejmenším v tom, že jedna ze své podstaty vrací 0 až n prvků (kolekci objektů) zatímco druhá vrací 0 nebo 1 prků (objekt nebo null).
Pokud abstrahujeme od toho, že se jedná o interpretovaný jazyk a chtěli bychom tento přístup aplikovat v kompilovaném jazyce, kde bychom čekali od kompilátoru nějakou podporu pro odhalování chyb a kontrolu, žádné bychom se nedočkali. Kompilátor by totiž nemohl vědět, zda funkce vrací jeden nebo žádný objekt, pokud textový parametr funkce začíná křížkem, nebo vrací kolekci objektů, pokud začíná na něco jiného. Kompilátor jednak nerozumí významu parametrů a jednak neví, nad jakým dokumentem funkce pracuje.
Ad SQL – vstupem je nějaký příkaz ve formě textu + jeho parametry a výstupem je výsledková sada nebo počet změněných záznamů, případně vyhozená výjimka. Stačí se podívat, jak je to řešené třeba v JDBC – PreparedStatement
má metody jak execute()
, tak executeQuery()
nebo executeUpdate()
. A každá z nich vrací odpovídající datový typ. Můžu z nich dostat i několik výsledkových sad (z jednoho SQL příkazu) nebo libovolnou kombinaci výsledkových sad a updateCount
ů – ani tak údajně hloupý jazyk jako je Java mě v tom nijak neomezuje.
To je hodné zamyslenia, ale v dynamickom jazyku je to šuma fuk.
Interpretovaný/kompilovaný jazyk (čo je vôbec zlý termín, jedná sa len o implementáciu jazyka) a dynamický/statický jazyk sú dve rôzne veci. Predpokladám, že Vám ide o tú statickú kontrolu pri kompilovaní. To je samozrejme o niečom inom. Bolo by treba napísať kompilátor tých selectorov a potom by sa dalo kontrolovať aj staticky, nevidím problém.
Nepoznám Javovské SQL knižnice. Môžete bližšie vysvetliť rozdiel medzi execute a executeQuery? Tak či onak, pri SQL (rovnako ako selectoroch) nemáte žiadnu statickú kontrolu. Napríklad si predsavte, ze máte SQL "select ... where primary_key=...". Jedná sa o výsledok, ktorý vracia vždy 0 alebo 1 objekt. Je v Jave pravda, že nedostanem kolekciu, ale objekt? Nie je. Prečo chcete rozlišovať medzi rôznymi SQL príkazmi pomocou programatických funkcií, ktoré tak či tak do toho SQL nevidia a teda už z princípu nemôžu vedieť, či sa vráti objekt, alebo kolekcia. Museli by ste napísať kompilátor SQL, aby ste boli schopný túto informáciu zistiť. A to je samozrejme nereálne.
Nepoznám Javovské SQL knižnice. Môžete bližšie vysvetliť rozdiel medzi execute a executeQuery?
http://java.sun.com/j2se/1.5.0/docs/api/java/sql/PreparedStatement.html
Napríklad si predsavte, ze máte SQL "select ... where primary_key=...". Jedná sa o výsledok, ktorý vracia vždy 0 alebo 1 objekt. Je v Jave pravda, že nedostanem kolekciu, ale objekt? Nie je.
JDBC — Java Database Connectivity. Již ze samotného názvu vyplývá, že se jedná o univerzální přístup k databázím. Metody typu int executeQueryReturningInteger(String, Object[])
v takovém frameworku opravdu nemají co dělat.
Prečo chcete rozlišovať medzi rôznymi SQL príkazmi pomocou programatických funkcií, ktoré tak či tak do toho SQL nevidia a teda už z princípu nemôžu vedieť, či sa vráti objekt, alebo kolekcia. Museli by ste napísať kompilátor SQL, aby ste boli schopný túto informáciu zistiť. A to je samozrejme nereálne.
Možná proto, že SQL se dělí na DDL, DML, DCL a TCL? A mezi námi, ani ten kompilátor ti nevyndá, protože když bude SQL příkaz ve stylu
EXECUTE my_procedure :1 go
ani kompilátor nepozná, kolik ResultSet
ů ti to volání vrátí, že?
Dík, ale chcel som len jednu vetu, to by bolo pre nás oboch jednoduchšie ako hľadať API a hlavne, dôvod, prečo o tom vôbec písal
Súhlasím. Lenže táto diskusia je presne o tom, že takéto metódy nechceme (teda aspoň ja nie), lebo je to neelegantné a inak nevýhodné.
Nie o to mi nešlo. Išlo mi skutočne o to, že pre vonkajší jazyk (Java) je domain-specific jazyk (SQL) čierna skrinka, s ktorou si staticky bez kompilátoru neporadí. Ale dík, za upozornenie, že si s ním neporadí ani tak. To je tým, že SQL je dynamický jazyk a preto tam tá statickosť nefunguje. Ale keby bol statický (ako napríklad tie CSS selectory, tie AFAIK sú), tak je ten kompilátor aspoň v princípe možný. Ničmenej, môj argument práve bol, že rozlišovanie medzi takýmito funkciami (vracajúcimi kolekciu/pole) je chybné (aspoň do doby, kým nebudeme mať poriadne statické silne typované jazyky a poriadne možnosti ich previazania).
Dík, ale chcel som len jednu vetu, to by bolo pre nás oboch jednoduchšie ako hľadať API a hlavne, dôvod, prečo o tom vôbec písal
Já nic nehledal. URL si pamatuji.
Súhlasím. Lenže táto diskusia je presne o tom, že takéto metódy nechceme (teda aspoň ja nie), lebo je to neelegantné a inak nevýhodné.
Nie o to mi nešlo. Išlo mi skutočne o to, že pre vonkajší jazyk (Java) je domain-specific jazyk (SQL) čierna skrinka, s ktorou si staticky bez kompilátoru neporadí. Ale dík, za upozornenie, že si s ním neporadí ani tak. To je tým, že SQL je dynamický jazyk a preto tam tá statickosť nefunguje. Ale keby bol statický (ako napríklad tie CSS selectory, tie AFAIK sú), tak je ten kompilátor aspoň v princípe možný. Ničmenej, môj argument práve bol, že rozlišovanie medzi takýmito funkciami (vracajúcimi kolekciu/pole) je chybné (aspoň do doby, kým nebudeme mať poriadne statické silne typované jazyky a poriadne možnosti ich previazania).
Já se s dovolením dále této diskuze účastnit více nebudu. Na mě je to jen zbytečné teoretizování. Beztak zejtra přijdu do práce a musím dealovat s realitou. Takže místo teorie se s dovolením půjdu věnovat realitě.
Uau.
Nech sa páči. Už aj tak tu skoro nie je o čom diskutovať. Ja som inak v práci aj dnes, a bez problému stíham diskutovať. A to všetko len vďaka tomu, že nepoužívam Javu
Já ji také v práci nepoužívám. A docela mě to mrzí, protože se mi to prostředí docela líbí. Pro mě má Java nejméně omezení ze všech ostatních. Ale což; život nás dovedl jinam…
A abych jen vyjádřil svůj názor ke zde diskutovanému zkratkování — já jsem zásadně proti. Prostě pokud má nějaká void main(String[])
být vstupním bodem programu, pak musí být public static
. Hoši nademnou vysypali snad všechny důvody, proč to tak být má a proč ne. Souhlasím s nimi.
Třeba kolega Ládíček (doufám, že to byl on), který zde představil jeho meta-jazyk skrývající typy v implementaci. Tak s tím já prostě musím nesouhlasit. Ať si zkusí v takovém metajazyku bez typů naimplementovat třeba to neblaze proslulé JDBC API. Psal jsem tu test-casy pro JDBC fasádu, tak jsem byl nucen naimplementovat mock verzi JDBC. Hnus prašivej. Ale bez typů v implementujících třídách by to prostě nešlo.
Dále:
def variable = function_call(arg1, arg2);
Nesouhlasím. Tento kód znamená, že proměnná variable bude typová až od té doby, co funkce function_call() něco vrátí. V případě refaktoringu kódu se může návratová hodnota function_call() změnit a kód se mi může vysrat až za běhu. Kdyby tam bylo rovnou:
String variable = function_call(arg1, arg2);
tak mě kompilátor (nebo IDE) rovnou upozorní, že tam není něco košér. Uznávám, že refaktor takového kalibru je hodně drsnej (mění se nejen implementace ale i API), ale občas prostě člověk šlápne do … (do toho, do čeho při měsíčku). Ano, můžu si pak nechat nají usages pro každou metodu, ale proč, když to může být by design?
Takže asi tak, no… Ale já jsem jen amatér, kterej používal IDE.
Hm, už to bolo diskutované, ale ten static mi nedá, lebo môj komentár ti asi ušiel. A to totiž, že ak by Java bol poriadny OOP jazyk, kde aj trieda je objekt, tak je keyword static nepotrebný Druhá otázka je, aký overhead má byť čistý OOP jazyk a ak na to designéri Javy mysleli a navrhli Javu ako čiastočne OOP kvôli rýchlosti, tak ok, v tom prípade sa nedá svietiť. Ale len toľko som chcel, že existujú aj alternatívy (a IMHO lepšie
).
Čo je to za príklad, to def variable? Porovnávate Javu s dynamickými jazykmi? V tom prípade samozrejme nejaký compile time type checking moc nefunguje Ale ak ju porovnáte napríklad s Haskellom (silný statický jazyk s poriadnym type inference), tak je to už niekde inde.
Njn, to sa holt nedá svietiť, IDE corrupts even the best of us
Hm, už to bolo diskutované, ale ten static mi nedá, lebo môj komentár ti asi ušiel. A to totiž, že ak by Java bol poriadny OOP jazyk, kde aj trieda je objekt, tak je keyword static nepotrebnýNěco mi říká, že by to znamenalo pouze klíčové slovo
static
nahradit jiným klíčovým slovem, nebo třeba definicí v jiném souboru. Tedy ono záleží na tom, co přesně byste chtěl k Javě přidat, abyste javovskou třídu uznal za objekt.
Nie, to teda neznamenalo. Príklad, mám triedu (a zároveň objekt) DogClass. Ak spravím DogClass.static_method = ..., tak som zadefinoval statickú metódu. Ak si chcem vytvoriť inštanciu triedy, tak Dog = DogClass.new a ten môže používať ako svoje vlastné metódy, tak metódy statické (ale záleží od jazyka, niektoré pre to majú špeciálnu syntax a inde sa musí robiť niečo ako Dog.Class.static_method). V každom prípade netreba žiadne ďalšie kľúčové slovo, ak je teda trieda skutočne plnohodnotným objektom.
Hm, máte pravdu, to ja stále zabúdam na tie statické objektové jazyky Ale určite by to nejako vymyslieť šlo. Aspoň dúfam.
Druhá varianta je zrejmá, ale skutočne by to bol už iný jazyk.
Ono to svým způsobem jde – program si přes class loader může natahovat další třídy nebo se dá použít BeanShell (ten dělá Javu docela dynamickou, to by se mohlo některým lidem líbit) … klidně by mohl existovat program, který by se sám upravoval, sám se kompiloval a za chodu by si ty nové třídy načítal a spouštěl jejich metody, mohl by být třeba i uměle inteligentní a rozvíjet se… ale pracovat s ním by bylo asi docela peklo (natož ho ladit a vyvíjet)
Čo to je za sprostý pohľad na metaprogramovanie? To mi chcete povedať, že ste ešte nepočuli o programoch, ktoré modifikujú sami seba a iné programy?
Virusy?
To je pravda druh metaprogramovania Ale napríklad aj kompilátor? Počuli sme už také slovo?
Hm, už to bolo diskutované, ale ten static mi nedá, lebo môj komentár ti asi ušiel. A to totiž, že ak by Java bol poriadny OOP jazyk, kde aj trieda je objekt, tak je keyword static nepotrebnýDruhá otázka je, aký overhead má byť čistý OOP jazyk a ak na to designéri Javy mysleli a navrhli Javu ako čiastočne OOP kvôli rýchlosti, tak ok, v tom prípade sa nedá svietiť. Ale len toľko som chcel, že existujú aj alternatívy (a IMHO lepšie
).
To mi ušlo záměrně. Java je taková, jaká je a je na tobě, jestli ji takovou přijmeš, nebo ne. Spíš mě štve package protected
, neexistence unsigned
primitivních typů, hrozba closures (nebo jak se ten hnus jmenuje) a ignorace generik ve Swingu (TableModel
a jeho příbuzní). Celý to teoretizování na úrovni co by kdyby řadím do kategorie Pozdě bycha honiti — tedy ztrátu času a energie.
Čo je to za príklad, to def variable? Porovnávate Javu s dynamickými jazykmi? V tom prípade samozrejme nejaký compile time type checking moc nefungujeAle ak ju porovnáte napríklad s Haskellom (silný statický jazyk s poriadnym type inference), tak je to už niekde inde.
Jen jsem chybně papouškoval, co jsem zde zahlédnul. A mezi námi — je mi jasné, že ten, kdo je schopen odstranit modifikátory viditelnosti (zavést defaulty) popřípadě datové typy v implementacích, sáhne i na toto. Proto se to snažím mým odsouzením zarazit hned v počátcích, jinak to dopadne jako ty closures. Já v Javě tyhle nesmysly nechci a prostě tam nebudou.
Njn, to sa holt nedá svietiť, IDE corrupts even the best of us
Není vůbec pravda. IDE jen zjednodušuje práci. Nic víc. Na práci vývojáře nemá vůbec vliv. Já třeba psal jednoduchý nástroje v Javě na AIXu jen pomocí mkdir
, cat
, sed
, javac
a jar
. Bez chyby a s komentáři.
Ja viem, že je to na mne a neprijal som ju (slabé slovo) už dávno Ničmenej, určite sa dajú diskutovať rôzne riešenia použité pri návrhu Javy a kopa ďalších vecí a porovnania s rôznymi jazykmi za účelom zistenia, či sa jazyk nedá zlepšiť (a odpoveď je áno, preto sa stále zvyšuje číselko za JDK
). Closures je hnus? Nejaký argument proti by sa našiel? Skutočne som zvedavý, lebo closures sú lambda funkcie vo svojej podstate a teda ultimátne základ všetkého programovania (viď Alfonso Church) izomorfný Turingovým strojom (a tým nechcem povedať, že sú rovnako zlé použiteľné v praxi
).
Nerozumiem stále, o čo s tým defaultom išlo a už vôbec ako to súvisí s uzávermi :-/
Jak sa to vezme. V ťažkopádnejších jazykoch ako je Java, za programátora odvedie kopec práce pri vypĺňaní balastu. V normálnych jazykoch oveľa menej
Drobná oprava: Lambda kalkulus je izomorfný Turingovým strojom. Ale Lambda kalkulus bez lambda funkcií je tak trochu, jak to povedať...
Closures je hnus? Nejaký argument proti by sa našiel?Closures v Javě jsou hnus. Protože je to pouze zkrácený zápis anonymní třídy s jednou metodou bez parametrů (mimochodem mne nenapadá žádný interface, který by téhle specifikaci odpovídal).
Chci zapisovat do proměnných z definující metodyTo ale nijak nesouvisí s uzávěry. To vám Java nepovolí uzávěry neuzávěry, a pokud to povolit chcete, žádné uzávěry k tomu nepotřebujete.
chci nelokální návratOpět jen zkrácený zápis pro něco, co se prakticky vůbec nepoužívá.
A ano, chci zkrácený zápis, protože mi tenhle styl programování vyhovuje a narážím na to dnes a denně.Pak byste asi měl zvolit jiný jazyk, třeba Groovy. Existuje takový vtip, že opravdový programátor ve Fortanu programuje ve Fortranu v libovolném programovacím jazyce. U Javy to evidentně funguje opačně – spousta programátorů se v Javě snaží programovat Groovy, C++, PHP, Haskel, Python…
spousta programátorů se v Javě snaží programovat Groovy, C++, PHP, Haskel, Python…
jj, tohle je zajímavé – a rád bych věděl, co je vede k používání té blbé javy, když jsou daleko lepší jazyky. Je to platforma? Nebo jim někdo psát v Javě nařídil? Nebo…?
To je pochopitelně nesmysl a o vytváření vlastních řídicích struktur už jsem psal výše. A to je jenom začátek, s uzávěrama můžete dělat ještě zajímavější věci (rada: kontinuace)Psal jsem „něco nového“. Věci, které se teď bez problémů v Javě dělají bez uzávěrů nepovažuju za nic nového.![]()
Že je považujete za nepřehledné už jste tady napsal. Váš názor bohudíky není názorem většiny.Tak si schválně zkusme vzít příklady z BGGA a přepsat je klasickým způsobem, ať můžeme porovnat přehlednost:
{ => new Runnable() { public void run() { System.out.println("hi from Prague"); } } }.invoke().run(); // invoke() returns an instance of Runnable and we // call run() on it immediately
new Runnable() { public void run() { System.out.println("hi from Prague"); } }.run();
// this will print "31 is odd" and return 15 int half = { int x => if (x % 2 != 0) System.out.printf("%d is odd%n", x); x / 2 }.invoke(31);U uzávěrů má jím asi o to, že je možné je přiřadit do nějaké proměnné a použít jinde. V blogu Zdeňka Troníčka to sice uvedeno není, ale je to v odkazovaném návrhu. Tak si porovnejme i to.
// this will print "31 is odd" and return 15 int x = 31; if (x % 2 != 0) { System.out.printf("%d is odd%n", x); } int half = x / 2;
public interface Function { Runnable invoke(); } Function f = { => new Runnable() { public void run() { System.out.println("hi from Prague"); } } };Ušetřili jsme tři řádky vygenerované automaticky IDE. A to se vyplatí!
public interface RunnableFactory { Runnable createRunnable(); } RunnableFactory f = new RunnableFactory() { public Runnable createRunnable() { return new Runnable() { public void run() { System.out.println("hi from Prague"); } }; } };
{ => new Runnable() { public void run() { System.out.println("hi from Prague"); } } }.invoke().run();To myslíte vážně?
{ => System.out.println("eff off"); }.invoke();Zbytek téhle demagogie nehodlám komentovat.
{ => System.out.println("eff off"); }.invoke();To myslíte vážně?
System.out.println("eff off");
executor.execute(new Runnable() { public void run() { System.out.println("..."); } });vs.
executor.execute({ => System.out.println("..."); });Což mimochodem právě u Zdeňka Troníčka najdete.
executor.execute() { System.out.println("..."); }
Předpoklady v realitě, na kterou jste navyklý, v jiné nemusí vůbec platit.Pak by bylo dobré najít takové příklady uzávěrů v Javě, které mají opodstatnění v reálných Javovských programech. Je zbytečné mít uzávěry, které se budou dobře vyjímat akorát v příkladech na užití uzávěrů.
Jo a data, data pochopitelně máte – právě z lexikálního uzávěruA to je právě to, co nechci. Pokud ta data patří jenom tomu kódu, nemá k nim mít nikdo jiný přístup.![]()
Jinak to, co jsem napsal přetím, by mohlo být ještě trochu líp: executor.execute() { System.out.println("..."); }Kdy v reálném javovském programu potřebujete někam předat krátký kus kódu, který se nikdy nikde jinde zaručeně nepoužije? Já kdykoliv bych na něco takového narazil, udělám z toho normální metodu, kterou můžu zavolat z více míst, třeba z testu.![]()
Pak by bylo dobré najít takové příklady uzávěrů v Javě, které mají opodstatnění v reálných Javovských programech.Zkuste si porovnat Fork-Join bez uzávěrů a s nimi.
Kdy v reálném javovském programu potřebujete někam předat krátký kus kódu, který se nikdy nikde jinde zaručeně nepoužije?Neustále. Hledání, řazení, transformace, *Template, callbacky. Možná uvažuju jinak než vy, ale na to mám plné právo.
Zkuste si porovnat Fork-Join bez uzávěrů a s nimi.Zrovna nedávno tady byl dotaz na SwingWorker, kdy tazatel použil klasický příklad použití SwingWorkeru jako anonymní třídy, ale pak zjistil, že je lepší mít ten worker v oddělené třídě – a bylo potřeba zapomenout na anonymní třídu a jistou „magičnost“ toho kódu, pochopit,jak SwingWorker doopravdy funguje, a pak jej použít. S uzávěry by ten kód v nějaké učebnici byl ještě magičtější, ovšem po přikročení k reálnému programování by opět bylo nutné říct: zapomeňte na uzávěry a nastudujte si znova, jak se to dělá správně.
Neustále. Hledání, řazení, transformace, *Template, callbacky. Možná uvažuju jinak než vy, ale na to mám plné právo.Vy máte spoustu kódu pro řazení, který se používá pouze v jediné metodě a zaručeně se nikdy nepoužije nikde jinde? To samé s transformacemi, callbacky, šablonami? Nebo ten kód používáte na více místech, ale místo volání jedné a té samé metody prostě okopírujete příslušný kód? Taky musí být výborné psát pro takovýhle kód testy. Jak to děláte – testy nepíšete,a doufáte, že to bude řadit správně, nebo do testu ten výkonný kód řazení zkopírujete a doufáte, že až se změní výkonný kód, nezapomenete jej znova okopírovat i do testu? Tenhle přístup nezadržitelného toku kódu má v oblibě třeba Spring nebo Struts – spousta kódu v jedné metodě, a když chcete v potomkovi pozměnit chování, musíte si pěkně okopírovat 200 řádků kódu té původní metody a v něm pak jeden řádek změníte. Aneb znovupoužitelnost kódu v praxi.
class DescendingComapartor implements Comparator<String> { public int compare(String s1, String s2) { if (s1 == null) { return s2 == null ? 0 : 1; } return -s1.compareTo(s2); } } … String[] a = …; Arrays.sort(a, new DescendingComapartor());Metodu
equals
vynechávám, abych vám nedával zjevně neřešitelné úkoly.
Comparator<String> comparator = { String s1, String s2 => s1 == null ? (s2 == null ? 0 : 1) : -s1.compareTo(s2) }Když teda pominu, že váš úchvatný
DescendingComparator
je skvělý kandidát na zrušení a nahrazení obecným ReverseComparatorem
, pro řetězce v kombinaci s přirozeným řazením. Získáte ho v každé druhé javovské knihovně a máte po starostech. _To_ je znovupoužitelnost a testovatelnost, na kterých kupodivu apriori lpíte bez ohledu na to, jestli se jedná o jednorázový skript nebo projekt na dvacet let.
comparator
je privátní člen nějaké třídy nebo proměnná v metodě. Pokud by to byl veřejný statický člen třídy, je to úplně to samé, jako definice třídy – stačí rovnítko nahradit za kulaté závorky.
Ten příklad samozřejmě může fungovat s kterýmkoli jiným objektem a kód pro porovnání může být složitější, což pouze nahrává ve prospěch třídy a v neprospěch uzávěru. Pouze jsem nechtěl v kódu používat další neznámou třídu.
class DescendingComapartor implements Comparator<String> { public int compare(String s1, String s2) { if (s1 == null) { return s2 == null ? 0 : 1; } return -s1.compareTo(s2); } } … private void doSomething() { String[] a = …; Arrays.sort(a, new DescendingComapartor()); } private void doSomethingElse(String[] names) { Arrays.sort(names, new DescendingComapartor()); } … public Test { @Test public void testDescendingComparator() { String[] a = new String[] {"a","z","c"}; Arrays.sort(a, new DescendingComapartor()); Assert.assertArrayEquals(a, new String[] {"z", "c", "a"}); } }
class Trida1 { private void doSomething() { String[] a = …; Arrays.sort(a, { String s1, String s2 => s1 == null ? (s2 == null ? 0 : 1) : -s1.compareTo(s2) }); } } … class Trida2 { private void doSomethingElse(String[] names) { //TODO kopie kódu z třídy Trida1. Zrušit uzávěr a nahradit společnou implementací Arrays.sort(names, { String s1, String s2 => s1 == null ? (s2 == null ? 0 : 1) : -s1.compareTo(s2) }); } } … public Test { @Test public void testDescendingComparator() { //TODO až bude zrušen uzávěr použitý v třídách Test1 a Test2 a nahrazen společným kódem, dopsat pro něj test } }
Mimochodem právě před chvilkou jsem zase zalitoval, že v Javě nejsou uzávěry, a musel (po kolikáté už?!) vytvořit jednometodové rozhraní, které má právě jednu anonymní implementaci. Abych znovupoužil existující odladěný kód bez jeho jediné změny. A víte, co si u toho myslím? Že mi Java háže klacky pod nohy, protože očekává primitivní uvažování a je zoufale nepružná.Příklad by náhodou nebyl? Aby bylo možné se podívat, zda je to chyba Javy nebo chyba vašeho kódu.
null
hodnot) třeba
public static <T extends Comparable<T>> void reverseSort(List<T> list) { Collections.sort(list, { T o1, T o2 => o2.compareTo(o1) }); } public static <T> void reverseSort(List<T> list, Comparator<T> comparator) { Collections.sort(list, { T o1, T o2 => comparator.compare(o2, o1) }); }a pak pro
List<String> list
používat
list.reverseSort(); list.reverseSort({ String s1, String s2 => ... });Akorát si teď všímám, že existuje
Collections.reverseOrder()
, o tom ani nevím with(CompassSession sess : compass.openSession()) { sess.queryBuilder().queryString("...").hits().each(CompassHit hit :) { System.out.println("Found " + hit.resource().id()); } }Upozorňuji, že by se to dalo napsat i jinak, možná i o trochu líp, to už by záleželo na návrhu API – já to napsal pro existující API projektu Compass (akorát že
CompassSession
snad neimplementuje Closeable
). Ty statické metody, za které mne tak prcáte, by tady byly dvě:
<T extends Closeable> void with(T resource, { T => void } callback) { try { callback.invoke(resource); } finally { resource.close(); } } <T> void each(Iterable<T> iterable, { T => void } callback) { for (T element : iterable) { callback.invoke(element); } }Jestli nechápete, že to vede k lepšímu API a čitelnějšímu kódu, budiž vám země lehká. Amen.
for (CompassHit hit : compass.openSession().queryBuilder().queryString("...").hits()) { System.out.println("Found " + hit.resource().id()); }
Jestli nechápete, že to vede k lepšímu API a čitelnějšímu kódu, budiž vám země lehká.Ano, to nechápu, protože jsem zatím neviděl jediný příklad, na kterém by to bylo vidět. Všechny příklady měly buď horší API, nebo se nakonec dospělo k APi srovnatelnému s tím, jaké je možné navrhnout dnes, a uzávěry tam byly zbytečné – maximálně sloužily k zamlžení kódu. Opravdu rád bych někdy viděl příklad na uzávěry v Javě, který bude pořádně napsaný (tj. bude splňovat nějaké požadavky na kvalitu kódu) a který nepůjde triviálně přepsat na kód bez uzávěrů. Zatím to totiž vypadá, že uzávěry v Javě jsou dobré jenom k tomu, aby bylo možné rychle naprasit nějaký kód, který pak následně bude muset stejně někdo upravit, vyčistit (a při té příležitosti mu uzávěry samy od sebe zmizí).
Krom toho už na těch pár řádkách jste dokázal zahodit jednu klíčovou věc: tu session je třeba nakonec zavřít! Neuznáváte metodu with? No to už jste ještě dál než Josh Bloch, který je sice vášnivým odpůrcem BGGA, ale je mu jasná aspoň potřeba "automatic resource managementu". (Klíčová slova: CICE, ARM).Na to stačí jeden další řádek. Ostatně ve vašem kódu se ta session také nezavírá, a pokud to dělá
with()
, je to přesně ten druh magického provádění na pozadí, který do Javy nepatří. Pak bude každý druhý programátor opisovat with()
z nějakého příkladu, a vůbec nebude tušit, že je potřeba session zavřít, a že když se to nepodaří, je třeba na to nějak reagovat (protože to třeba znamená, že se data nikam nezapsala).
Možná Java není určená pro lidi, kteří přemýšlí takhle, ale vyhrazuju si právo chtít opakTo právo vám nikdo neupírá, jenom doufám, že pro vaše požadavky vznikne jiný jazyk (co třeba Groovy, to by vám nevyhovovalo?), a Java se bude dál rozvíjet svým směrem.![]()
Na to stačí jeden další řádek.Nestačí. Na to potřebujete blok
try { } finally { }
.
Ostatně ve vašem kódu se ta session také nezavíráZavírá.
pokud to dělá with(), je to přesně ten druh magického provádění na pozadí, který do Javy nepatříJo, dělá. Taky jsem vám tam definici
with
napsal. Ohó, magie?! To je ta vaše znovupoužitelnost a testovatelnost. Jestli vám
CompassSession sess = compass.openSession(); try { ... } finally { sess.close(); }přijde lepší než
with(CompassSession sess : compass.openSession()) { ... }pak asi každý mluvíme o jiné znovupoužitelnosti, testovatelnosti, jednoduchosti a kvalitě vůbec. To není magie, to je modularita. Prostředky je nutné uvolňovat (víte, že jste vlastně tím svým zjednodušením v minulém příspěvku vyrobil memory leak?) a tohle je bezkonkurenčně nejjednodušší způsob, jak toho jednotně dosáhnout. JDBC, Hibernate, práce se soubory, se sítí, whatever. Tam všude píšete
try { } finally { zavři(prostředek); }
a testujete, že k uvolnění došlo a došlo k němu správně? Pak jste to vy, kdo neustále bezmyšlenkovitě kopíruje kód, který lze vytknout do jediné pomocné metody. Snippety v IDE, pravda? pro vaše požadavky vznikne jiný jazyk (co třeba Groovy, to by vám nevyhovovalo?), a Java se bude dál rozvíjet svým směremGroovy mi vyhovuje, jak už jsem tady psal, a proto ho používám, kde můžu. Ale nebojte – dřív nebo později se buďto BGGA nebo CICE/ARM do Javy dostanou
with
obyčejně znamená, že se dále bude pracovat s daným kontextem (aby nebylo nutné neustále opakovat např. přístup ke stejné proměnné). To, že vaše with
ještě navíc uzavírá zdroje, navíc bez nějakého ověřování, zda se uzavření podařilo, je chyba. Stačí, že pak budu chtít se session dál pracovat, ale ono to nepůjde, protože mi ji with()
mezitím uzavřelo pod rukama.
Ano, ten kód s try … finally
mi připadá lepší, protože je tam vidět, co se tam děje. Váš kód je srovnatelný se spoléháním na uzavření zdrojů ve finalizátoru – také k němu někdy možná dojde a programátor se o to nemusí starat.
Ano, try … finally
píšu, protože tam samozřejmě stejně mám try … catch
, takže dopsat finally
větev už je to nejmenší. A hlavně nemusím pokaždé přemýšlet o tom, zda ve finally chci udělat ještě něco jiného, a pak zvolit try … catch … finally
, nebo zda mi stačí uzavřít zdroje, a pak stačí try … catch
obalené nějakým close { … }
.
with
také třeba v JavaScriptu. Samodokumentující ten kód není ani náhodou, a rozdíl mezi opakováním with{…}
a try … finally …
také nevidím. Třeba při použití více zdrojů (u JDBC jsou zpravidla potřeba minimálně 3) budete mít do sebe tři vnořené with
a já pořád jeden try … finally …
.
try catch finally
u JDBC už jsme v téhle diskusi viděli a je to poměrně hnůj. Já se tu těm výjimkám vyhýbám, protože vůbec není jednoduchý to napsat správně. Ale právě proto je výhodnější mít to napsané jen na jednom místě… třeba v takové pomocné metodě typu with InputStream
em:
InputStream in = ...; try { in.read(); ... } catch (IOException e1) { ... } finally { try { in.close(); } catch (IOException e2) { // ??? } }To samo o sobě je dost děsivé. Když k tomu přidáte
OutputStream
, jako že to není neobvyklé, bude to ještě horší. Tři zdroje – hrůza pomyslet. U toho JDBC je to trochu jednodušší než v obecném případě, ale rozhodně dostatečně komplikované na to, aby si příčetný člověk nedovolil psát to pokaždé znovu.
S with je to rázem o poznání jednodušší, a to i když budete mít jen variantu pro jediný Closeable. Což ovšem není nutné, klidně můžete mít pro dva:
<T extends Closeable, U extends Closeable> void with(T resource1, U resource2, { T, U ==> void throws IOException } callback) throws IOException { boolean wasExceptionThrown = false; try { callback.invoke(resource1, resource2); } catch (IOException e1) { wasExceptionThrown = true; throw e1; } finally { try { resource2.close(); } catch (IOException e2) { if (!wasExceptionThrown) { wasExceptionThrown = true; throw e2; } } finally { try { resource1.close(); } catch (IOException e3) { if (!wasExceptionThrown) { throw e3; } } } } }Je to trochu komplikovanější než kdyby to bylo pokaždé napsané znovu, ale ne o tolik (je tam navíc jen to zapamatování, zda už byla nějaká výjimka vyhozena, abych nevyhazoval žádnou další), a hlavně je to obecné. Nechcete psát takovou hrůzu pokaždé, že ne? Samozřejmě ani teď si nejsem jistý, že to je doopravdy správně, ale vím jistě, že nic podobného se mi nechce psát (ani kopírovat) pokaždé znova. Takovouhle metodu může napsat někdo, kdo tomu opravdu rozumí, a všichni ostatní mohou už jen psát
with(InputStream in, OutputStream out : new InputStream(...), new OutputStream(...)) { in.read(); out.write(); ... }a při chybě dostanou zadarmo tu správnou výjimku včetně korektního (pokusu o) uzavření obou streamů. Ještě nevidíte výhody? Pojďme dál. S JDBC byste mohl dosáhnout s trochou úsilí mnohem lepšího výsledku než je pouhé zavírání konexí, statementů a resultsetů, například:
doInTransaction(Connection conn : openConnection()) { List<ObjectInfo> infos = Lists.newArrayList(); // <T> void iterateResults(Connection conn, String sql, { ResultSet ==> void } callback) iterateResults(ResultSet rs : conn, "SELECT id, name, create_time FROM objects LIMIT 100") { ObjectInfo info = new ObjectInfo.Builder() .setId(rs.getLong("id")) .setName(rs.getString("name")) .setCreateTime(rs.getDate("create_time")) .build(); infos.add(info); } // nebo jinak // <T> List<T> collectResults(Connection conn, String sql, { ResultSet ==> T } callback) infos = collectResults(ResultSet rs : conn, "SELECT id, name, create_time FROM objects LIMIT 100") { new ObjectInfo.Builder() .setId(rs.getLong("id")) .setName(rs.getString("name")) .setCreateTime(rs.getDate("create_time")) .build(); } // <T> int batchUpdate(Iterable<T> list, Connection conn, String sql, { T, PreparedStatement ==> void } callback) int updatedCount = batchUpdate(ObjectInfo info, PreparedStatement stmt : infos, conn, "UPDATE objects SET name = ?, create_time = ? WHERE id = ?") { stmt.setString(1, info.getName()); stmt.setDate(2, info.getCreateTime()); stmt.setLong(3, info.getId()); } }K jednotlivým voláním jsem se pokusil do komentáře připsat signaturu, rozšíření o SQLException (asi nejpitomější kontrolovaná výjimka vůbec) a implementaci ponechávám jako cvičení na libovůli ctěného čtenáře
finally
volám jednoduše IOUtil.close(stream)
, IOUtil.close(stream, logger)
, nebo něco podobného, co se v daném projektu používá (a nepotřebuju mít příslušnou metodu přetíženou na 7 parametrů, prostě zavolám funkci close()
sedmkrát ve správném pořadí, aniž bych musel studovat, zda je správné pořadí zleva doprava nebo opačně). Ty transakce se úplně stejně řeší anotací na metodě, a vede to přesně k tomu, že mají (skoro) všichni pocit, že o transakce se něco stará automagicky (chtěl jsem napsat automaticky, ale ono je to s tím překlepnutým „g“ vlastně přesnější). Než bych zjišťoval, co doInTransaction přesně s transakcemi dělá, napíšu si ten jeden nebo dva řádky raději sám. A ten vnitřek? Je to lepší než čisté JDBC, ale není to nic nového – tohle už se v Javě dávno používá.
doInTransaction
bez podpory uzávěrů? Obojí je přes ruku. Uzávěry umožňují vyjádření podobných konceptů jednoduchým kódem bez syntaktického smetí.
Mimochodem, dneska jsem četl esej od Bertranda Meyera (tvůrce Eiffelu), ve které dokazuje "nadřazenost" objektově orientovaných jazyků nad funkcionálními. Jako jednu z klíčových věcí v takovém objektově orientovaném jazyce považuje agenty, což je eiffelovská obdoba sýšárpích delegátů a obecně uzávěrů. S jejich pomocí (protože uzávěry přirozeně zahrnují reference na metody) dokázali například z ohavného návrhového vzoru visitor udělat srozumitelnou a snadno použitelnou komponentu, která nevyžaduje žádnou přípravu na straně "navštěvovaných" tříd a její API má dvě metody. Disertace Karine Arnoutové From Patterns to Components, ze které to pochází, vypadá jako dost zajímavé čtení.
Nemůžu si pomoct, ale pořád tam vidím jen zkratku pro new Runnable() { public void run() {}}
a ne nějakou kvalitativní změnu, která by mi umožnila v javě dělat něco, co mi dneska neumožňuje.
A vzhledem k tomu, že tam uvnitř máme většinou nějaký složitější program a ne jen System.out.println();
, přijde mi zbytečné kvůli úspoře jednoho řádku zavádět do jazyka nové konstrukce a zvyšovat jeho složitost.
Closures je hnus? Nejaký argument proti by sa našiel?
Třeba to, že základem objektového modelu Javy je Objekt jako instance. A tato instance je dána svou Class
, ClassLoader
em a samozřejmě instančním identifikátorem.
Closures prostě v tomto modelu dělají bordel a proto tam nemají co dělat.
Jak píše pan Jisrák níž, je to nová syntax pro anonymní třídy a já dodávám — pěkně hnusná. Dělaj z Javy Perl či bash — prostě něco podobného výstupu programů md5sum
či sha1sum
.
MethodHandle
, která nebude než, tradá, referencí na metodu! Method
z Reflect API.
Všechny návrhy uzávěrů pro Javu počítaly s tím, že to bude objekt. Ale některým objektistům se to asi málo líbilo, že tolik křičeli Končíme tak jako tak. Je mi to celý úplně jedno. S Javou už do styku patrně nepřijdu. Strávil jsem s její nejlepší verzí nejlepší časy, tak si zachovám aspoň vzpomínky. Dělejte si s ní, co chcete.
.class
pro metody a fieldy? To je podle mne věc, která by properties pomohla víc, než všechny zkrácené zápisy setterů/getterů dohromady.
Je možné, že v Jave to robí bordel, ale jazyky, ktoré majú ako uzávery, tak sú plne objektové dokazujú opak toho, čo píšete
Nevidel som konkrétne syntax Javy (ani som netušil, že sa bavíme o Java uzáveroch), hovoril som o uzáveroch obecne a to je jeden z najmocnejších konceptov v programovaní a obvykle je dobré mať preňho peknú syntax. Idem teda pozrieť na ten návrh do Javy, nech sa trochu poučím.
Prostě pokud má nějaká void main(String[]) být vstupním bodem programu, pak musí být public static. Hoši nademnou vysypali snad všechny důvody, proč to tak být má a proč ne. Souhlasím s nimi.Vstupním bodem programu má být jeho první řádek. Naprosto nejpřirozenější řešení
meta-jazyk skrývající typy v implementaci. Tak s tím já prostě musím nesouhlasit. Ať si zkusí v takovém metajazyku bez typů naimplementovat třeba to neblaze proslulé JDBC APINe ne ne ne ne ne ne, jednak to není metajazyk a jednak má typy. V
def variable = function_call(arg1, arg2)
má variable
stejný typ, jako návratová hodnota function_call
, a je to kompilátorem kontrolováno! Návratová hodnota function_call
musí mít typ, který je zjistitelný při překladu. V případě API (resp. rozhraní) z deklarace, v případě implementace (resp. třídy) buď z deklarace, nebo odvozením.
Hele! To je zajímavý. Ale! Jak kompilátor z kódu
def variable = …
pozná, jakého typu ta proměnná má být? Líbilo by se mi něco jako:
def Type variable = …
A vůbec. Přístup PL/SQL (based on Ada) se mi líbí vůbec nejvíc — deklarace proměnných oddělená od kódu. Další věc, kterou bych v Javě zavedl.
def variable : Type := value
, s tím, že : Type
je nepovinné a := value
koneckonců taky.
Odvozování typů je principielně vcelku jednoduché (detailní implementace nejspíš už moc ne, ale o tu jsem se ještě nepokoušel String transform(String)
. Pak pokud a : String
, potom def b := transform(a)
je určitě taky String
. Existují i drsnější metody odvozování typů, které nepotřebují ani to deklarované API, ale to já bych zase ponechal, protože názvy a typy jsou jednoznačně nejdůležitější částí dokumentace API. A navíc to ten inferenční algoritmus významně zjednoduší Java Database Connectivity. Již ze samotného názvu vyplývá, že se jedná o univerzální přístup k databázím. Metody typu int executeQueryReturningInteger(String, Object[])
v takovém frameworku opravdu nemají co dělat.
Možná kdyby návrháři JDBC přemejšleli hlavou a ne prdelí, nemusíme dneska mít Spring JDBC Já se JDBC vůbec nezastávám. Naprosto souhlasím, že kvalita je přinejmenším diskutabilní. Ale ona není vina jen na straně autorů; třeba takový Oraclí driver — no to je maso. Zase na druhou stranu —
SELECT
z dual
u je velmi dobré cvičení na try … catch … finally
a jejich vzájemné zanořování. Na všem musíš hledat něco pozitivního.
Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = ...; stmt = conn.prepareStatement("SELECT 1 FROM dual"); rs = stmt.executeQuery(); if (rs.next()) { ... } } catch (SQLException e1) { throw new RuntimeException(e1); } finally { try { if (rs != null) { rs.close(); } } catch (SQLException e2) { } // I'm screwed! try { if (stmt != null) { stmt.close(); } } catch (SQLException e3) { } // I'm screwed! try { if (conn != null) { conn.close(); } } catch (SQLException e4) { } // I'm screwed! }Uff, a to si jsem poměrně jistý, že jsem tam udělal chybu a že se to má psát ještě jinak, ještě příšerněji.
Na to si stačí napsat jednu metodu zavri() a ušetříš si tím těch asi deset řádků u každého dotazu.
BTW: vyrábět RuntimeException
z SQLException
, no fuj.
Na to si stačí napsat jednu metodu zavri() a ušetříš si tím těch asi deset řádků u každého dotazu.Never! Using JDBC directly should be a sackable offence. Správnou odpovědí je Spring JDBC.
vyrábět RuntimeException z SQLException, no fujNechtěl jsem do příkladu psát
public class DatabaseFailedException extends RuntimeException { public DatabaseFailedException(Exception cause) { super(cause); } }už tak byl dost dlouhý. To spíš zachytávat
Exception
na místě, kde hrozí SQLException
, je fuj.
Říká se to, ale takhle silná slova si nech do nějaké prezentace, kde potřebuješ upoutat pozornost diváků v praxi to na neplatí na 100%.
Díky Springu se to dá smrsknout na jeden řádek (+ odchytávání výjimek) nebo ho využít jako (hodně) lehkou alternativu k ORM, ale ne vždy je to nutné.
Co se týče převodu výjimky – na místě by možná bylo zaobalení do nějaké vlastní výjimky a vyhození, abychom měli výjimky na stejné úrovni abstrakce jako metoda a její vstupy a/výstupy (záleží na situaci), ale určitě by to neměla být běhová výjimka (která někam nečekaně vyhučí).
To spíš zachytávatException
na místě, kde hrozíSQLException
, je fuj.
Čím bych si tím pomohl? Ten kus kódu prostě říká: „pokus se uzavřít spojení (výsledek, dotaz), a ať už to dopadne jakkoli, pokračuj dál “.
Já bych ty nekontrolované výjimky zakázal :-P
throws HorribleException
, pak ji překladač u volajících bude kontrolovat, ale u jiných metod, které ji nedeklarují, nikoliv.
Kontrolované výjimky jsou hezká myšlenka. Ale realita je taková, že jde o experiment, který fatálně selhal.
Ale vždyť ti nic nebrání se ke kontrolovaným výjimkám chovat jako k nekontrolovaným – prostě je všechny nasekáš do throws
dané metody a necháš je vybublat nahoru.
Je v tom jediný rozdíl – v případě kontrolovaných výjimek na první pohled vidíš, co vybublává nahoru a jak vysoko*. V případě nekontrolovaných výjimek strkáš hlavu do písu a spoléháš se na to, že tam nahoře někdo z vlastní iniciativy tu výjimku odchytne. Jenže spousta programátorů to neudělá (jelikož je k tomu kompilátor nedonutí), a proto máme tolik ošklivých hlášek, které vyletí až k uživateli a tolik programů, které čas od času spadnou.
*) jestli do nějaké mezi vrstvy, nebo k dialogu pro uživatele nebo až úplně nahoru a program se pak nečekaně hroutí.
Ale vždyť ti nic nebrání se ke kontrolovaným výjimkám chovat jako k nekontrolovaným – prostě je všechny nasekáš do throws dané metody a necháš je vybublat nahoru.A přesně tohle (
throws Exception
) bohužel musí dělat řada frameworků, a leckde to taky tak dělám, prostě protože někdo označil za kontrolovanou takovou výjimku, která se nedá nijak ošetřit, jen zalogovat a zobrazit chybu. Přitom rozumné použití kontrolovaných výjimek by umožnilo robustnější zpracování "business" chyb, takhle je z toho hybrid.
Jak jsem psal, nejsem proti kontrolovaným výjimkám. Jsem proti jejich nadužívání a zneužívání, stejně jako Josh Bloch v 58. a 59. kapitole Ale vždyť ji musíš ošetřit tak jako tak – v případě kontrolovaných ti to akorát připomene kompilátor.
A je jen na tobě, na jaké úrovni je ošetříš (ty byznys výjimky můžeš ošetřovat v byznys logice), ostatní klidně něčím zabalíš a pošleš nahoru k uživateli. Některé zaloguješ a zahodíš. Je to prostě jen přehlednější – víš na čem jsi a nikde ti nelétají vzduchem nekontrolované výjimky, které programátoři zapomínají odchytávat.
throws Exception
, ztrácím všechny výhody, které by mi kontrolované výjimky mohly poskytnout, když ne, musím se na všech vrstvách starat o naprosto nezajímavé věci, které zaneřádí kód ještě víc. Případně je konvertovat, aby každá vrstva měla svou sadu výjimek, což se tuším považuje za dobrou praxi, já mám ale podezření, že to je kvůli umlčení lidí, kteří říkají to, co jsem napsal v předešlých větách HandlerExceptionResolver
, jinde podobné věci. V nouzi nejvyšší Thread.UncaughtExceptionHandler
. S tím si vystačím.
Děkuji, ale nechci. S takovým přístupem jsem se setkal v C# a jsem rád, že jsem v tom nemusel dělat víc než jednu semestrálku IMHO spíš selhávají programy ve VisualBasicu nebo C#, kde není potřeba výjimky odchytávat (resp. kompilátor takový kód v klidu přeloží).
Chtělo by to vyřešit NPE – součástí definice typu by bylo i to, zda připouští null nebo ne a všechny parametry metod by deklarovaly, zda připouštějí null nebo ne. A v případě konfliktu* by bylo nezbytné výjimku odchytávat. A pak bych zrušil všechny nekontrolované výjimky.
*) jako parametr, který nepřipouští null, bychom se snažili podstrčit proměnnou, která je deklarována jako potenciálně nullová.
def a : String? := null // Type? je nullable typ, Type je non-nullable, ala C# with (b := a as String) { // tenhle kód se nevykoná; jinak b by bylo typu String, čili non-nullable }
Přikládám aktuální obrázek pro milovníky nekontrolovaných výjimek
Za domácí úkol si tam doplň logování. Je to hnus, no…
Abych trošku zateoretizoval (to je tady móda ): JDBC se snaží být na databázi nezávislé, ale nezávislé ve skutečnosti není. Jako ukázkový příklad může sloužit třeba práce s
((N)C)LOB
y pod Oraclem.
Zase na druhou stranu — mám mít pro každou databázi jiné API nebo se naučit těch pár rozdílů? Podle mě je ve finále jednodušší mít JDBC API (ať je jaké je) a ve fasádě pár if
ů.
zavri()
, kterou zmínil Xkucf03, nebo do nějaké podobné.
No tak ten balast odsuneš do funkce, no. To je vážně rozdí.
Na toto už je ale AFAIK ďaleko lepšie aspektovo orientované programovanie. Používate/poznáte? Jedna z prvých implementácií bola tuším práve ako preprocesor pre Javu a volala sa JAspect. Len to proste dovoľuje človeku špecifikovať množinu funkcií, ktoré majú pred/po zavolaní vykonávať nejaký kód (typicky kontrola typov, logovanie, zachovanie atomicity, bezpečnosť a pod.) a nie je potrebné prasiť celý kód dopredu týmito metódami "zavri". Je to veľmi zaujímavá myšlienka, ale o moc viac o tom neviem, takže uvítam upresnenie
ServiceLocator
). Případně by také pomohlo, pokud by existovaly metatřídy či metainterface – mimochodem, nemáte náhodou tohle na mysli, když říkáte, že javovské třídy nejsou objekty? Nyní jsou javovské třídy objekty typu Class, metatřídou myslím to, že by třída byla instancí potomka třídy Class.
JBoss (RedHat) má Runtime implementaci aspektů řízenou anotacemi. Může samozřejmě i šoustat byte kód — bez této killer featury by to nikdo nikdy nestáhnul. Sám jsem měl tuto knihovnu vyhlídnutou…
Tady je link…
Source
, a javac
(dříve apt
) by k třídě
class Test { @AOP public void test() { } }vygeneroval
class TestImpl extends Test { public void test() { preMethod(); super.test(); postMethod(); } }
To by ale neměl být až zas takový problém naprogramovat. Stačí vohnout javac
.
To práve vôbec nie je problém naprogramovať, myšlienka je to jednoduchá (hoci myslím, že AOP má aj pokročilejšie myšlienky). A vo flexibilnejšom jazyku ako je LISP ani nemusíte ohýbať kompilátor, necháte ten program spracovať samého seba a on si to tam už pridá
javac
nijak ohýbat, se zpracováním anotací v době překladu se to dá napsat se současnými prostředky Javy (v Javě 5 použijete apt
, Java 6 už to má do javac
integrované). Jediný problém je pak to, že když chcete instanci třídy Test
(ona by ta Test měla být abstraktní, aby ji nikdo nezkoušel vytvářet přímo), musíte zavolat new TestImpl()
. S IoC nebo service locatorem se to dá vyřešit, ale není to univerzální řešení.
Aha, dík za upresnenie. Nie som si istý, či by bolo lepšie, aby to bolo priamo v jazyku. Na jednu stranu určite, je tam veľa problémov, ktoré sa dajú riešiť priamo v jazyku čistejšie, ale na druhej strane sa zjavne jedná o myšlienku, ktorá je tak povediac "jazykovo nezávislá", každý jazyk z nej bude profitovať a IMHO lepšie by bolo, keby Java podporovala nejaký mechanizmus, ktorým by sa podobné myšlienky dali implementovať. Netuším, ako sa aspekty používajú v iných jazykoch, ale napríklad je jasné, že v tých dynamickejších to asi bude jednoduchšie a napríklad v LISPe by to vôbec bola pohoda pomocou makier.
Viacmenej myslím niečo podobné, to sa týkalo tých statických metód. Aby ste ich mohli pridávať bez keywordu, tak samozrejme treba metatriedu pre každú triedu. Aspoň teda samozrejme AFAIK, určite existujú aj iné prístupy k OOP, o ktorých neviem.
aspektovo orientované programovanieAOP je určitá forma metaprogramování a současné staticky typované objektově orientované jazyky jsou bez něj prakticky poloviční. Dobře to ví například lidi, kteří se snaží na Javu napasovat architekturu založenou na doménovém modelu – bez AOP se prakticky nedá vyhnout anemickému modelu (nebo zaprasenému kódu
Interpretovaný/kompilovaný jazyk (čo je vôbec zlý termín, jedná sa len o implementáciu jazyka) a dynamický/statický jazyk sú dve rôzne veci.
To sice jsou, ale v tomto případě je důležitá právě ta vlastnost kompilovaný/nekompilovaný – protože jen u kompilovaného můžu nějaké chyby odhalit (provés kontrolu) už při kompilaci, zatímco u nekompilovaného jazyka musím program prostě spustit a sledovat chyby/varování (jenže to musím s programem nějakou dobu pracovat, aby se prošly všechny možné části kódu – kdežto u kompilace se projdou všechny jedním krokem, nemusím simulovat práci s programem).
Napríklad si predsavte, ze máte SQL "select ... where primary_key=...". Jedná sa o výsledok, ktorý vracia vždy 0 alebo 1 objekt.
Nevrací, protože nikde není psáno, že sloupeček se jménem „primary_key“ bude skutečně primárním klíčem – pokud nemáme při ruce tu konkrétní databázi s daty, nemůžeme o tom rozhodnout – a pokud nemáme při ruce daný databázový stroj (konkrétní implementaci, např. PostgreSQL nebo MySQL v konkrétní verzi), nemá ani cenu nějak ten SQL dotaz kompilovat, nejsme toho schopni, protože v tu chvíli nevíme, nad jakou databází poběží.
Je v Jave pravda, že nedostanem kolekciu, ale objekt? Nie je. Prečo chcete rozlišovať medzi rôznymi SQL príkazmi pomocou programatických funkcií, ktoré tak či tak do toho SQL nevidia a teda už z princípu nemôžu vedieť, či sa vráti objekt, alebo kolekcia.
Dostaneš kolekci, i když se jedná o výsledek, který obsahuje jeden řádek a jeden sloupeček, protože dokud se ten dotaz nevykoná, nevíš, co se z dané DB vrátí. Ale předem víš, že když budeš pouštět UPDATE, dostaneš updateCount
, tudíž budeš volat executeUpdate()
, tudíž si do kódu můžeš napsat int početZměněnýchŘádků = ps.executeUpdate();
a nemusíš si komplikovat život – prostě použiješ metodu pro daný účel (s konkrétními datovými typy).
Pokud nevím, co z DB přijde, řeším to např. takhle:
ps = db.prepareStatement(sql); boolean isRS = ps.execute(); if (isRS) { rs = ps.getResultSet(); v.getTabulky().add(zpracujVysledek(rs)); } /** * Ošetříme případ, kdy uživatel zadá SQL příkaz, který nevrací výsledkovou sadu. */ while (ps.getMoreResults() || ps.getUpdateCount() > -1) { rs = ps.getResultSet(); if (rs == null) { /** Jedná se o „update count“. */ } else { v.getTabulky().add(zpracujVysledek(rs)); } }
Zkus mi to přepsat do jiného jazyka, nějak přehledněji, lépe…
(pozn. ta -1 znamená, že se jedná o výsledkovou sadu, nebo že jsme došli na konec – jelikož se o výsledkovou sadu nejedná (viz podmínka před ||), došli jsme na konec)
Súhlas.
Samozrejme, že nie. To bola moja pointa Tak prečo chceš rozdeľovať to, aký výsledok ti vráti jQuery selector, ktorý vyzerá určitým spôsobom? Tak isto nemusí mať človek validný HTML kód a duplikátne ID a v tom prípade je výsledok buď množina výsledkov, alebo nie je špecifikovaný. To však nie je podstatné. Išlo mi o to, že špecifikovať dichotómiu 0..1 / 0..n pre nejaký domain-specific jazyk nad ktorým človek nemá kontrolu je nesystémové.
Ok, to beriem, ale to je o niečom inom. Pri selectoroch sa skutočne jedná o select, nie o update
Netuším, v akom jazyku to chceš vidieť, ale ak by bolo v rozumnom tvare ps (zoznam, iterátor, atď), čo by malo byť splnené, ak pracujeme v dobrom jazyku, tak napríklad v pythone to bude vyzerať takto (a v mnohých ďalších jazykoch podobne):
[v.getTabulky().add(zpracujVysledek(rs)) for rs in ps if rs != null]
Ďakujem za dobrý príklad toho, ako veľmi sa dá až balast z Javy zjednodušiť. Sám by som nevymyslel lepší
P.S., môj príklad teda robí ešte viac ako ten tvoj a to, že zbiera výsledky z v.getTabulky().add volaní do zoznamu. To sa môže a nemusí hodiť, ale pre upresnenie som to spomenul. Inak, ak ťa to zaujíma, tak je to len syntaktický cukor pre klasické funkcionálne map/filter. Jedno volanie filter na lambda funkciu nám vyfiltruje zoznam (v pythone 'if' rs != null časť) a volanie map na inú anonymnú funkciu (v.getTabulky...(rs) for rs) a zoznam (in ps).
Rozvediete? Podľa mňa robí presne to isté (len vyžaduje správne definovaný iterátor pre ps, ale ten som neimplementoval, pretože rovnako tak xkucf neposkytol implementáciu prepareStatement).
Ok, je možné, že tomu tak je, v tom prípade som nepochopil úlohu. Ničmenej, ak by sme boli v inom jazyku, tak je jasné, že tam by ten iterátor už bol napísaný tiež v knižnici daného jazyka (že v Jave to tak nie je je prinajmenšom s podivom).
Nemusíte to cpať všetko na jeden riadok preboha (aj keď záleží od jazyka, zrovna python je čo sa white-spacov týka dosť zvláštny jazyk)! To už sa ale bavíme fakt o prkotinách.
Ničmenej, ak by sme boli v inom jazyku, tak je jasné, že tam by ten iterátor už bol napísaný tiež v knižnici daného jazyka (že v Jave to tak nie je je prinajmenšom s podivom).Nedivte se, tohle je JDBC. Ono tedy bývá kritizovaná za kde co neprávem, ale za spoustu věcí také právem.
Ak Vám ide o to, že je vynechaný tá update časť, tak tú som vynechal, lebo tam nebol kód
Riešenie je jednoduché, pridá sa ďalší podobný riadok, ktorý bude obsahovať kód, ktorý sa má vykonať a podmienka bude rs = null. Ale v tomto prípade už môže byť vhodnejšie (aby sa pole neprechádzalo 2x) zapísať to ako
for rs in ps:
v.get... if rs != null else bla bla
Stále je 10x krajšie, kratšie a čitateľnejšie ako ten Javovský bordel.
for rs in ps: v.get... if rs != null else bla bla
To dělá opravdu něco úplně jiného. Toto na mě působí, že to v cyklu zpracovává celé ResultSet
y, což je zavádějící. Více výsledkových sad podporuje jen SyBase ASE a IBM DB2 LUW… Oracle, PostgreSQL a MySQL nic takového neumí…
Původní kód zpracovává iterativně jednotlivé řádky právě jednoho (prvního) ResultSet
u.
Tak to asi niečomu nerozumiem, ale v pôvodnom kóde je v cykle rs = ps.getResultSet();
čo mi evokuje, že sa iteruje cez resultSety. Vysvetlíte mi to lepšie?
Statement.getResultSet()
vrací první ResultSet
vrácený z databáze. Když chceš skočit na další, musíš zavolat Statement.getMoreResults()
. Když tato metoda vrátí false
, znamená to, že jich víc není. Vrátí-li true
, pak následující volání getResultSet()
vrátí další v pořadí.
Pro krokování po řádcích ve výsledkové sadě slouží ResultSet.next()
či ResultSet.previous()
(když je ResultSet
scrollable); tedy instance objektu vrácená metodou Statement.getResultSet()
.
To je mi všetko jasné, ale v tom príklade bolo len iterovanie cez ResultSety, už nie cez jednotlivé riadky
Nerozumím přesně tomu tvému výčtu, ale právě s PostgreSQL pracuji ve své aplikaci (odtud pochází ten příklad) a tato databáze vícenásobné výsledkové sady podporuje – klidně si tam naflákáš několik SELECTů oddělených středníkem, spustíš a uživatel dostane několik tabulek
Můj kód zpracovává ResultSet
y – předává je metodě zpracujVysledek() a ta z nich sestavuje tabulky (které se pak zobrazují uživateli).
Yup, presne to isté robí aj môj kód, som rád, že som to pochopil dobre a tá druhá verzia dokonca aj so spracovaním updatov
Já mluvím o databázi. To, že JDBC driver rozparsuje dotaz na dotazy a zpracuje je "v jednom", je hezké, ale databáze samy o sobě nic takového neumí. U Oracle to jde vochcat přes OUT
parametry typu REF CURSOR
, ale pořád to není úplně ono. :-/ Narozdíl od SyBase ASE či DB2 LUW, které mají vyloženě možnost vracet více výsledkových sad.
Ještě jsem to nepotřeboval (naštěstí), ale i v PostgreSQL můžu napsat funkci, která vrací refcursor[]
– tedy pole kurzorů – několik výsledkových sad.
tak tú som vynechal, lebo tam nebol kód
On i ten „zbytečný“ řádek, na kterém není kód má svůj smysl – až k tomuhle zdrojáku přijdu po měsících nebo letech (nebo k němu přijde někdo jiný teď), bude na první pohled zřejmé, proč je program napsaný právě takhle a co který IF znamená. Až tam budu chtít dopsat zpracování počtu změněných řádků, budu přesně vědět, kam do kódu to napsat. Kompilátoru je jedno, kolik takhle prázdných řádků nebo komentářů tam je – ale kód by se měl psát primárně pro lidi
Myslieť na to, že o 4 roky si možno ku kódu sadnem a na presne vymedzené miesto niečo dopíšem? Sorry, ale to fakt nie je myslenie pre mňa Môj kód sa mi mení pod rukami, mám rád dynamické jazyky a rád prototypujem.
Jediné, co je na tom kódu v Javě divné nebo ošklivé je to, že k prvnímu ResultSetu
přistupujeme jiným způsobem než k těm dalším.
Kdyby se k němu přistupovalo stejným způsobem (což je věc implementace dané třídy, nikoli jazyka), byly by oba zápisy stejně složité – prostě jeden* cyklus, jedna podmínka a jedno volání metody (jen já bych to nenamastil na jeden řádek).
Ale když se nad tím člověk zamyslí, je jasné, proč to inženýři v Sunu udělali takhle a proč první RS získáváme jinak, než ty další: většinou totiž platí, že co jeden dotaz, to jeden RS – takže je lepší, když programátor může napsat:
rs = ps.getResultSet();
místo aby musel psát vždycky:
ps.getMoreResults(); rs = ps.getResultSet();
A těch pár exotů, kteří používají dotazy vracející více výsledkových tek kód musí psát složitěji – jenže se to takhle vyplatí, jelikož v 99% se používá jen ten první RS.
*) složitost spočívající v počtu cyklů, větvení atd., to je složitost, která by nás měla zajímat – ne nějaký počet řádků nebo písmenek, ten je celkem bezvýznamný.
Nie, to nie je jediná divná vec. Ďalšou divnou vecou je, že iterátor sa realizuje pomocou podivného volania niekoľkých metód. Ale to už spomínal pán Jirsák, že je problém JDBC a veľa s tým nespravíme.
Zložitosť nás zaujíma v závislosti na tom, aký problém sa rieši. Určite je niečo iné písať kernel a niečo iné webovú aplikáciu. Optimalizácie až nakoniec (čím nechcem povedať, že nejakú hrubú predstavu o solídnych algoritmoch a nejakých štruktúrach netreba mať v hlave od začiatku. Ale nemusí to byť presné a už vôbec nie myslieť na takéto blbosti).
foreach
.
Ja viem, že to nie je iterátor, ale obyčajné metódy. Ale správny prístup k tomu, aby sa to dalo rozumne používať je práve iterátor.
Kdyby bylo po mém, tak by PreparedStatement měl metodu getResultSet(), která by vracela první RS (jako je tomu teď) a potom metodu getResultSets(), která by vracela kolekci všech RS (včetně toho prvního), které vzešly z daného dotazu. Přes to by se dalo krásně iterovat. Ale jak jsem psal – je to věc konkrétní implementace dané knihovny, nikoli jazyka – jazyk nás v tomto případě neomezuje!
Na druhou stranu by pak byl problém s těmi updateCounty – v současnosti je mám ve správném pořadí, zadal jsem např. tři dotazy, první a třetí vrátily RS a prostřední vrátil updateCount – teď vím, co k čemu patří. Pokud bych ale dostával kolekci RS a k tomu kolekci čísel, nevěděl bych, co ke kolikátému dotazu patří. Dalo by se to řešit snad tak, že by to byla kolekce obecných objektů (některé by byly RS a některé celá čísla).
Samozrejme (hoci to o tom neobmedzovaní platí len od doby, od kedy má Java foreach. Tiež tomu tak nebývalo vždy Ale v niektorých prípadoch asi aj antisyntatizátori ustúpili a uznali, že určité zápisy sú elegantnejšie a prehľadnejšie).
To sú už detaily.
Pokud abstrahujeme od toho, že se jedná o interpretovaný jazyk a chtěli bychom tento přístup aplikovat v kompilovaném jazyce, kde bychom čekali od kompilátoru nějakou podporu pro odhalování chyb a kontrolu, žádné bychom se nedočkali. Kompilátor by totiž nemohl vědět, zda funkce vrací jeden nebo žádný objekt, pokud textový parametr funkce začíná křížkem, nebo vrací kolekci objektů, pokud začíná na něco jiného.To nemusí být vždycky pravda a výše jsem odkázal na protipříklad
V tom prípade Vám ale nerozumiem už vôbec. Chcete teda aj metódy getByAttribute a getByChild a getByElementName a ďalších 10 podobných a ďalších 100 ich kombinácií? Netuším prečo/načo/začo.Nechci vyrábět stovky kombinací. Programátor typicky potřebuje získat přístup k nějakému konkrétnímu elementu. K tomu slouží v DOMu metoda
getElementById()
. Někdy je potřeba vybrat sadu nějakých elementů – pak je jednoduchá možnost projít celý strom a u každého elementu testovat, zda má do sady patřit, nebo ne. A nebo je možné použít nějakou metodu, která umožňuje ten výběr podle určitých pravidel udělat – podle třídy, podle XPath nebo podle CSS selektoru. Implementačně může getElementById()
použít některou z těchto metod, ale prakticky, z pohledu uživatele, je to každé něco jiného.
Prečo chcete obmedzovať silný selectorový jazyk kvôli dvom špeciálnym podprípadom?A proč chcete silný jazyk dnešních počítačů – strojový kód – omezovat nějakými vyššími programovacími jazyky? Vždyť v nich oproti strojovému kódu mohou být maximálně nějaká omezení. Jestli ale nebude rozdíl v úrovni abstrakce. Stejně jako získání elementu podle ID je fakticky speciálním případem získání elementu podle nějakých pravidel, ale po uživatelské stránce je to pokaždé něco jiného – jednou je to „dej mi tento element“, podruhé „které všechny elementy splňují tato pravidla?“.
skôr ide o dvojnásobne vyššiu rýchlosť produkcie kódu (čo IMHO ide takmer vždy)To už jsem pochopil, že vám jde hlavně o produkci kódu. V reálném světe jde ale spíš o to, aby ten kód fungoval – a to pak přestává být důležitá rychlost psaní, a začíná být důležitá rychlost čtení kódu. Protože pokud se neměří jen množství vyprodukovaného kódu, připadá na jedno napsání řádku kódu několik (někdy třeba desítek, možná ještě víc) čtení kódu.
To nie je pravda. V mojom typickom jQuery kóde som potreboval zhruba rovnako často selectovať podľa id, podľa názvu elementu, podľa dieťaťa, atď. Takže Váš príklad typického programátora neplatí prinajmenšom na mňa a myslím si, že aj na kopu ďalších ľudí.
Rozdiel je v tom, že DOM je primitívna štruktúra (oproti jQuery). Ale je to dobrý príklad. Ak skutočne potrebujete selectovať podľa ID, použite nízkoúrovňové metódy. Nepoužívajte na to vysokoúrovňovú knižnicu.
To je diskusia o 0..1 vs. 0..n, ktorá tu už bola rozobratá, nebudem sa opakovať. V dynamickom jazyku podobné otázky nemajú čo robiť. A v statickom jazyku tak isto, lebo dovnútra toho selectoru nevidíte. A opäť, použite primitívnu DOM metódu a ste v suchu
Nejde mi hlavne o to, ale je príjemné, keď sa človek nemusí zdržovať rituálmi na uspokojenia kompilátora, ale môže sa sústrediť na programovanie (a medzi inými aj to, ako písať bezchybný a kvalitný kód). Samozrejme, čítanie s tým tiež súvisí. A mne osobne sa Javovský kód (spolu s C++) hneď po Perle a PHP číta zďaleka najhoršie zo všetkých jazykov (dôvodom je opäť balast, ktorý mi to celé zneprehľadňuje. V PHP a Perle je to proste neskutočný syntaktický bordel, tam natrafiť na pekný kód je takmer zázrak).
To nie je pravda. V mojom typickom jQuery kóde som potreboval zhruba rovnako často selectovať podľa id, podľa názvu elementu, podľa dieťaťa, atď. Takže Váš príklad typického programátora neplatí prinajmenšom na mňa a myslím si, že aj na kopu ďalších ľudí.Vy používáte různá ošklivá slovíčka na Javu, já bych je zase použil pro kód, který potřebuje pro manipulaci s DOMem příliš často něco jiného než ID nebo kolekci potomků. Ony se sice interprety JavaScriptu v prohlížečích i manipulace s DOMem neustále zrychlují, přesto bych ale zatím JavaScript v prohlížečích nezařadil do kategorie „vždyť je to počítač, tak ať počítá“ a naopak mi připadá rozumné optimalizovat celý kód a to už od návrhu HTML struktury.
Aha, takže celý ten mechanizmus selectorov je tam vlastne zbytočný a je tam len kvôli tomu, že všetok javascriptový a HTML kód je nesprávne navrhnutý? Počuli ste už niekedy o prototypovaní? Proste sa s tým kódom (js aj HTML + serverový kód) hráte a upravujete si ho do finálnej podoby, až kým nemáte skutočne dobrú predstavu, jak to má vyzerať a až potom má zmysel niečo optimalizovať ("Early optimization is a root of all evil"). Ja osobne nemám rád dokonalé návrhy nejakej štruktúry a dlhé premýšľanie nad ňou, lebo obvykle je to príliš rigidné a aj tak sa po chvíli práce s ňou (praktické nasadenie) ukáže, že ju bude treba výrazne pozmeniť (niekedy až prepísať od začiatku). Preto mám práve radšej dynamické jazyky, ktoré mi dovoľujú si všetko priohnúť tak ako sa mi zachce.
Jeden príklad za všetky: jednu aplikáciu nad Symbian OS sme prototypovali v Pythone a keď už bolo jasné, ako to má vyzerať, prepísali sme to do J2ME (pretože bola potrebná rýchlosť (ten python veľmi nestíhal) a iný jazyk nebol reálny: Symbian C++ je veľmi nepohodlný jazyk na programovanie.
Ad druhý odstavec. Ono niekedy je lepšie spoľahnúť sa na kompilátor, hoci to na prvý pohľad nevyzerá. Tak ako sú ešte stále zástancovia assembleru, ktorí si myslia, že dokážu tvoriť optimálnejší kód ako kompilátor (a možno jeden taký človek skutočne existuje), tak v drvivej väčšine prípadov ich kompilátor prevalcuje. Podobne je to pri typoch, kedy kompilátor odvodí typy inteligentnejšie, než by si to mohol myslieť človek.
Príklad (zopakujem to vyššie v Haskelli, lebo nie je veľa iných jazykov s pokročilou type inference), človek by mohol napísať:
nasob_dvomi :: Int -> Int
nasob_dvomi cislo = 2 * cislo
a vyzerá to celkom normálne, však?
Lenže ak človek napíše
nasob_dvomi cislo = 2 * cislo,
tak Haskell je tak inteligentný, že z toho vydedukuje niečo ako
nasob_dvomi :: Number -> Number
a uvedenú funkciu môžete bez problému použiť napríklad na komplexné čísla! Tak silný systém to je. A ak ju skúsite použiť napríklad na string
nasob_dvomi "huhu",
tak Vám to vypíše compile-time chybu (samozrejme ak String nepodporuje násobenie ako napríklad v Perle a PHP), presne tak, ako by ste čakali. Rozdiel oproti tej Jave a "chytrému" programátorovi je, že si neobmedzujete zbytočne typy funkcií tam, kde nemusíte a ten istý kód môžete použiť na oveľa pestrejšiu varietu typov, než ste si mysleli. A hlavne, nemusí nad typmi veľmi uvažovať, ono to proste funguje! Rovnako ako assembleristi nepochopia, že netreba uvažovať v inštrukciách a adresách do pamäte a nechať to na kompilátor. Ono, chce to hlavne vyskúšať si to v praxi, rozhodne Vám Haskell doporučujem, ak si nájdete chvíľu času, lebo vidím, že máte rád statické jazyky a veľa kontroly nad jazykom. V Haskelli sa dajú robiť s typmi tak pekné veci, ako napríklad:
f :: (Ord a, Eq b) => a -> b
čo znamená, že f je funkcia, ktorá zobrazuje ľubovoľný objekt, ktorý spĺňa axiómy usporiadania na ľubovoľný iný, ktorý spĺňa axiómy ekvivalencie (v Jave by sa niečo podobné asi riešilo pomocou interfejsov). Ale najsilnejšie na tom je, že túto informáciu vie opäť vydedukovať z implementácie funkcie (čo už môže byť pre programátora celkom problém) a tú funkciu budete môcť použiť tam, kde by Vás to zo začiatku ani nenapadlo (viď horeuvedené rozšírenie použitia z Int -> Number). Samozrejme, nič Vám nebráni tie anotácie tam písať, ak to potrebujete a pri exporte knižnice je to celkom zrejme užitočné (aj keď kto vie, kam sa vývoj type inference posunie v budúcnosti).
Ok, dávam Vám za pravdu, že anotácie nemusia byť zlý programátorský štýl, ale je to len jedna z možností ako robiť veci a nemám rád, keď mi jazyk niečo vnucuje.
Int
, Java se ale daleko víc používá v programech, kde jsou objekty typu Faktura
nebo Zákazník
. A tam programátor často řeší opačný problém, než vy – vy máte radost z toho, že když umíte násobit celá čísla, budete umět násobit i komplexní. V enterprise systémech ale programátor často řeší to, že faktura přijatá se ukládá do archivu nějakým způsobem ale faktura vydaná úplně jiným.
Príklad Int uvádzam kvôli jednoduchosti, lebo keby som chcel uviesť komplexnejší príklad, musel by som vyrobiť celú triedu, atď. Ale verte tomu, že v Haskelle sa typ Int v ničom nelíši (aspoň navonok, kvôli optimalizáciám môže) od typu Faktúra. Tak ako Int spĺňa axiómy Eq a Ord, tak môžete faktúre nadefinovať, že spĺňa axiómy úradného dokumentu a pod. (nech je to už čokoľvek). Ale čo je podstatné, tak kompilátoru to stačí a opäť všetko vydedukuje sám a Vy nebudete mať problém funkcie, ktoré ste síce napísali pre prácu s Faktúrou, ale nevedomky ste v skutočnosti využívali vlastnosti len úradných dokumentov, použiť inde. A čo je hlavné, nikam tie typy netreba písať a všetko funguje. Netvrdím, že je to jediný správny prístup. Ak skutočne potrebuje vynútiť typ, tak máte možnosť funkcie anotovať a máte z Haskellu Javu (v tomto ohľade). Len som proste chcel, aby ste si to skúsili na vlastnej koži, možno by Vás Haskell presvedčil, alebo aspoň zaujal.
Prosím rozviesť to o ukladaní faktúry do archívu. Kde je problém s automatickým odvodzovaním typov?
Vy nebudete mať problém funkcie, ktoré ste síce napísali pre prácu s Faktúrou, ale nevedomky ste v skutočnosti využívali vlastnosti len úradných dokumentov, použiť indeAle to je právě ten problém! Protože ony ty funkce sice třeba jdou formálně napasovat na typ úřední dokument, ale prakticky mají na úředním dokumentu jiný nebo žádný význam. Z tohoto důvodu se třeba v programech používají asserty. Pokud je někde třeba vstupní hodnota mimo přípustný rozsah, je potřeba vyvolat chybu. Ale také může být případ, kdy funkce s nějakými parametry zavolat jde, třeba i něco udělá, ale jenom programátor takové použití nezamýšlel – pak použije právě assert. Ten neříká, že nutně musí dojít k chybě (proto je možné je v produkčním prostředí vypnout), ale říká, že s tímhle použitím se nepočítalo. Což je přesně to, co dělá kontrola typů – tu funkci by bylo možné zavolat i na jiném typu a volání by třeba prošlo, ale nebylo to tak zamýšleno. Budu se opakovat, ale nikde netvrdím, že statické typování a povinná deklarace typů je jediná možnost. Pokud budu psát program pro nějaký výpočet, budu jej stavět jakoby pro celá čísla, ale kompilátor pak zjistí, že jej můžu použít i pro komplexní čísla a matice, je to pro mne plus, protože jsem „zadarmo“ dostal mnohem silnější program. To je ale proto, že stejně deklarované operace mají na celých číslech, komplexních číslech i maticích stejný význam. V informačních systémech máte ale spoustu operací se stejnou deklarací, které ale mají pokaždé jiný význam, a jakékoli zobecňování je na závadu.
Tomu nerozumiem. V tom prípade máte nesprávnu predstavu o tom, čo je to formálny systém. Keď mám asociativitu, tak je úplne jedno, kde ju použijem, vždy to bude správne. Neexistuje nič ako nesprávne použitie asociativity. Máte objekty, ktoré ju spĺňajú a objekty, ktoré nie. Ak napíšete funkciu využívajúcu len asociativitu (a už nie napríklad komutativitu), tak je objektívne jedno, aký objekt jej predhodíte (samozrejme ak je asociatívny). Tak isto ten úradný dokument. Ak ste schopný zaxiomatizovať, čo to je, tak to bude fungovať. Iná vec je, že táto úloha môže byť dosť náročná na premýšľanie.
Asserty sú jeden z príkladov toho, čo musí človek často písať ručne, ak nemá dosť silný kompilátor. Samozrejme, ze kompilátor nie je orákulum; nezistí, čo ste presne mysleli všade. Ale často to zistí a netreba na tom tráviť zbytočne čas a explicitne ho upozorňovať na niečo, čo je zrejmé. Napríklad, asi sa zhodneme, že uvedený kód je úplne zbytočný:
Int a;
assert (a.typeof(Int));
Takže určite existujú asserty užitočné a asserty zbytočné. Otázka, ktoré sú ktoré, závisí silne na kompilátore. Preto sú programy v Haskelli tak robustné: písanie Unit Testov je z väčšej miery triviálne a veľa práce urobí kompilátor za Vás.
S týmto súhlasím a idem si pozrieť Váš príklad o add(Int), že čo presne tým myslíte.
Keď mám asociativitu, tak je úplne jedno, kde ju použijem, vždy to bude správne. Neexistuje nič ako nesprávne použitie asociativity.To platí v matematice. V reálném světě platí, že když máte zákonem danou jednu věc, tak k tomu máte deset výjimek a třicet výjimek z výjimek.
Asserty sú jeden z príkladov toho, čo musí človek často písať ručne, ak nemá dosť silný kompilátor.To mne ani nenapadlo. Vzhledem k tomu, že většinou používám silný javovský kompilátor, jsem asserty vnímal jako způsob, jak dát kompilátoru (a programátorům) vědět věci, které plynou z významu kódu (a o kterých tedy kompilátor nemůže nic vědět). Že je potřeba někde používat asserty i pro věci, které jsou odvoditelné z kódu, to mne nenapadlo.
Prepáčte, že som idealista, ale snažím sa tú matematiku v čo najväčšej miere aplikovať na ten reálny svet, aby som v tom bordeli výnimiek zaviedol trochu poriadok.
Samozrejme, často sú používané aj na veci, ktoré sú odvoditeľné (aspoň v princípe), proste preto, že to ten jazyk (resp. jeho kompilátor) sám nevie (hoci iný, lepší jazyk by mohol). Ale použitie na vysvetlenie sémantiky kompilátoru je obvykle správne, v tom sme asi zajedno.
Samozrejme, nič Vám nebráni tie anotácie tam písať, ak to potrebujete a pri exporte knižnice je to celkom zrejme užitočné (aj keď kto vie, kam sa vývoj type inference posunie v budúcnosti).Nic v tom sice nebrání, ale stejně je podle mě dobrý nápad je tam psát. Když například napíšu anotaci funkce, ale něco v ní popletu, tak na mě kompilátor zařve, že předložená anotace funkce neodpovídá té, kterou si sám z kódu funkce odvodil. Tak mám možnost hned podchytit chybu, kterou bych jinak nesmírně těžko hledal. Tím, že jsem tu anotaci poskytl jsem dal vlastně kompilátoru najevo, co chci, aby daná funkce dělala. Navíc, ohromně to může urychlit chápání kódu. Pokud má funkce alespoň trochu rozumný název, tak z něj a z její type signature poznám, co dělá (nebo minimálně co rozhodně nedělá), aniž bych mrknul na jediný řádek kódu. Jinak je samozřejmě z teoretického hlediska nepotřená věc, to je fakt. Ale já osobně tu inferenci beru jako další "síť" na odchytávání nepříjemných a jinak těžko zjistitelných bugů.
Bolo to už povedané prakticky všetko, ale opakovanie je matka múdrosti
interface HelloService { void sayHello(String hello) } class HelloServiceImpl exposes HelloService { def sayHello(hello) { def greetz = hello.split("\\s+") // List<String> def first = greetz[0].toUpperCase() // String def rest = greetz.sublist(1) // List<String> println("Hello, ${first}! [${whatever(rest)}]") } def whatever(strings) { ... } }Žádná informace o typu se neztratila. Bohužel se mi momentálně nechce vymýšlet zhovadilost třeba s
Map<String, List<String>>
, tenhle nesmysl mne vyčerpal dost A co když rozhraní bude vypadat takhle?
interface HelloService { void sayHello(String hello) void sayHello(Integer hello) }
A kdy ten jazyk vyjde pro veřejnost?
BTW: abstrakce se někdy dost hodí. Např. můžu deklarovat, že moje metoda vrací Collection
, ale ve skutečnosti budu vracet ArrayList
. Pak klidně změním implementaci metody a budu používat jiný typ – ale okolní kód touto změnou nebude nijak dotčen, protože jsem nikdy nikomu nesliboval, že budu vracet ArrayList
, vždy jsem jen deklaroval, že budu vracet nějakou kolekci, ale jakou, to je moje věc.
Abstrakce – programátor, potažmo program, který vytváří, může abstrahovat od některých detailů práce jednotlivých objektů. Každý objekt pracuje jako černá skříňka, která dokáže provádět určené činnosti a komunikovat s okolím, aniž by vyžadovala znalost způsobu, kterým vnitřně pracuje.
vi
, a pak najednou k přečtení zdrojáků potřebujete kompilátor.
Ale v příspěvku nebylo napsáno, že kompilátor je potřeba ke čtení.
Naučte sa čítať, to reagujete na niekoho iného, ktorý to chcel využívať v IDE (xkucf -- sorry za skomolenie) Ja hovorím o compile-time checkingu, čo s týmto vôbec nesúvisí. Bez ohľadu na editor a IDE, program skôr či neskôr skompiluje a spustí každý, otázka je, kedy Vám dáva možnosť kontrolovať chyby
Až sa naučíte trochu čítať a rozmýšľať, ozvite sa znovu
Až sa naučíte trochu čítať a rozmýšľať, ozvite sa znovu
Nějak se nám tu ta diskuse zvrhává, už na to pře
Ja som horkokrvný človek. Prosím berte ma všetci s nadsádzkou a humorom, nič nemyslím v zlom a napriek spôsobu vyjadrovania si väčšinu spoludiskutujúcich vážim
add(Int)
, ta metoda může mít ale u každého typu úplně jinou sémantiku. Ano, v programu který jenom počítá se to třeba nestane, a pak může být automatické odvozování typů užitečné, protože z hlediska sémantiky pracuje program jenom s jedním typem.
Nie, to som nikde netvrdil (aspoň nie takto úplne priamo). Ja naopak tvrdím, že závisí od konkrétneho problému. Máme tu kopu jazykov dynamických/statických silných/slabých a ja nie som schopný jednoznačne povedať, čo je lepšie. Páčia sa mi ako výhody tých statických, tak tých dynamických a úplne najlepšie by bolo, keby nejaký jazyk nejakým magických spôsobom podporoval oba prístupy (sila dynamických jazykov, ale compile-time checking tých statických). Čo sa tých statických jazykov týka, tak som toho názoru, že sme zatiaľ len na začiatku (poriadne spravené jazyky ako Haskell a spol. a výskum v tejto oblasti je záležitosť posledných desiatok rokov) a tá forma, ktorá je v Jave nie je rozhodne ideálna (je to viac menej relikt typového systému už od C a nie aplikácia nejakých zaujímavých a netriviálnych myšlienok). V istom zmysle typy poznať nepotrebujete (v zmysle, v akom som písal ten dlhší komentár o Haskelli a automatickom zisťovaní typov).
Tomu príkladu add(Int) celkom nerozumiem. Môžete to trochu rozviesť? Ideálne vymyslieť nejaký príklad a ilustrovať, kde presne je problém pri automatickom odvodzovaní.
Položka_v_nákupním_košíku
(vazební objekt, který obsahuje odkaz na nákupní košík a na druh zboží). Ten může mít metodu Add(Int)
, která způsobí to, že se do nákupního košíku přidá příslušný počet kusů onoho zboží. Takže když zákazník bude nakupovat a zvolí, že chce do košíku přidat ještě jeden kus tohoto zboží, zavolá se Add(1)
.
Pak můžeme mít objekt Text
, který má také metodu Add(Int)
, která způsobí přidání daného čísla v dekadickém zápisu na konec textu. Takže String("Číslo ").Add(5)
dá na výstupu "Číslo 5". V obchodě se to třeba bude používat pro výpis cen apod.
Obchod pak může pořádat nějakou slevovou akci, nabídne „3 v jednom“, takže bude mít funkci Zákaznická_akce(x)
, která bude implementována jako
Zákaznická_akce(x) { x.Add(3) }Takhle bez určení typu ji ale klidně můžete zavolat i jako
Zákaznická_akce("Číslo ")
a dostanete "Číslo 3"
. Z pohledu kompilátoru je vše v pořádku, ale z pohledu smysluplnosti kódu ne – funkce Zákaznická_akce
má definován význam jenom pro položku v nákupním košíku.
Ve spoustě jazyků má programátor možnost typ nepovinně uvést, i když nemusí, takže by mohl funkci nadefinovat Zákaznická_akce(Položka_v_nákupním_košíku x)
. Jenže ve spoustě aplikací, které skoro nic nepočítají a jenom přehazují data vidlema sem a tam, je potřeba typ uvést v 99,99 procentech případů. Bylo by možné to uvést v pravidlech projektu a kontrolovat to může nějaký programátor zodpovědný za kvalitu kódu, může to kontrolovat i nějaký automat, kterému se řeknou pravidla, jak má kód vypadat. Ale to by toho člověka nebo ten automat potřebovala každá firma vyrábějící takový software. Není tedy jednodušší tohle zabudovat rovnou do pravidel jazyka? Jazyk se tím zároveň zjednoduší, programátor se nemusí zabývat nějakou výjimkou, že by někdy v programu mohl narazit na deklaraci bez uvedení typu. Prostě se může spolehnout na to, že typ je v deklaraci vždy uveden, takže se mu pak kód i líp čte (nemusí vyhodnocovat tolik možností, co daný kód znamená).
Toto by v Haskelli (nemám teraz po ruke kompilátor) myslím neprešlo. Povedal by Vám niečo o nejednoznačnom type x a že nie je možné formálne zistiť jeho typ (formálne ten systém dedukuje podobne ako bežný programátor, tj. Add je zobrazenie buď Text.Int, alebo Položka_v_nákupním_košíku.Int a z toho plynie, ze x je buď Text, alebo Položka_v_nákupním_košíku). Takže v niektorých prípadoch skutočne musíte uviesť typy (ako som písal inde, kompilátor nie je orákulum), ale na rozdiel od Vás si myslím, že to v 99% prípadov nie je potrebné. Je to kvôli tomu, že kompilátor tu hrá úlohu Vášho programátora zodpovedného za kvalitu kódu a IMHO mu to ide veľmi dobre. Ale ťažko sa o tom môžeme seriózne baviť, kým tomu nedáte aspoň šancu.
Súhlasím, že sa tým zjednoduší jazyk a nikto s tým nemá problém. Okrem ľudí ako som ja, ktorí sa pýtajú, či je to skutočne absolútne nutné. Lebo ak nie je, tak je to očividne úplne zbytočná strata času, na ktorej sa trvá len z historických dôvodov.
Ďalej súhlasím, že niekomu sa to môže lepšie čítať. Ale ja môj spôsob nikomu nenútim a Haskell tiež nie, lebo dovoľuje anotovať metódy (a občas dokonca vynucuje, ak je niečo nejednoznačné), takže aj ľudia ako Vy by mali byť s takýmto systémom spokojní. Toť vsjo
Ďalej súhlasím, že niekomu sa to môže lepšie čítať. Ale ja môj spôsob nikomu nenútimNenutíte, jenom o jazycích, které to nemají, píšete, že jsou příšerné, nemají žádný návrh a kód programů v nich je plný balastu.
To je síce pravda, ale nikoho nenútim to meniť. Ak niekomu zlý jazyk plný balastu nevadí, nech si ho používa. Len som mal pocit, že často je to skôr z neznalosti alternatív, než z iných dôvodov. Vyskúšanie a ako také ovládnutie 10 ďalších jazykov (čo nie je môj prípad, ale chcem sa tam časom dostať) a zistenie, že skutočne je napriek tomu Java jazyk vhodnejší na veľa vecí viac ako iné jazyky IMHO bude oveľa menej častý prípad ako to, že je to niekoho prvý jazyk (v lepšom prípade ešte človek ovláda PHP a C). Takže poukazujem na tie nedostatky, ktoré mi na Jave vadia a na alternatívy, ktoré snáď niekoho zaujmú. Ak nie, tak nie. Vy si používajte Javu, ja ju používať nebudem a všetci sme šťastní.
Toto by v Haskelli (nemám teraz po ruke kompilátor) myslím neprešlo.
Když bychom měli třeba následující třídu
class XXX a where add :: Int -> a -> a
a její instance pro Int
a String
, tak by to prošlo.
Samozrejme, lenže toto je dosť odlišný prípad. Je to ako povedať, že mám triedu pre asociativitu (XXX), ktorá spĺňa axióm asociativity (add). Potom ak si deklarujem inštanciu tej asociatívnej triedy (Int, String), tak už je len a len na mne si ustrážiť, že to spravím správne. Inými slovami, žiadny jazyk mi nezabráni deklarovať asociativitu pre štruktúru, ktorá ju v skutočnosti nemá. Lenže takto sa neprogramuje (aspoň nikto rozumný by takto neprogramoval). Keď si už vytvorím nejakú triedu a od nej inštancie, tak preto, lebo skutočne sú to inštancie tej triedy a to rovnocenné. Príklad pána Jirsáka sa zakladal na tom, že tá funkcia rovnocenná nebude (resp., že bude mať inú sémantiku) a teda sú to dva rozdielne typy. V tomto prípade Vám už Haskell nedovolí chybu spraviť. Snáď som sa nevyjadril príliš nejasne.
Je to ako povedať, že mám triedu pre asociativitu (XXX), ktorá spĺňa axióm asociativity (add). Potom ak si deklarujem inštanciu tej asociatívnej triedy (Int, String), tak už je len a len na mne si ustrážiť, že to spravím správne. Inými slovami, žiadny jazyk mi nezabráni deklarovať asociativitu pre štruktúru, ktorá ju v skutočnosti nemá.
Ale já jsem nic takového netrvrdil, jen jsem řekl, že to jde a jak to jde.
Fajn, len to je v tom prípade trochu (píšem trochu a myslím dosť) mimo kontext. Ale už mlčím
(formálne ten systém dedukuje podobne ako bežný programátor…
Jen doplním, že se jedná o unifikaci.
V podstate súhlas, až na to prirovnanie Javy k C. To je úplne mimo. C je napriek všetkému čistý jazyk s malou špecifikáciou, Java je bordel (len také trochu uhladené C++), snažia sa hrať na objektový jazyk, ale ani tým to stále nie je, atď. Nehovoriac o silnej previazanosti Javy s veľmi zle navrhnutou virtuálnou mašinou (ktorá sa už postupne mení a snáď zvládne v najbližšej dobe aj dynamické jazyky)
C je napriek všetkému čistý jazyk s malou špecifikáciou, Java je bordel (len také trochu uhladené C++)Tak to v žádném případě, Java je zgruntu navržený jazyk, který skřípe jenom na několika málo místech (no s generikama už to skřípe trochu víc
Nehovoriac o silnej previazanosti Javy s veľmi zle navrhnutou virtuálnou mašinouJe pravda, že JVM byla navržena s ohledem na Javu, ale žádná provázanost tam není, JVM je specifikována úplně samostatně a je dostatečně univerzální na to, aby zvládla víc a různorodějších jazyků než kterákoli jiná
Je pravda, že JVM byla navržena s ohledem na Javu, ale žádná provázanost tam není, JVM je specifikována úplně samostatně a je dostatečně univerzální na to, aby zvládla víc a různorodějších jazyků než kterákoli jináMožná po přidání invokevirtual... Ale stejně si myslím, že kompilovat do java-bytecode něco, co se Javě dost nepodobá, musí být docela voser., a to s velmi dobrým výkonem. Už to tu padlo: Java, Scala, Ada, Ruby, Python, JavaScript, Groovy, Clojure…
Yup, zrovna včera som si o tom čítal a ľudia sa na to sťažovali, že ani to moc nepomôže a skôr vkladali nádej do Da Vinci Machine a ešte ďalší hovorili, že aj tá je na hovno
Inštrukčná sada != Virtuálna mašina
Viem, že je navrhnutá od základu, ale jedným s počiatočných zámerov bolo uhladenie C++, to mi nikto nevyhovorí. Ten jazyk proste dojmom uhladeného C++ pôsobí každým riadkom kódu v ňom napísanom Jasné, že implementácia je iná, ale to, že sa dochovali všetky public static balasty hovorí jasne samé za seba. A ten jazyk skutočne škrípe na mnohých miestach, je to proste bordel. Rozhodne sa môžeme hádať o tom, že je ďaleko horšie navrhnutý ako C (ktoré to v podstate nemá kde pokaziť, je to len drobné zobecnenie assembleru
).
Prečo nechcete OOP schopnosti jazyka brať do úvahy? Existuje niekoľko charakteristík OOP a podľa toho, do akej miery ich daný jazyk spĺňa, tak do takej miery je objektovo orientovaný. Pritom je zrejmé, že na kopu výhod OOP treba mať tie charakteristiky splnené čo najviac. Napríklad "všetko je objekt" je geniálna vec, ktorá v Jave vôbec nefunguje a musí sa riešiť boxovaním a pod. Prečo by opravdový objektový jazyk musel mať dynamické typovanie? Ja si viem predstaviť aj statické a ešte veľa ďalších vecí, ktoré prinesie vývoj v tejto oblasti si predstaviť neviem. Ak zoberieme napríklad CLOS, čo plne objekto orientovaný systém je a zamyslíme sa nad tým, čo všetko má od napr. smalltalku odlišné, tak je jasné, že s OOP to nie je tak jednoduché. Ničmenej, Java je, čo sa OOP týka za CLOS aj smalltalkom o 100 rokov vzadu
Súhlasím, ale to nič nemení na to, že JVM je šitá Jave na mieru a kopa dynamických jazykov bude mať na nej problémy a nebude optimalizovaná.
A koľko tých virtuálnych mašín vôbec existuje? A ktoré z nich sú financované obrovskými spoločnosťami a podporované masívnou reklamou? Ja sa šírim o mizernom návrhu a nie sú to mýty. Ja sa len teším na parrot, ktorý už teraz toho dokáže množstvo, čo JVM asi nebude vedieť nikdy
Samozrejme, chce to napísať prekladače do toho stroja a to chce čas, ale v každom prípade neberiem argument, že len preto, že je niečoho najviac, tak je to najlepšie. Windows je najviac, takže sú jasne najlepším OS, nie? Rovnaký argument ako počet podporovaných jazykov v JVM (bez ohľadu na šírku ich podpory, ktorá je pri dynamických jazykoch vskutku mizerná)
Prečo by opravdový objektový jazyk musel mať dynamické typovanie?Protože všechno musí být as lazy as possible. To je jeden ze základních principů OOP, ne?
Ja sa šírim o mizernom návrhu a nie sú to mýty.Tak se šiřte, zatím jsem nezaznamenal nic než tvrzení "je to mizerné"
O tom, či je to jeden zo základných princípov by som sa hádal, nevidím nejaký absolútny rozpor medzi statickosťou a OOP princípmi. Ale zjavne si obaja pod OOP predstavujeme niečo iné, keď sem nechcete ťahať CLOS, čo je efektívne úplný OOP systém, len sa nesústredí na dáta, ale na funkcie. Lebo kde je napísané, že OOP musí byť založené na triedach? To je práve len predstava ľudí zdegenerovaných primitívnym OOP v Jave S tými vyjadrovacími prostriedkami súhlasím, ale ničmenej to spolu veľmi súvisí. Kvalitné OOP jazyky majú vyjadrovacie prostriedky veľmi silné práve vďaka podpore OOP princípov (a presne preto, okrem iného, ich má Java tak slabé).
Už som to napísal, jedná sa hlavne o podporu dynamických jazykov, ktorú má JVM _nulovú_ (momentálne; pracuje sa na tom, ale v súčasnosti je to na nič). Videl som prednášku o Parrote, kde boli spomínané všetky možné výhody dynamického virtuálneho stroja oproti Jave a je ich dosť. Proste ten stroj nemôže pri dynamických jazykoch robiť takmer žiadne optimalizácie, lebo v dobe jeho návrhu sa nad tým nikto ani nezamyslel (a to nezamyslenie trvalo prakticky až doteraz). Ak chcete, tak vám to video nalinkujem, ale možno ste ho videli aj sám a musel by som ho teraz hľadať. Na ten Váš link sa pozriem, chcem mať na Parrot pohľad aj z druhej strany. Ničmenej, hoci má určite aj kopu nedostatkov, tak je to rozhodne nádejný systém, ktorý je úplne inde ako jvm
OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.Jestli máte na mysli přednášku o Parrotu z JVM Language Summitu, tak tu jsem po pár minutách vypnul, ale třeba ji ještě někdy dokoukám. Ale – k čemu je dynamický virtuální stroj, když chceme mít staticky typované jazyky?
Ja viem, že to viete, ale podľa mňa to o tom je Keď zahodíte ten CLOS a Self, tak z toho, čo Vám zostane (triedy) si spravíte úplne inú predstavu o OOP (a presne tak to bohužiaľ funguje, nevzdelané javovské opice si pod OOP predstavujú len niektoré jeho okrajové vlastnosti, hoci je to z trochu iného dôvodu a to tým, že java je dokonca slabý odvar aj toho triedového OOP), ako z kompletného obrazu. Jj, zatiaľ je to slabé, ale časom... kto vie? V každom prípade, tvrdenie OOP musí byť dynamické je podľa mňa silné a prehnané a len odráža súčasný stav.
Njn, ale to je len jeden pohľad na OOP a nie každý sa s ním musí stotožniť. Ten late-binding mi tam pripadá skutočne nadbytočný, zvyšok súhlas.
Myslím práve tú; na začiatku, ak si dobre spomínam, nebolo vôbec nič. Zaujímavé to začalo byť až ďalej.
To je tým, že je to misnomer Statické jazyky nie je tak ťažké podporovať a robí to už jvm (hoci problematika statického typovania a type inference siaha oveľa ďalej, viď Haskell, a som si istý, že ani tam nebolo povedané posledné slovo, takže neskôr sa prístup k virtuálnym strojom bude musieť možno opäť prehodnotiť), ale dynamické sú ten bonus, preto "dynamický VM" neznamená, že na tom nespustíte statický jazyk. Aspoň teda IMHO, AFAIK a LOL
Je to možné a momentálne to vidím podobne, dynamickosť je silná vec. Len som chcel proste povedať, aby sme to statické OOP nezatracovali a ešte si pár (10, 20, 30, ...) rokov počkali a potom sa uvidí
Súhlas.
No, tak to tiež neviem. Je samozrejme možné, že parrot bude mať problém s optimalizáciou statických jazykov. A je celkom možné, že kvôli hype jaký je práve kvôli dynamickým jazykom to nikoho ani nenapadlo doteraz (použiť parrot na statické jazyky). Ale teraz varím z vody, zas až tak moc do toho nevidím. Ale vidím, že nie som sám. Ideálna možnosť začať flame o niečom, o čom ani jeden moc nevieme K tomu invokedynamic viď túto diskusiu(opäť, už to bolo pod týmto blogpostom linkované, ale zdá sa, že som jediný, kto tie linky navštívil, takže treba ešte raz a explicitne
) -- mne to prišlo veľmi rozporuplné.
Ouki douki. Pokojne sa o tom neskôr rozpíš do blogu, ak sa ti bude chcieť, celkom by ma zaujímalo, jak to teda presne je.
přednášku o Parrotu z JVM Language SummituOsvícen z toho sice zrovna nejsem, ale je to zajímavý poslech. Akorát na můj vkus tam bylo dost balastu. Ty zajímavosti: Řízení běhu založené na CPS? Pěkné, i když si dovedu představit i tradiční zásobník v podobě spojového seznamu uloženého normálně na heapu a podléhajícího GC. Jsem zatížený na zásobníkové virtuální mašiny
Mnohokrát dík za zhrnutie. Ja som už na vačšiu časť obsahu tej prednášky už zabudol a je pekné to tu mať pekne pokope
http://en.wikipedia.org/wiki/List_of_JVM_languages
Třeba takový Ioke vypadá zajímavě...
Mimochodem, můžete mi někdo vysvětlit , co si mám představit pod pojmem Prototype-based programming?
Druh OOP, kde sa nedeklarujú triedy, ale robí sa rovno s objektami. Napríklad už mám hotový objekt Zviera, tak si ho forknem (oddedím) a vytvorím napríklad objekt Pes. Vtip je, že sa nededí ako v bežných OOP jazykoch, ale klonuje sa, čiže Pes = Zviera.clone() (preto prototyp) a je na mne, či pridám Psovi nejaké nové metódy, aby sa líšil od pôvodného zvieraťa. Keď chcem ďalšieho psa, tak spravím Pes.clone() a mám identickú kópiu. Teraz môžem oddediť od Psa číslo 1 a spraviť si nejaký poddruh psa a oddediť od klonovaného psa (psa číslo 2) a spraviť iný druh a neskôr napríklad zmením niečo v psovi 1 (pridám mu metódu štekaj) a bude to vidieť len v jeho potomkoch (ale nie nutne, v niektorých prototype-based jazykoch sa pri klonovaní kopíruje rodič do dieťaťa, čiže tam nie je referencia späť, takže neskoršia zmena rodiča už nemá na potomka vplyv. Jeden jazyk to tak robil, ale zabudol som jeho meno) a podobne pre psa 2. Ak je to moc nepochopiteľné, tak sa proste jedná o OOP bez tried. Príkladom budiž javascript.
Nechce sa mi teraz ten ioke študovať. V čom je zaujímavý?
Hm, tak je fakt, že teraz som excitovaný ako elektrón: LISP a poriadne OOP, to môže byť prevratná myšlienka, alebo to môže byť brutálny bordel nevyužívajúci naplno ani jeden z týchto prístupov. Ale prototype + makrá, to určite stojí aspoň za drobné preskúmanie
Já jsem uživatel, ne programátor... zatím...
Jinak zajímavě také vypadá Lisaac.
A mohol by si zhrnúť nejaké skúsenosti + dať nejaké zaujímavé príklady (ideálne killer feature, ktorú v inom jazyku nevyrobím)? Letmo som pozrel sem a bol som celkom zhrozený z toho, akú kopu syntaxe to má. Aspoň na to, že je to inšpirované LISPom, ktorý má prakticky len zátvorky
Mimochodem, můžete mi někdo vysvětlit , co si mám představit pod pojmem Prototype-based programming?
http://video.google.com/videoplay?docid=5776880551404953752
nebo v lepší kvalitě http://www.smalltalk.org.br/movies/Self_big.mov