Spíš hodně jazyků (které se nějak vyvíjejí) směřuje k tomu, že jsou multiparadigmatické a přidávají prvky, které v nich původně nebyly. Tohle IMHO budoucnost má.
Otázka je, jak vhodný a jakou budoucnost má čistě funkcionální jazyk. Z matematického/teoretického hlediska je to sice moc hezké, ale proč se dosud neprosadily v běžné praxi? Času na to měly spoustu, ne? Proč se v nich běžně nepíší operační systémy, kodeky, podnikové aplikace, hry atd?
"Proč se v nich [funkcionálních jazycích] běžně nepíší operační systémy, kodeky, podnikové aplikace, hry atd?"
1) Nejsou dostatečně kvalitní kompilátory (možná s výjimkou jazyka OCaml)
2) Funkcionální přístup pracuje s daty, ale nikoliv se změnou stavu. Jakmile tedy máte problém kde je nutnost udržovat stav nějaké datové struktury (modelování nějakého systému a nikoliv jen číst měnit a zapisovat proud dat) a tu měnit, tak funkcionální přístup nelze použít.
Pro operační systémy a kodeky je zásadnější bod 1, pro hry a podnikové aplikace spíše bod 2.
> Jakmile tedy máte problém kde je nutnost udržovat [a měnit] stav [..] tak funkcionální přístup nelze použít.
Uhm... aku mas oblubenu farbu?
Java:
http://blog.tmorris.net/posts/dear-java-guy-state-is-a-monad/index.html
https://dzone.com/articles/do-it-in-java-8-state-monad
Scala:
https://www.reddit.com/r/programming/comments/2isa9q/the_state_monad_in_java/cl54f4i/
Mám trochu obavy, z té multiparadigmatické budoucnosti, ve světě kde každý řeší jak se co nejrychleji napíše ideálně s použitím funkcionálního přístupu v objektovém jazyce.
Pro mě je cenný jazyk a prostředí, ve kterém budu hravě udržovat systém s milionem řádků kódu, desítkama různých komponent, větším množstvím programátorů co se můžou měnit cca po půl roce . To chce kulturu a jednotnost alespoň v rámci komponenty.
Když si to někdo nepohlídá bude mít od jednoho programátora věci objektově , od druhého ve funkcích a od třetího dohromady.
Z tohoto pohledu mi Java s omezenější množinou jazykových konstrukcí tak nějak okolo 1.5 byla milejší.
Mno, spis pochopili, ze funkcionalni programovani ma svoji pomerne uzkou niku, kde je uzitecne.
Hlavne v oblasti proudoveho zpracovani dat.
Ze se nekdo snazi narvat pomoci rovnaku na ohybaky funkcionalni pristup na modelovani objektoveho sveta kolem nas, to uz je jiny pribeh.
Spíš OOP je falešný pokus modelovat svět "realisticky". Takže máme objekt kámen, který dostane zprávu a když se rozhodne, že je to vhodné, poletí. Funkcionální přístup je jenom jeden ze způsobů, jak popsat, co se má stát, namísto toho, jak se to má stát. Jenže ta procedurální složka prostě někde být musí, deklarativní popis nestačí, proto "čisté FP" nemá úspěch. Rozhodně to ale neznamená, že OOP je řešení, to je myslím už dnes dostatečně zřejmé.
Komicky blabol.
Pokud nekdo modeluje svet kolem sebe pomoci letajicich kamenu znamena to, ze OOP "neni reseni a je to zrejme"
Genialni logika.
Apropos, zprava objektu je prave popis co se ma stat, jak se to stane je vnitrni problem objektu.
Ostatne root je plny potroubku, co vyrabej OOP modely, kde kartotecni listky samy skacou do sanonu, kameny letaji, pisek aktivne skace na cekajici lopatu.
A pak se divi. Teda nedivi, OOP je k hovnu a je to kazdenu zrejme...
> kartotecni listky samy skacou do sanonu, kameny letaji, pisek aktivne skace na cekajici lopatu.
Presne. Moc hezky receno. Je videt, ze objektovy navrh i v dnesni dobe ne kazdy zvlada. Problem ale je, ze ani Java takovym nepomuze. Tam jde o to byt "in" a o zbytek se postaraji 3rd knihovny a my to uz nejak slepime. A kdyz neco nefunguje, muze za to ta blba knihovna. Jako bych byl zpet u sveho predchoziho zamestnavatele.. :)
Ja si hraji jak s Javou tak .Net core a pro me proste skoro vse, co se tyka developmentu, od MS je par let pozadu. Od IDE pocinaje, tak po podporu CICD procesu. Tak treba prace s dependency managementem v mavenu je super, nugety, mno co rict a neurazit, proste vymysleji kolo, co na tom, ze je hranate ... Schvalne si zkuset udelat dva projekty na sobe zavisle v jave (pres pom) a pres nugety a developte v obou projektech a debugujte. V MS jednoduse nemozne.
Celkem souhlas. .NET Core je prijemna technologie, pouzivam to u nekolika projektu, ktere se migrovali z stareho ASP.NET a nikdo je nechtel cele prepisovat.
Proti puvodnimu .NET velke zlepseni, ale samozrejme to trpi syndromem nove technologie, jeste se to vychytava a ladi. Java si touhle fazi uz prosla, takze Gradle / Maven je opravdu nekde jinde.
O vyvojovych prostredich ani nemluve.
Upozorňuji, že nejsem ani Java, ani C# developer. Jen bych rád podotkl, že b naší krásné korporaci vyvíjíme řešení, které je (bohužel) napůl v Javě a napůl v C#. To, co je v Javě je všeobecně příšerné, pomalé, náročné na zdroje, vývoj trvá dlouho, špatně spravovatelné a problematicky navržené i implementované byť jde často o výrazně jednodušší komponenty než co implementují C# týmy . Věřím, že za to mohou lidé, ale mnoho z toho je pro Javu a lidi kolem ní docela signifikantní. Nevím proč.
A jak píšu, berte to s rezervou. Developer ani na jedné z těch platforem nejsem.
Já dal mínus přesně za to, co sám píšete: že tam žádný argument není. Jen manipulativní "nema smysl vubec premyslet". Asi jsem ze staré školy, protože nás učili, že má smysl přemýšlet. Občas to trochu bolí a člověk tím zabije moře času, ale vyplatí se to. Vadí mi, když někdo tvrdí opak.
problem .net je to, ze ho skoro nikdo krome MS nepouziva
https://en.wikipedia.org/wiki/Programming_languages_used_in_most_popular_websites
pokud chces delat predrazeny zakazky pro statni spravu, tak .Net je dobra volba, ikdyz i tam se asi vic pouziva Java. Nicmene pokud checes delat na nejakem zajimavem projektu (pr: nejaka cloud sluzba), tak se jazyky nad JVM nebo GO pouzivaji mnohem casteji. Minimum startupu pouziva .Net ve srovnani s jazyky nad JVM nebo GO.
C# je asi lepsi jazky nez Java, ale to neni vsechno. Navic pokud ti vadi Java, muzes pouzit Kotlin nebo Scalu, pak uz nemas jediny duvod, proc bys chtel pouzit .Net
Článek ve kterém se dají najít odkazy na několik různých žebříčků oblíbenosti programovacích jazyků:
https://medium.freecodecamp.org/best-programming-languages-to-learn-in-2018-ultimate-guide-bfc93e615b35 .
Osobně považuji za seriozní např. TIOBE žebříček (přímý okda: https://www.tiobe.com/tiobe-index/ ). Každopádně i ve všech ostatníchžebříčcích C# dlouhodobě pouze padá a i když ho mám docela rád, rozhodně nevypadá do budoucna jako nejlěpší volba (určitě ne jako jediný případně primární jazyk).
Tak C i C++ zrovna v TIOBE (kupodivu) drzi poslednich 20 let stabilni pozici (1. nebo 2., max. treti misto) - mozno zkontrolovat zde: https://www.youtube.com/watch?v=ZkP4sv3H6g8 . Nakonec C# taky, jenom postupne pomalu klesa z 3. mista v roce 2012 na soucasne 6. misto 2018. Neprikladam tomu zvlastni vahu, ale trendy to podle me zachycuje dobre, vcetne ruznych modnich vln.
Ta grafu https://www.tiobe.com/tiobe-index/c/ je ten propad vidět. Existuje k tomu nějaké vysvětlení?
Koukám, na grafu je nějaká fluktuace vidět u C a Javy, ale celkové pořadí v žebříčku to nijak neovlivnilo. Viz https://cs.wikipedia.org/wiki/Soubor:Tiobe_index.png . Vysvětleni jsem nenašel, pouze spekulace, např. https://www.i-programmer.info/news/98-languages/10398-c-slides-in-tiobe-index.html. Osobně se spokojím s tím, že je to prostě "artefakt" :)
Odkedy orakul "prebral" Javu od SUN-u, prestal som jej vyvoj sledovat, ale pisat, ze je zufaly, ked vlastne z nej nic nema a su tu openJava alternativy je trochu prehnane. Z clanku mi vyplyva, ze sa za tie roky, co Javu aktivne nesledujem moc nezmenilo. Akurat ten nativny kod pribudol. Ale aj to bolo planovane este SUN-om ak si dobre pamatam.
Kludne mozete k teme napisat blogovy prispevok tu na roote, ja si ho zase velmi rad precitam. Javu som kedysi protezoval, odkedy sa odstala k orakulu, skor ju zaznavam. Ale mozno mi zmenite nazor.
V sucasnosti mam nutenu volbu .NET/C# alebo Javu tak neviem ktore zlo je to mensie.
>>Go je jazyk navržený od začátku tak, aby řešil problémy při psaní nízkoúrovňových programů spjatých s operačním systémem. Go to zvládá velmi dobře. Na druhou stranu Go zvolilo přístup, který v sobě má jistá omezení.
Takhle je napsaný každý jazyk, nežijeme v ideálním světě.
Go je evolucí C/C++ podobně jako je Kotlin evolucí Javy, podobně jako je Ruby evolucí Pythonu, stejně jako je BASH evolucí Bourne shelu, který je evolucí Thompson Shellu…
>>Go překladač je od základu napsán Go týmem. Nevyužívá žádné z obecně rozšířených systémů jako je GCC či LLVM. Vše je od začátku do konce napsáno Googlem. To se samozřejmě negativně odráží na šíři podporovaných fíčurek, ale i na rychlosti. Go tým prostě není nafukovací a nemůže všechny požadavky řešit tak rychle, jak by si uživatelé přáli.
Autor téhle hate-speech nejenom že předkládá ničím nepodložená fakta, ale zjevně přehlédl projekt gollvm.
Mimochodem MS Visual Studio take nestaví na GCC nebo LLVM, je psán jenom týmem Microsoftu –> taky o něm budete tvrdit že je kvůli tomu omezené a „nemůže všechny požadavky řešit tak rychle, jak by si uživatelé přáli“???
Re. "zjevně přehlédl projekt gollvm" - Nepřehlédl. Naopak beru jej jako podporu svého tvrzení. Zdá se, že i Go komunita si uvědomuje, že napsat překladač odshora dolů vlastními silami má své nevýhody. Takže ano, pokusy to napravit existují (jak do LLVM tak i do GCC), ale povšimněte si prosím poznámek typu "Gollvm is currently in development -- releases are not yet available for download" či "It compiles and passes most of the standard library test suite and a substantial portion of the gc test suite, but there are some corner cases that are known not to be handled correctly yet"
Tak já nějaké používám, nejčastěji asi fzf ( https://github.com/junegunn/fzf ).
A také i další psané v rustu, C, pythonu, perlu, bash... ale snad žádnou malou utilitu psanou v javě.
Java je u mne spíše doménou velkých programů (např. Intellij Idea), u kterých člověk čeká velkou náročnost a nevadí pomalejší start.
Přiznám se bez obalu, že nesnáším tyto nadšenecké články. Ve slaboduchých vyvolávají mylné dojmy iluzích různých pozitivních změn(revolucí), tvz. jsou manipulativní a ti jsou pak zklamaní . Jako člověk co využívá Javu tak vyjádřím aktuální negativa u Javy :
- změna licenčních podmínek u Oracle Java
- rychlejší vydávání verzí JavySE
- pomalé vydávání oprav JavaEE např. GlassFishu ( samozřejmě vím že přešel nedávno pod Eclipse, ale když byl pod Oracle vyšli pro EE7 pouze 3x opravy - za cca 3 roky )
- katastrofální podpora multimedií v API
- nekvalitní dokumentace k API ( jako kdyby to psaly Indové, triviální věci jsou napsané pod psa ale skutečně obtížné věc jenž se často nepoužívají jsou napsané katastrofálně )
Autore odkud bereš informaci že se jedná o native-image ? Dle specifikací se jedná o JEP 220 (Modular Run-Time Images), takže se jedná o run-time image. Já osobně na to čekal od Java6 ale faktem je že to přišlo příliš pozdě, tato věc tu měla být tak na konci 90.let a nikoliv 2017. Java prakticky DESKTOP sektor prohrála a ani toto to nezmění.
I kdyby byl PÁN BŮH, specifikace je jednou standardizovaná a pojmenovaná a tím to hasne.
https://openjdk.java.net/jeps/220
Vlastní označení(pojem) může neznalé vést ke zmatenosti.
Evidentně patříš mezi hlupáčky, na které podpis pod jménem dělá DOJEM. Doporučuji nejdříve si to nastudovat, naučit, pochopit a používat vlastní mozek. Stejným způsobem tu po revoluci přišel Kožený, oháněl se titulem s Hardwardu a naivní hlupáci(jejíchž si zjevně potomek dle zákonu genetiky) z něj padaly na hubu. A pak až si uvědomily, že s nimi bylo vymrdáno bylo už pozdě.
Mě přijde že mateš ty, a to dost šíleně. native-image vytvoří z javovských zdrojáků přeloženou nativní binárku, která už nepotřebuje k běhu virtuální stroj. JEP 220 mluví o reorganizaci JRE a JDK a změně formátu JARek (které se pak asi budou jmenovat jinak). Reálná souvislost mezi native-image a JEP-220 (a tedy i článkem a tvým komentářem) je velmi nízká, snad až na to že JEP 220 počítá s tím, že by v "nových JARkách" mohlo být možné mít uložené předkompilované verze bytekódu.
Už se moc nedivím, že ti dokumentace Javy přijde špatná. Porozumění ti moc nejde.
native-image
není (zatím) specifikována žádným JEPem, takže to určitě není to samé jako JEP 220. Navíc GraalVM 1.0.0 RC9 je rozšířením JDK8 - a ten JEP 220 je jen v JDK9 a více.
Tomuto ty říkáš odpověď?
Proč v tvém příspěvku NENÍ jako argument použit standard(specifikace JEP) která v Javě tvz. native-image definuje nebo aspoň používá ? Takto to tvou odpověď dělá pouze lichou a bezpředmětnou, kdy opakuješ fráze které ví snad každý.
Jak další argument bych akceptoval kdybys popsal tedy "správnou "definici" "run-time image". Jenže jsi tak zjevně hloupí, že ani to tě nenapadlo.
Souvislost mezi JEP220 je zásadní a to proto hned z několik důvodů :
1) že JEP220 a odkazuje se na další JEP které jsou pro to nutná (proto jsem tu dal link) - ty jsi se na žádný url odkaz ani nevzmohl
2) je součástí specifikací Modularity, stejně jako jlink a bez modularity dané řešení nefunguje. Staré projekty v jar bez module-info.java by se tedy neměli takto převést.(ovšem aktuálně to nemám otestované, neboť v betě Java9 před 2 lety kdy jsem to zkoušel to nefungovalo)
PS. a ano, skutečně jako menza jedinec mám dost často problém s porozuměním výplodů slabomyslných mozečků. Dost často totiž pletou páté přes deváté(z důvodu zmatenosti) a nic jim pořádně nefunguje, často při výzvách selhávají, mají problémy se pořádně vyjádřit( tzv. vymáčkout ), ty jsi toho přímí důkaz.
PSS. Když ti je vše jasné, a domníváš že tomu rozumíš, co ti brání nechovat je jako LÍNÝ CIGÁN a udělat na to český tutoriál. Snad jenom to, že se domníváš chybně, uvědomuješ si to a proto se bojíš to zveřejnit(jít s kůží na trh). Anebo máš pravdu, já se mýlím a můžeš nás všechny poučit. Jak říkám stačí nebýt LÍNÝ JAKO CIGÁN.
PSSS. já už si v tom několik programů( to i vč. GUI - abych si to pořádně otestoval) za poslední dva roky udělal, co ty ?
PS. = post scriptum
PSS. = post scriptum scriptum
PSSS. = post scriptum scriptum scriptum
stejná logika jako u oblečení
S small
M medium
L large
XL extra large
XXL extra extra large
XXXL extra extra extra large
nebo označení pařby
party = hlavni událost večera(noci)
after party = mejdan u někoho po ránu(dopoledne)
after after party = další mejdan u někoho dalšího nebo pokračování chlastání v hospodě odpoledne
atd...
tedy tak to za nás aspoň 90tých fungovalo.
většinou nereaguji, ale ty se chováš jako bys spolkl všechen rozum světa - což je průvodní jev toho, že ve skutečnosti víš howno - ale kolega tu s tebou polemizuje o tom tvém PSSSSS - protože jsi opět odpověděl jako trotl, tak ti dám poslední šanci se opravit a zamyslet nad: post scriptum scriptum scriptum vs post post post scriptum - možná toto pomůže lépe chytrolíne: post scriptum scriptum scriptum == nesmysl vs post (post (post scriptum)) a na závěr, změň své vyjadřování, protože, když jsi d3bil, což zjevně jsi (hodnotím tvůj projev zde), tak aspoň zkus omezit svou aroganci, i když si myslíš, že jsi hrozně chytrej
Desktop sector? Native-image ma praveze velky zmysel v cloude,kde potrebujete okamzity start sluzby - idealne ak si pamata svoj stav a po vykonani zase uspat...aspom co sa tyka resource managementu...
Viete vy vobec ako dlho trva inicializacia springoveho (spring boot) kontaineru v beznych podmienkach?
"Viete vy vobec ako dlho trva inicializacia springoveho (spring boot) kontaineru v beznych podmienkach"
Jo, to nahodou vim.
Samotny spring boot container pro commandline plaikaci tak kolem 1 sekundy, s embedded Tomcatem cca 5 sekund, s navic pribalenym Apache CXF 7 sekud, s navic pribalenym Spring security, hibernate, primefaces (celkem 70 MB FAT JAR) cca 10 sekund.
Vse mereno na nobeooku Thinkpad T430 Core i5 z roku 2012.
Nespravne, je uplne jedno, jestli pul roku bezici microservice startuje sekundu nebo pet.
GO ma vyhodu u mikrotransakci hlavne z duvodu lehkych threadu channels/goroutines.
Java ma thready mnohem tezsi a s velkym overheadem pri vytvareni/zavirani.
Java se to snazi resit reaktivne, ale prace s takovym kodem je opruz.
Channely a gorutiny jsou jedina vec, co ma Go lepsi nez Jawa, jinak je to slabota.
Nespravne, je uplne jedno, jestli pul roku bezici microservice startuje sekundu nebo pet.
A BaaS ti nic nehovori ? Platite v cloude 24/7 cenu? No tak to sa nedivim, ze je to potom drahe !!! Je rozdiel, ked mam obsluhovat poziadavku raz za 5 sekund a kvoli tomu startovat springovy kontainer alebo pouzitim native-image mam perzistovany stav microsluzby... btw 1 za 5 sekundy znamena 80% usporu nakladov.
> změna licenčních podmínek u Oracle Java
Oracle Java je primarne urcena pro platici zakazniky. Nejsi jim? Tak potom je pro tebe AdoptOpenJDK.
> - rychlejší vydávání verzí JavySE
V cem je tohle presne nevyhoda?
> Java prakticky DESKTOP sektor prohrála a ani toto to nezmění.
Souhlas. Java desktop sektor prohrala a desktop trh navic jeste umrel:))
GraalVM je pro microservices a ne pro desktop.
Glassfish mal mat odnoz Paraya, vraj je to rychlejsie opravovane. Raz som to skusal, ani mi to neslo. S Glassfish som mal vzdy nejake problemy. Jedine co mi poriadne funguvalo z volne dostupnych bol Wildfly.
K spomenutym negativam Javy by som este pridal neistotu ohladom buducnosti (kvoli Oracle) a neexistenciu normalnych funckii. Nutnost trepat vsetko do tried je velke minus Javy. Dalej je to extremna celkova narocnost a strma krivka ucenia. Onedlho nebude nik, kto by chcel do toho ist.
Co se týče budoucnosti Javy, toho bych se nebál. Osobně vkládám velké naděje do Correto což je JDK od Amazonu, který se rozhodl udržovat vlastní verzi Javy 8 ještě dalších 5 let a plně zadarmo(plus nové verze také jsou). Myslím že Oracle na svou nenažranost dojede a změna licence javy se mu vymstí. Amazon to sice dělá kvůli cloudu ale je to bezproblému použitelné pro linux desktop i mac.
Jak čtu ten článek, tak mě napadá z ufologie klasický Fermiho Paradox - "Tak kde tedy všechny jsou"?
Reálných Javovských programů (tedy ne akademických cvičení) jsem viděl pěknou řádku, některé z nich musím občas provozovat (třeba až na nenažranou Javu velmi povedené Serviio, kde ale sežere java víc paměti než ffmpeg pod tím kterej dělá online transcoding, což je ostuda, JDownloader nebo FRD, Minecraft server pro děti, pracovně pak nějaké applety v ILO nebo pár managementů) a ač se snažím sebevíc, nevzpomínám si na ani jeden jediný případ, který je svižný a nežravý.
Nevím, jak tohle vysvětlit. Třeba jazyk vede k používání krajně neoptimálních konstrukcí? Nebo je psaní efektivních programů sice možné, ale dostatečně komplikované, takže to nikdo nedělá? Netuším. Ale (pravda, ta rozšířenost není tak velká takže to není až tak fér srovnání) příklad podobného molocha v go by se asi hledal velmi těžko.
Ve skutecnosti je spatnej i klient ... nastav si trochu vetsi dohled a uvidis sam. Server je na tom samo radove hur, protoze na stroj kterej udrzi 100 lidi abys nakoupil HW za 1/2M. Pokud si nekdo chce jen tak zahrat s kamosema a nema dedikovanej HW na server, tak ma problem. Protoze i7 se zapoti uz pri 2 lidech.
A to vse vyhradne a pouze proto, ze to je v jave. Coz, jak tu zaznelo, prozmenu prinasi pohodovou a snadnou modifikovatelnost ... ale vykon je proste tragickej. Coz ostatne opakovane uznal i autor.
> Třeba jazyk vede k používání krajně neoptimálních konstrukcí?
Je to jen a jen můj dojem, ale snad každý kód napsaný v Javě, který jsem viděl, byl nehorázně ukecaný a rozplizlý. Občas to ve mě vyvolávalo dojem, že by autor nejraději vytvořil pár interfaců a tříd i na porovnání dvou integerů.
Pricemz by sis brutalne nabehl.
GO nesnese srovnani ani s Jawou, ani s C++.
Neumi generika, neumi ani triviali typu ordered Map, nebo Set, neumi ani vyjimky, pricemz to nahrazuje idiotskymi defer funkcemi.
Go je neskutecny hype tlaceny fanboys, muze poslouzit jako nahrada C nebo Perlu, Jave ani C++ nesaha po kotniky.
Jedina pekna vec na GO jsou channely a gorutiny, jinak je to slabota.
Ja teda Javu nemusim, ale pokud jste nekdy delali s Bigdata/IoT infrastrukturou, tak s prekvapenim zjistíte, ze se pouziva ve velkem (proc, to nedokazu rict). Mam na mysli projekty jako: Hadoop, Nifo, ElasticSearch, Cassandra a pod. Asi je to kvuli skalovatelnosti a moznosti pouzit odlisne architektury...nevim.
Většina těch projektů má základy v akademické sféře - a Java je posledních 15 let standardním jazykem pro výuku - což bych viděl jako primární důvod. Sekundární - všechno už jsou to CAP projekty - s horizontálním škálováním, takže potřebujete pořešit síťovou vrstvu, případně sandboxing. Na to je Java, a její knihovny dobrá - v C, C++ by to bylo dost nepříjemná práce, a GO v době vzniku těchto projektů nebylo nebo bylo v plenkách. Rychlostně to není nic extra, dá se ale horizontálně škálovat, a v základu je nějak řešena dostupnost - a díky Javě experimentování nebylo extra programátorsky náročné, vývoj zlevnilo i reuse relativně komplexních komponent - např. ElasticSearch používá Lucene, atd. Pro práci je to dost rychlé, když máte dost paměti, rovnou je tam nějaké HA, které alespoň, když jsem s tím dělal, bylo docela potřeba, a je to zadarmo. Alternativní bigdata nástroje jsou pekelně drahé.
Větu "Pro práci je to dost rychlé" jsem chtěl napsat "Pro práci je to DOSTATEČNĚ rychlé".
Po roce 2000, kdy se začalo s BigData, se volný, veřejný kód psal téměř výhradně v Javě - a v Apache Foundation se vybudovalo docela široké portfolio komponent a projektů. CPU optimized BI jsou stále proprietární projekty a nejde o nic levného.
Presne a este by som doplnil, vela dodavatelov su vlastne dodavatelia hotovych rieseni tretich stran. Vzdy sa ide po cene a Java ma kopec hotovych modulov, kniznic a rieseni takze sa len nieco dolepilo a predava sa to ako hotove riesenie. Nic nezvycajne ked tool na management je vlastne Eclipse s plugin modulmi.
K tomu bych i doplnil, že nad Javou se daleko lépe (čti levněji) zajišťuje QA než s C/C++. Zajišťovat v dnešní době nad Go LTS je také problematické a v Javě nikoliv, ono se to v budoucnu možná překlopí, i v Apache Foundation jsou slyšet kritické hlasy vůči Javě, ale v současné době se jde primárně za funkcionalitou a nikoliv za výkonem.
Pokud vím tak java je nenažraná právě díky implementaci garbage collectoru (kterému se navíc musí předem říct, kolik si má vzít maximálně paměti... a on si tu paměť pak vezme (ostatní programy mají smůlu, a díky "fragmentaci" swapspace moc nepomůže). Takže hlavní nevýhodu prý řeší "nízké paměťové nároky" ale co to znamená? Stejně špatný GC jen s menším overheadem na start programu? To bychom si moc nepomohli, ale nikde není zmíněno, že je tomu jinak.
Ostatně celý článek zní více jako übernadšenecký trolling, než jako reálné zhodnocení výhod a nevýhod GraalVM (což je to co asi ten článek měl být?). Dokonce není GraalVM ani zmíněn v nadpisu.
Nedavno tu byl clanek na tema GraalVM, staci najit, nebo domovska stranka prpjektu taku funguje, pry i Google :)
Tak ve strucnosti: Nastavovat max pamet nemusis.(ale muze se hodit nekdy),Java jako jazyk zadny konkretni GC nema, Hotspot (coz je asi pro tebe ta Java) jako JVM jich zase ma nekolik, SubstrateVM ma zase jine.
Dobrá otázka. Rychlost startu je totiž přesně to, v čem native-image
z GraalVM vyniká!
Takže jsem nelenil a přepsal ten svůj příklad tak, aby počítal jen jedno prvočíslo. Nu a zde je výsledek:
sieve/go$ go build; time ./go First prime is 2 One prime number in 0 ms real 0m0.001s user 0m0.000s sys 0m0.000s java/algorithm$ JAVA_HOME=/graalvm mvn clean install -Psvm -DskipTests sieve/java/algorithm$ time ./target/sieve First prime is 2 and took 0 ms real 0m0.001s user 0m0.000s sys 0m0.000s
Tak asi tak. Nula nula nic. Prostě zkuste uvěřit, že kód vygenerovaný pomocí native-image
není ta stará a pomalá Java. Je to dost dobrá náhrada v místech, kde se do teď hodilo používat Go.
PS: Omlouvám se, že jsem tento příklad neuvedl v článku. Hodil by se tam.
Ještě mne napadlo přidat to samé měření na normální JVM:
java/algorithm$ time java -jar target/sieve-algorithm-1.0-SNAPSHOT.jar First prime is 2 and took 1 ms real 0m0.091s user 0m0.092s sys 0m0.008s
Startuje to asi tak stokrát pomaleji. Jak jsem psal: nenažraný interpretovaný bumbrlíček.
Ano, je to tak. Pokud přežijete fázi interpretování a necháte JIT kompilátor vygenerovat pořádný kód, může to být velmi rychle (minule jsem napsal rychlejší než Céčko a dost jsem to schytal, ale asi tak nějak):
sieve$ mvn -f java/algorithm/ package exec:java Hundred thousand primes computed in 90 ms sieve$ JAVA_HOME=/graalvm mvn -f java/algorithm/ exec:java Hundred thousand primes computed in 84 ms sieve$ ./c/sieve Hundred thousand prime numbers in 98 ms sieve$ git log | head commit 64aed1ac16a71b193449898b5c79d97b89401f3e
Problém standardní Javy není v tom, že by její JITovaný kód nemohl být rychlý, ale v tom, že k tomu potřebuje strašně moc metadat. S native-image
je kód o něco pomalejší, ale běžící proces je výrazně úspornější hlavně z pohledu spotřeby paměti.
Predpokladam, ze to Ccko je kompilovane s patricnymi optimalizacemi, vcetne -fwhole-program nebo , aby to bylo fer?
Vlastni program v C je jina otazka, asi by to clovek takhle normalne nenapsal - predpokladam ze boxovani celych cisel ma nejaky hlubsi smysl, stejne jako pouzivani DL seznamu misto pole? To vyplivl nejaky automat, nebo to je podle nejakych Javovskych best practices? Jako kompilator si s s tim poradi, ale opravdu se nekomu cte tohle lepe nez normani Ccko?
O drobnostech jako testovat ve smycce nextPrime zda je promenna inicializovana namisto testu venku/jeji inicializace predem.
Tohle je jiné porovnání, než si asi představujete. Tohle je snaha porovnávat rychlost jazyka v typických úlohách (ne v typických úlohách pro daný jazyk, ale v úlohách, které jsou asi nejběžnější napříč všemi aplikacemi). Takže to není kód, který by byl optimální v daném jazyce a už vůbec ne optimalizace překladu. Ono by se to takhle samozřejmě nenapsalo ani v Javě. Proto je tam to boxování celých čísel a spojový seznam, aby tam byla nějaká práce s dynamickou pamětí, což je typická úloha.
Myslím, že srovnaní Go a Javy z hlediska vláken není vůbec na místě. Oba jazyky k nim přistupují úplně jinak. A podpora green threads je právě ta věc která je na go podstatná. A vypočet prvočísel opravdu tuto vlastnost nemůže odhalit. Malý http server a testování 10k souběžných spojení už ano.
Zajímavé. Java nemá koroutiny. Ale protože native-image
pracuje s jakýmkoli JVM jazykem, tak by mělo být možné použít Kotlin. Tam koroutiny jsou. Výsledek by snad měl být podobný goroutinám (alespoň nevidím důvod, proč by to mělo dopadnout výrazně jinak), ale muselo by se to samozřejmě vyzkoušet.
Bylo by možná dobré připomenout jeden z důvodů, proč se Go relativně dobře rozšířilo. Je to mj. i díky gorutinám a kanálům, jak jejich podpoře v jazyku, tak i jejich "lehkotonážnost" při použití. Co takto namísto mikrobenchmarků nahodit něco paralelního, kde se dají kanály a gorutiny použít?
Ano, na potřebu "skutečného" benčmárku jsme již také narazili. Hrál si s tím Michal, můj kolega z jiného týmu a patra. Vytvořil web-fmwks-perf-comparision, kde chce testovat reálné scénáře: HTTP, parsování JSONu, přístup do databáze, atd. Zatím je tam to HTTP.
Pomáhal jsem mu to uchodit s native-image
. Bylo dost těžké Go dohnat, ale nakonec se to snad povedlo. Akorát jsem musel nahradit Netty za NanoHTTPD. Zdá se, že v Netty je příliš mnoho abstrakcí a na obyčejném Hello World příkladu to příliš zpomaluje. Po přepsání a znovu využití vláken ta Java verze přeložená native-image
dokázala odpovědět na patnáct tisíc dotazů za sekundu. Asi tak stejně jako Go.
Ale zrovna HTTP server je příklad použití, kde by normální JVM po dosažení optimálního stavu (po pár tisících dotazech) zřejmě fungovala rychleji než native-image
...
Chtěl jsem zkusit ten native-image, rychlý start pro cli programy by byl pěkný.
$ java -version openjdk version "1.8.0_192" OpenJDK Runtime Environment (build 1.8.0_192-20181024121959.buildslave.jdk8u-src-tar--b12) GraalVM 1.0.0-rc9 (build 25.192-b12-jvmci-0.49, mixed mode) $ cat HelloWorld.java public class HelloWorld { public static void main(String[] args) throws Exception { System.out.println("Hello, World"); } } $ javac HelloWorld.java && java HelloWorld Hello, World $ native-image --static -cp . HelloWorld Build on Server(pid: 32471, port: 44227) [helloworld:32471] classlist: 171.66 ms [helloworld:32471] (cap): 103.20 ms [helloworld:32471] setup: 174.61 ms fatal error: com.oracle.svm.core.util.VMError$HostedError: java.nio.charset.UnmappableCharacterException: Input length = 1 at com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:70) at com.oracle.svm.hosted.c.codegen.CSourceCodeWriter.writeFile(CSourceCodeWriter.java:183) at com.oracle.svm.hosted.c.codegen.CSourceCodeWriter.writeFile(CSourceCodeWriter.java:160) ... zkráceno Error: Processing image build request failed
Zdá se, že to ještě má mouchy, ale třeba jsem tomu jen nevěnoval dost času...
Děkuji za vyzkoušení. Je mi líto, že to spadlo. Můžete zadat chybu na https://github.com/oracle/graal/issues a přidat nějaké detaily, protože mně to na Kubuntu 16.04 prošlo...
Bingo! Přeci jenom funguje, tak uvidím jak si povede až zkusím něco reálnějšího.
Třeba ještě dostane java šanci i pro cli nástroje...
Jasně, že hello world není reprezentativní program, ale zaujalo mě několik věcí:
Velikost ~7MB u staticky linkované binárky je dost (ale chápu, že tam je runtime s gc a ostatním příslušenstvím), dynamicky linkované ~6MB je pořád dost. Z GO padají binárky o podobné velikosti. Kompilace do binárky trvá u hello world 20sec - to mi přijde jako hodně, ale zase kompilaci člověk nepouští tak často. Start výsledné binárky je okamžitý, subjketivně rychlejší než klasické jvm.
$ mv ~/Stažené/graalvm-ce-1.0.0-rc9 ~/Sandbox $ export PATH=~/Sandbox/graalvm-ce-1.0.0-rc9/bin:$PATH $ javac HelloWorld.java && java HelloWorld && native-image --static -cp . HelloWorld Hello, World Build on Server(pid: 8989, port: 35763)* [helloworld:8989] classlist: 1,090.04 ms [helloworld:8989] (cap): 1,032.43 ms [helloworld:8989] setup: 2,087.33 ms [helloworld:8989] (typeflow): 4,684.50 ms [helloworld:8989] (objects): 2,183.62 ms [helloworld:8989] (features): 79.43 ms [helloworld:8989] analysis: 7,054.64 ms [helloworld:8989] universe: 323.77 ms [helloworld:8989] (parse): 831.03 ms [helloworld:8989] (inline): 1,367.12 ms [helloworld:8989] (compile): 5,685.21 ms [helloworld:8989] compile: 8,498.63 ms [helloworld:8989] image: 726.43 ms [helloworld:8989] write: 201.11 ms [helloworld:8989] [total]: 20,041.28 ms $ time ./helloworld Hello, World ./helloworld 0,00s user 0,00s system 93% cpu 0,002 total $ ls -lah helloworld -rwxr-xr-x 1 martin martin 7,1M 4. pro 14.51 helloworld $ ldd helloworld není dynamickým spustitelným kódem $ native-image -cp . HelloWorld zsh: correct 'HelloWorld' to 'helloworld' [nyae]? n Build on Server(pid: 8989, port: 35763) [helloworld:8989] classlist: 190.99 ms [helloworld:8989] (cap): 601.78 ms [helloworld:8989] setup: 1,002.38 ms [helloworld:8989] (typeflow): 3,407.67 ms [helloworld:8989] (objects): 1,644.25 ms [helloworld:8989] (features): 69.44 ms [helloworld:8989] analysis: 5,211.27 ms [helloworld:8989] universe: 164.07 ms [helloworld:8989] (parse): 516.41 ms [helloworld:8989] (inline): 577.43 ms [helloworld:8989] (compile): 3,090.78 ms [helloworld:8989] compile: 4,514.93 ms [helloworld:8989] image: 418.64 ms [helloworld:8989] write: 113.15 ms [helloworld:8989] [total]: 11,644.94 ms $ time ./helloworld Hello, World ./helloworld 0,00s user 0,00s system 93% cpu 0,003 total $ ls -lah helloworld -rwxr-xr-x 1 martin martin 6,3M 4. pro 14.59 helloworld $ ldd helloworld linux-vdso.so.1 (0x00007ffc5a7fb000) libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f7e71422000) libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f7e7141d000) libz.so.1 => /usr/lib/libz.so.1 (0x00007f7e71206000) librt.so.1 => /usr/lib/librt.so.1 (0x00007f7e711fc000) libcrypt.so.1 => /usr/lib/libcrypt.so.1 (0x00007f7e711c2000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f7e70ffe000) /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f7e71a56000)
Ano. Lze to. Pokud tomu rozumím, tak se používá třída NodeSourcePosition. Pozice se obvykle vyskytuje v bajtkódu a po naparsování do grafu se přiřadí k jednotlivým vrcholům. Kompilátor ten graf pak různě mění, ale i když nějaké vrcholy zahodí a vytvoří místo nich jiné, tak jim předá vhodnou pozici. Vrcholy, které zbudou v poslední fázi (a generují nativní instrukce), tak stále mají jakýsi vztah k původním pozicím. Tak asi tak. Více jsem to nezkoumal.
No, mám tady na stole jednu desku. Procesor honím na 168MHz (vychází tak nejlíp časování periferek, dal by o něco víc). Má to 4x64 kiB RAM + 2x 1MB FLAH.
Mám tam ovladače pro Ethernet dělat v Javě? VM tam nedostanu ani omylem, nevím co Java přibalí z knihoven a jestli toho nebude v té binárce 0,5GB - pokud jo, nic s tím neudělám. Zaintegrovat HW pro HASH a HW crypto engine by byla ještě o level větší sranda... A nesmí to kleknout kvůli fragmentaci paměti.
Článek je o tom, že je Java použitelná i na low level věci. Tak se ptám, jestli by Java dala i takovouhle věc.
Ono totiž
- C blbě pracuje s objektama (socket atd. se jako třída přímo nabízí, takže to smrdí OOP)
- C++ má náročnou správu paměti
- Go - zatím jsem nezkoumal možnosti
- Java - viz komentáž výše. Nevím, co všechno se tam pokusí narvat
Napadá někoho jiný řešení?
Z hlediska programátora - musí se rozmyslet, kde objekt založí - heap nebo stack, kdo bude vlastníkem, kdy je případně třeba vlastnictví předat, nově do toho přichází unique/shared. To vše ovlivňuje jak se bude objekt předávat dál (hodnota, reference, pointer, ...), jak bude algoritmus navržen atd. U složitějších algoritmů to v podstatě vede na to, že programátor píše vlastní obdobu GC zas a znovu.
Z hlediska runtime - je zde mnohem složitější logika jak při alokaci tak dealokaci, výkonnostní dopady v případě sdílených pointerů, nevyhnutelné problémy jako např. defragmentace. To následně dále vyvolává tlak na programátora, aby tomu ještě víc přizpůsoboval design programu, musel optimalizovat apod.
Ve výsledku je programátor nucen zabývat se těmito aspekty v C++ násobně déle než kolik na to je potřeba třeba v javě (ale vlastně v čemkoli co má rozumný GC).
Jedinou výhodu kterou za to dostaneme jsou nižší paměťové nároky a někdy se může hodit deterministická dealokace. Samozřejmě existují případy, kdy je lepší to psát v C++ (programátor je dostupnější než RAM), ale většinou jsou výše uvedená negativa příliš.
No a nie je to skôr tak, že sa človek primárne rozhoduje o iných veciach, ako napríklad či chce mať prístup k danému prostriedku zdieľaný, alebo či je jeho vlastníctvo exkluzívne, alebo či potrebuje presne vedieť kedy skončí životnosť objektu, alebo podobné záležitosti a na základe toho potom vyplynie typ objektu, miesto jeho existencie a signatúra funkcie? Ja si myslím, že je :-) No a ak má chaos v tom ako to vlastne má byť, tak je jasné, že to bude prepisovať. Ale je to chyba C++? To ani náhodou.
C++ dáva možnosti. Pokojne môžeš písať program s tým, že každá dátová štruktúra je dynamicky alokovaná a zdieľaná, fungovať to bude a nemusíš nič prepisovať. Je to efektívne? Nie. Ale efektivita nie je zadarmo, musíš o nej niečo vedieť a niečo pre ňu urobiť. Existuje programovací jazyk, ktorý dáva tieto možnosti automaticky a človek pre to nemusí nič urobiť? Ja neviem, rád sa niečo nové naučím, ale dosť o tom pochybujem.
A potom, ktorý rozumný programátor by používal C++, keď nepotrebuje možnosti, ktoré C++ poskytuje?
U naprosté většiny objektů nepotřebuju řešit, zda bude sdílen či ne, kdy skončí životnost apod. Dokonce je to tak, že díky tomu, že tyto věci není potřeba vyhodnotit, tak to vede na jednodušší algoritmus a kód.
Dále, ať už je objekt takový či makový, nemá to vliv na hlavičku funkce, do které ho chci poslat. To samozřejmě výrazně usnadňuje vývoj, údržbu, předělávky atd.
To že v C++ musím dělat tato rozhodnutí pro každou jednotlivou instanci a každý jednotlivý parametr je samozřejmě vlastnost C++ (nenazýval bych to až tak chybou), v jazycích jako java to pro většinu instancí není nutné.
Další faktor je, že z mnoha důvodů je dobré mít konstantní objekty (abych nemusel řešit to sdílení apod.). To ovšem vede na vyšší nároky na alokátor, jenže založit objekt je v C++ výrazně dražší než třeba v JVM. To opět zvyšuje pravděpodobnost, že toho programátor v C++ bude muset řešit víc než je nutné jinde.
> Pokojne môžeš písať program s tým, že každá dátová štruktúra je dynamicky alokovaná a zdieľaná, fungovať to bude a nemusíš nič prepisovať
To samozřejmě fungovat nebude, stačí mít mezi objekty cyklus a už nemůžu použít shared_ptr. Pokud ho nepoužiju, musím řešit vlastnictví. A už se to veze...
> efektivita nie je zadarmo, musíš o nej niečo vedieť a niečo pre ňu urobiť
Anebo můžu použít platformu, která 95% těch situací vyřeší sama a já se zatím můžu zabývat tím co chci řešit já.
> U naprosté většiny objektů nepotřebuju řešit, zda bude sdílen či ne, kdy skončí životnost apod.
Keď niečo neriešiš osobne, tak to za teba vyrieši niekto iný a je otázka, či ti to tak vyhovuje. Mne nie.
> Dále, ať už je objekt takový či makový, nemá to vliv na hlavičku funkce, do které ho chci poslat.
To aký je objekt nie, to ani nikto netvrdí. Vlastníctvo a pod. neriešime kvôli samotnému objektu, ale kvôli tomu, ako s ním pracujeme. Vo funkciách. Riešime, či je objekt vo funkcii vytvorený a vrátený volajúcemu, alebo či z prijatého objektu vo funkcii iba čítame alebo ho aj modifikujeme alebo objekt kompletne nahradíme iným objektom, alebo či ten objekt vo funkcii končí svoju životnosť, v iných prípadoch je naopak rozumné zabezpečiť, aby objekt počas volania funkcie nezanikol, atď. (Nepochybujem, že toto vieš aj sám.) A podľa toho akú požadujeme funkčnosť volíme argumenty funkcií.
> To že v C++ musím dělat tato rozhodnutí pro každou jednotlivou instanci a každý jednotlivý parametr
Stále si myslím, že to naozaj nemusíš. Môžeš sa správať na základe štandardných odporúčaní, teda opakovať stále jedno počiatočné rozhodnutie pre daný kontext, a v odôvodnených prípadoch sa môžeš rozhodnúť pre niečo iné. Keď vieš, že za to získaš niečo, čo potrebuješ.
> jenže založit objekt je v C++ výrazně dražší než třeba v JVM
S JVM nepracujem, tak neviem ako to myslíš, ale keď chcem, aby som mal v C++ objekt vytvorený rýchlo, čo sa týka objektov, ktorých mám v aplikácii kvantum, tak si odhadnem koľko ich asi budem mať, predalokujem pamäť pre všetky naraz (zjednodušene povedané), vytvorím vlastný "alokátor" a vytvárané objekty budú existovať v rámci predalokovanej pamäťovej oblasti. Keď chcem, tak tú oblasť môžem mať inicializovanú blokom objektov načítaných z disku, alebo iba namapovanú zo súboru, na základie služieb OS. Takže vo finále vytvorenie jedného objektu je vlastne práca s ukazovateľom a s nejakou internou dátovou štruktúrou, v ktorej je evidencia voľných a obsadených blokov (zoznam, strom, bitová mapa, čokoľvek iné), prípadne ešte inicializácia jednotlivých členských premenných vytváraného objektu, pokiaľ ich naozaj vytváram a neboli načítané alebo namapované. Uvoľnenie jednotlivej položky je ešte jednoduchšie a uvoľnenie celého bloku ani nemusím písať. Fragmentácia nula. JVM má nejakú rýchlejšiu/lacnejšiu metódu?
> ... že toho programátor v C++ bude muset řešit víc než je nutné jinde.
Naozaj zďaleka nie vždy a pokiaľ za to dostane niečo, čo inde nie, tak v tom nevidím problém.
> To samozřejmě fungovat nebude, stačí mít mezi objekty cyklus
Nechápem.. Myslíš cyklus ako for, while, atď? Tu neviem, čo napísať, už dávno používam štandardné algoritmy.
Alebo myslíš dva objekty, ktoré na seba vzájomne držia ukazovateľ? O tom sa ale nebavíme, reagoval som na zmienku o argumentoch funkcií. A pokiaľ nechceš, aby sa inkrementoval počet, tak ten zdieľaný ukazovateľ odovzdáš odkazom.
Alebo môžeš do funkcií posielať holý ukazovateľ. Aj tak nechceš riešiť vlastníctvo, tak je to jedno, nie? :)
> Anebo můžu použít platformu, která 95% těch situací vyřeší sama
To samozrejme môžeš, ale vtedy asi nespadáš pod definíciu poslednej vety môjho komentára, pretože tam spadá tých "5%" vecí, ktoré sa samé nevyriešia.
Vo finále nechápem o čom sa bavíme, možno iba nepatríš medzi tých, ktorí vlastnosti C++ potrebujú. Ale to je úplne v poriadku.
> Vo finále nechápem o čom sa bavíme
Původně jsem vysvětloval MarSikovi tvrzení, že C++ má náročnou správu paměti. Tvůj příspěvek to dokresluje naprosto skvěle.
Vytváření vlastních alokátorů je věc, kterou jsem viděl mockrát, dokonce jsou jedinci (i přítomni v této diskuzi), kteří se tím chlubí. Ukazuje to, jak je správa paměti v C++ špatná.
> JVM má nejakú rýchlejšiu/lacnejšiu metódu?
Samozřejmě, posune pointer a vrátí původní hodnotu, je to zhruba na 2 instrukce.
> Alebo myslíš dva objekty, ktoré na seba vzájomne držia ukazovateľ? O tom sa ale nebavíme,
O tom se musíme bavit. V C++ prostě nemůžeš automaticky vše udělat shared a doufat, že to bude fungovat. A nemůžeš vše jen tak předávat raw pointerem, protože pak nevíš, kdy to zmizí. Tvůj návrh prostě nelze korektně realizovat.
Ja suhlasim z predoslim prispevkom (od zulu). To, ze sa programator moze rozhodnut kam da objekt ci na haldu alebo heap je neskutocna vyhoda a nie len v perfomace.
V Jave (a inych GC jazykoch) je vetyvornie objektu stale drahsie ako jeho vytvorenie na halde v C++ a to niekolko nasobne a nie je to len pusnutie pointera. (C# to riesi tym, ze vies pouzit struktury, ktore su na zasobniku, alebo direktivou stackalloc).
>O tom se musíme bavit. V C++ prostě nemůžeš automaticky vše udělat shared a doufat, že to bude fungovat. A nemůžeš vše jen tak předávat raw pointerem, protože pak nevíš, kdy to zmizí. Tvůj návrh prostě nelze korektně realizovat.
To napriklad Qt riesi elegantne registraciou v "parent" objekte.
Ono tie vycitky vysie na spravu objektov v C++ pramenia z jeho absolutnej neznalosti a neznalosti novych srandardov. V nich sa o spravu pameti clovek nemusi starat skoro vobec. Staci pochopit tu fylozofiu.
> To, ze sa programator moze rozhodnut
Znovu opakuji - ne že se může rozhodnout. On to rozhodnutí _musí_ dělat pokaždé u každé instance. To je poněkud rozdíl.
> V Jave (a inych GC jazykoch) je vetyvornie objektu stale drahsie ako jeho vytvorenie na halde v C++
Lze snadno vyvrátit benchmarkem. Mě vyšla průchodnost JVM asi desetinásobná oproti C++ v MSVC. Pokud si dobře pamatuju, C++ dokázalo alokovat nižší desítky milionů objektů za sekundu, JVM byla na stovkách.
> To napriklad Qt riesi elegantne registraciou v "parent" objekte.
A co když něco jako "parent" neexistuje? To tam pak musím uměle dodat? Pokud to jsou GUI komponenty, tak je to jasné, ale jsou datové struktury, kde jeden parent není.
> z jeho absolutnej neznalosti a neznalosti novych srandardov. V nich sa o spravu pameti clovek nemusi starat skoro vobec. Staci pochopit tu fylozofiu.
Jasně. A pak to změříš a zjistíš, že je to pomalé a necháš standardy standardama.
> V Jave (a inych GC jazykoch) je vetyvornie objektu stale drahsie ako jeho vytvorenie na halde v C++ a to niekolko nasobne a nie je to len pusnutie pointera. (C# to riesi tym, ze vies pouzit struktury, ktore su na zasobniku, alebo direktivou stackalloc).
Citation needed. Zni to spis jako tvuj pocit, protoze to neni pravda :-)
Napr. jeden microbenchmark (nutno dodat, velmi stary): https://blog.cfelde.com/2010/06/c-vs-java-performance/
Samozrejme hodne zalezi na konkretnim use case, obecne jsou situace kdy C++ alokace je rychlejsi a kde alokace JVM je rychlejsi, ale to co tvrdis je pitomost, protoze nekolikanasobne pomalejsi alokace v Jave proste obecne neni vuci C++.
> Původně jsem vysvětloval MarSikovi tvrzení, že C++ má náročnou správu paměti. Tvůj příspěvek to dokresluje naprosto skvěle.
To je tvoj osobný názor, pravdepodobne na základe toho, že nepotrebuješ komplexnú funkčnosť a stačí ti obmedzená sada.
> Samozřejmě, posune pointer a vrátí původní hodnotu, je to zhruba na 2 instrukce
A dostaneš tým tú istú funkčnosť? Objekt alokovaný v rámci sady objektov v bloku alokovanom naraz a uvoľnenom naraz, držanej lokálne v jednej oblasti pamäti, prípadne úplne spojito a bez medzier (až na prípadné zarovnanie)? Alebo si myslíš, že to sú veci, za ktoré nie je nikto ochotný zaplatiť? A aj rýchlosť? A to všetko na 2 inštrukcie? Porovnávame naozaj porovnateľné?
> O tom se musíme bavit.
Nie. O tom by sme sa teoreticky mohli baviť, keby som reagoval na tento kontext. Ja som reagoval na hlavičky funkcií.
> V C++ prostě nemůžeš automaticky vše udělat shared a doufat, že to bude fungovat
Ja to tak samozrejme nerobím, nijako ma neobťažuje deklarovať veci podľa potreby. Paradoxne, rebase kvôli tomuto naozaj nerobievam. Ale ak to niekoho obťažuje, nevidím dôvod prečo by to v hlavičkách funkcií nefungovalo.
A keď by sme sa teda mali baviť o dátových štruktúrach s cyklickými odkazmi, tak máme silné ukazovatele a slabé ukazovatele.
> A nemůžeš vše jen tak předávat raw pointerem, protože pak nevíš, kdy to zmizí.
Všimol si si, že o holých ukazovateľoch píšem v kontexte, že neriešiš životnosť? Písal si to v príspevku, na ktorý reagujem. Tak prečo ju riešiš teraz?
Odhliadnuc od toho, zmizne "to" vtedy, keď to uvoľníš. Alebo keď ukazovateľ prepíšeš iným obsahom. Keď to neuvoľníš a keď ukazovateľ neprepíšeš, tak to nezmizne.
Základný problém v správe pamäti ale nie je ani tak to, že niečo zmizne, keď nechceš, aby to zmizlo, ale to, že niečo nezmizne vtedy keď už nechceš, aby to existovalo, teda napríklad pri neošetrenej výnimke.
Ale aj táto časť debaty je v podstate zbytočná, pretože vyššie som spomenul, že vo väčšine prípadov použiješ odporúčania, ktoré už nejaký čas sú v zmysle čo najviac objektov v zásobníku s ich automatickou deštrukciou, odovzdávanie odkazom, prípadne presunutie do volanej funkcie a používanie toho istého mechanizmu v rámci RAII.
> To je tvoj osobný názor, pravdepodobne na základe toho, že nepotrebuješ komplexnú funkčnosť a stačí ti obmedzená sada.
To je na základě toho, že jsem si pár algoritmů zkusil napsat v C++ i v javě a zjistil jsem, že abych dostal v C++ lepší výkon, tak jsem musel řešit asi 10x víc věcí, optimalizovat atd. V javě lze z pohledu C++ proramátora dost prasit (čti využívat funkcionální principy jako konstantní objekty atd.), což sice vede na větší zátěž VM, ale ta je na to optimalizovaná a programátor se většinou může spolehnout, že to dopadne dobře.
Samozřejmě jsou extrémní případy, kdy je nutný low level jazyk, ale v praxi se spíš setkávám s takovými C++ programátory, kteří optimalizují každou ptákovinu aniž vědí proč a bojí se, že by o to v javě přišli.
Konkrétně jsem jeden takový C++ kód předhodil v jedné diskuzi a první co matlal udělal bylo, že přepsal předávání všech struktur na const &. Sice to na výkonu nezměnilo ani prd, ale měl z toho dobrý pocit.
> Konkrétně jsem jeden takový C++ kód předhodil v jedné diskuzi a první co matlal udělal bylo, že přepsal předávání všech struktur na const &. Sice to na výkonu nezměnilo ani prd, ale měl z toho dobrý pocit.
A zeptal ses, proč to udělal? Ono to IMO nebylo primárně kvůli výkonu. V c++ je idiomatické předávat const & vždycky když nemáš nějaké speciální požadavky. Stejně tak je idiomatické vracet hodnotou a ne jako pointer na nově alokovaný objekt. Pak v obou případech nemusí autor funkce opravdu řešit, jestli ty objekty budou na zásobníku nebo na haldě.
> A zeptal ses, proč to udělal? Ono to IMO nebylo primárně kvůli výkonu...
Neptal jsem se. Úkol byl urychlit to, takže předpokládám, že si myslel, že se to tím zrychlí. Prostě takový ten každodenní cargo cult, který u zažraných C++ programátorů vidím každou chvíli. Je nezajímá, že mají algoritmus O^4, oni chtějí ušetřit na předávání reference.
Přijde ti v pořádku argumentovat tím, že mě cituješ slovy, které jsem nevyslovil?
Řekl jsem, že je to matlal. Když někomu dám urychlit kus kódu (jednorázový, testovací), on tam udělá mraky změn ale přitom neurychlí vůbec nic, tak to splňuje definici matlala ať už jsou jeho záměry sebevznešenější. To znamená, že nemá smysl se ho ptát na důvody, protože případná odpověď nemá vliv na fakt, že řešil něco jiného než řešit měl.
A tento příklad dobře ukázal, jak je programátor odváděn od problému a místo toho řeší specifika daného jazyka.
> Přijde ti v pořádku argumentovat tím, že mě cituješ slovy, které jsem nevyslovil?
Jak slovy, které jsem nevyslovil? Když ve svém textu nahradím "pitomec" za "matlal", tak mám skoro doslova to, co jsi tu napsal.
Skoro se bojím hádat, jak mohlo vypadat to zadání. Podle toho, co tady kolem píšeš se bojím, že jsi typicky po Javovsku naalokoval mračna malých objektů (odhaduju podle poznámky o dynamicky alokovaném 3D vektoru). Pak se to zamozřejmě urychlit nedá. Tam není problém rychlost jazyka. Tam je problém, že žádné CPU nezvládá kód, který skáče po paměti jako divý. Tenhle přístup trestají všechny jazyky +- stejně, protože cache miss stojí +- stejně.
> čti využívat funkcionální principy jako konstantní objekty atd
To sa predsa dá aj v C++
Okrem toho, šablónové metaprogramovanie je vlastne funkcionálne programovanie
> Samozřejmě jsou extrémní případy, kdy je nutný low level jazyk
Stačí ak píšeš pre platformu, ktorú nemáš pod kontrolou a pre ktorú nemáš inú možnosť.
> s takovými C++ programátory, kteří optimalizují každou ptákovinu
To sa týka programátorov, nie jazyka, takí sú všade a v každom obore :-)
> a bojí se, že by o to v javě přišli
Nemusí ísť iba o jazyk samotný, ale aj ekosystém, knižnice, atď., je v tom veľa know-how, ktorý sa neoplatí zahodiť len kvôli tomu, že sa niečo môže zdať niekomu nepohodlné.
Nízkoúrovňový program != jádro ani ovladač. Já si pod tím představuji programy spouštěné na příkazové řádce nebo ve skriptu, které spustíš, mají rychle něco udělat a pak skončit. Případně nějaké déle-běžící démony. Osobně jsem tyhle věci začal psát v C++ (i když jako hlavní jazyk mám pořád Javu), ale dost se těším, až GraalVM ještě trochu dozraje a rozšíří se do distribucí a budu to moci psát v klidu v něm (zatím mi to přijde přeci jen ještě poměrně čerstvé oproti zaběhnutým a rozšířeným prostředím).
Přece malbolge: https://cs.wikipedia.org/wiki/Malbolge
Ok, ted vážně. Chceš jeden jazyk na všechno?
C++ 17 je dobře použitelné. Rust je dobře použitelný.
Python i přes všechny jeho pitomosti používám sám velmi často, protože se mi hodí.
Jedna formální poznámka:
Proč je v článku kolem 10 odkazů na native-image, která vede na dvě věty?
1) Nešlo by se držet praxe třeba z Wikipedie, kdy se odkazuje pouze při prvním výskytu výrazu? Taklhe to vypadá jako špatně udělaný SEO článek.
A u člověka se střídá stav očekávání, že konečně bude nějaký lepší odkaz, se stavem zklamání, že je to pořád ten stejný,
2) Opravdu neexistuje lepší zdroj?
nejde o to samotne tema clanlu, ale o argumenty autora, a samotne skladanie viet... Znie to jak teleshoping na Javu... Z clanku srsi ze autor je hater googlu, příznivec Javy, a clanok je formulovany tak akoby autor hladal tyzdne situaci, jeden algoritmus v ktorom bude Java vykonnejsia a z toho urobil Boom. Uplne zamlcava prednosti Go ako napr. Gorutines.
Celkovo sa mi zda ze autor clanku nechape a ani nechce chapat jak funguje Go a ake su jeho vyhody a preco. Proste clanok znie a je manipulativny.
autor ocividne diskuzi sleduje, a uz na nejakou pripominku reagoval. takze si myslim, ze kdyz jasne a vecne bez sarkasmu napises co je treba zlepsit, tak priste tu autor da kvalitnejsi clanek. nikdo uceny z nebe nespadl.
druha vec je ze normalne to dela redakce. (treti vec je ze root je "zdarma" at to znamena cokoliv)
Javu jsem zavrhl kvůli
- alchymii statických a dynamických objektů (které spolu nemohou kooperovat, jak by bylo potřeba),
- totálně nepřehledné a nelogické syntaxi
- a naprosto šílené dokumentaci.
K tomu poslednímu: Člověk by potřeboval vědět něco ve smyslu "třída ta a ta má ty a ty metody, metoda A má ty a ty argumenty a dělá s nimi to a to a pro ty argumenty jsou nastaveny (při jejich nezadání) ty a ty implicitní hodnoty". Dolovat tento údaj z oficiální dokumentace, představující z 99% slovní salát a jen asi jediné procento smysluplné informace mě opravdu nebavilo.
S blbou syntaxí souhlasím, ale nerozumím, co ti vadí na té dokumentaci. Když náhodou kliknu třeba na dokumentaci ConcurrentHashMap
https://docs.oracle.com/javase/7/docs/api/
co v té dokumentaci není přesně tak, jak popisuješ, že by se ti líbilo? Je tam seznam metod třídy, u každé metody se píše k čemu slouží parametry, a že java umí nezadané argumenty ani nevím. A slovního salátu jsem si moc nevšiml, v popisu třídy jsou podle mě dost relevantní věci.
Pardon, ta dokumentace k ConcurrentHashMap je zde: https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/ConcurrentHashMap.html
WTF? :( Toto nie je dokumentacia toto vyzera ako 5. diel Война и мир od Tolstoja.
Mna ucili ze programovanie je o kompozicii malych jednotiek do vacsich celkov. Zdoraznujem "malych". A teraz pozeram do kodu... trieda ConcurrentHashMap ma vyse 6000 riadkov! SRSLY ?!?!?!? :(
1) Toto je dokumentace, a řekl bych, že má všechny vlastnosti, o kterých původní tazatel tvrdil, že tam chybí. To, že je dlouhá, souvisí s tím, že toho ConcurrentHashMap umí hodně a jsou to netriviální věci. Kdyby byla tato dokumentace krátká, OP by nadával, že není zdokumentované všechno. Nadávat, že rozsáhlá věc má rozsáhlou dokumentaci, mi přijde takový.. no asi si dovedeš domyslet.
2) Obecně s poučkou souhlasím, ale ConcurrentHashMap mi přijde jako dost atomická věc. Ale rád se nechám poučit. Jak by jsi dekomponoval funkcionalitu ConcurrentHashMap do menších jednotek? Jsem velmi zvědavý.
> Jak by jsi dekomponoval funkcionalitu ConcurrentHashMap do menších jednotek?
Chces aby som si za pol hodky nastudoval 6000 riadkov kodu? Uhm, no dobre uvidim co najdem... aaa tak napriklad mkrni na triedy
MapReduceKeysToIntTask http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/concurrent/ConcurrentHashMap.java#l6078
MapReduceValuesToIntTask http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/concurrent/ConcurrentHashMap.java#l6128
MapReduceKeysToIntTask
Toto smrdi copy-pastom! No a ked tak na to hladim, zda sa mi ze asi vacsina tried MapReduce.*To.*Task bude podobnych a komentar vysvetlujuci preco to nie je "abstracted away" evidente chyba.
> Nadávat, že rozsáhlá věc má rozsáhlou dokumentaci, mi přijde takový.. no asi si dovedeš domyslet.
Nekriticky tvrdit ze vec je rozsiahla lebo rozsiahla byt musi... no domyslel som si.
Jo, smrdí to copy-pastem, nevím proč je to implementovaný tak jak to je. Abstrakce by v tomhle případě asi znamenala přidat nějaký getter, který by vracel buď key nebo val, takže tipuju, že je to takhle "unrollnutý" kvůli výkonu, ale najisto nevím.
Každopádně za dekompozici považuju něco jiného, než co ti (nám) vadí na příkladu co jsi našel. A s uživatelskou dokumentací tenhle příklad nesouvisí vůbec, tyhle třídy jsou "implementační detail".
Ah :) dobra poznamka https://youtu.be/TVHcdgrqbHE?t=2187
ty si dobry amater
objekt - je instancia triedy. Staticky/dynamicky objekt - to si kde cital? Niekde v referate nejakeho stredoskolaka, ktory nieco skopiroval z wiki a ani sam nevie o com pisal? Prosimta, ja som uz som programoval kdeco, ale nikdy som nemusel riesit nejake dynamicke/staticke objekty ale iba objekty.
A keby si vedel aspon zaklady objektoveho programovanie tak by si mohol vediet, ze rozhranie netvoria iba metody, argumenty, triedy ale ze maju aj svoje stavy a svoje spravanie - to je ten salat co k tomu potrebujes vies. Lebo bez toho nemozes ani len tusit, co sposoby spustenie jednej metody. myslis ze Object.clone() to len tak nakolonuje objekt lebo sa vola clone a netreba ti poznat teoriu za tym?
A co multiparalelne prostredie na serveri ty macher? Kodil si uz aj nieco ine ako jednudchy konzolovu appku s jednym vlaknom? Naco ti bude nazov metody, ak nevies ci je thread safe? A co rozne factories a buildery v multivlaknovom rpostredi? Takym ako ty dat nakodit serverovu appku, tak ak by to bola banka asi vsetci ludia pridu o svoje uspory.
S tvojim pristupom, staci pozriet na zdrvojaky Linux kernela - tamen subor ma take a take funkcie a hned ovladas cely kernel do podrobna.
Nelogicka syntax - uplne najlogickejsia - ved vychadza z Ccka. To si este nezazil asi funcionalny pristup v Java 8 a funkcionalne programovanie v JavaScripte alebo moderne jazyky ako Ruby. Uz radsej ani nehovorim o C++ ktoreho syntax ti umoznuje spravit uplne vsetko preto je oproti Jave sialna, pretoze Java syntax je zuzena na objektove programovanie. Mimochodom pointre a nieco medzi pointrom a referenciou mas uz aj v C# a kvoli prehladnosti to asi nebude.
Practical API Design je dobrá knížka. Sám si v ní občas rád zalistuji.
K těm odkazům. Články píši v MediaWiki a používám odkazy na ostatní wiki stránky. Tak je napsána původní anglická verze Forget Go. Go, Java go!. Při přepisu do češtiny jsem tam ty odkazy nechal. Potěšilo mne, že je tam redakce nechala také a že se dostaly až na Root. Je to hezká reklama, ale nelpím na nich.
Článek mi nevadí - proč by nemohla na Rootu vzniknout polemika ve formě článků? Je zde sice trochu kontrast mezi stylem, šíří a hloubkou záběru pana Tišnovského a pana Tulacha, ale ve výsledku to může přinést obohacení čtenářům, autorům i Rootu samotnému.
Jinak pokud GraalVM dotáhnout k použitelnosti a nezabijí to nějakou nesmyslnou politikou a nebo nějakým krokem stranou, tak své uplatnění určitě najde. Tím spíš pokud bude integrovat celou škálu jvm jazyků.
Souhlad instaloval jsem SAP na HP-UX a bylo to o tom, že jedna část vyžadovala 1.4.1 a jiná verzi 1.4.2, atd. O nenažranosti na paměť nemluvně. Dodnes musím virtuál s CentOS5, starou Javou a Firefoxem, abych mohl přistupovat na KVM do serverovny... Nekompatibilní Java od Sunu a Microsoftu a pod. Se divim, že Java kompletně neumřela a stala se COBOLem dnešní doby...
Pripravit prostredi pro prasata, jako je Software Aus Pakistan nebo IBM (prozmenu vesmes z Indie) je naopak s Jawou pro systemaka uloha prajednoducha.
Staci rozzipovat JRE ve verzi, se kterou SAP/IBM style zprasek cirou nahodou jede a nastavit $JAVA_HOME - problem solved.
V pripade appletu je nutno si drzet cele stare image s browserem, kde to nahodou jede, SAP/IBM style prasata dokazou v Jave neuveritelne veci, treba dokazou zcela zamerne vyuzivat znamou chybu ve stare JVM nebo vyrobit v Jawe memory leak, jsou hodne dobri.
Termin "Deprecated" znamena po indicku "per to tam".
Systemak, ktery ma problem rozjet java program musi byt opravdu pripad, naopak poradne peklo dokaze pripravit bare OS, HP UX fixne deravou knihovnu, soft se seype a delat s tim nejde nic. Bezne jsem potkaval pripady, kdy na jednom stroji jel soft jenom s knihovnou verze 1.0 a jiny soft jenom s verzi 1.1. Prakticky neresitelne, v jave trivialita rozbaleni jednoho zipu a $JAVA_HOME
Problem nativneho prekladu javy je hlavne v tom, ze vseci radi generuju/stahuju bytekod. GCJ malo v sebe koli tomu interpreter a cele to nestalo za nic.
Samozrejme, ide to aj bez toho (android), ale velke riesenia (spring) sa bez toho nepohmu, nie ze by sa nedali prerobit (na annoation procesory/reflection/java.lang.reflect.Proxy), ale znizuje to hodnotu existujuceho ekosystemu.
No ale Spring prafe tu reflection / reflect.Proxy pouziva :-) Diky cemuz bylo mozne tohle:
https://jira.spring.io/browse/SPR-16991
Samozrejme, je to jen pocatek podpory, ale nevypada to jako nic neresitelneho.
A obecne prechod k annotation procesorum je urcite vhodny i z mnoha jinych duvodu.
Obecně záleží na tom, jak se různé variace (Javy) ujmou. Android byl z počátku nekompatibilní s kde čím, ale díky jeho popularitě jej mnoho knihoven začalo podporovat. Což zřejmě vyžadovalo změny v kódu speciálně pro Android. S native-image
je to podobné. Funguje to trochu jinak, ale zdá se to být užitečné. Budou-li si to myslet tvůrci knihoven a frameworků, tak se do pár let přizpůsobí.
Znáte Micronaut? Tam se pánové dost snaží a mají i speciální mód pro podporu GraalVM. Nedávno jsem zahlédl, že mají i podporu hlavních anotací ze Springu. Zkuste to. Jestli odvedli dobrou práci, tak to bude fungovat téměř samo.
bolo by fajn keby sa tu nevyjadrovali kinder- programatory a "seniory" ktorych seniorita spociva akurat v tom, ze 20 rokov bastlia kod pre jeden korporat na jednej stolicke a nepresli si desiatkami technologii
mudrlanti - piseste tu o .NET Core a ani neviete o com to je ... kazdy architekt by Vas vysmial, ze ako architekti zlyhavate a maximalne kvakate ako programatory ktory vidia len po svoj nos a kazdy silou mocou presadzuje len tie svoje naoblubenejsie technologie nevidiac aky a ci vobec maju z pohladu architektury prinos - a pre "pravovernych" Linuxakov - myslim skutocnu softverovy architekturu a nie to, ako spojit zopar Linux strojov cez siet a nainstalovat tam podporny softver
nechapem ako moze niekto napisat: ".Net Core je cool" a potom "jasne ze trpi syndromom novej technologie"
preto ju Java EE pretoze nim netrpi a kto chce najnovsie cool vychytavky tak pouzije Spring, ktory dokaze zavadzat novsie technologie ako EE a stale ostat co najviac bez toho aby trpel syndroom novej technologie
ak chcete technologiu so syndromom novej technoloigie - vykaslite na sa .Net Core - pouzite Ruby on The Rails - toto je daleko daleko daleko (uz minimalne 5 rokov) pred .Net-om aj pred Javou, akurat - trpi syndromom novej technologie, ale oproti Railsom je cely .Net brutalny overkill .... bolo by fajn, keby sa tu prestali vyjadrovat decka, ktory o technologiach nic nevedia ..... a hlvne - nezacnite argumentovat rychlostou kompilovanych aplikacie pokial nie ste architekti ktory sa staraju o portfolio 10 aplikacii s vysokoou dostupnostou a vysokou skalovatelnostou a vyskym loadom ktore pouzivaju nie miliony ale desiatky milionov pouzivatelov z celej Europy
takze este raz pre vsetkych kinder zastancov .Net - chcete technologiu ktora trpi syndromom novej technologie - vykaslite sa na .Net, pouzite Rails, alebo Node.js ... ale kludne aj PHP Symfony - tie vase web appky kde v jednom case prihlaseny jeden uzivatel pobezia rovnako rychlo aj v tychto ovela jednoduchsich technologiach ... .Net Core a serverovu Javu prenechajte profikom, ty uz budu vediet zvazit, ktora ma ake vyhody/ nevyhody a v akom prostredi je ktora viac prinosom
Kdybyste to tady cetl casteji, tak byste vubec neocekaval, ze se o Graalu a Jave nebudou vyjadrovat decka. To je realita mistniho prostredi, ale je tu aspon sranda, stejne jako na piskovisti s babovickami a malymi caparty.
Jardu znam bezmala 30 let, a kdybych vedel, ze chce tady publikovat o Graalu, tak mu duverne reknu, at neblbne. Tady najde bohuzel minimum ctenaru, kteri by pochopili o cem jim vypravi. A myslim si, ze po precteni tehle diskuze to uz vi sam.
Ano, na odreagovani to je tady mnohdy lepsi jak hardrock narez :-) Podle meho nazoru je Graal natolik prinosny, ze nepotrebuje vyznavace jedne sekty. Ja bych s tim sel klidne do Big Data komunity, tam se porad iteruje nad int[], nebo se jede nejaky stavovy, prip. zasobnikovy, automat ... tam by ten vykon musel byt dobre poznat. Hlavne jsou za temi algoritmy penize, a naklady rostou s delsi dobou behu. Graaal by jim mozna vyrazne snizil naklady, a to by je mohlo motivovat k ucasti.
celkove vzato:
- clanek psal fanda do javy, ktery se snazi jakkoliv argumentovat pro Javu a proti cemukoliv
- je tady hodne silna zakladna javistu, kteri jakoukoliv kritiku, ci negativni nazor na Javu, 'odmenuji' minuskovanim
chapu to, akceptuji jejich nazor, ale ... proste maji svoje kladivo a ve vsem hledaji ty slavne hrebiky.
zpocatku jsem to bral jako formu recese :)
Příjde mi trochu zvláštní, že tu zase neběsní oni přísní strážci "čistoty" jazyka a nevyhrožují autorovi ohněm pekelným za přemíru expresivních výrazů, objektivních soudů a dojmologie použité ve "vědeckém článku". (mi osobně to nevadí a nemám s tím problém)
:-D :-D :-D
Esli vono to nebude spíš o té tradiční (víceméně) české zapšklosti a přízemní tuposti...
Dalsi obet koroporatniho vymejvani mozku, az to uz neni ani vtipne.
Posledne nam jisty Svedek Oracluv s podobne zaslepenym nadsenim cpal Truffle Ruby. Nebudu napinat, nechali jsme to dojit az tak daleko, ze se na nem pustily integracni testy a dopadlo to katastrofalne. Jednak vykonnostne a spotrebou pameti a nektery ani regulerne nedobehly. Pad s behovou chybou, rucni sestreleni pri neukonceni ani po vic nez dvojnasobne dobe behu. Pritom bez problemu bezi nad JRuby i CRuby.
Mozna to casem vychytaji, ale nemeli s tim prijit v takovem pre-alfa stavu. Znovu to ale pokouset uz nebudeme.
Je mi lito, ale clanek je ryzi demagogie.
Snazi se postavit argument, ze hlavni hype go je jeho rychlost a moznost staticke kompilace.
Ve skutecnosti hlavni vyhodou go oproti jave je, ze je to proste lepsi jazyk. I kdyby bylo 5x pomalejsi, porad stoji za to.
Pochopil bych, kdyby se autor snazil srovnat go treba s kotlinem, ale java je opravdu mimo.
Go je trivialni jazyk (syntakticky jednodussi nez cecko), coz vam umoznuje prijit defacto k jakemukoliv projektu a okamzite vidite, co se deje. Nepouzivaji se zadne silene frameworky, zadne builder patterny. Zadne desitky trid a interfacu jen proto, ze nekdo v nejake knize napsal ze to tak ma byt.
V go mate moznost predavat hodnoty ...hmm...hodnotou. Ze zacatku to cloveku uplne nedojde, ale vlastne to supluje imutabilitu, protoze volana funkce nema sanci zmenit strukturu(aka tridu), kterou si drzi volajici. Zaroven to umoznuje kompilatoru drzet si hodnotu na stacku a tim omezit garbage.
Nemusite resit null pointery.
Ne vazne, kolik jste v zivote videl zbytecneho kodu a padu programu kvuli null pointerum? Kolik nevysvetlitelnych chovani programu, protoze nekde nejaka funkce zmenila neco v objektu co dostala, co menit nemela? Kolik popasnych stranek vymyslejicich, jak udelat objekt immutable, jen proto, ze samotny jazyk na neco takoveho nepamatuje?
Porovnavat vlakna v jave s go a kanalama je spatny vtip (uznavam, ze jsem javu od sedmicky nepouzival). V zadnem z mainsteamovych programovacich jazyku jsem nevidel nic tak elegantniho a efektivniho, jako moznost si v go vzit normalni snadno testovatelnou synchronni funkci, na trech radcich ji obalit anonymni funkci a spustit v jine subrutine a pozdeji jednoduse a bezpecne v selectu vyhodnotit jeji navratovou hodnotu nactenou z kanalu.
System balicku go nedovoluje cyklicke zavislosti, coz, jakkoliv pro javisty neintuitivni, cloveku zarucuje, ze kdyz se nori hloubeji a hloubeji do projektu, tak se mu zuzuje pohled. Nestane se, ze nekde na konci toho tunelu je pointer zase zpatky na zacatek. Vyrazne to usnadnuje orientaci.
Je toho vic, co se mi na go libi a taky dost, co se mi nelibi, ale verte mi, vsechny ty projekty jako docker, kubernetes, cockroachdb etc nejsou v go napsane jen proto, ze je celkem rychle a kompiluje se do jedne binarky.
Ma osobni zkusenost je, ze go mi umoznuje daleko vic se soustredit na navrh projektu a neresit nesmyslne framewroky a sofistikovane navrhove vzory. Ve finale si myslim, ze jsem o dost efektivnejsi a rozhodne napisu pro stejnou funkcionalitu min kodu a vygeneruju jen zlomek souboru, coz hodne prispiva k prehlednosti.
a hlavne: najednou je to programovani zase desne zabavny
Děkuji a respektuji Váš názor. To poslední, do čeho bych však chtěl zabřednout, je diskuze o tom, který jazyk je ten nejlepší. OracleLabs zastávají následující postoj: "Pište si v čem chcete, my se postaráme, aby to běželo rychle!"
Pokud Vám Go vyhovuje, držte se ho! Mým cílem není konvertovat Vás k Javě, ale vysvětlit Javistům, že pokud hledají něco, co běží podobně jako Go, tak je to blíže než by se mohlo zdát. Určitě kvůli tomu nemusí měnit jazyk.
Je fajn, že si "diskuzi užíváte". Článek o native-image jsem jednoznačně uvítal, ale raději bych se z něj dozvěděl proč je GraalVM a native-image skvělý, nikoliv proč je Go špatný. V článku mi chybělo, co všechno (zatím) native-image neumí správně přeložit, jak je to s podporou běžně používaných knihoven třetích stran, zda jste zkusili aplikovat na nějaké reálné projekty (byť třeba jen v testovacím režimu a ne v produkci), čeho se tedy mám při psaní programu vyvarovat abych nebyl nepříjemně překvapen... Místo porovnání s Go bych uvítal porovnání s "plnotučným" JRE.
Pokud bude někdy další článek zabývající se možnostmi native-image do větší hloubky, velmi rád si jej přečtu...
> Ve skutecnosti hlavni vyhodou go oproti jave je, ze je to proste lepsi jazyk. I
> kdyby bylo 5x pomalejsi, porad stoji za to.
Lepší na co? Na vysokoúrovňovou logiku nebo zpracování dat totiž rozhodně ne. Ano, if a for strojově vyjádří všechno, ale vývojář z toho nepozná záměr.
Naopak funkce jako třeba map, filter, reduce zcela jasně deklarují co se má dít, aniž by čtenáře zatěžovaly tím jak je to implementované. Obzvláště viditelné je to u paralelních variant. Případně kolekce a funkce typu getOrDefault, putIfAbsent.. vše napíšete i s pomocí ifu. Ale nebude to tak čitelné.
A pokud se prosadí generika dle https://go.googlesource.com/proposal/+/master/design/go2draft.md tak věřte, že ty kolekce podobného typu brzy vzniknou i pro Go.
Alternativa k NumPy v go ale asi nikdy nebude (stejně jako není v Javě). Pro tvorbu DSL se ten jazyk prostě nehodí a matematici nechtějí psát V.dot(V2).
> V go mate moznost predavat hodnoty ...hmm...hodnotou.
To v C++ taky :) V Pythonu jak co. V Javě jen primitiva.. ale máte final.
> V zadnem z mainsteamovych programovacich jazyku jsem nevidel nic tak
> elegantniho a efektivniho, jako moznost si v go vzit normalni snadno
> testovatelnou synchronni funkci, na trech radcich ji obalit anonymni funkci a
> spustit v jine subrutine
await, async v Pythonu 3 [1]
Futures a ExecutorService v Javě nejsou taky o nic horší [2]
> Ma osobni zkusenost je, ze go mi umoznuje daleko vic se soustredit na
> navrh projektu a neresit nesmyslne framewroky a sofistikovane navrhove
> vzory.
Moje je zase přesně opačná, Go importy z githubu, knihovny různé kvality a třeba neexistence explicitního seznamu chyb (throws v Javě) mě dost brzdí.
Ty frameworky jsou v Go taky a naopak v Javě Vás nikdo EE nebo Spring používat nenutí (moje blbinky v čistém Java 8 SE + pippo [3] by mohly vyprávět).
Chce to příště trošku větší rozhled než se pustíte do srovnávání jazyků. Každý se totiž hodí na něco malinko jiného a dá se používat různě.
[1] https://docs.python.org/3/library/asyncio-task.html
[2] třeba https://www.callicoder.com/java-callable-and-future-tutorial/ ale nemusí to být ani lambda, Java 8 umí method reference
[3] http://www.pippo.ro/
Ve skutečnosti jsou věci které se mi na Go nelíbí často jeho předností. Je to takové PHP kompilovaných jazyků: programátor se v něm rychle zorientuje a může začít brzy programovat nebo dělat code review nějakého patche. Osobně se mi Go nelíbí, ale pokud bych si měl vybrat kompilovaný jazyk (rozuměj jazyk s rozumnou statickou analýzou) pro projekt na kterém se budou často střídat vývojáři (často měřeno v počtu man-hours investovaných do programu) tak bych volil Go. Jiný jazyk jedině pokud bych měl zaručeno, že stále bude k dispozici tým vývojářů v daném jazyce zběhlých.
Co 3rd-party package? Když budu mít závislost třeba na commons-lang3, tak jej native-image zahrne do výsledného executable taky? To by potom: 1) narostlo, 2) zastavilo jakékoli security updates (podobný problém jako má dnes Go například).
Ostatně, to je jedna z věcí, které mi chybí u existující #!java přidané v Java 11, core Java je sice hezká na vypočítání prvočísel, ale pokud potřebuju napsat už jen JSON parsování a nějaký jednoduchý klient pro HTTP service, tak okamžitě potřebuju další package.
Závislosti se do výsledné binárky zahrnou taky. Samozřejmě jsou na ty závislosti kladená stejná omezení, jako na váš kód. Bezpečnostní updaty jsou úplně stejné, jako u kterékoli jiné Java aplikace – dodavatel vám prostě musí dodat novou verzi.
To, že je java modulární a má spoustu knihoven, a vy si vyberete jen ty knihovny, které potřebujete, je snad v pořádku, ne? A jinak Java 11 už má přímo v základní knihovně HTTP klienta, který se dá používat.
> Bezpečnostní updaty jsou úplně stejné, jako u kterékoli jiné Java aplikace – dodavatel vám prostě musí dodat novou verzi.
Když v aplikaci použiji např. /usr/share/java/postgresql.jar
místo své vlastní kopie, tak se mi ta knihovna bude aktualizovat společně s distribucí.
Zdaleka ne všechny knihovny tam budou a navíc ve verzích, které potřebuji, takže často tento přístup použít nejde, ale pro úplnost ho uvádím. Zrovna u těch JDBC ovladačů mi to přijde dobře použitelné a můžeme nechat jejich aktualizace na distribuci.
To jsem přesně myslel. Neřeším teď server side aplikace, kde má stejně větší smysl klasický JIT.
Primární cíl podle výhod uvedených v článku vidím v nahrazení současných skriptovacích jazyků používaných v distribuci, tedy perl, python atd., něčím použitelným se statickým typováním a efektivním na vývoj. Ale v takovém případě bych čekal, že budou "běžné" závislosti součásti distribuce místo, aby se tahaly s každou binary.
Tak zrovna na tohle to na 99% nikdo pouzivat nebude a hlavne nikdo nebude prepisovat perl / python skripty do Javy proto, aby to mohl kompilovat pomoci GraalVM.
Proboha, co by to melo za smysl?
Smysl GraalVM je naopak ta server side aplikace (kde se mimochodem nepouziva JIT, ale spise AoT pri startu).
Proč ne? Jestli něco ve scriptování chybí, tak je to právě staticky typovaný jazyk. Honit v runtime undefined variables v python či perl (ten je na tom ještě pořád líp kvůli povinné deklaraci) je to, co dělá vývoj extrémně neefektivní. Mít na tohle Javu, respektive rychlou Java, by na běžné skriptování vyřešilo spoustu problémů. Buď se tam dlouhodobě prosadí Java, Go nebo příšernost typu Powershell.
GraalVM je užitečný samozřejmě všude, alo AoT je na server side kontraproduktivní (pokud se po nějaké době sám nenahradí kódem z JIT). AoT na rozdíl od JIT nemá v době překladu důležité informace pro optimalizaci.
Tak zrovna nedefinovanou proměnnou v Pythonu snadno odhalí (statickou analýzou, netřeba čekat na runtime) nástroje typu Pylint, dokonce už máme i anotace typů, na tomhle se pracuje. Docela by mě zajímalo, kolik jsi napsal řádků v Pythonu, že Ti připadá neefektivní v něm psát, protože já takové zkušenosti nemám.
Pravdou ale je, že na "skriptování" se dá použít ledacos, třeba i ten Haskell nebo Lisp - důležité je cílový jazyk trochu znát a mít po ruce základní knihovny pro práci se systémem. Pár svých pracovních skriptíků, které jsem měl napsané (a tedy vymyšlené) v Pythonu, jsem si v nějaké volnější chvilce mezi normálními úkoly z legrace přepsal do Rustu, netrvalo to nijak dlouho a výsledek ani není o moc ukecanější. Uměl bych si pro podobné účely představit Julii, Go, Ruby nebo Nim, je to skoro úplně jedno.
Jo ale nedefinovaný atribut objektu už běžné pythoní nástroje neodhalí. Teď si hraju s mypy, ale pořád to není: co se zkompiluje, v tom není hloupá chyba (překlep), nebo špatné použítí typu. Navíc neexistence block-scope zanáší taky různé chyby (kdo by čekal, že mimo 'for' blok bude řídící proměnná stále nadefinovaná). Osobně jsem toho napsal v Pythonu dost na to aby mě ta jeho dynamičnost bolela. Bohužel musím v některých skriptech počítat se spuštěním Pythonu 2.5 až 2.7 a to teprve bolí. Tam kde si můžu dovolit Python 3.5 (Python 3 se neměl jmenovat Python, vždyť se změnily takové základy jako třeba operátor / ) tak tam zkouším dostat mypy, a je to o řád lepší (oproti třeba Go ale stále cca třikrát horší).
Přesně to jsem měl na mysli. V perl jsou samotné proměnné vyřešené, protože se musí povinně deklarovat, navíc je vidět jejich scope (tedy při zapnutém strict). Ale stejně jako v ostatních dynamicky typovaných jazycích, pokud volám metodu nebo šahám na atribut objektu, tak tak kontrola už tam není prakticky žádná.
Co se těch nástrojů týče, tak to vystihuje celou absurditu dynamicky typovaných jazyků - na začátku se tvrdí, že vlastně statické typování není třeba a pak se přes šílené workaroundy v komentářích či anotacích snaží ty typy dostat, aby byly přístupné aspoň pro statickou analýzu, když už ne v runtime :-/
Samozřejmě odhalí: http://pylint-messages.wikidot.com/messages:e1101 - pokud Ti to nefunguje, máš nějakou vadnou verzi Pylintu nebo něco děláš špatně. Python 2 už je legacy záležitost, jestli měl být přechod takto drsný, je věc názoru. Ale zajímá mě ten block scope - jak podle Tebe vypadá typický kód, kde to vadí? Není ta funkce/metoda moc dlouhá nebo nepoužívá se jedna proměnná/identifikátior k ukládání různých věcí? V Pythonu, jako v každém jazyce, doporučuju moc neprasit. Když má člověk trochu disciplíny a používá vhodné nástroje, spousta chyb vůbec nevznikne.
V Javě žádné běžné závislosti nejsou, s výjimkou standardní knihovny, která je součástí JRE. Jedna z výhod Javy je, že má obrovský ekosystém knihoven – z toho plyne samozřejmě i ta „nevýhoda“, že neexistují běžné závislosti. Navíc Java programátoři nejsou moc zvědaví na to, že budou používat nějakou deset let starou knihovnu jenom proto, že v nějaké rozšířené distribuci nikdo nepovažoval za nutné jí aktualizovat.
On vůbec celý tenhle koncept sdílených závislostí za běhu prostě nefunguje. Ve světě Javy se na to akorát přišlo dřív, ve světě C a C++ už se na to také přišlo nebo někde ještě právě přichází, akorát to ještě většinou není pojmenováno. Všimněte si, že vše, co v poslední době hýbe světem IT, je odklon od tohohle modelu. Nodejs sdílené závislosti za běhu nemá, Go je také nemá. Distribuce softwaru v kontejnerech má jediný cíl – odstranit závislosti za běhu a nahradit je přesně definovaným prostředím. Všimněte si, že technologie pro oddělení jmenných prostorů tady byly i dřív, ale skutečný boom kontejnerů začal teprve v okamžiku, kdy se někdo rozhodl aplikaci odizolovat i od distribučních knihoven.
Už k tomu naštěstí směřují i některé rozšířené distribuce, ne jen ty nové zaměřené na kontejnery. Od distribuce už se nebude chtít, aby poskytovala miliony balíčků, které jejich správci nestíhají aktualizovat. Naopak se od ní bude chtít, aby poskytovala stabilní a aktuální základ (jádro, správce služeb spolu s kontejnery a automatizací), a k tomu už si každý přidá přesně to, co potřebuje. Distribuce, které se neustále zaměstnávají tím, že backportují bezpečnostní patche a vyrábějí tak nové a nové verze softwaru, který nikdo netestuje a skoro nikdo nepoužívá, budou ještě pár let zajímavé pro enterprise řešení, než se i tam podaří to přirozenou výměnou nahradit. A ta doba není tak daleko – i banky, které jsou tradičně velmi konzervativní, dnes přecházejí rovnou na cloud a mikroservisy. Bude kolem toho ještě spousta trápení, někde to nezvládnou napoprvé, ale nemyslete si, že když už se k tomu rozhodly, že nakonec couvnou a řeknou, že je tohle ještě příliš nové a že couvnou o pět let zpět. Ne, to to radši budou těch pět let zkoušet znovu a znovu.
Opačný pangejt (žádné závislosti, viz kontejnery) je úplně stejně špatně. Zářným příkladem je SSL knihovna. Pokud vyvinu aplikaci a nechám ji běžet více než pět let, tak se přestane mít možnost bavit po SSL (pardon dnes se tomu říká TLS) s nejovším software. Takže je potřeba dobře oddělit to co má admin upgradovat a co může zůstat přesně ve verzi se kterou byla aplikace vyvinuta. Tam kde je šance dělat security (nebo feature) update bez zásahu vývojáře, tam se sdílené knihovny hodí. Tam, kde je potřeba nasazovat knihovnu patchnutou, nebo se stejným vývojovým cyklem jako aplikaci, tam jsou sdílené knihovny zbytečné.
Nikoli, to je právě ta mylná představa, že je možné aplikaci aktualizovat z venku, bez spolupráce autora. Nová SSL knihovna vám u pět let staré aplikace nijak nepomůže, protože ta aplikace případné nové protokoly nebude umět zapnout nebo je používat. Pokoušet se dělat security update bez zásahu vývojáře je loterie – v některých výjimečných případech to jde, ve spoustě příkladů bude bezpečnostní chyba přímo v aplikaci, a ve spoustě dalších případů bude bezpečnostní chyba ve způsobu používání knihovny, takže se opět musí opravit v aplikaci. Těžko může někdo opravdu věřit tomu, že má pět let nezáplatovanou aplikaci, ale ta aplikace je bezpečná, protože přece aplikoval bezpečnostní záplaty na knihovny.
Ve většině případů to možné je. Samozřejmě jsou díry i v aplikacích samotných, ale povětšinou ve sdílených knihovnách. Pokud je možnost upgrade globálně pro celý systém, je to mnohem efektivnější cesta. Nehledě na to, že zvláště komerční aplikace můžou být bez přístupu k jejich kódu, takže jakýkoli upgrade je komplikovaný.
Způsob, co má Java (Maven) nebo Go, není taky samospasitelný. Kromě výše uvedeného je stejně třeba poskytovat zpětnou kompatibilitu jednotlivých knihoven, bo v případě tranzitivních dependencí se jeden nebo druhý package stejně rozbije.
Aplikace či jejich závislosti si deklarují závislost na minimální verzi dané knihovny, takže případná nekompatibilita je detekována ještě v čase spuštění. Musí být zajištěna binární kompatibilita, což je o něco větší problém pro C knihovny, ještě větší pro C++, ale minimální problém pro Java s klasickým JIT. Ve chvíli, kdy upgraduju třeba z Qt3 na nekompatibilní Qt5 a mám na tom další závislost, tak se knihovna defakto stává součástí platformy, ale opět viz výše - nemůžu mít část dalších závislostí běžící s Qt3 a část s Qt5, to je problém, který existuje pořád, bez ohledu na typ balíčkování aplikace.
K tomu, aby byly díry převážně ve sdílených knihovnách, není žádný důvod. Vůbec nechápu, jak jste na něco takového přišel. Třeba chyby přetečení bufferu – to jako že aplikační programátoři umí příslušné funkce volat správně a programátoři knihoven ne? Chyby typu SQL injection budou jenom v aplikacích. Atd.
Tranzitivní závislosti nevadí, problém je, pokud na jedné knihovně závisí různé části (typicky různé knihovny nebo knihovna) a závisí na různých verzích. Jenže ona i zpětná kompatibilita má různé úrovně, a chyby se velmi často vyřeší tak, že knihovna je dál zpětně kompatibilní pro ten kód, který s chybou přímo nesouvisel. Navíc od Javy 9 jsou řešitelné i ty vícenásobné závislosti, protože modul závisí jen na modulech, které deklaruje, a závislosti jiných modulů ho neovlivňují.
Závislost jedné aplikace na Qt3 i Qt5 nemusíte jako administrátor řešit, protože ten problém vyřešil už autor té aplikace.
Ohledně bezpečnostních děr: Protože aplikace se píšou na vyšší úrovni, často ve vyšších jazycích, s použitím frameworků, které od většiny bezpečnostních chyb abstrahují. Navíc jsou poměrně časté chyby třeba v protokolech souvisejích s kryptografií, což bývá často chyba konceptu, ne kódu jako takového. Samozřejmě i na aplikační úrovni lze něco udělat špatně ("select "+...), ale s použitím běžných knihoven a good practice je to riziko řádově menší.
Ohledně tranzitivních závislostí - to je to, co jsem psal. Ohledně modulů v Java - jo, do té doby, než budu potřebovat, aby spolu ty dvě nekompatibilní verze fungovaly. Tuhle feature Java 9 považuju spíš za kontraproduktivní, bo dává falešný pocit, že tím řeší víc, než ve skutečnosti dokáže. Šedá je teorie, zelený strom života.
Ohledně Qt3 vs Qt5 - nevyřešil, protože to v principu vyřešit nejde. Ten problém existuje na obou úrovních - už v rámci vývoje a případně znovu v rámci distribuce (izolovaný container řeší potenciálně tu druhou část, se všemi zápory, které se tu diskutovaly).
Ty vyšší jazyky nejsou dobrý příklad, drtivá většina knihoven používaných v Javě je napsaná také v Javě (nebo jiném jazyce nad JVM). Navíc není pravda, že by vyšší jazyky abstrahovaly od většiny bezpečnostních chyb, naopak je to jen úzká skupina chyb. Kdyby se dalo bezpečnostním chybám jednoduše vyhnout tak, že se budou používat vyšší jazyky, dávno se v ničem jiném nepíše. Pokud je chyba v protokolu, je potřeba navrhnout nový protokol, který pak aplikace musí použít. Někdy se takové chyby dají obejít úpravou používání protokolu, což obvykle zase musí udělat aplikační programátor. Chyby konceptu jsou velice časté právě v rozhraní knihoven, kdy je možné tu knihovnu používat nebezpečným způsobem – to se opět musí opravit v aplikaci. Netuším, jak jste přišel na to, že u aplikací je to riziko řádově menší.
Pokud by spolu měly dvě nekompatibilní verze knihovny komunikovat, musí to zprostředkovávat přímo aplikace, tudíž to nebude tranzitivní závislost ale přímá závislost, a bude tam samozřejmě jen jedna verze. To samozřejmě neřeší problém, že by jedna z těch knihoven závisela na nějaké staré verzi. Ale tenhle problém má jenom jedno univerzální řešení – vykašlat se na to používat nějaké staré verze a používat všude vždy nejnovější verzi. Pak mají všichni ty závislosti stejné.
Ohledně Qt3 a Qt5 – vývojář to samozřejmě nějak vyřešil (nejspíš tak, že použije jen Qt3 nebo Qt5), protože kdyby to nevyřešil, ta aplikace vůbec nebude existovat a vy jí tudíž nemůžete někam instalovat. Navíc nikdo neodpíská vývoj aplikace jenom proto, že by se mu hodilo použít zároveň Qt3 i Qt5, ale musí si vybrat a použít jenom jednu z nich.
Tímto bych zrovna neargumentoval. Java je typickým příkladem jazyka, který byl z pohledu CS zastaralý už v době vzniku. Úkol zněl jasně - vzít v té době nejpoužívanější jazyk, tj. C++, vykuchat z něj ty největší pasti, tj. pointery, vícenásobnou dědičnost a ruční práci s pamětí, odstranit makroprocesor a překládat do multiplatformního bytekódu místo do strojáku. Jazyk měl dle tehdejších propagačních informací sloužit k programování mixérů a jiného drobného harampádí, měl sloužit k vývoji malých aplikací - "appletů" a měl umožnit programování i těm, kteří nedávají C++. C++kaři měli být schopni se ho naučit za pochodu, čímž měl být zaručen dostatek Java-ready vývojářů. To vše zaštítěno a licencováno Sunem.
Microsoft nesměl samozřejmě zůstat pozadu, čímž vznikla microsoftí verze Javy, v podstatě i se všemi nedostatky své předlohy (asi jako když Jára Cimrman inspirovav se románem Babička napsal román Dědeček).
Vůbec nešlo o vytvoření něčeho nového - právě naopak, ty "nové" jazyky měly být všem vlastně důvěrně známy, šlo čistě o marketingové projekty bez pokusu o nějaké inovace. Sami někteří z autorů Javy z toho byli rozčarováni, vědouce, že je právě promarňována příležitost vytvořit opravdu moderní jazyk na úrovni tehdy známých znalostí a zkušeností (podle původního záměru se měla Java mnohem více podobat Smalltalku než C++).
Tím, že je Java postavena na C++, dokonale demonstruje sama na sobě ono přísloví, že z ho..a bič neupleteš.
Já taky nepsal o dnešní Javě (ani dnešním C++), ale o Javě a C++ v době vzniku Javy - když už předřečník argumentoval koncepční zastaralostí. Obojí se od té doby někam posunulo od původních záměrů. (z obojího se stává větší a větší patlanina à la dort Pejska a Kočičky, což plyne prostě z toho, že obojí má v základech stejné koncepční nedostatky - objektový model postavený na statickém typování bude už z principu vždycky kulhat na všechny končetiny, co má; to je prostě pokus o kvadraturu kruhu)
Neprogramuji dobrovolně ani v jednom. Ale kdybych si musel vybrat, tak sáhnu po Go, už jen kvůli neskutečné ukecanosti Javy.
K obsahu:
"...každý Turingově úplný jazyk musí podporovat (if větvení, while cykly, přístup do paměti, alokaci na haldě či její čištění)"
Opravdu musí *Turingovsky* úplný jazyk podporovat tohle? If napíšu pomocí while, nebo naopak; tudíž stačí jedno z toho. Alokace na haldě a její čištění je podmínkou odkud? Necucá si tu autor trochu z prstu?
Otálel jsem jak jsem mohl, ale nechci vypadat, že se vyhýbám odpovědi. Přesto si myslím, že tohle by bylo lepší na diskuzi u piva. Zkusím něco napsat, ale obávám se, že to povede spíš na babylon neporozumění...
Podle základní informatické teze ze třicátých let minulého století má být Univerzální Turingův stroj schopen simulovat jakýkoliv počítač či jazyk. Neboť Turingův stroj je svého druhu počítač, tak jazyk jenž se zve Turingovsky úplným musí být schopný simulovat Turingův stroj. Tak a co teď z toho vyvodit?
Turingův stroj musí být schopen rozhodnout jestli posune pásku doleva či doprava. Na to potřebujete něco, co se v běžných jazycích jmenuje if
.
Turingův stroj má nekonečnou pásku. Dopředu nejde odhadnout jak velkou pásku budete potřebovat. To znamená, že v Céčku, Javě a podobných jazycích je potřeba postupně alokovat paměť. Máte pravdu, čištění potřeba není. Stačí mít té paměti dost a nebo ji čistit automaticky a nebo ji znovu využívat.
A nakonec cykly: jak moc mocné musí být? Asi nejznámější důsledek Turingovy formalizace počítacího stroje je takzvaný "halting problém". Tedy neschopnost strojově (Turingovsky) analyzovat kód a rozhodnout jestli něco vypočítá a nebo se zacyklí. Což znamená, že Turingovsky úplný jazyk se musí umět zacyklit. Ač se nám to často stává, tak to zase není tak jednoduché. Nestačí if
, nestačí for
(cyklus s pevným počtem opakování jako v Pascalu, ne ten for
z Céčka, Javy, a jiných odvozenin kde se for
cyklus ambivalentně s while
cyklem). Na zacyklení potřebuje cyklus s dopředu neznámým počtem opakování. Tedy v nám vcelku známých jazycích while
.
A co Haskell? Jasně, Haskell žádné while
cykly nemá. Je Turingovsky úplný? Ano, je. Jak to dělá? Rekurzí. Turingův stroj rekurze nemá (vše se píše do jedné funkce - žádná volání tam nejsou). Ale už od třicátých let minulého století se ví, že to je výpočetně stejně silné.
Tolik k vysvětlení, proč jsem si dovolil napsat, že "...každý Turingově úplný jazyk musí podporovat (if větvení, while
cykly, přístup do paměti, alokaci na haldě či její čištění)". Zbytek bych raději řešil si dostatečným alkoholem v krvi.
No, raději bych operoval s pojem "se stejnou výpočetní silou jako Turingův stroj" (či něco takového), ale prosím. Turingův stroj může potřebovat měnit i stavy, ale prosím. Jenže
- if není potřeba, pokud mám while
- while nebo rekurze, to je vcelku jedno (ona by ta rekurze šla najít i v TS, pakliže bychom pracovali s "výpočtem" - ale ano, toto už je jedno)
- ano, obecně má Turingův stroj nekonečnou pásku, ale pro Turingovskou úplnost stačí dvě "políčka", na která mohu zapisovat neomezeně velká (řekněme třeba přirozená) čísla - takže ani ta "halda" není třeba (čištění už vůbec ne, prostě to přepíšu)
- mimochodem je to Turingovsky úplný, ne Turingově úplný (výjimečně je to i na odkazované wiki správně)
Každopádně děkuji za odpověď. Upřímně jsem ji nečekal. :)
Autor řeší zcela nerelevantní věci, hlavní síla Go je čistost a čitelnost. A tak to má zůstat i nadále. Java je pravý opak, mnoho let se tam věci přidávají a přidávají. Srovnávat tyto jazyky je srovnávání hrušek s jablky. A hlavně dělat srovnání na základě nějakých mikrobenchmarků nebo nejhůř doby startu to snad v éře webových aplikací a služeb ani nemá cenu komentovat.
Jak říká Rob Pike, ať si kažý používá jaký jazyk chce, na co chce! Já stále na text processing používám Perl, protože se mi to prostě dělá nejlíp. Mimochodem Docker není kontajner, ani kontejner. Ale pobavilo.
> hlavní síla Go je čistost a čitelnost
Čitelnost samotné syntaxe ano.
Jenže čitelnost algoritmů v Go napsaných už moc ne. "Neexistence" výjimek (vím o panicu), neexistence generik, rozumných kolekcí a algoritmů znamená, že pro stromy (ify, fory a error handling) nevidíte les (vysokoúrovňový záměr).
> Já stále na text processing používám Perl, protože se mi to prostě dělá nejlíp.
V pořádku. Však na to byl Perl určený a má na to specializované nástroje.
Presne tak citelnost GO je velice mizerna.
Java priklad
try {
businessMethod1();
businessMethod2();
}
catch (Exception1) {
...
}
catch (Exception 2) {
...
}
GO:
func ... {
err1 = businessFunc1();
if(err1) {
defer errHandler1();
}
err2 = businessFunc2();
if(err2) {
defer errHandler2();
}
}
func errHandler1() ....
func errHandler2() ...
V Jave, kdyz chci pochopit korektni business kodem, musim precist 2 radky volani business metod..
V go musim precist 8 radku kodu, 75% radku je error handling balast, ktery me pri studovani business kodu nezajima. Procist ho musim vzdy, nevim, jestli je dany if pouze error handling nebo soucast business kodu.
Nopak, pokud chci v jave nastudovat error handling, podivam se na chatch bloky a throws klausuli.
V GO musim proskenovat cely zdrojak, vyhedat defery, coz jsou casto uplne jine funkce na druhem konci zdrojaku.
To jsou pořád hádky...stejně ale nikdo, pokud nedělá jádro výkonově specifické aplikace, tak neoptimalizuje natolik, aby ho vytrhlo pár procent výkonu (a ten nepoužije ani C#, ani go, ani javu). Go je dobrej jazyk, Java je dobrá i C# je výbornej jazyk...
Jako hlavní rozdíl mezi GO a javou vidím v GO zprzněnou dědičnost a jinak v podstatě to samé, co jsou nevýhody C - chce to seniorního architekta, aby udržel rozsáhlejší projekt strukturálně čistý, rozhodně v tom nejde nic psát na první dobrou.
Aplikací tohohle pravidla pak vzniká jedinej rozdíl mezi vývojem v C# a v Javě. Outsourcing je pak zlatej důl pro firmu, když zaměstnají kdejakého ňoumu s jedním semestrem javy, aby to nějak zbastlil, náročnost svedou na Javu, zaplatit si nechají jako profesionála a mají vystaráno. To je hlavní důvod, proč se většina firma k javě nechá překecat. C# není v módě, aby se učil na pseudoškolách, člověk s ním přijde do kontaktu jen, když opravdu sám chce. Většinou s tím přichází i nějaká předchozí znalost programování v několika jazycích a pro takového člověka je C# jenom jedna z možností, jak aplikaci zapsat.Takový člověk už přemejšlí spíš nad návrhem, než aby se pral s tím, jak to zbastlit, aby to šlo zkompilovat a dělalo přibližně, co to dělat má.
C# ja hlavne donedavna wokna only, .Net Core je uplne nova zalezitost.
Takze v C# hlavne matlaj korporatni wokenni matlalove pro wokkenni "servery" a MSSQL.
Vsechny trochu rozumne backend aplikace bezej na Jave hlavne z toho duvodu, ze wokenice si da na backend jedine masochista.
A taky proto, ze C# ekosystem se s Javou nemuze merit. .Net runtime toho umi sice vic nez holy JVM, lec v pripade C# na teto urovni koncime.
V Jave mame Apache Foundation a Maven central, na tohle C# nelepi ani omylem.
Vyhoda tohoto pristupu je hlavne v tom, ze samotna java se nezasira modnimi poryvy, samodna java je porad mala a jednoducha.
. Net Core ostatne vznikl prave proto, ze stary .Net nafukovanim tak zmolochovatel, ze uz to bylo do budoucna neunosne.
Co se tyce .Net Core, je to zrejme poctive a slusne pojata iniciativa, ale proc chodit ke kovarickovi, kdyz muzu ke kovari...
====
chce to seniorního architekta, aby udržel rozsáhlejší projekt strukturálně čistý, rozhodně v tom nejde nic psát na první dobrou.
====
Udržení rozsáhlejšího projektu "strukturálně čistý" (jinými slovy "aby v něm nebyl bordel") vyžaduje vždycky zkušenosti, ať je psaný v čemkoliv. Ba dokonce bych řekl, že na použitém jazyce v tomto ohledu ani moc nezáleží.
IMHO to bylo spise mysleno tak, ze kdyz uz ujely cvicky a bordel vznikl, jsou jazyky a vyvojove prostredi, kde se to da jeste rozumne podchytit v zarodku a vycistit, nez se to zesere cele.
Treba Java IDE typu Eclipse/IntelliJ/Netbeans spolu s modularnim mavenem maji luxusni podporu refaktorizace, xml config validace apod.
V jave mi prijde na review nejaka hrozna spageta, a tam buch-buch "extrac method", "extract interface", "change method signature", "rename" a uz to lita. IDE se postara, ze se zmeny zpropagujou vsude.
V jazycich jako je C nebo GO to jde mnohem obtizneji a jenom rucne. Hlavne z duvodu neexistence vyjimek, v Jave muzes beztrestne kus kodu ze spagety extrahovat do metody, IDE samo automaticky prida potrebne throws klausule. V GO, kde mas dohromady zmatlany business kod a error handling to musis vypreparovat rucne, je to hrozny oser nachylny na chyby, casto je snazsi napsat zpraseny kod nacisto odznova.
Tak to rozhodně, úpravy legacy kódu v Javě dělám úplně stejně. Máme to jako první krok každého změnového požadavku. Asi jsem ten původní post blbě pochopil.
Přesně proto "embedded" Javě fandím, protože i na kratší projekty se hodí používat kvalitní IDE a mít kód pořádně pod kontrolou. Píši teď trošku větší projekt (10+ funkcí) v octave a i obyčejné přejmenování funkce bolí. Ono to tedy bolí i v pythonu, který se pro větší věci běžně používá...
Ani PyCharm není věštec a neumí spolehlivě rozeznat volání metody Class1.metodaA() od Class2.metodaA(), když se jmenují stejně, ale přejmenuji jen Class1.metodaA -> metodaB(). Type hinty u instancí sice pomáhají a PyCharm se snaží věštit ze všech sil, ale zdaleka ne tak, aby se na to dalo spolehnout. Proto se v pythonu snažím používat jména co nejpopisnější, aby se minimalizovala pravděpodobnost takovýchto kolizí.
Navíc spoustu "doporučovaných" postupů používá názvy metod/fieldů ve stringu (např. kontrola "vhodnosti" vstupních parametrů přes hasattr(), to už je úplná konečná).
Kazdemo, co jeho jest, kazdy si pod pojmem uzivatelsky privetivy jazyk asi predstavi neco jineho. Mne treba u Javy vadi spousta veci - pocinaje jejim az dogmatickym lpenim na tridach a konce nemoznosti pouzivat normalni operatory pro uzivatelske typy (vcetne treba BigDecimal a spol.).
Je to podobné, o tom žádná, ale nepřijde mi to moc hezké, je to asi na delší debatu. V C++ jsem programoval před lety, živím se hlavně Pythonem, z dalších jazyků se mi (z různých pohledů) líbí třeba Julia, Rust nebo Scala. Každý z těchto jazyků umí přetěžovat základní operátory, stejně jako to umí Lisp, Haskell, Ruby, C#, F#, Kotlin a já nevím, co ještě, každý jazyk to samozřejmě dělá po svém, pro některý je to prostě třeba infixová funkce, pro některý je na to trait, jiný zase má magické metody třídy...
Java i Go v tomhle z mého pohledu tragicky selhaly. Nepláču po >> z C++, ale u číselných typů bych rohodně čekal konzistenci.
IMHO to bylo spise mysleno tak, ze kdyz uz ujely cvicky a bordel vznikl, jsou jazyky a vyvojove prostredi, kde se to da jeste rozumne podchytit v zarodku a vycistit, nez se to zesere cele.
Treba Java IDE typu Eclipse/IntelliJ/Netbeans spolu s modularnim mavenem maji luxusni podporu refaktorizace, xml config validace apod.
V jave mi prijde na review nejaka hrozna spageta, a tam buch-buch "extrac method", "extract interface", "change method signature", "rename" a uz to lita. IDE se postara, ze se zmeny zpropagujou vsude.
V jazycich jako je C nebo GO to jde mnohem obtizneji a jenom rucne. Hlavne z duvodu neexistence vyjimek, v Jave muzes beztrestne kus kodu ze spagety extrahovat do metody, IDE samo automaticky prida potrebne throws klausule. V GO, kde mas dohromady zmatlany business kod a error handling to musis vypreparovat rucne, je to hrozny oser nachylny na chyby, casto je snazsi napsat zpraseny kod nacisto odznova.
minulou stredu prave uverejnili specifikaci pro Fortran 2018. My vsichni, co jsme odevzdavali nase semestralky na dernych paskach, patrime mezi opravdove programatory. Nechapu, jak muze programator pouzivat programovaci jazyk s vestavenou automatickou spravou pameti. To je prece trapne.
Hmm, tak si zkuste udělat strukturu "struct point { float x, y }.
A pak si udělejte pole obsahují milión takových struktur. V C, C++ i GO vám to sežere jeden objekt na haldě o velikosti 8MB.
Zatímco v javě to struct point musí být třída - class point a vy vlastně vytváříte pole ukazatelů na třídy. Každá z těch položek "class point" bude mít ukazatel na tabulku metod i zcela zbytečný ukazatel na mutex (poněvadž jakákoli třída v javě se může chovat jako mutex). Sežere to víc paměti a gc s tím bude mít víc práce.