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 - Idris

Stran: 1 ... 89 90 [91] 92 93 ... 153
1351
Děkuji za příspěvek.

Na jednu stranu je to co píšeš dost inspirativní. Na druhou stranu si nejsem úplně jist, zda tě dobře chápu.

Cítím v tvém popisu defer z Go. Taky mi přijde, že mluvíš vlastně o určité podobě transakcí - kód změní stav, a pokud vznikne chyba, tak se vrátí původní stav. Je to to co myslíš? Jak se práce se stavem promítne do věcí jako side effects (zapisování do souboru, posílání emailu)? Nechtěl by si napsat nějakou ukázku kódu, jak by to mělo fugovat?

To co popisuješ, existuje to v nějakém jazyce, nebo je to jen studie/úvaha?

Dělal jsem si jednu studii, kdy jsem měl jazyk, který si jednak hlídal při kompilaci, zda jsou všechny scénáře pokryty, zda nemůže dojít k nějaké neošetřené chybě. A dále si při každém spuštění apky kontroloval, zda jsou dostupné externí závislosti (nainstalované knihovny, dostupné externí rutiny/binárky, dostupnost k databázi, filesystému). Čímž jsem chtěl zajistit, aby vlastní běh té aplikace nemohl selhat.
Jestli by měl z mého příspěvku být cítit nějaký jazyk, tak C++. O exception safety se primárně mluví právě v souvislosti s c++ i když je to obecnější koncept. Ale právě v c++ je tohle uvažování vcelku běžné. Strong exception safety jsou transakce, jen se neřeší atomičnost z pohledu jiných vláken.

Zápis do souboru jako transakce je myslím poměrně známý postup :
- Vytvořím pomocný soubor zapíšu ho a flushnu na disk. Pokud tohle selže, pak je původní soubor stále netknutý.
- Přejmenuju pomocný soubor. Pokud má tahle operace strong exception safety, pak ji bude mít i celý zápis souboru.

A stejně se dá uvažovat i o jednotlivých objektech programu. Např při přidávání do dynamického pole mi může selhat alokace, nebo kopírování nějakého objektu. Takže alokuju nový kus paměti, všechno do něj nakopíruju a nakonec swapnu odkaz na nový blok paměti.

Obecně pokud mám swap, který dokáže prohodit vnitřnosti objektů bez možných výjimek, pak se na tom dá stavět transakční chování pro větší a větší bloky programu. A dobrým zvykem je, pokud je to možné, dávat vlastním objektům rozumný swap který jen prohodí ukazatele a nemůže házet.
Takže jsi myslel trasakčnost na úrovni jazyka a to včetně externích závislostí. Zajímavé.
Zajímavé je, jak by se něco takového provedlo v čistě funkcionálním kódu.
To mi moc zajímavé nepřijde. Funkcionální kód nemá efekty. Tudíž transakce je jednoduchá - zahodit ;-) (Tady trochu provokuju.)
Přesně to jsem myslel :)

1352
Děkuji za příspěvek.

Na jednu stranu je to co píšeš dost inspirativní. Na druhou stranu si nejsem úplně jist, zda tě dobře chápu.

Cítím v tvém popisu defer z Go. Taky mi přijde, že mluvíš vlastně o určité podobě transakcí - kód změní stav, a pokud vznikne chyba, tak se vrátí původní stav. Je to to co myslíš? Jak se práce se stavem promítne do věcí jako side effects (zapisování do souboru, posílání emailu)? Nechtěl by si napsat nějakou ukázku kódu, jak by to mělo fugovat?

To co popisuješ, existuje to v nějakém jazyce, nebo je to jen studie/úvaha?

Dělal jsem si jednu studii, kdy jsem měl jazyk, který si jednak hlídal při kompilaci, zda jsou všechny scénáře pokryty, zda nemůže dojít k nějaké neošetřené chybě. A dále si při každém spuštění apky kontroloval, zda jsou dostupné externí závislosti (nainstalované knihovny, dostupné externí rutiny/binárky, dostupnost k databázi, filesystému). Čímž jsem chtěl zajistit, aby vlastní běh té aplikace nemohl selhat.
Jestli by měl z mého příspěvku být cítit nějaký jazyk, tak C++. O exception safety se primárně mluví právě v souvislosti s c++ i když je to obecnější koncept. Ale právě v c++ je tohle uvažování vcelku běžné. Strong exception safety jsou transakce, jen se neřeší atomičnost z pohledu jiných vláken.

Zápis do souboru jako transakce je myslím poměrně známý postup :
- Vytvořím pomocný soubor zapíšu ho a flushnu na disk. Pokud tohle selže, pak je původní soubor stále netknutý.
- Přejmenuju pomocný soubor. Pokud má tahle operace strong exception safety, pak ji bude mít i celý zápis souboru.

A stejně se dá uvažovat i o jednotlivých objektech programu. Např při přidávání do dynamického pole mi může selhat alokace, nebo kopírování nějakého objektu. Takže alokuju nový kus paměti, všechno do něj nakopíruju a nakonec swapnu odkaz na nový blok paměti.

Obecně pokud mám swap, který dokáže prohodit vnitřnosti objektů bez možných výjimek, pak se na tom dá stavět transakční chování pro větší a větší bloky programu. A dobrým zvykem je, pokud je to možné, dávat vlastním objektům rozumný swap který jen prohodí ukazatele a nemůže házet.
Takže jsi myslel trasakčnost na úrovni jazyka a to včetně externích závislostí. Zajímavé.
Zajímavé je, jak by se něco takového provedlo v čistě funkcionálním kódu.

1353
Vývoj / Re:Jake používáte prostředí pro vývoj (C++)_
« kdy: 29. 10. 2020, 22:31:34 »
Xcode a Visual Studio (Code)

1354
V tomhle se mi hrozně líbila jedna z posledních přednášek Herba Suttera - jen označit řádky (nebo možná celý blok) co můžou házet a bude se to propagovat nahoru. Překladač by pak mohl zkontrolovat že ty neoznačené kusy házet nemůžou. Tohle by mi přišlo jako rozumný kompromis. Propagace by byla automatická, ale při čtení by bylo vidět, odkud to může lítat.
Takhle to má Swift a musím přiznat, že mě to příjemně překvapilo.

1355
Domníváš se, že Efekty nejsou lepší řešení takovýchto záležitostí? Nic nebrání, aby to bylo součástí signatury. Jen ta informace teče jinudy - cukr. Řekl bych.
Je to v podstatě to samé, prašť jako uhoď. A furt to je složité, běžný Franta to nepobere. V praxi je nejlepší co nejjednodušší jazyk, aby v něm nešla páchat zvěrstva :) FP je v podstatě pro fajnšmekry, kteří jsou schopní si napsat vlastní překladač, takže do detailu vědí, kudy v programu tečou data.

Já chci jazyk, který mě nepustí udělat chybu. Je mi jedno, zda to bude jednoduchostí, nebo díky AI.
Za druhé chci, aby když dělám něco špatně, tak abych to byl schopen z té chybovky pochopit ("no jo, text místo čísla, jasný").

Navrhnout jednoduchý jazyk je jednoduché (Lua, Python) - stačí vyrazit typy. Napsat jazyk, kterej mě bude hlídat, a přitom budu produktivní, to už je jinej kumšt (Rust).
Ten Rust to ale splňuje, tak kde je problém? Ono i moderní C++ (C++20) je na tom podobně. Na neexistenci rozumného jazyka bych si nestěžoval.

1356
V hlavách bych neškrtal, vždyť ten null se občas hodí.

Co se na tomto hodí? >:(
Kód: [Vybrat]
[TestMethod]
public void Test()
{
Print(null);
}

private void Print(Foo x)
{
System.Console.WriteLine(x.GetType());
}

Tohle beru:
Kód: [Vybrat]
[TestMethod]
public void Test()
{
Print(null);
}

private void Print(int? x)
{
if (x != null) {
System.Console.WriteLine(x.GetType());
}
}
Ber to jako v ObjC, null je taky jen objekt a má své metody ;) Tam se teda jmenuje nil.

Tenhle kiks jde samozřejmě ošetřit jen za běhu, ale ten druhý kód je v podstatě to, o čem jsem psal. Čili asi se shodneme.

1357
Domníváš se, že Efekty nejsou lepší řešení takovýchto záležitostí? Nic nebrání, aby to bylo součástí signatury. Jen ta informace teče jinudy - cukr. Řekl bych.
Je to v podstatě to samé, prašť jako uhoď. A furt to je složité, běžný Franta to nepobere. V praxi je nejlepší co nejjednodušší jazyk, aby v něm nešla páchat zvěrstva :) FP je v podstatě pro fajnšmekry, kteří jsou schopní si napsat vlastní překladač, takže do detailu vědí, kudy v programu tečou data.

1358
Java je stará věc. Člověk to chápe.
Jenže pak vyšel C# a člověk se zděšením zjišťuje, že je to úplně stejná záležitost. V ničem není vidět ty desítky let zkušeností a vývoje.
A pak narazíš na kód a zjišťuješ, že i to C# je pro mnoho programátorů složité...

Jak velká práce by bylo v jazyce vyškrtnout null? A kolik zisku by to přineslo. Ale on ten problém je v tom vyškrtnout ho z hlavy programátorů.

Co třeba Kotlin dokonce Scala? Ty se s těmi typy IMHO poprali velice slušně.
Jo, Scala to má celkem rozumně, v rámci možností. V hlavách bych neškrtal, vždyť ten null se občas hodí. Uživatelsky nejlepší je sice mít typovou kontrolu, ale bez uvádění typů (plná inference), protože pak se jazyk tváří jako dynamický, ale zároveň je typově bezpečný. Většina moderních jazyků to tak do značné míry má. I to C# se snaží.

Skutečná lahůdka je typová inference pro generické typy, protože typové operátory jsou v podstatě takový Prolog a vše stojí a padá s unifikací. Byl by z toho pěkný kurz na VŠ pro všechny, kteří naříkají nad příliš teoretickou výukou tvorby překladačů :)

1359
- Výjimky byli vymyšleny, aby se dalo psát toto:
Kód: [Vybrat]
if (((countOfFilesIn(dir1) + countOfFilesIn(dir2)) / countOfFilesIn(dir3)) == 0) { ... }
. Což bez nich prostě nejde.
Ve funkcionálních jazycích to jde ;) Akorát dá o dost víc práce pochopit, jak kód v takovém případě funguje.
Právě.
Ale stojí to za to :)

1360
Jsem silně poznamenaný funkcionálním programováním a způsob ošetřování chyb v Go se mi extrémně nelíbí.

V žádném jazyce, co má rozumné součtové typy a pattern matching, jsem neviděl že by někdo vracel chyby tuplem. Ono to nedává smysl. Obvyke nechci vrátit hodnotu A chybu, ale hodnotu NEBO chybu. Go mě nutí aby každý typ měl nějakou defaultní/prázdnou/nesmyslnou hodnotu, kterou můžu vrátit v případě chyby, i když jinak není k ničemu a ani nedává smysl.
To je otázka zvyku a nedostatku představivosti.

Haskelliho Maybe/Either taky není jen hodnota. Vždycky vracíš dvojici. V Go to prostě udělali bez typu. Může se ti to nelíbit, může se mi to nelíbit, ale principielně je to prašť jak uhoď - v porovnání s výjimkama.
Zrovna Maybe/Either je implementačně to, co v Go interface{}, ale ono jde spíš o koncept. Ono ale není tak snadné rozumně spojit podtypový polymorfismus a generické typové operátory, mám čerstvou zkušenost s implementací a je to peklo, ten typový systém vždycky někde kulhá, není třeba sound, potřebuje podporu v runtimu apod. Po takové zkušenosti se člověk nediví, že v Javě je typový systém tak tupý, ono totiž každé jeho rozšíření přináší bolehlav.

1361
Jsem silně poznamenaný funkcionálním programováním a způsob ošetřování chyb v Go se mi extrémně nelíbí.

V žádném jazyce, co má rozumné součtové typy a pattern matching, jsem neviděl že by někdo vracel chyby tuplem. Ono to nedává smysl. Obvyke nechci vrátit hodnotu A chybu, ale hodnotu NEBO chybu. Go mě nutí aby každý typ měl nějakou defaultní/prázdnou/nesmyslnou hodnotu, kterou můžu vrátit v případě chyby, i když jinak není k ničemu a ani nedává smysl.

Až moc mi to připomíná Hoareho bilionový omyl.

Z Go mám nepříjemný pocit promrhaného potenciálu. Ten jazyk by mohl být o tolik lepší, kdyby jeho autoři (záměrně?) neignorovali skoro všechno "nové" kolem překladačů a jazyků.
Go nemá zrovna světobornou syntax, jeho síla je v runtimu (kanály a korutiny). Ale výjimky (stack unwinding) má, jen se jim říká jinak. A ano, součtové typy by to vyřešily, autoři zřejmě mají jiné priority. Ruku na srdce, kdo by chtěl psát síťové služby v Haskellu?

1362
Silná stránka C++ jsou šablony, které fungují jinak než v Javě. Šablony v Javě jsou jen syntax sugar místo castování. Šablony v C++ generují zdrojový kód jako makro a tím jednak umožňují v kontejnerech uložit zadaný typ přímo bez balení do objektu a navíc instance šablony ten typ zná a proto jej může instanciovat metoda v šabloně. Kontejner v šabloně může jen ukládat reference na objekty vytvořené mimo kontejner.
Kód: [Vybrat]
map<int,vector<int>> multimapa;
multimapa[5].push_back(6);  // operátor [] najde existující vector nebo automaticky vytvoří nový
A generika v Go 2 se jako na potvoru inspirovala javovskou verzí. Aneb Go se v ..... obrací.

1363
- Výjimky byli vymyšleny, aby se dalo psát toto:
Kód: [Vybrat]
if (((countOfFilesIn(dir1) + countOfFilesIn(dir2)) / countOfFilesIn(dir3)) == 0) { ... }
. Což bez nich prostě nejde.
Ve funkcionálních jazycích to jde ;) Akorát dá o dost víc práce pochopit, jak kód v takovém případě funguje.

1364
Jo a to pribalovanie dát som si práve vygooglil:

https://stackoverflow.com/questions/18161680/how-do-i-stdbind-a-non-static-class-member-to-a-win32-callback-function-wnd#18162974

Na tento konkrétny prípad sa to hodí.

Ale môžu nastať aj iné podobné situácie kde sa to už hodiť nemusí. (Napr pri hookoch LowLevelKeyboardProc) Preto som hľadal čo najvšeobecnejšie riešenie. Prvé ma napadlo použiť labdu s captures, lenže tá neni kompatibilná s pointerom na funkciu. ďalej som skúšal použiť std::bind (a tiež std::mem_fun), tie fungovali, ale tiež neboli kompatibilné s C-čkovým pointerom na funkciu ale len s C++osvým std::function.

Takže pre C-čkový pointer na funkciu všeobecné riešenie asi ani neexistuje (mimo použitia static). Ja sa snažím čo najviac využívať moderné konštrukcie z C++ ale pri RegisterClass to žiaľ nejde. Ale aspoň som sa dnes niečo nové naučil aj o C-čkových typoch.
Ono to nejde z principu, uzávěry mají kontext. Proto mají vždy callbacky v C parametr pro uživatelská data (typicky ukazatel). Pro tu klávesnici je ve WinAPI taky, v KBDLLHOOKSTRUCT.

1365
Keby sa dal do štruktúry určenej pre funckiu RegisterClassEx (WNDCLASSEXW) vložiť typ std::function tak mám po probléme, std::function je veľmi flexibilný a viem ho nabindovať, ale ten už potom neviem skonvertovať na typ WNDPROC.
To samozřejmě nejde, musí se předat čistá céčková funkce, která si pak vezme ten ukazatel na funktor a zavolá jej. To už jde snadno. Volaný objekt si prostě žije na haldě včetně kontextu a ten callback si musí ukazatel přetypovat a zavolat.

Stran: 1 ... 89 90 [91] 92 93 ... 153