Mať 4 staré a 4 nové spôsoby ako definovať jednu funkciu mi príde také... uh. Ktorý z tých 8 spôsobov mám použiť? Aký je rozdiel medzi nimi? Čo sa stane ak zvolím tento spôsob? Má to nejaký vplyv? Čo ak....
začiatočníci budú mať veľa chaosu.
ostatne je vtipné že doteraz bolo potrebné napísať tisíc riadkovú slohovku v kóde aby si vytvoril hello world program. Proste boilerplate a boilerplate, ktorý sa teraz snažia zredukovať.
Aký .NET používate? Nový konzolový project je:
// See https://aka.ms/new-console-template for more information Console.WriteLine("Hello, World!");
a nový webový project je:
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); var app = builder.Build(); ... app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run();
Top-level statements majú veľa využití: konzolové aplikácie, skripty, ukážky kódu, tutoriály a knihy, Jupyter a iné embedded prostredia, rôzne API a microservisy.
Moderné programovacie jazyky vo veľkom kopírujú rôzne populárne postupy, napr. rekord typ, match pattern, async/await, funkcionálne programovanie atď. Akurát to public static void main si nik neobľúbil, dokonca ani Java platform jazyky. Čím to je?
Netuším kde je problém. Kompiler vytvorí objekt a sám zavolá main metódu. (Nie som si úplne istý, ale tak by to zrejme mali robiť aj Kotlin a Groovy.) Tým že je main statická, tak musia byť aj premenné s ktorými pracuje statické. A to je presne to, čo v 99.999% prípadoch nechcete. A preto kóšer Java kód pre minimálnu aplikáciu musí mať nie jednu triedu, ale rovno dve. Pretože tá prvá je len Application starter.
Ak sa toto niekomu páči... Ale čo ja viem, ja som len obyčajný F#/Groovy programátor.
> A preto kóšer Java kód pre minimálnu aplikáciu musí mať nie jednu triedu, ale rovno dve.
Nemusí. Funkce main() je obvykle jenom wrapper, ale může vytvořit objekt ze stejné třídy a zavolat její metodu. Můj typicky kód pro hodně jednoduché věci (bez DI a jiných komplikací):
public class A { public static void main(String[] args) { System.exit(new A().run(args)) } public int run(String[] args) { // do the actual stuff } }
To zjednodušení v Java 21 je nejspíš cíleno na skriptování apod, pro větší program to smysl nemá.
Když kompilátor vytvoří objekt, musí ten objekt mít bezparametrický konstruktor. Co kdybyste chtěl zařídit, aby ten „hlavní“ objekt byl singleton? Co kdybyste chtěl instanci toho objektu někam předat – asi budete muset z konstruktoru někam předávat this
, což je prasárna na entou.
Aneb abyste si mohl zjednodušit život a ušetřit jedno klíčové slovo u definice metody, musíte kolem toho vyrobit celý aparát složitých pravidel. Jsou jazyky, které to tak dělají, třeba Kotlin. Java na to jde přesně opačně – pár jednoduchých pravidel, z nichž už se pak dají složitější věci poskládat. Občas to znamená napsat trochu víc písmenek, ale dneska už máme IDE, která ta písmenka píšou za nás. A kdo chce ušetřit písmenka, nepoužívá Javu.
Kde tak Kotlin činí? IIUC, v Kotlinu máte dvě možnosti:
a. Udělat main mimo třídu, pak se Vám pro JVM automaticky vygeneruje třída MainKt (nebo tak nějak) s public static void main.
b. Udělat companion object a v něm metodu main s @JvmStatic. Companion object je v podstatě singleton (takže tam neřešíte žádné parametry pro konstruktor), přijde mi to jako lépe navržená alternativa statických metod. Anotace JvmStatic pak zajistí, že se při kompilaci pro JVM vygeneruje i statická proxy metoda.
První způsob je multiplatformní, tedy bude fungovat i na Kotlin/Native. On Kotlin obecně k některým věcem (např. kolekce) dělá v podstatě aliasy, aby mohl fungovat multiplatformně.
Druhý způsob je víc low-level a funguje jen na JVM, nebude tedy fungovat např. s Kotlin/Native nebo Kotlin/JS. Resp. i na dalších platformách to půjde zkompilovat (pokud kompilátor bude mít na classpath anotace pro JVM), ale nevyrobí to žádný entry-point.
> Netuším kde je problém. Kompiler vytvorí objekt a sám zavolá main metódu.
No já v tom vidím problém v tom, že je to ještě jeden další "neviditelný" krok navíc. Rozdíly mezi statickými proměnnými a nestatickými proměnnými v nějakém "statickém" unikátním objektu jsou dost kosmetické.
A pokud ten main objekt není jen jeden, ale chcete pak vytvářet další, tak mi to zas smrdí porušením single responsibility principle.
Co mi přijde příčetné je opustit Cčkoidní main funkci a mít přímo kus kódu, který se zrovna vykoná (jak je oblíbené u skriptovacích jazyků). Jestli si pro to chce překladač vytvořit nějaké svoje pomocné objekty, ať si poslouží. Ale pro mně jako pro programátora jsou tak dobře schované, že vlastně ani neexistujou a nemusím jejich existenci nijak řešit.
Chápu jak ten statický main historicky vznikl. Jistým zvráceným způsobem mi přijde že Java zahodila špatné části Cčka a dobré části C++.
To nejlepší, co šlo pryč? Podle mě hodnotová sémantika. V c++ je zvykem, pokud to jenom jde, aby se i vaše typy chovaly jako int (bez Cčkovských podivností). Proměnná je chlívek na hodnotu, ne odkaz na nezávisle existující (a potenciálně sdílenou) entitu.
V kombinaci s mutabilitou (což je v Javě obvyklé) to přidává věci na které musí programátor myslet. Změní mi volaný ten předaný objekt a kdy? Můžu volajícímu ten objekt upravit, nebo si ho musím naklonovat? U velkých (nebo spíš high level) objektů to až tak nevadí, ale je to bolest pro ty malé dílky (kontejnery, 3d vektory a podobně). A takových je IMO drtivá většina.
Naprostou souhlasím.
V problémvé doméně jsou dva druhy objektů. 1) enity s životním cyklem a rovností přes nějaký druh identity (id) a 2) hodnotové typy bez životního cyklu s rovností definovanou jejich atributy. Těch druhých je neskonale větší procento. V některých dménách vlastně skoro všechny (např. simulace). A pro hodnotové typy se přidala podopora pár let nazpět, jinak se t muselo stále řešit otravným předefinováním metod. Python na tom nebyl dlouho o moc lépe. Asi prostě relikt 90kových "OO" jazyků.
Nepřijde mi, že by byla nepopulární. Quarkus, Micronaut, Apache Camel, Kogito tohle všechno jsou frameworky, které jsem v poslední době viděl v nespočetných instancích napříč různými odvětvími. Počínaje tour operators, přes iGaming po Telco. Jeden z nejpopulárnějších open data table format Apache Iceberg, opět Java. Vlastně když nad tím přemýšlím Delta Lake je opět Java. Ja osobně bych v JVM ekosystému v některých případech dal přednost Kotlinu a to i v případě backend, ale sehnat kvalitního backend developera s Kotlinem je trochu oříšek. Jinak pokud bychom mluvili o tom, že Java programmers jsou drazí, tak kvalitní Python programmer, vás v Estonsku vyjde cca na 5000 Eur čistého. Obdobně jako Java. Ja osobně Javu nemám moc v oblibě, ale rozhodne bych se neodvážil tvrdit, že je nepopulární, většina toho hejtu nemá logický základ, nebo je založených na dávno neplatnych předpokladech.
> Netuším kde je problém. Kompiler vytvorí objekt a sám zavolá main metódu.
Kdyby toto měl mít na starost kompilátor, musel by něco vědět o metodě main. Vsadil bych se, že ve zdrojáku javac nenajdete žádný kód, který by se věnoval specificky metodě main, protože tam žádný takový nebude.
> Nie som si úplne istý, ale tak by to zrejme mali robiť aj Kotlin a Groovy.
U Groovy nevím, nicméně u Kotlinu vím jen o jednom zjednodušení – hodíte main úplně mimo třídu. Tam to ale dává smysl i kvůli tomu, že Kotlin je multiplatformní, nejen pro JVM.
No jo, no. Kotlin s něčím přišel, tak to tam musejí mít taky. Výsledek je jako když pejsek a kočička vařili dort. Zdánlivě to věc zjednoduší, ale pokud tomu chcete rozumět, tak je to ve skutečnosti složitější.
Jinak teda po přechodu z Pascalu na C jsem taky nechápal proč musím mít funkci main a po přechodu z C na Javu jsem zase nechápal, proč to musí být ve třídě. Ale takhle to tam lepit do verze 21 skoro 30 let po vzniku jazyka...
Je opravdu rozumné to učit takhle? Než se začátečníkům vysvětlí, co ty části znamenají a začne to dávat smysl přece netrvá nějak extrémně dlouho. A pak už to zvládnou napsat z hlavy protože to celkem jasně vyplývá z toho, co to má dělat.
A než to poberou, tak to přece nemusí sypat z hlavy a můžou to kopírovat z předchozích zdrojáků.
Nevím, jestli to chápu správně, ale tvrdíte, že mnemotechnické pomůcky nemá cenu používat? Nebo že to myslím tak, že to studentovi vůbec nevysvětlím a řeknu mu jen tu pomůcku? Samozřejmě, že mu to vysvětlím. Kraniální nervy v medicíně taky nejsou nic těžkého na pochopení a přesto na ně mají medici pomůcku "Ooh, Ooh, Ooh, to touch and feel very good velvet. Such heaven!" Neznám situaci kdy by bylo hrozně špatné použít při učení mnemotechnickou pomůcku (nebo cokoliv, co pomůže paměti).
Spíš že tam toho na zapamatování moc není. Akorát tak int/void a velikost M. Public, static a pole stringů vyplývají z fungování.
A začátečníkovi zase ta pomůcka nedá zbytek minimálního programu - třeba tu třídu do které to musí být zabalené.
Argument s těmi nervy nechápu. To je přece dlouhá řada jmen, které se z ničeho moc vydedukovat nedají.
Presne. Typicky ceskoakademicky nesmysl jak to nedelat. To nejde ucit jak poradi strun na kytare. Zvlast kdyz to vychazi z anglictiny - ano v teto dobe uz umi kdejaky jazykovy dropout. Nedava smysl cpat do toho cestinu ktera studenta odstini od skutecneho vyznamu veci.
Tyhle veci nejde ucit jak zednika technologicky postup nebo montazni prirucku pro nekvalifikovanou pracovni silu na lince. Inzenyr musi vedet proc.
V cecku treba tusim az co mi z main vygeneruje compiler v objektu/spustitelne binarce a co v kterych pripadech ho nepouziji. Treba si to zkusit z tcc ktery je kiss bez optimalizace. Co delaji ta makra predtim na zacatku. Ten boilerplate neni tezke vysvetlit. A nechat si s tim studenty trochu pohrat at chyti souvislosti. Samozrejme po tom co si neco uz naprgaji aby jim nezvadla motivace.
A to je minimum. Aby alespon bylo nejake povedomu. Neresim staticke/dynamicke libky. Pripadne primitivni kod pro mikrokontrolery.
Tak zrovna mix češtiny a angličtiny je v pohodě. Kór když to zůstane v hlavě programátora. To bychom stejně tak mohli obrozenecky lynčovat lidi, kteří v českém textu používají anglická slovíčka (ehm ehm, dropout, ehm ehm)
Co mi přijde divné je používat memotechnické pomůcky pro nabiflování něčeho, co má svou vnitřní logiku a pravidla. Biflování se hodí na věci, které takovou vnitřní logiku nemají. Průměr země z ničeho nevydedukuju, public static void pro main jo.
Navíc ta memotechnická pomůcka obsahuje jen asi polovinu "keců" potřebných pro minimální Javovský program. :)
Na pořadí modifikátorů nezáleží, takže může být public static
i static public
. Že se píše nejdřív návratový typ a pak až jméno metody je potřeba vědět tak jako tak. Stejně jao je potřeba vědět, že modifikátory patří na začátek. A pak už není potřeba se na tom nic učit. A když už by se na tom někdo chtěl něco učit, tak psvm<Tab>
.
To je filozofická otázka. Java z toho spraví na pozadí triedu a z main metódu tejto anonymnej triedy. Ja by som sa priklonil k tomu, že je to funkcia. Je podružné, ako sa to na pozadí transformuje a kompiluje.
Ináč takto to robí aj Kotlin aj Groovy. Aby boli kompatibilný s Java API, musia robiť takého krokolomné hacky.
Áno, program môže mať zadefinované viaceré main metódy a tie sa podľa parametrov volajú.
6. 10. 2023, 18:39 editováno autorem komentáře
Pokud jsem to dobře pochopil, tak by to umožnilo mít např. Collection<int> namísto memory- a CPU-žravého Collection<Integer>.
Dále by to umožnilo nadefinovat např. typ ID, který by byl podkladově int (tedy primitivní typ s nejvyšší efektivitou), ale v kódu by nebylo možné ID zaměnit s jiným intem. Typicky při předávání parametrů do metod je riziko záměny ID s jiným intem (nebo longem) - stačí přehodit parametry - a kompilátor nemá šanci to odhalit. Takhle by šlo bez ztráty výkonu (v obou případech by se interně předával jen int) tyhle data od sebe bezpečně oddělit - užitečné i pro refaktoring, úpravy parametrů metod atd... Každá dodatečná ochrana na úrovni kompilátoru se počítá, je potřeba minimalizovat prostor pro chyby.
Jazyková rodina není to jediné, podle čeho se dají jazyky posuzovat. Java se drží principu, že samotný jazyk a jeho syntaxe má jen pár nejnutnějších věcí, a zbytek se dožene knihovnami nebo podporou generování kódu. Proto nemá Java např. speciální syntaxi pro listy, mapy, nemá přetížené operátory. Proto velmi dlouho neměla interpolované stringy, proto se lambda výrazy zaváděly tak opatrně. Proto neměla enumy a donedávna neměla recordy – a obojí bylo zavedeno jako „magie“ kompilátoru a překládá se to na standardní třídy. Zároveň Java velmi přísně dbá na zpětnou kompatibilitu.
Kotlin naproti tomu zpětnou kompatibilitu neřeší a co se týče „minimalismu“ jazyka, je na opačné straně, než Java – skoro platí, že na co se dá vymyslet syntactic sugar, na to Kotlin syntactic sugar má.
Oba přístupy mají své opodstatnění, oba si najdou své příznivce – a je nesmysl pokoušet se to míchat do jednoho jazyka, který by byl neslaný nemastný.
Mimochodem, to, že Java takhle vypadá a tím pádem se to odráží i v JVM, umožnilo, aby vůbec Kotlin/JVM vznikl. Kdyby Java měla v jazyce podporu pro kde co, nejspíš by to bylo i v JVM a pak pro Kotlin bylo velmi obtížné udělat to jinak. A týká se to i ostatních jazyků postavených nad JVM – ten jednoduchý základy Javy odrážející se v JVM umožnil vznik specializovaných jazyků nad JVM jako Groovy, Scala nebo právě Kotlin.
Chtít ve 21. století, aby se všechny číselné typy sčítaly operátorem + snad není přehnaný požadavek. To peklo je vycucané z prstu, kdo dokáže zamezit tomu, aby někdo vytvořil metodu add(), která odečítá nebo násobí? Co je na operátoru tak specifického, že se ho bojíme? Jenom to, že to někdo někdy odmítl nebo to neumí implementovat.
Chtít ve 21. století, aby se všechny číselné typy sčítaly operátorem + snad není přehnaný požadavek.
To vůbec nesouvisí se stoletím. Někomu vyhovuje sčítání číselných typů operátorem + i za cenu, že to někdo zneužije pro typy, které by jiní vůbec nepovažovali za číselné, nebo za cenu, že pro některé typy nebude + komutativní. Někomu zase vyhovuje, když je operátor + jednoduchá věc, na kterou se vždy může spolehnout, a záludnosti typu „dělá to něco jiného, než bych čekal“, si ponecháme až pro metody.
Mimochodem, když už se přetíží operátor * pro sčítání všech číselných typů, někoho možná napadne, proč nepřetížit i operátor *. A proč se omezovat na číslené typy na obou stranách, když třeba taková operace 6 * "ahoj"
má také svůj význam.
ovsem + neni komutativni ani v Jave, ze? A taky se pouziva na necelociselne typy (a aby to bylo jeste "lepsi", tak jde o referencni typy).
V jakých případech není komutativní? Neceločíselné typy já řadím mezi číselné typy. Pro referenční typy se plus nepoužívá (s výjimkou toho Stringu) – možná vás mate to, že se nejprve dělá unboxing.
no je :) https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.18
to ze interne je to slozitejsi (unboxing + reseni strictfp a dalsi chutovky) neznamena, ze neni podporovan.
Ale pointa je jina - ta komutativita hodne hapruje celkove, obecne je docela tezke ji dosahnout
Prima. Tak si tu sekci teďka přečtěte. Zjistíte, že rozlišuje dva operátory – 1) operátor pro spojování řetězců a 2) operace pro sčítání a odčítání numerických typů. Přičemž pro numerické typy je komutativní, pokud operandy nemají vedlejší efekty. A nejprve se aplikuje unboxing, pak až operátor sčítání. Když máte metodu, která jako parametr dostává int
, také nikdo netvrdí, že kompilátor na pozadí vytvoří přetíženou metodu akceptující Integer
– pořád je tam jenom jedna metoda, jen kompilátor automaticky provede unboxing.
vyborne takze jsme si to precetli oba. O scitani numerickych typu je to tam napsano jinak - operator + je definovan pro hodnoty prevoditelne (unboxingem) na primitivni ciselne typ (coz je ovsem neco jineho nez to, ze je definovan pro primitivni ciselne typy). To zaprve (btw s tou metodou co uvadite je to naopak - pokud budu mit metodu akceptujici Integer, tak budu tvrdit, ze ta metoda akceptuje referencni typ!).
Zadruhe - pokud se podivame na definici pojmu "komutativita", tak to hapruje i u nekterych ciselnych typu v Jave.
Nikoli, operátor + (pro sčítání) je definován pro primitivní numerické typy. Ono by jaksi bylo zbytečné definovat ho pro referenční typy, když u nich kompilátor podle specifikace vždy nejprve provede unboxing, pokud se objeví jako operandy toho operátoru +. To, že se referenční typy mohou objevit jako operandy operátoru +, neznamená, že je pro ně operátor definován. (Kdyby byl, nemusí pro ně kompilátor provádět unboxing.) Je to stejně jako s tou metodou, jak jsem psal – metoda akceptující int
(to není Integer
) nemusí mít přetíženou metodu akceptující Integer
, a ani žádnou takovou metodu nevyrobí kompilátor. Kompilátor prostě jen proveden unboxing, když je to potřeba.
Přímo v té vámi odkazované specifikaci je uvedeno, že operace sčítání numerických typů je komutativní (pokud operandy nemají vedlejší efekty, to je jasné). Takže pokud chcete rozporovat specifikaci, měl byste uvést nějaký důkaz, ne jen opakovat své tvrzení pořád dokola.
Zadruhe - pokud se podivame na definici pojmu "komutativita", tak to hapruje i u nekterych ciselnych typu v Jave.
Tak nebuď slušný a uveď příklad! Tohle miluji, někdo jen tak do tmy a pak několikrát opakuje, že to tak je, ale i přes žádost o uvedení přikladu to zopakuje. To neznamená, že ti nevěřím, ale ukázaná platí.
Jo, tohle není úplně dobrý příklad. Zaregistroval jsem i případ, kdy jistý matematický purista tohle porovnávání vs vracení dost řešil.
A propagaci NaNů, která je jednoznačně nekomutativní, Java nechává koňovi. Na nějaký payload se moc nehraje. Využít ho moc nejde, ale to v jazyce co zahodil i uint to není nějaké velké překvapení.
Tak to me mrzi, ze je to hloupe, kdyz to presne muzeme napasovat na definici komutativity:
https://en.wikipedia.org/wiki/Commutative_property#Mathematical_definitions
A jak jsem psal to neni az tak problem + jako spis == u FP, ale porad bych si tedy v CS nertroufl rict, ze je to komutativni operace, kdyz to "for all x,y in S" neplati minimalne u 2^60 pripadu.
Akorát že v definici komutativity není nic o Javovském operátoru ==
. Problém vidím v tom, že jste si místo „stejnosti“ jen tak dosadil operátor ==
. Takže já bych zůstal u toho, že operace sčítání (numerických hodnot) v Javě je komutativní, protože nezáleží na pořadí, výsledek je pořád stejný.
Vedle toho tu máme operátor ==
, u kterého pro hodnoty NaN
není možné říci, které chování je jediné logické – takže si autoři Javy museli jedno chování vybrat, tedy je to věc, kterou si musíte nastudovat, jak to v Javě funguje.
No právě proto to vytáhl. Jako příklad že vaše "že to někdo zneužije pro typy, které by jiní vůbec nepovažovali za číselné" už v Javě je i bez nějakého přetěžování.
Jinak "číselný typ" je trochu vágní pojem a krásné téma na flame. String je přímo ukázkový monoid, takže operátor + tu sedí jak prdel na hrnec. A podobných skvěle sčítatelných "nečíselných" typů není málo.
Tak si přečtěte ještě jednou tu citaci. Já jsem psal o číselných typech. Tj. operátor po spojování řetězců jsem dal úplně stranou. Operátor + se pro spojování řetězců používá tradičně, používá ho tak většina z jazyků, které žádné přetěžování operátorů neznají. Prostě je to jeden symbol použitý ve dvou významech, podobně jako kulaté závorky – jak už jsem psal.
"používá ho tak většina z jazyků, které žádné přetěžování operátorů neznají. Prostě je to jeden symbol použitý ve dvou významech," - je to jeden operator, ostatne ho takto popisuje i Java specification. A protoze je pouzit pro vice typu (stacilo by uz int a float), tak je to pretizeny operator jaksi z definice tohoto pojmu.
A vida - Javiste s tim nemaji problem, pouzivaji tento syntakticky cukr a to presto, ze je chovani + v Jave docela slozite.
Java zná dvě různé operace – spojování řetězců a sčítání numerických typů. Sám jste na příslušnou část specifikace odkazoval. Java nezná pojem „přetížený operátor“, takže těžko něco může splňovat tuto neexistující definici. A pokud byste chtěl použít nějakou obecnou definici přetíženého operátoru, zabřednete do spousty nejasností, třeba jestli „numerické typy“ může nebo nemůže být bráno jako jeden typ.
Plus se pro spojování řetězců používalo dávno před Javou. Ono zas tolik znaků na klávesnici nebylo. I když logičtější by bylo třeba &
. ||
z SQL také není špatné. Ale, to, že za sčítání řetězců považujete jejich spojení, je dané jenom tím, že jste si na to zvykl. Klidně by to mohlo být třeba sčítání jejich bitových reprezentací.
Všimněte si, že jste vytáhl dva binární operátory.I když jste mohl klidně použít symbol, který je jinde použitý v úplně jiném významu. Treba Luovské ".." je pěkné.
Já bych řekl, že je to tím, že přetěžování operátorů je intuitivní a rozumné řešení. A jestli to slovo dokumentace používá je celkem jedno.
Jinak + je pro spojování řad velice intuitivní. Už školáci, když skládaji jablka vedle sebe, si to spojí se sčítáním. Ten & je tak logický, že bych si při překladu do češtiny musel dávat pozor, aby ta souvislost ten překlad vůbec přežila.
&
jsme použil čistě jako symbol, nevybavuju si, jestli to nějaký jazyk používá pro spojování řetězců. ||
jsem uvedl jako příklad, kde už se to jako operátor spojení řetězců používá.
Nemyslím si, že by to většina programátorů z jazyků, které neznají přetěžování operátorů, vnímala jako přetěžování operátoru. Podle mne to vnímají tak, jak to popisuju já – jako dva různé způsoby použití jednoho znaku. Stejně jako třeba ty kulaté závorky.
Když školáci skládají jablka vedle sebe, spojí si se sčítáním počet jablek, ne jablka samotná. Žádný školák si nepředstaví, že když sčítáte jablka, dostanete na konci řadu slepených jablek.
Nevím, co je na spojce a nelogického – vždyť přesně tak se to v češtině (i angličtině) používá. „Vypište na výstup vedle sebe dvě slova, ‚ahoj‘ a ‚světe‘.“ Dokonce se naopak to a lidově používá pro sčítání – „dvě a tři je pět“.
Psal jste, že to & je logičtější. Takže jsem čekal že jste to někde viděl použíté. Mně by tenhle znak ani nenapadl a myslím, že nejsem sám.
No vidíte. Sám jste to napsal. To & dává smysl jen pokud ho četete tak, že by tam mohlo být i +. Zkuste "a zároveň" nebo něco jiného, co by sčítání být nemohlo, a podobnost s konkatenací řetězců je pryč. Přesně proto jsem vytahoval problém s překladem do češtiny.
Jinak k tomu, že to někdo nemusí vnímat jako přetěžování operátorů mě napadá podobnost s jistým sprostým M-slovem. Tam se programátoři obvykle podělají hrůzou a pak jim dojde, že už to vlastně dávno používají.
9. 10. 2023, 11:05 editováno autorem komentáře
Význam znaku v běžné řeči je ovšem „and“ nebo česky „a“, žádné „a zároveň“. Firma „Novák&syn“ je firma „Novák a syn“, ne „Novák a zároveň syn“. Stejně tak se v běžné řeči pro skládání věcí dohromady běžně používá slovo „a“ („and“ v angličtině), „plus“ má odborný význam. Neříkáte „byl tam Petr plus Pavel plus Lucie“, ale „byl tam Petr, Pavel a Lucie“, případně „byl tam Petr a Pavel a Lucie“. Nebo „kup housky a mléko“, ne „kup housky plus mléko“.
Proto by bylo & logičtější, protože je to přenesení významu toho znaku z běžné řeči do programovacího jazyka. Rozhodně to dává pro spojování řetězců větší smysl než +.
Scratch má potenciál. Dnes jazyk pre animovanie obrázku mačičky, zajtra kritické operácie.
Čo sa dalo čakať. Java nie je už ten cool zázračný jazyk, ktorý všetko vyrieši od mladej dravej dynamickej firmy Sun Microsystems. Už je to smrdutý jazyk na písanie bankových systémov od dinosaurej firmy Oracle.
Já jsem to sice věděl, ale čistě didakticky pro autora článku přidávám, že dneska tyhle věci dokáže velmi obstojně (i ve slovenštině) vysvětlit i ChatGPT 3.5:
Já: Prečo musí byť metóda main v jazyku Java statická?
ChatGPT:
V jazyku Java je metóda main statická z dôvodu konkrétneho spôsobu, ako Java spracúva spustenie programu. Statické metódy sú metódy, ktoré patria triede ako celku, a nie konkrétnym inštanciám tejto triedy. Metóda main je statická, pretože je volaná pri spustení programu, predtým než je vytvorená akákoľvek inštancia triedy.
Keď spustíte program Java, systém Java volá metódu main bez toho, aby vytvoril inštanciu triedy, v ktorej je definovaná. To znamená, že metóda main musí byť statická, aby bola dostupná systému Java na úrovni triedy, a nie na úrovni konkrétnej inštancie. Statická metóda môže byť volaná bez toho, aby bola vytvorená inštancia triedy, čo je presne to, čo sa deje pri spustení programu.
Tým, že je metóda main statická, umožňuje systému Java spustiť program bez toho, aby musel vytvárať inštanciu triedy, a zároveň umožňuje prístup k metóde na úrovni triedy, čo je potrebné pre správne spustenie programu.
Vy čekáte od ChatGPT vysvětlení? Vždyť je to skvělý nástroj, pokud potřebujete něco okecat.
Jinak vytvořit instanci by samozřejmě šlo. Ale proč? Má smysl vytvářet i další instance té třídy? Jestli ne, pak je rozdíl mezi statickou a nestatickou metodou nebo proměnnou dost kosmetický.
Co když z té třídy s metodou main něco odvodím. Bude se vytvářet báze nebo ta odvozená? "A metoda main musí být ve třídě, která je (z neznámého důvodu) final." :)
Jak dlouho ta třída žije? Bude se na ní volat finalize?
Ve výsledku bu to byla další neviditelná funkcionalita s hromadou dodatečných pravidel.
Asi proto, že se na to nikdo nezeptal.
Důvod je ten, že když chcete vytvořit instanci třídy, musíte vědět jak. Konstruktorem, tovární metodou, builderem? Asi byste řekl, že konstruktorem. Pak ale ta třída musí mít veřejný bezparametrický singleton. A bude třeba velmi komplikované z toho udělat singleton. Takže byste musel přidat spoustu dalších pravidel a programátorům byste svázal ruce. Ale proč? Aby se při zápisu ušetřilo jedno klíčové slovo?
Bingo! Už som si myslel, že som tu sám. Google/GTP musí človek používať ako pomôcku, nemôže to preberať nekriticky. Musíme naďalej rozmýšľať. Pretože oba nástroje sú jednak omylné a jedna podsúvajú nejakú agendu či ideológiu. A to platí aj v technických smeroch.
Celé toto "vysvetlenie" je len dôsledkom pôvodných návrhových rozhodnutí, ktoré zaviedli ktovie prečo. Možno preto, že v 90 rokoch tak letelo OOP a preto všetko musí byť strašne objektovo.