Zobrazit příspěvky

Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.


Příspěvky - Filip Jirsák

Stran: 1 ... 164 165 [166] 167 168 ... 375
2476
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 23:37:45 »
Ještě abyste pochopil ten rozdíl:

Kód: [Vybrat]
assert !(new Integer(1) == new Integer(1));
boolean b = Integer.valueOf(1) == Integer.valueOf(1);
assert b || !b;

Na prvním řádku se vytvářejí dvě instance, musí to tedy být dvě různé reference. Operátor == u objektů porovnává reference, takže rovnost na prvním řádku nikdy nemůže být splněna.

Na druhém řádku se volá statická metoda, ta mi vrátí nějakou referenci. Nikde není řečeno, zda pro stejné hodnoty to bude vracet jeden objekt nebo dva různé objekty. V té metodě klidně může být orákulum, které vám v polovině případů bude vracet objekt z poolu a v druhé polovině případů nové instance. Takže o té rovnosti nelze bez znalosti konkrétní implementace rozhodnout, zda platí nebo neplatí.

2477
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 23:30:24 »
Filip má velmi efektivní selektivní vnímání ;)
Nikoli, já pouze vím – na rozdíl od vás – jak to funguje.

2478
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 23:29:20 »
Omyl. Můžu si myslet, že to má Java vyřešeno stejně dobře jako Erlang atomy. Napíšu si na to i unit testy, ale jako na potvoru tam použiju "malá" čísla. A na produkci se objeví "velká" čísla.

Byla to neznalost programátora? Ano.  Byla to chyba programátora? Ano.

Programátor si myslel, že konstrukci rozumí a dokonce to i byla pravda - chtěl porovnávat reference (!!!) ). Co neznal, byly internals implementace poolu "malých" hodnot.

Byl jazykem překvapen? Byl. Má ideální jazyk programátora překvapovat? Nemá.

Zopakuje Filip Jirsák po stopadesáté první, že někdo nechápe rozdíl mezi referencí a hodnotou a s poolem to nemá co dělat? Nevíme, ale je to velmi pravděpodobné.
Když ono to z vašich komentářů opravdu vypadá, že netušíte, o čem píšete.

Napsal jste, že programátor chtěl porovnávat reference. A pomocí == opravdu reference porovnává. Byla to neznalost programátora? Ne. Byla to chyba programátora? Ne. Fungoval mu program správně v testu s malými čísly? Ano. Fungoval mu správně na produkci s velkými čísly? Ano. Vracelo porovnání true, když byly reference stejné? Ano. Vracelo porovnání false, pokud byly reference jiné? Ano. Snažil se Mirek Prýmek popsat nějaký problematický příklad, a přitom popsal příklad, ve kterém je vše v pořádku, vše funguje správně a podle programátorova očekávání? Ano.

Jediná chyba tedy byla v tom, že jste si myslel, že je tam něco špatně. Takže mi z toho vychází akorát: Rozumí Mirek Prýmek rozdílu mezi hodnotou a referencí v Javě, rozumí tomu, jak funguje pool Integerů? Ne.

Další váš omyl je v tom, že píšete o jazyce. Pool Integerů není žádná vlastnost jazyka, je to normálně implementované ve třídě Integer (a podobně ve třídě String). Nic vám nebrání, abyste si takovou třídu napsal sám, občas se to používá.

Podívejte se do implementace metody Integer.valueOf(int), jak je to naprogramované. Celý ten zázrak má tři řádky:

Kód: [Vybrat]
if (i >= IntegerCache.low && i <= IntegerCache.high)
  return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);


Ok. A ten příkad teda?
Ten následoval hned po té části, kterou jste citoval.

Nevím, proč bysme měli. Třídy ekvivalence mají být součástí definice typu. Jistě, jsou situace, kdy se dají nadefinovat různě. To už je na programátorovi, jak si je chce nadefinovat. Ale nevidím v tom sebemenší problém, natož abychom na něj "vždy naráželo".
Ano, takže jste sám potvrdil, že intuitivnost ekvivalence naráží na to, že pro stejné typy dávají smysl různé třídy ekvivalence. Můžete si sice nadefinovat, že Zlomek1 porovnává zlomek po převedení do základního tvaru a Zlomek2 porovnává zlomky tak, jak jsou, ale intuitivní to není. A pak si ještě zkusíte porovnat Zlomek1 se Zlomkem2, a vzápětí Zlomek2 se Zlomkem1, a máte z toho pořádný guláš.

2479
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 23:08:53 »
U zlomků by jeden očekával algebraickou rovnost
Myslím, že kdybyste ve zdrojáku napsal 2/4 a TeX by vám to vysázel jako 1/2, velice rychle byste změnil názor.

u floatu se taky rovná 1.2 a 1.2000000, pokud na ně tedy neudělám napřed toString(), hejže?
Po té, co se začínající programátoři v druhé lekci dozví, jaký je rozdíl mezi hodnotou a referencí, a že objekty nikdy nemají porovnávat pomocí ==, hned ve třetí lekci se dozví, že floaty se nikdy neporovnávají na rovnost. float 1.2 se nerovná floatu 1.2000000. A to není žádná specialita Javy, tak to mají všechny jazyky, které používají čísla s plovoucí čárkou dle IEEE-754.

Ostatně moderní jazyky to takto mají právě z toho důvodu, že to dává největší smysl.
Problém je v tom, že někdy prostě nejde vybrat, co dává největší smysl. Uváděl jsem tu příklad s elementem z DOM XML – tam dávají stejný smysl všechny tři varianty. Porovnávat identitu, porovnávat název elementu a jmenný prostor, a porovnávat název elementu, jmenný prostor i prefix jmenného prostoru.

2480
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 23:01:01 »
Neřešíme už tu několik stránek to, že přesně tohle se v Javě děje? Vestavěné typy se porovnávají podle hodnoty a naše podle reference. ::)
Ne, neděje. Už jsem to psal několikrát, primitivní typy se porovnávají podle hodnoty, objekty se porovnávají podle reference. String je taky vestavěný typ, ale je to objekt, takže se porovnává podle reference. Java obecně se hodně snaží vyhýbat magii s vestavěnými typy a pojem „vestavěný typ“ se u Javy ani nepoužívá. Vlastně jediná „magie“, která mne napadá, je sčítání řetězců. Jinak se v Javě snad všechno tváří jako uživatelské typy – jako třídy, které by mohly být kompletně implementovány koncovým programátor.

2481
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 22:55:39 »
Pokud implementuju zlomky, pak je to stejné.
A nebo různé, záleží na okolnostech. Třeba když budu implementovat systém pro matematickou sazbu (TeX), rozhodně nechci, aby mi klidně místo 2/4 vysázel 1/2, protože je to přece stejné.

Jsou stejné. Liší se počet bytů, ne znaků. Našemu pojmu znak (ve významu používaném v běžném životě) spíš odpovídá pojem grapheme cluster, které mají oba řetězce po jednom. Zase je to o tom, jestli chci pracovat s textem, nebo polem bytů a tohle už můžu odlišit na úrovni typového systému.
Neliší se jen počet bytů, liší se i počet znaků. V první textu je jeden znak „č“, v druhém textu jsou dva znaky – malé „c“ a za ním háček pro kombinování. Aby byly ty řetězce shodné i na počet znaků, musíte nejprve provést jejich normalizaci – pak budou opravdu na bit stejné. Ale opět – někdy nechcete provádět žádnou normalizaci, někdy chcete provádět standardní normalizaci Unicode, a někdy chcete řetězce porovnávat třeba bez ohledu na velikost písmen a na diakritiku.

Je to jen aplikace unboxingu konkrétních typů na další operátor. Když se to může dít  při jiných operacích (přiřazování, vkládání parametrů), je jen věcí dohody, že se to může dít i při porovnávání.
Unboxing se neaplikuje na operátory, ale na výskyt konkrétních hodnot (konstant nebo proměnných). A unboxing se v Javě nikdy nedělá svévolně, že by kód byl validní i bez unboxingu, ale kompilátor se rozhodl, že typy změní. Autoboxing/unboxing se aplikuje jedině v případě, že daný kód nejde přeložit, ale aplikováním boxingu/unboxingu přeložit půjde. Tedy se aplikuje jenom tam, kde je ve zdrojovém kódu nesoulad typů, např. máte metodu, která má jako parametr velký Integer, ale cpete do něj malý int. Na kódu Integer == int se uplatní, protože jinak by to nešlo přeložit. Integer == Integer je ale validní javovský kód, a kompilátoru nepřísluší hodnotit, jak moc je takový kód pravděpodobný.

2482
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 22:25:31 »
Ztracim se. Prece se tu rikalo, ze problem neni v tom operatoru, ale v te kesi....
Ne,v keši žádný problém není. Problém je jenom v programátorovi, který použil špatný operátor, když měl použít metodu equals().

2483
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 22:20:19 »
V javě sice neprogramuju, ale z mého pohledu není problém samotné chování "==" ale spíš kombinace s umožněním zápisu:
    Integer a = 1024;
Vlevo objekt, vpravo primitivní typ, já bych už křičel při syntaktické kontrole, že správně má být něco jako:
    Integer a;
    a.value = 1024;
nebo
    Integer a = {value:1024};
Pak to upozorní každého, že Integer není int.
Dříve to tak v Javě bylo. Když se zjistilo, že primitivní typy byly omyl, zavedl se autoboxing/unboxing, kdy se mezi primitivním typem a jeho objektovou variantou převádí automaticky. Tohle je jeden důsledek. Kde kdo tvrdí, jak je Java ukecaná, a když se nějaký zápis vynechá, je to taky špatně… Ale v praxi tohle žádný problém není, protože programátoři za prvé vědí, že == porovnává reference, za druhé se objektové Integery používají nejčastěji pro identifikátory (např. databázové – protože umožňují mít null pro nové entity bez identifikátoru), které se v aplikaci málokdy porovnávají. A za třetí při porovnání referencí  vás bude varovat IDE, protože je to opravdu jen výjimečná operace a takové použití spíš vypadá na chybu.

Nebo kompilátoru vysvětlit, že pro konkrétní vestavěné objektové typy se == prostě automaticky používá na hodnoty a ne na reference. Protože nevím o žádném smysluplném důvodu porovnávat reference na dva objekty typu Integer.
To by teprve byl zmatek, kdyby se objekty někdy porovnávaly podle reference a někdy podle hodnoty.

2484
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 22:11:21 »
Hodnota není až takový problém.
Každý složený datový typ jde porovnat prvek po prvku. Invarianty na tom nic nezmění, ty jenom vyloučí některé možnosti. Navíc se takovéhle porovnání dá generovat i automaticky.
Co tím může zamíchat je zavedení nějakých tříd ekvivalence (zlomky, floaty). Nejjednodušší způsob, jak je zavést konzistentně je nějaká forma normalizace.
Problém je, že těch tříd ekvivalence často může být několik. Prostě někdy chcete, aby 1/2 byla to samé jako 2/4, a někdy to nechcete.

Definice == na řetězcích nebo celých číslech tak, aby se porovnávala hodnota, je intuitivnost sama, nic intuitivnějšího nejde vymyslet. Pokud někdo obhajuje nesmysl, je buď fanatik, nebo prostě mimo.
Vážně? A jak daleko s tím chcete zajít? Co třeba zlomky? Ostatně problém jsou i ty řetězce – jsou řetězce „č“ a „č“ stejné? Jsou? A neměly by stejné řetězce mít stejný počet znaků? První má jeden znak, druhý dva…

2485
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 21:53:34 »
No já Javu znám těžce okrajově, ale to "to ničemu nevadí" tak, z předcházející diskuze, nevypadá, když má vliv na návratové hodnoty operátoru.
Nemá vliv na návratové hodnoty operátoru. Operátor == v Javě při použití na objekty porovnává reference. Integer ani String nejsou definovány jako singletony, takže v běžící aplikaci může existovat víc instancí, které shodou okolností obsahují stejnou hodnotu. Pokud tedy operátorem == porovnávám reference ukazující na stejnou hodnotu, je věcí náhody, zda dostanu true nebo false. Pool opakovaně používaných instancí akorát zvyšuje pravděpodobnost, že se pro stejnou hodnotu použijí stejné instance, ale nikdo nemůže zaručit, že nevznikne jiná instance se stejnou hodnotou.

Každopádně pokud někdo chce v Javě porovnávat hodnoty objektů a použije ==, je to těžce začátečnická chyba. Připadá mi zbytečné pořád dokola řešit, co se stane, když někdo takovouhle hrubou chybu udělá. Je to jako bychom řešili, že někdo chtěl dvě čísla sečíst a místo toho je odečetl, a pak bychom dlouze zkoumali, jak moc je matoucí, že pokud byl druhý operátor 0, dostal přesto správný výsledek.

Ano, v Javě a v mnoha dalších jazycích když se použije == pro porovnání referencí, ale programátor si bude myslet, že porovnává hodnoty, může někdy dostat „správný“ výsledek (tedy ten, který by dostal při porovnání hodnot). Každý, kdo chce programovat v jazyku, kde == porovnává reference, ale tohle musí vědět. Na rozdíl mezi == a equals() se ptáme u pohovorů na juniorní programátory těch uchazečů, u kterých vidíme, že s programováním začínají. Pokročilejšího juniora bych se styděl na takovou samozřejmost zeptat.

2486
Server / Re:Email z cronu přes vzdálený SMTP server
« kdy: 15. 05. 2019, 21:28:31 »
u msmtp (kterej mi prijde(narozdil od OpenSMTPd) na prvni pohled stejne light a easy jako ssmtp)
Souhlas.

vidim alespon moznost pouzit script msmtp-queue (soucast msmtp baliku) kterej zajistuje frontu
Jo, to jsem si říkal, jestli některý z nich neumí neodeslané e-maily alespoň zapsat lokálně do fronty. Protože správce toho SMTP klienta bude obvykle ten samý, jako správce hlavního poštovního serveru, o jeho nedostupnosti by se měl dozvědět, takže pak není problém to odbavení fronty spustit ručně. A nebo ho třeba spouštět cronem. msmtp-queue mi připadá jako dostatečně robustní řešení, které je ale pořád jednoduché a obejde se bez trvale běžícího serveru.

2487
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 20:56:44 »
Nebo jednou větou: podle mě by to singleton buď měl nebo neměl být z definice.
O Integeru a Stringu v Javě nikdy nikdo netvrdil, že je to singleton. Naopak třeba enumy jsou singletony. A že mají třídy Integer a String optimalizaci a někdy použijí už existující instanci, když je to možné, to ničemu nevadí, protože –jak praví klasik – na funkci to nemá vliv. Ale v žádném případě to z těch instancí nedělá singletony.

2488
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 20:48:38 »
Připomínám předmět vlákna. Bavíme se o ideálním jazyce. Ne o nejhorších možných, na které si člověk může vzpomenout. C, C++, JavaScript jsou všechno možné, jen ne nematoucí.
Už dlouho se tu řeší jedna odbočka. Bavíme se tu o Javě, C, C++, JavaScriptu, takže je snad každému jasné, že ideální programovací jazyk se tu opravdu neřeší.

Nemohu souhlasit. Stačí se na to dívat tak, že porovnáváte hodnotu versus identitu, a není problém.
Je to problém, protože u spousty struktur nedokážete určit ani co je to ta identita, o hodnotě ani nemluvě.

2489
Server / Re:Email z cronu přes vzdálený SMTP server
« kdy: 15. 05. 2019, 20:44:56 »
Doporučil bych zvážit si, jak moc mi na samotné existenci nebo obsahu odesílaných mailů záleží. Protože tyhle klientské "hračky" jako ssmtp v případě neúspěchu při odesílání mailu jej neumí uložit do nějaké fronty a za čas pokus o odeslání opakovat. Když ten server na druhé straně je zrovna odstavený nebo z jakéhokoliv důvodu dočasně nepřijímá, tak maily budou mizet v černé díře.

OpenSMTPD má v cílech uvedeno, že nemá ztrácet e-maily, které potvrdí k odeslání, a má umět zpracovat i dlouhou frontu e-mailů. Takže předpokládám, že frontu má.

Mně to ale připadá spíš jako nevýhoda – výhoda těchhle jednoduchý klientů je právě to, že tam nemusí trvale běžet žádný proces. Pokud je ta zpráva tak důležitá, že o ní nechci přijít, stejně bych ji logoval i lokálně a nespoléhal bych na to, že ten e-mail vždy dorazí. On se může ztratit i kdykoli dál po cestě, ne jen na prvním hopu.

Ale je to dobrá připomínka a každý by si měl zvážit, jak pravděpodobné je, že primární poštovní server vypadne, a zda pak může o ty e-maily přijít. Vlastně mne trochu překvapuje, že ani ssmtp ani msmtp nepodporují fallback na záložní server. Když už chci u e-mailu řešit vysokou dostupnost, udělám to právě druhým serverem – protože protokoly doručování e-mailů tuhle moderní fíčuru (vysokou dostupnost) podporují už víc než třicet let.

2490
Vývoj / Re:Ideálny programovací jazyk
« kdy: 15. 05. 2019, 20:25:59 »
V tom ale ten problém není, to tady všichni chápeme, i když se vám třeba zdá, že ne. Problém je v tom poolu konstant, u kterého nikdy nevím (?), jestli tam to číslo je nebo ne.
No evidentně to problém je. V tom poolu konstant žádný problém není – když chápete rozdíl mezi hodnotou a referencí, nemůžete hodnotu Integerů nikdy porovnávat pomocí ==. Tím pádem nikdy nezjistíte, jestli tam nějaký pool konstant je nebo není. A když rozdíl mezi hodnotou a referencí nechápete a budete používat == pro porovnání hodnot objektů, bude ten kód špatně bez ohledu na to, zda pool konstant existuje nebo neexistuje.

protože operátory jsou vždy v nějakém případě kontraintuitivní
Můžete uvést příklad z Elixiru nebo Rustu?
Tak třeba Rust má spoustu operátorů, které nejsou vůbec intuitivní, to je problém sám o sobě. Ale pokud vím, některé operátory se tam dají přetěžovat, včetně ==, což nás vrací zpět na začátek této diskuse – každý operátor rovnosti, který podporuje i něco jiného, než primitivní typy, je kontraintuitivní, protože u složitějších typů vždy narazíme na to, že prostě není jasné, co je to rovnost. No a když je někde == definováno jenom pro primitivní datové typy, pro někoho bude kontraintuitivní, že pro „jednoduché ne-primitivní“ typy nebude definován. Kdyby Java podporovala == jen pro primitivní typy, byl by tu úplně stejný komentář Johnyho, akorát by se podivoval, proč to kompilátor nepřeloží.

Kontraintuitivní jsou vlastně i všechny jazyky, které mají operátor / pro celočíselné operandy definován jako celočíselné dělení. V tomto případě je vítězem JavaScript :-)

Nebyl jste to vy, kdo mi vyčítal, že mluvím za vás a podsouvám vám něco, co jste netvrdil?
Horší řešení nás v této diskusi nezajímají. Stejně dobrá vlastně taky ne, protože z těch stejně dobrých řešení se jedno muselo vybrat – ale pokud máte další stejně dobrá řešení, sem s nimi.

Stran: 1 ... 164 165 [166] 167 168 ... 375