Ideálny programovací jazyk

Re:Ideálny programovací jazyk
« Odpověď #240 kdy: 15. 05. 2019, 21:40:18 »
Je to problém, protože u spousty struktur nedokážete určit ani co je to ta identita, o hodnotě ani nemluvě.
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.
Pokud nějaký objekt nemá jít porovnat hodnotou, tak je to spíš proto, že to má být neprůhledný blackbox, než že by ani interně žádnou hodnotu neměl.


Re:Ideálny programovací jazyk
« Odpověď #241 kdy: 15. 05. 2019, 21:43:29 »
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í.

On existuje jazyk, který je ve všem nematoucí?

To samozřejmě netuším. Ale domnívám se, že některé jazyky jsou na tom výrazně hůře, než jiné. (Nebo narážíš na ten dvojitej zápor? :-P)

Ne, dvojité zápory mi nevadí. :) Mohl bys to s těmi některými jazyky trochu rozvést? Opravdu mě to zajímá, protože třeba když jsem nad tím přemýšlel, tak v jisté chvíli jsou matoucí jazyky všechny... byť je pravda, že některé třeba ze začátku, jiné později... vyjma Prologu, ale ten dělali Francouzi...  ;D

Zmínil bych Haskell. Ten mi přijde těžkej, ale matoucí ne. Většinou jsem se dostal do situace, kdy jsem si říkal, že jsem prostě jen málo inteligentní. Ale, že by dělal něco nelogického, nebo matoucího, to ne.

Z opačné barikády bych zmínil jazyk Lua. Občas jsem tam narážel na to, že mi něco scházelo, nebo tak. Ale že bych měl potřebu mu něco vytýkat, to ne.

Z novějších jazyků nemůžu sloužit. Nemám je ještě tak pod kůží.

Ano, tak to se asi shodneme. Byť třeba čísla mi v Haskellu zpočátku nepřišla dvakrát intuitivní (fromIntegral, apod.). Ale ano, na tom jazyku se dost projevuje ta vyšší vstupní bariéra. :)

Pak je samozřejmě třeba definovat, co že to považujeme za matoucí, a jak moc. Zvyknout se dá na všechno :-)

+1

Re:Ideálny programovací jazyk
« Odpověď #242 kdy: 15. 05. 2019, 21:52:44 »
...

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.
Jakej vliv ma ta kes na navratove hodnoty operatoru?

Re:Ideálny programovací jazyk
« Odpověď #243 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.

Re:Ideálny programovací jazyk
« Odpověď #244 kdy: 15. 05. 2019, 21:56:25 »
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.

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.
« Poslední změna: 15. 05. 2019, 22:01:30 od Tomas-T »


Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Ideálny programovací jazyk
« Odpověď #245 kdy: 15. 05. 2019, 22:04:03 »
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.
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. I to blbé Go, které nemá obecné přetěžování operátorů, umí správně porovnat dva řetězce pomocí ==. Porovnání referencí na řetězcích nebo číslech je k ničemu, ostatně rozumné jazyky mají řetězce jako hodnotové typy. Některé tak mají i třeba kolekce (např. Swift), protože to dává ve většině případů větší smysl.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Ideálny programovací jazyk
« Odpověď #246 kdy: 15. 05. 2019, 22:05:11 »
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í.

On existuje jazyk, který je ve všem nematoucí?

To samozřejmě netuším. Ale domnívám se, že některé jazyky jsou na tom výrazně hůře, než jiné. (Nebo narážíš na ten dvojitej zápor? :-P)

Ne, dvojité zápory mi nevadí. :) Mohl bys to s těmi některými jazyky trochu rozvést? Opravdu mě to zajímá, protože třeba když jsem nad tím přemýšlel, tak v jisté chvíli jsou matoucí jazyky všechny... byť je pravda, že některé třeba ze začátku, jiné později... vyjma Prologu, ale ten dělali Francouzi...  ;D
Zmínil bych Haskell. Ten mi přijde těžkej, ale matoucí ne.
Spíš jen jinej.

BoneFlute

  • *****
  • 2 046
    • Zobrazit profil
Re:Ideálny programovací jazyk
« Odpověď #247 kdy: 15. 05. 2019, 22:05:48 »
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.

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 tě nezachrání:
Kód: [Vybrat]
Integer a = {value:1024};

// dlouhej kód
if (a == b) {
}

A v Javě je dlouhej kód úplně cokoliv :)

Re:Ideálny programovací jazyk
« Odpověď #248 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…

Re:Ideálny programovací jazyk
« Odpověď #249 kdy: 15. 05. 2019, 22:11:35 »
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.
Tohle už je flíkování, které jenom odsouvá problém dál. Ten problém vychází z toho, že jeden operátor dělá různé věci pro různé typy (jednou porovnává umístění, jindy co na tom místě leží). Systematické řešení by bylo vybrat jen jednu možnost.
V ideálním jazyce by nemělo jít poznat, jestli je nějaký typ vestavěný nebo implementovaný v knihovně.

Re:Ideálny programovací jazyk
« Odpověď #250 kdy: 15. 05. 2019, 22:15:10 »
To tě nezachrání:
Kód: [Vybrat]
Integer a = {value:1024};

// dlouhej kód
if (a == b) {
}

A v Javě je dlouhej kód úplně cokoliv :)
Nejde o záchranu, jde o to, že zápis Integer a = 1024 mě utvrzuje v tom, že s tím můžu pracovat jako s hodnotou, protože jsem tam vložil primitivní hodnotu.
Když v c# použiju typy Int16, Int32, Int64 tak jsou to myslím taky objekty (mají na sobě nějaké metody), ale při použití snad jakéhokoliv operátoru se chovají jko primitivní typy.

Re:Ideálny programovací jazyk
« Odpověď #251 kdy: 15. 05. 2019, 22:17:20 »
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.
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. I to blbé Go, které nemá obecné přetěžování operátorů, umí správně porovnat dva řetězce pomocí ==. Porovnání referencí na řetězcích nebo číslech je k ničemu, ostatně rozumné jazyky mají řetězce jako hodnotové typy. Některé tak mají i třeba kolekce (např. Swift), protože to dává ve většině případů větší smysl.

Ztracim se. Prece se tu rikalo, ze problem neni v tom operatoru, ale v te kesi....

Re:Ideálny programovací jazyk
« Odpověď #252 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.

Re:Ideálny programovací jazyk
« Odpověď #253 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().

Re:Ideálny programovací jazyk
« Odpověď #254 kdy: 15. 05. 2019, 22:28:51 »
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.
Pokud implementuju zlomky, pak je to stejné. Pokud implementuju dvojice čísel, pak je to různé. Rozliším to typovým systémem. Pokud se na to koukám jako na hodnoty, tak dává smysl i občasná konverze mezi tím zlomkem a dvojicí čísel.

Citace
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…
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.