Ideálny programovací jazyk

Re:Ideálny programovací jazyk
« Odpověď #210 kdy: 15. 05. 2019, 15:23:39 »
Lepší by pochopitelně bylo přetížení operátoru ==.
Bylo by to lepší jen při pohledu z rychlíku. Myslím, že programátor například neočekává, že mu při použití operátoru vypadne výjimka.

Některé jazyky umožňují přetěžovat operátory, což pak vede k tomu, že programátor nikdy neví, co se při použití operátoru stane. Java byla navržena jako jednoduchá, takže tohle záměrně neumožnila – a jediné přetížené (ve smyslu „implementované kódem v metodách“) operátory v Javě jsou ty pracující se Stringy. Přičemž samotný objekt String je v Javě final a má speciální podporu kompilátoru. Nebo-li autoři specifikace mohli zaručit, že se metody Stringu implementující operátory budou chovat slušně a operátory nebudou mít žádné nečekané efekty. Pokud byste operátor == přetížil jako volání equals() (a třeba i ošetřil null hodnoty), pořád bude použití toho operátoru volat uživatelský kód, který může vyhazovat výjimky, dělat dotaz do databáze, equals() ani nemusí být komutativní.

Přetížený operátor == by teprve byl pořádně kontraintuitivní.
Tenhle problém ale není omezený jenom na operátory. V jazyce, který umožňuje přetěžovat operátory, může prase napsat třeba operátor +, který nic nesčítá. V jazyce bez přetěžování napíše stejné prase funkci nebo metodu "add", která bude matoucí úplně stejně. Zákaz přetěžování operátorů tu nepomůže.


Re:Ideálny programovací jazyk
« Odpověď #211 kdy: 15. 05. 2019, 15:24:12 »
Rozhodně je to nekonzistentní. že budou vestavěné typy a objekty podporovat jiné operace bych bral, že ale stejná operace funguje na obou jinak mi přijde jako past na nováčky.
To je jedna z těch variant, o které jsem psal – nepovolit operátor == pro reference. Ano, dávalo by to smysl, ovšem těžko to mohlo projít v době vzniku Javy. Tenkrát mnohým připadalo jako přílišné zjednodušení i to, že Java nepodporuje přetěžování operátorů. A kdybyste jim vzal i == (pro reference)…

Jinak nejde o vestavěné typy ale o primitivní typy. String je také vestavěný typ, ale je to objekt.

Intuitivní by mi přišlo mít dvě porovnání, jedno na identitu a jedno na hodnotu, a nechat je chovat se konzistentně pro všechno. Samotná syntaxe těch dvou porovnání už je vlastně detail.
Pro primitivní typy není rozdíl mezi identitou a hodnotou.

Ve skutečnosti je problémem Javy existence primitivních typů, všechno ostatní, o čem píšeme, jsou až důsledky. Jenže to víme dnes – v době vzniku Javy byly primitivní typy považované za nezbytné, aby aplikace vůbec mohla mít nějaký výkon. Taky se tenkrát nepočítalo s tím, že JVM bude provádět nějaké velké optimalizace – takže to, že by JVM interně objektový integer nahradila jednoduchým typem bylo z říše snů. Primitivní typy v Javě byly už tenkrát vnímány jako ústupek, ale byl to ústupek tomu, aby (tehdy) Java byla vůbec nějak použitelná.

Re:Ideálny programovací jazyk
« Odpověď #212 kdy: 15. 05. 2019, 15:26:42 »
Tenhle problém ale není omezený jenom na operátory. V jazyce, který umožňuje přetěžovat operátory, může prase napsat třeba operátor +, který nic nesčítá. V jazyce bez přetěžování napíše stejné prase funkci nebo metodu "add", která bude matoucí úplně stejně. Zákaz přetěžování operátorů tu nepomůže.
Operátory programátor vnímá jako součást jazyka a očekává od nich, že budou dělat to, co se od nich intuitivně čeká, a že se budou chovat slušně. I když C++ programátoři pravděpodobně čekají čertoviny i od operátorů. U metod naopak každý počítá s tím, že je to uživatelsky implementovaný kód a může dělat cokoli.

Re:Ideálny programovací jazyk
« Odpověď #213 kdy: 15. 05. 2019, 15:42:18 »
Lepší by pochopitelně bylo přetížení operátoru ==.

Nesouhlasím. Ale ano, potom bychom se dostali do situace, že by se to Javě omlacovalo o hlavu jako třeba JavaScriptu. :)

Re:Ideálny programovací jazyk
« Odpověď #214 kdy: 15. 05. 2019, 15:42:50 »
Tenhle problém ale není omezený jenom na operátory. V jazyce, který umožňuje přetěžovat operátory, může prase napsat třeba operátor +, který nic nesčítá. V jazyce bez přetěžování napíše stejné prase funkci nebo metodu "add", která bude matoucí úplně stejně. Zákaz přetěžování operátorů tu nepomůže.
Operátory programátor vnímá jako součást jazyka a očekává od nich, že budou dělat to, co se od nich intuitivně čeká, a že se budou chovat slušně. I když C++ programátoři pravděpodobně čekají čertoviny i od operátorů. U metod naopak každý počítá s tím, že je to uživatelsky implementovaný kód a může dělat cokoli.
Tak tady bych silně nesouhlasil. Jsem C++ programátor a od operátorů očekávám, že čertoviny dělat nebudou. A taky ve všech knihovnách, které používám, žádné čertoviny nedělají. Úplně stejně očekávám od metod, že budou dělat to, co vyplývá z jejich jména. Ano, bugy se vyskytují, ale to i v součástech jazyka, takže tam rozdíl není.
Opravdu Javisti automaticky počítají s tím, že uživatelsky implementovaný kód může dělat cokoliv? Na takovéhle prasení vážně nejsem zvyklý a celkem mě překvapuje.


Re:Ideálny programovací jazyk
« Odpověď #215 kdy: 15. 05. 2019, 15:51:24 »
To, že operátor == v Javě porovnává hodnoty primitivních typů a reference u objektů mi nijak neintuitivní nepřipadá.
Je to kontraintuitivni - jestlize o Jave nic nevim, muzu si rict tak leda "WTF" - vubec me nenapadne, proc by se to jednou melo chovat tak a jindy jinak.

Uz to samotne vase "jenom pro větší čísla" ukazuje na neco, co vypada divne. "Vetsi cisla"? To je co? Vime to? Je to nekde v dokumentaci? Nebo se to chova "nahodne" (podle toho, jak velky je zrovna ten pool)?


Kdo o Javě nic neví, tak musí pochopit, že == na objektech porovnává reference. A že pokud porovnává objekty, které neudělal, tak je to implementačně závislá věc. Ten efekt se může dít u jakékoli knihovny apod.

Myslím, že u jakékoli jiné implementace toho operátoru bych musel napsat mnohem víc, abych vysvětlil jeho chování. A že takové jazyky máme a jsou i rozšířené :-)

gill

  • ****
  • 270
    • Zobrazit profil
    • E-mail
Re:Ideálny programovací jazyk
« Odpověď #216 kdy: 15. 05. 2019, 16:02:35 »
Lepší by pochopitelně bylo přetížení operátoru ==.

Nesouhlasím. Ale ano, potom bychom se dostali do situace, že by se to Javě omlacovalo o hlavu jako třeba JavaScriptu. :)

JS pretezovani operatoru take neumoznuje.

Re:Ideálny programovací jazyk
« Odpověď #217 kdy: 15. 05. 2019, 16:11:48 »
Tak tady bych silně nesouhlasil. Jsem C++ programátor a od operátorů očekávám, že čertoviny dělat nebudou. A taky ve všech knihovnách, které používám, žádné čertoviny nedělají.
Třeba to, že se operátor > používal pro zápis do streamu (což je blokující operace, navíc může vyhodit výjimku), tu už se v C++ nedělá?

Úplně stejně očekávám od metod, že budou dělat to, co vyplývá z jejich jména.
To já také. Jenže u spousty typů je tolik různých variant, co může dělat add() nebo equals()… Třeba máte dvě instance reprezentující v DOM následující dva XML elementy:

Kód: [Vybrat]
<f:element xmlns:f="http://example.com/namespace" />
<x:element xmlns:x="http://example.com/namespace" />

equals() vracet true nebo false?

Opravdu Javisti automaticky počítají s tím, že uživatelsky implementovaný kód může dělat cokoliv? Na takovéhle prasení vážně nejsem zvyklý a celkem mě překvapuje.
S tím počítají všichni dobří programátoři. Nejde o to, že by ten kód dělal něco nepředvídatelného (i když i to se stává). Ale když mám třeba kolekci, za kterou mám lokální nebo dokonce síťovou databázi, počítám s tím, že volání add() může trvat dlouho nebo může skončit třeba síťovou výjimkou. Když volám equals() na databázové entitě, ověřím si, zda se identita zjišťuje podle primárního klíče, podle hodnot nebo podle čeho. A tak dále. U operátoru ale čekám, že budou jednoduché, nebudou blokovat, nebudou vyhazovat výjimky, budou mít jednoznačný význam. V tom je operátor == v Javě opravdu trochu nešťastný, protože tam je potřeba vědět, že porovnává reference. Ale zrovna C++ to má stejně, nemýlím-li se.

Re:Ideálny programovací jazyk
« Odpověď #218 kdy: 15. 05. 2019, 16:13:12 »
JS pretezovani operatoru take neumoznuje.
Sice ne, ale zrovna pro JavaScriptové == existuje spousta takových těch příkladů–chytáků, kdy se máte snažit uhodnout, jak se ten kód vyhodnotí – a málokdo to trefí.

Re:Ideálny programovací jazyk
« Odpověď #219 kdy: 15. 05. 2019, 16:27:55 »
JS pretezovani operatoru take neumoznuje.

To nepopírám, ani netvrdím opak. Spíš jsem tím myslel to, že se JavaScriptu == a === vyčítá. :)

Re:Ideálny programovací jazyk
« Odpověď #220 kdy: 15. 05. 2019, 16:35:36 »
Jenže on neporovnává dvě čísla, ale dvě reference.
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.

protože operátory jsou vždy v nějakém případě kontraintuitivní
Můžete uvést příklad z Elixiru nebo Rustu?

moznych jinych reseni
lepších řešení?
Nebyl jste to vy, kdo mi vyčítal, že mluvím za vás a podsouvám vám něco, co jste netvrdil?

BoneFlute

  • *****
  • 2 046
    • Zobrazit profil
Re:Ideálny programovací jazyk
« Odpověď #221 kdy: 15. 05. 2019, 16:39:13 »
To, že operátor == v Javě porovnává hodnoty primitivních typů a reference u objektů mi nijak neintuitivní nepřipadá.
Je to kontraintuitivni - jestlize o Jave nic nevim, muzu si rict tak leda "WTF" - vubec me nenapadne, proc by se to jednou melo chovat tak a jindy jinak.

Uz to samotne vase "jenom pro větší čísla" ukazuje na neco, co vypada divne. "Vetsi cisla"? To je co? Vime to? Je to nekde v dokumentaci? Nebo se to chova "nahodne" (podle toho, jak velky je zrovna ten pool)?


Kdo o Javě nic neví, tak musí pochopit, že == na objektech porovnává reference. A že pokud porovnává objekty, které neudělal, tak je to implementačně závislá věc. Ten efekt se může dít u jakékoli knihovny apod.

Myslím, že u jakékoli jiné implementace toho operátoru bych musel napsat mnohem víc, abych vysvětlil jeho chování. A že takové jazyky máme a jsou i rozšířené :-)

Myslím, že vzhledem k tématu tohoto vlákna je to jedno, proč to Java má tak jak to má. Intuitivní to není, a to je to, oč tu běží. Já bych takovouto schízu v Ideálním jazyce nechtěl.

Re:Ideálny programovací jazyk
« Odpověď #222 kdy: 15. 05. 2019, 16:58:02 »
Tak tady bych silně nesouhlasil. Jsem C++ programátor a od operátorů očekávám, že čertoviny dělat nebudou. A taky ve všech knihovnách, které používám, žádné čertoviny nedělají.
Třeba to, že se operátor > používal pro zápis do streamu (což je blokující operace, navíc může vyhodit výjimku), tu už se v C++ nedělá?
Zrovna iostreamy jsou obecně jedna z nejhůř navržených (a taky nejstarších) částí standardní knihovny obecně. Na druhou stranu zrovna tady je z kontextu dost jasné, že tenhle operator<< opravdu nedělá nic jako bitový posun. Naproti tomu se potkávám se spoustou matematických knihoven, kde operátory dělají přesně to, co od nich intuitivně čekám.
Citace
Úplně stejně očekávám od metod, že budou dělat to, co vyplývá z jejich jména.
To já také. Jenže u spousty typů je tolik různých variant, co může dělat add() nebo equals()… Třeba máte dvě instance reprezentující v DOM následující dva XML elementy:

Kód: [Vybrat]
<f:element xmlns:f="http://example.com/namespace" />
<x:element xmlns:x="http://example.com/namespace" />

equals() vracet true nebo false?
No ale tohle je přesně to, na co narážím. Funkce equals nebo operátor== můžou být úplně stejně neintuitivní a matoucí. Zákaz přetěžování operátorů nevyřeší vůbec nic. Když autor knihovny pojmenuje funkci blbě, tak je vlastně úplně jedno jaké přesné ascii znaky to jsou.
Citace
Opravdu Javisti automaticky počítají s tím, že uživatelsky implementovaný kód může dělat cokoliv? Na takovéhle prasení vážně nejsem zvyklý a celkem mě překvapuje.
S tím počítají všichni dobří programátoři. Nejde o to, že by ten kód dělal něco nepředvídatelného (i když i to se stává). Ale když mám třeba kolekci, za kterou mám lokální nebo dokonce síťovou databázi, počítám s tím, že volání add() může trvat dlouho nebo může skončit třeba síťovou výjimkou. Když volám equals() na databázové entitě, ověřím si, zda se identita zjišťuje podle primárního klíče, podle hodnot nebo podle čeho. A tak dále. U operátoru ale čekám, že budou jednoduché, nebudou blokovat, nebudou vyhazovat výjimky, budou mít jednoznačný význam.
No když mám objekt, co se tváří třeba jako matice, tak od + i od add budu čekat sčítání matic. Ani v jednom případě nebudu očekávat komunikaci se vzdálenou databází. Naopak kolekce, která potichu komunikuje s nějakou vzdálenou databází je dost zákeřná, pokud se tváří jako nějaká obyčejná. Tohle zase nemá s operátory společné prakticky nic.
Citace
V tom je operátor == v Javě opravdu trochu nešťastný, protože tam je potřeba vědět, že porovnává reference. Ale zrovna C++ to má stejně, nemýlím-li se.
V C++ se operátor== obvykle přetěžuje tak, aby porovnával hodnoty. Obecně je v C++ zvykem, pokud to jenom trochu jde, aby se všechno chovalo jako vestavěné typy. Ale c++ rozlišuje samotný objekt od ukazatele na něj. Takže nemusím vůbec řešit, jak porovnávat identitu dvou objektů. Porovnávám jejich adresy resp. hodnoty dvou ukazatelů.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Ideálny programovací jazyk
« Odpověď #223 kdy: 15. 05. 2019, 16:59:20 »
Jenže on neporovnává dvě čísla, ale dvě reference.
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.
To je ale jedno, ne? Prostě to je oficiálně nedefinované.

Re:Ideálny programovací jazyk
« Odpověď #224 kdy: 15. 05. 2019, 17:03:58 »
To je ale jedno, ne? Prostě to je oficiálně nedefinované.
Nevím jestli je to jedno a jestli zrovna tohle je vhodné nechat nedefinované.

Třeba ty zmíněné atomy v Erlangu jsou taky vnitřně uložené jako integery (takže obdoba ukazatelů), ale je jasně zadefinované, že když vytvářím atom třeba ze stringu, tak buďto v "cachi"/"poolu" už je, potom se ten integer zaručeně použije, nebo tam není, tak se vytvoří a pro příští volání se stejnou hodnotou bude platit první varianta.

Jasně, určitě existuje bambilion argumentů, proč to tak (alespoň v některých implementacích) javy není, nehodlám s nimi polemizovat. Čistě s BoneFlutem konstatuju, že mě by tohle v jazyce, ve kterém bych dělal, otravovalo.