abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
včera 21:55 | Zajímavý článek

Clear Linux je distribuce vyvíjená firmou Intel; vybočuje optimalizací na výkon, pročež se používá např. k běhu benchmarků, ale také pro vývojáře či do cloudu. Recenze na Ars Technica se zaobírá použitím Clear Linuxu jako uživatel: instalace, pozorování rychlosti spouštění Gimpu, správa balíčků a instalace Google Chrome nebo konfigurace OpenZFS. Praktické nasazení mimo specializace, kde je výkon kritický, nakonec nedoporučuje.

Fluttershy, yay! | Komentářů: 3
včera 21:44 | Nasazení Linuxu

Jižní Korea se z historických důvodů potýká se silnou závislostí na Microsoftu (konkrétně ActiveX), kterou se snaží postupně odbourat. Na jaře 2019 tamní ministerstvo vnitra oznámilo testování Linuxu na pracovních stanicích. Nyní, po skončení podpory Windows 7, byl přechod potvrzen s cílem omezit závislost na třetí straně a snížit náklady. Do roku 2026 je v plánu, že uživatelé budou používat notebooky s Windows, ale připojovat se na vzdálený linuxový desktop v cloudu. Některá ministerstva již Linux používají.

Fluttershy, yay! | Komentářů: 0
včera 16:44 | IT novinky

Vývojář webového prohlížeče Waterfox, forku Mozilla Firefox, veřejně oznámil dokončení přechodu projektu pod správu firmou System1, která na podzim 2019 zřejmě převzala také metavyhledávač Startpage. System1 se zabývá agregací a analýzou uživatelských dat za účelem využití v reklamě, proto např. web PrivacyTools již Startpage nedoporučuje.

Fluttershy, yay! | Komentářů: 11
včera 00:11 | Pozvánky

Spolek OpenAlt zve příznivce otevřených řešení a přístupu na 173. brněnský sraz, který proběhne v pátek 21. února od 18:00 v restauraci Suzie's Steakhouse Brno na adrese Kounicova 10.

Ladislav Hagara | Komentářů: 8
16.2. 16:33 | Nová verze

Byla vydána verze 2.0.0 aplikace pro digitální malování MyPaint (Wikipedie). Přehled novinek i s náhledy v příspěvku na blogu.

Ladislav Hagara | Komentářů: 0
16.2. 16:11 | Zajímavý článek

Článek na blogu LibreTechTips představuje a srovnává webové vyhledávače: nejen známé Google, Bing, DuckDuckGo či Yandex, proxy Startpage a Ecosia, ale také nezávislý Mojeek, metavyhledávače Metager a Searx, švýcarský Swisscows a francouzský Qwant. Srovnání spočívá v pohledu na výsledky čtyř hledání a čtyř specifických dotazů jako překlad slova nebo převod jednotek. Nejlépe hodnocený je Searx následovaný Google a s velkým odstupem Bingem, DuckDuckGo, Startpage atd.

Fluttershy, yay! | Komentářů: 15
15.2. 16:44 | Nová verze

Byla vydána verze 9.0 open source unixového operačního systému NetBSD (Wikipedie). Přehled novinek v poznámkách k vydání.

Ladislav Hagara | Komentářů: 0
14.2. 17:11 | Nová verze

Byla vydána nová verze 8.2 sady aplikací pro SSH komunikaci OpenSSH. Z novinek lze zdůraznit podporu hardwarových bezpečnostních klíčů podporujících FIDO/U2F.

Ladislav Hagara | Komentářů: 0
14.2. 14:33 | Komunita

Čtenářům a čtenářkám AbcLinuxu vše nejlepší k Valentýnu aneb Dni lásky ke svobodnému softwaru (FSF, I love Free Software Day, #ilovefs).

Ladislav Hagara | Komentářů: 13
14.2. 13:22 | Nová verze

Byla vydána nová verze 2.82 svobodného 3D softwaru Blender. Přehled novinek v oznámení o vydání a na YouTube.

Ladislav Hagara | Komentářů: 0
Vydržela vám novoroční předsevzetí?
 (9%)
 (7%)
 (2%)
 (82%)
Celkem 153 hlasů
 Komentářů: 0
Rozcestník

async a await je krok špatným směrem

6.3.2015 19:13 | Přečteno: 2488× | Programování | Výběrový blog | poslední úprava: 7.3.2015 12:09

Jelikož je asynchronní kód stále častějším jevem, přidávají programovací jazyky speciální podporu pro jeho zápis. Příkladem takové podpory jsou klíčová slova async a await, která se momentálně z jazyka C# 5 šíří do dalších jazyků. V tomto zápisku vysvětlím, proč async a await není dobrý nápad.

Nutnost psaní asynchronního kódu je dobře známá z JavaScriptu, budeme proto používat pseudokód podobající se JavaScriptu. Jako příklad uvedeme funkci showData, která načte data ze serveru a zobrazí je:

function showData(cfgUrl) {
  getJSON(cfgUrl)
  .then(function(cfg) {
    return getJSON(cfg.dataUrl);
  })
  .then(function(data) {
    alert(data);
  })
  .catch(function((e) {
    // osetrit chybu
  });
}

Funkce provádí dvě asynchronní volání getJSON. První volání načte konfiguraci, v níž je URL s daty, druhé volání načte samotná data. Funkce showData je zapsána pomocí tzv. promises (getJSON spustí požadavek na server a vrátí promise, na nějž funkce then a catch navěšují callbacky).

Oproti synchronnímu zápisu

function showData(cfgUrl) {
  try {
    var cfg = getJSON(cfgUrl);
    var data = getJSON(cfg.dataUrl);
    alert(data);
  }
  catch (e) {
    // osetrit chybu
  }
}

je výše uvedený zápis pomocí promisů delší a méně přehledný. Navíc jde při řetězení promisů snadno udělat chybu – stačí zapomenout return před druhým voláním getJSON.

async a await

Motivací pro async a await je zvýšení přehlednosti. S pomocí async a await se asynchronní kód podobá synchronnímu:

async function showData(cfgUrl) {
  try {
    var cfg = await getJSON(cfgUrl);
    var data = await getJSON(cfg.dataUrl);
    alert(data);
  }
  catch(e) {
    // osetrit chybu
  }
}

Klíčové slovo async označuje funkce, v jejichž definici lze použít await. V některých implementacích ovlivní async i chování funkce.

Klíčové slovo await spustí asynchronní volání a přeruší funkci, dokud volání neskončí. Kdybychom například na prvním řádku nepoužili await, tak by se do cfg nepřiřadil výsledek asynchronního volání, ale přiřadil by se tam objekt, jenž reprezentuje asynchronní volání. Opomenutí await pak vede k chybám.

Přirozenou otázkou je, proč await vůbec psát? Typická situace přeci vypadá tak, že asynchronní akci chceme spustit a chceme získat její výsledek. Proč tedy asynchronní kód nevypadá stejně jako synchronní a proč tam kompilátor nebo interpretr automaticky nedoplní awaity?

Argumentem pro explicitní await je skutečnost, že kód před awaitem a kód po awaitu mohou běžet v jiném prostředí. V době provádění asynchronní akce totiž může běžet jiný kód, který například změní globální proměnné. Anebo je kód po awaitu spuštěn v jiném vlákně. V takových případech await vyznačuje místa, kde ke změnám prostředí dochází.

Přínos takového vyznačení však minimalizuje fakt, že změny prostředí mohou provádět i funkce s vedlejšími efekty, jejichž volání nijak nevyznačujeme. Krom toho v jazycích s více vlákny může prostředí kódu změnit i jiné vlákno, a to kdykoliv. Nevidím tedy důvod, proč vyznačovat zrovna asynchronní akce.

Pokud by někdo na vyznačení asynchronních akcí trval, může použít stejnou konvenci jako C#, kde se pro asynchronní akce používá přípona Async. Osobně však nejsem příznivcem ani této maďarské notace, neboť se domnívám, že zhoršuje čitelnost kódu.

Závěr

Explicitní psaní awaitu by mělo smysl, pokud by uživatel v drtivé většině případů nechtěl await použít a asynchronní akci spouštět. Jenže skutečnost je přesně opačná, větší smysl by tedy dávalo klíčové slovo delay nebo lazy, které by zajistilo, že se výraz nevyhodnotí.

Přijde mi to jako vytvořit objektový jazyk s třídami, kde standardní viditelnost členských proměnných je public a standardní viditelnost metod je private, ač bychom to chtěli naopak.

S async a await přišly jako první C#, VB.NET a VC++, není mi však jasné, proč to okopíroval Hack, kopíruje to Dart a rovněž to někteří plánují i pro ECMAScript 7.


Update (7. března 2015 12:10): Na základě komentáře od backinabag (díky) byly změněny 2 poslední odstavce před závěrem. Pokusil jsem se lépe vysvětlit, proč je await zbytečný.

       

Hodnocení: 70 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

6.3.2015 19:46 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Co je na těch příkladech asynchronního, když následující operace čeká na výstup předchozí operace?
6.3.2015 19:50 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Neblokuje to vlákno, funkce se vzdá vlákna a může běžet něco jiného. Například v JavaScriptu může aplikace zpracovávat jiné události.
6.3.2015 20:54 pc2005 | skóre: 38 | blog: GardenOfEdenConfiguration | liberec
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Proč tohle neřeší VM (javaskriptu) (asi jako sched_yield() pro kernel), ale specifikace jazyka?
6.3.2015 21:26 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
To, jak se různé části programu prolínají, může mít vliv na chování (efekty) a výsledek programu, tudíž si myslím, že by to měla řešit specifikace jazyka, neboť specifikace jazyka přiřazuje programům význam.
6.3.2015 23:33 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Já vím, co je „asynchronní“, ale v uvedených příkladech se vůbec nic jiného neděje. Navíc, aby se mohl spustit druhý getJSON(), musí být známa hodnota cfg a to nastane až skončí první getJSON(). Jediné, co se dělá v původním vlákně je příprava spuštění druhého getJSON(). To ale celkově vypadá dost samoúčelně a potom jakákoliv syntaxe vypadá zbytečně. Možná kdybyste zkusil něco složitějšího, tak se ukáže, že ona syntaxe je nutná, aby vedla implicitní synchronizační magii za ručičku.
7.3.2015 00:34 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Navíc, aby se mohl spustit druhý getJSON(), musí být známa hodnota cfg a to nastane až skončí první getJSON().
Takhle sekvenční je to bohužel vždycky (i kdyby se cfg vůbec nepoužila). Napíšete-li například
async function f() {
  await readA();
  await readB();
}
tak se stejně napřed spustí readA a teprve poté, co úspěšně (bez vyhození výjimky) skončí, se spustí readB. Cílem je, aby se to chovalo podobně jako klasický synchronní program, což zde například znamená, že readB se nespustí, pokud readA neskončí, a to je obecně těžké zjistit (halting problém).

Ještě zmíním, že i zásobník se v některých implementacích tváří jako u synchronního programu, a to i přesto, že výpočet ve skutečnosti skáče po různých vláknech.
To ale celkově vypadá dost samoúčelně a potom jakákoliv syntaxe vypadá zbytečně.
I tak mi to přijde lepší než
function f() {
  readA()
  .then(function() {
    readB();
  });
}
Josef Kufner avatar 7.3.2015 02:12 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Javascript běží celý v jednom vlákně. Synchronizační magie se tedy nekoná. Asynchronnost zpracování programu v Javascriptu je více podobná obsluze unixových signálů než vláknům.
Hello world ! Segmentation fault (core dumped)
pavlix avatar 7.3.2015 11:36 pavlix | skóre: 54 | blog: pavlix
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Buď mi něco uniklo nebo se mi to vůbec nezdá podobné obsluze unixových signálů. K obsluze unixových signálů dochází naprosto kdykoli, takže s tím jsou snad ještě horší problémy než s vlákny, navíc se to musí synchronizovat samostatně a spousta systémových volání se právě kvůli tomu musela doplňovat o alternativy bezpečnější vůči signálům.
Já už tu vlastně ani nejsem. Abclinuxu umřelo.
Josef Kufner avatar 7.3.2015 21:53 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Callbacky navěšené na některé eventy v JS ti také mohou přijít kdykoliv, i když většinou se to chová o trochu líp.
Hello world ! Segmentation fault (core dumped)
pavlix avatar 8.3.2015 12:36 pavlix | skóre: 54 | blog: pavlix
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Nevím, jestli vůbec lze srovnávat „javascriptové kdykoli“ a prakticky absolutní kdykoli mimo blokování signálů tak, jak to funguje v nativních procesech. Nebo jinak, jsem zcela přesvědčen o tom, že se to srovnávat nedá, a to bez ohledu na to, že u javascriptu neznám přesné detaily.
Já už tu vlastně ani nejsem. Abclinuxu umřelo.
6.3.2015 20:19 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Neni mi z toho jasny proc by se teda ten await nemel pouzivat.

Argument ze to vyznaci IDE neberu, tohle by nemelo byt zaivsle na nejakych featurach IDE. Ne vzdy clovek cte kod v IDE, ne vsichni pouzivaji IDE, atd. A ES7 je prece dynamicky jazyk, takze tam tenhle argument uz vubec nedava smysl.

Co kdyz tu funkci chci volat normalne? Nebo co kdyz volani neprobiha v event loop vlakne?
objektový jazyk s třídami, kde standardní viditelnost členských proměnných je public a standardní viditelnost metod je private, ač bychom to chtěli naopak
Pokud vubec mit defaultni viditelnost, tak nejlogictejsi mi prijde private pro vsechno.
6.3.2015 21:10 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Neni mi z toho jasny proc by se teda ten await nemel pouzivat.
Vyznačení, že se volá asynchronní akce a funkce bude pravděpodobně přerušena, nepovažuji za tak důležité, aby mělo speciální syntax. Naopak v kódu, který dělá mnoho asynchronních volání, to snižuje přehlednost.
Nebo co kdyz volani neprobiha v event loop vlakne?
V C#, když není k dispozici event loop vlákno (přesněji, když je SynchronizationContext.Current == null), tak se kód spouští na ThreadPoolu – ten je k dispozici vždy.
Co kdyz tu funkci chci volat normalne?
Co myslíte volat normálně? Takové funkce typicky vrací objekt, který nějak reprezentuje asynchronní výpočet – např. Promise, Future, Task nebo Awaitable – tj. nějak se musíte dostat k návratové hodnotě, která je (možná) v tom objektu.
7.3.2015 12:11 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Argument ze to vyznaci IDE neberu, tohle by nemelo byt zaivsle na nejakych featurach IDE. Ne vzdy clovek cte kod v IDE, ne vsichni pouzivaji IDE, atd.
Díky, to je dobrá poznámka, argument jsem odstranil.
6.3.2015 20:34 Borec
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Threads are evil. Avoid them. (Richard Hipp, SQLite)

http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf
6.3.2015 20:46 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Threads are evil. Avoid them.
Vlakna jako takova zlo nejsou. Za vetsinu spatneho muze mutable state.
Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
6.3.2015 23:11 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Škoda že do dnešní doby neexistuje ani jeden skutečně čistě funkcionální jazyk. Haskell je implicitně čistý, IO monáda je ale nečistý zlo, potlačuje lenost i neměnnost dat. A tenké wrappery nad imperativními API jsou zlo taktéž (Zdravím GTK2HS). Zrovna teď jsem dopsal v Haskellu aplikaci s GUI, a jsem mírně zhnusen. Mám tam tolik měnitelného stavu díky různým IORef, TVar a Chan, že se to podobá imperativnímu jazyku. A co je nejhorší, nejde to jinak, protože jinak prostě nezajistím aby spolu komunikovali handlery eventů (a taky vlákna). Je samozřejmě řešení, reaktivně funkcionální programování. Bohužel, do dnešní doby není k dispozici reaktivní GUI knihovna se schopnostmi na úrovni GTK+ knihovny. A odpovídající dokumentací a přehledností. Pokud by někdo křičel že Clean je skutečně čistý, bude mít pravdu. Bohužel Clean je blbě zdokumentovaný, dokumentaci pro STD knihovnu sem teda našel, ale přišla mi malá. Nemá žádné knihovny třetích stran, blbou podporu linuxu a někam se zatoulala FFI. Takže to volba taky není, bohužel. Celkově ten jazyk a jeho platforma vypadá jako kdyby se nikam neposunul od 90 let. A to má tolik krásných nápadů. Škoda škoda. Jo, a přidávat prvky lenosti do imperativních jazyků je fakt blbej nápad. Ono, nekončí to dobře ...
7.3.2015 00:35 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Hmm... je imperativni programovani vzdy horsi nez funkcionalni? Ja bych rekl ze rozhodne ne, zalezi na situaci. Nektere problemy jsou nejcitelnejsi a nejjednoduseji vyjadrene imperativnim programovanim.

K tomu UI, idealni mi prijde model, ktery pouziva JS knihovna React. Konceptualne to je extremne jednoduche:

- UI se sklada z komponent, ktere mohou byt zanorene do sebe.

- Kazda komponenta je (zjednodusene) pure funkce, ktera dostane stav a vrati popis UI (na webu HTML).

- Jakekoliv zmeny UI se provadi tak, ze nastavim novy stav a cele UI se pregeneruje.

- Priklad: Mam komponentu vstupni pole (input). Jeji stav je pouze zadany text. Pri zmacknuti klavesy se zavola handler, ve kterem se podivam na aktualni stav - zadany text - a nastavim novy stav - predchozi text ke kteremu je na konec pridan zadany znak. Komponenta se po nastaveni noveho stavu pregeneruje.
7.3.2015 00:53 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Kazda komponenta je (zjednodusene) pure funkce, ktera dostane stav a vrati popis UI (na webu HTML).
Tohle ale není úplně praktické, často se hodí, když i jednotlivé komponenty mají vnitřní stav. Například stav scrollbaru nebo pozice kurzoru v textovém poli nebo stav nějaké animace – tyhle věci často nechcete mít v tom "hlavním" velkém stavu.
7.3.2015 01:05 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Presne tak to v Reactu je, stav komponenty ma dve casti: props, ten dostane zvnejsku od rodicovske komponenty a state, ktery si nastavuje sama v reakci na ruzne eventy.
Josef Kufner avatar 7.3.2015 02:17 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Ono by to také bylo značně neefektivní. Nicméně mezi teoreticky pěkným modelem vystaveným v podobě API knihovny a implementací GUI na straně prohlížeče může být schováno pár ošklivých hacků, které to celé umožní. Skrytí vnitřního stavu generované komponenty je jedním z nich.
Hello world ! Segmentation fault (core dumped)
7.3.2015 09:12 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Imperativni kód se špatně paralelizuje. To je jeho hlavní nevýhoda. Samozřejmě, pro low-level záležitosti je to jasná volba. Používáme imperativni cpu architektury. Ale pokud chceme dělat něco výše. AI, kompiler nebo něco podobného, funkcionalni paradigma nabízí vynikající možnost paralelizace, krátký kód, dobře čitelný kód a hlavně jednoduše napsaný kód. Rekurze se chápe snadněji, než iterační cykli, protože rekurze je přirozená a je všude kolem nás. Lidé sami o sobě jsou rekurzivni.

A při každé změně znova vygenerovat UI? Bleee, zkus tam udělat něco většího a bude se to sekat jak svině. Pro web dobrý, to jo. Ale jinak fakt ne.

Jak sem řek, reaktivne funkcionalni programování ...
7.3.2015 09:35 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
A při každé změně znova vygenerovat UI? Bleee, zkus tam udělat něco většího a bude se to sekat jak svině. Pro web dobrý, to jo. Ale jinak fakt ne.
To je bohužel pravda, v některých komponentách pak musíte implementovat shouldComponentUpdate, který zamezí zbytečným aktualizacím komponenty.
7.3.2015 09:48 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
funkcionalni paradigma nabízí vynikající možnost paralelizace
Co, když je úloha taková, že každý krok je závislý na výsledku předchozího kroku? V některých speciálních případech sice můžete zkusit spekulativní paralelizaci – například lexikální analýza – ale to jsou spíše výjimky.
7.3.2015 11:38 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
V takovém případě je možno zparalelizovat jednotlivé sekvenční kroky. Ono, jako celek se nedají navzájem na sobě závislé kroky zparalelizovat, ale jako samotné jednotlivé kroky už ano. Samozřejmě, pokud je výpočetní výkon potřebný na vyhodnocení kroku menší než výkon potřebný na vytvoření sparků (objekt obsahující pointer na funkci, a seznam argumentů s kterými je volána <+ scope>, tento objekt se poté vkládá do fronty pro zpracovatelské vláknu v runtime systému) pro paralelizaci, nevyplatí se daný krok zparalelizovat. To je bohužel v dnešní době častý problém, výkon potřebný pro vytvoření paralelní operace je moc velký (dáno architekturou CPU kterou používáme). Takže v dnešní době funkcionální paradigma ani nemůže pořádně ukazovat svou sílu.
7.3.2015 12:11 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
To je bohužel v dnešní době častý problém, výkon potřebný pro vytvoření paralelní operace je moc velký (dáno architekturou CPU kterou používáme). Takže v dnešní době funkcionální paradigma ani nemůže pořádně ukazovat svou sílu.

To se o Prologu říká taky :)

Třeba OpenPower plaforma s FPGA kartami zapojenými do IOMMU to změní.

7.3.2015 11:44 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Imperativni kód se špatně paralelizuje. To je jeho hlavní nevýhoda.
Hm, ne vzdy a navic kolik % kodu se paralelizuje? Jinak sdileny mutable state mi obcas prijde jako nejcistssi zpusob jak neco naprogramovat. Funkcionalni kod ma urcite vyhody, to nepopiram, moje pointa je, ze ne ve vsech situacich je to ten nejlepsi pristup.
A při každé změně znova vygenerovat UI? Bleee, zkus tam udělat něco většího a bude se to sekat jak svině. Pro web dobrý, to jo. Ale jinak fakt ne.
Taky moje prvni reakce byla, ze to musi byt strasne pomaly. Ale rychlost je naopak jedna z hlavnich prednosti Reactu, alespon ve srovnani s konkurenci (Angular, Ember). Pokud jsou vsechny komponenty opravdu pure funkce a vsechen stav je immutable, tak to lze udelat tak, ze se pregeneruji jenom komponenty ktere se zmenily, stavi porovnat minuly stav s novym. Myslim ze pak by se i u slozitejsiho UI vetsina updatu vesla do 1 ms a urcite by nemel byt problem dosahnout 60 FPS.
7.3.2015 12:07 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Některé problémy se nejefektivněji řeší pomocí měnitelného stavu. To je smutná a černá realita. Ale je to naštěstí poměrně malé množství problémů. V dnešní době se paralelizuje malé procento kódu ve funkcionálních jazycích, to je ale chyba použité procesorové architektury, nikoli paradigmatu. Funkcionální paradigma je prostě paralelní moc, a x86, ARM, SPARC a já nevím jaké ještě jsou všechno imperativní architektury s málo výkonným vytvářením paralelních operací. Výsledná situace pak vypadá tak, že kompiler nebo runtime není schopen zparalelizovat kód sám, a programátor ze strachu aby to ještě nezpomalil rači nic neparalelizuje. Popřípadě si tam dotáhne měnitelný stav protože musí a zabije hlavní výhodu funkcionálního paradigmatu tak, jako java, C# a spol OOP. Tragika nad tragiku, kdy už se konečně hne vývoj někam dál, a vznikne pořádná CPU architektura ...
7.3.2015 12:13 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Pokud vím tak si React dělá kopii DOMu, v které udělá více změn a poté jen vytáhne odlišnosti mezi obrazem DOMu a pravým DOMem, a ty realizuje. Takže není to neustálé generování UI tak nákladné jak by mohlo. Diffování DOMů ale sežere dost výkonu, zvláště když je DOM velký. Takže je to hezké a elegantní řešení, moc mu ale s výkonem nevěřím. Bylo by ale hezké ňáký takový nápad integrovat do nějakého GUI toolkitu funkcionálního jazyka. Třeba by zdržení nebylo moc znát, třeba...
7.3.2015 12:56 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Samotne diffovani by melo by extremne rychle - teda alespon pokud se diffuji dva virtualni DOMy (nevim jestli to takhle React dela). Stary i novy virt. DOM se vetsinou bude skladat z tech samych objektu az na par vyjimek, takze se budou vlastne jenom porovnavat reference na stejny objekt.

Pokud nastavim nejake komponente novy stav, tak se komponenta aktualizuje pouze pokud se stav zmenil (v Reactu to takhle defaultne nefunguje, jde mi obecne o tenhle model UI). To znamena ze pri zmene stavu se pregeneruje jenom nutne minimum.

Takze myslim ze mimo DOM by mely byt napr. i slozite animace naprosto plynule pokud to nebude nic dalsiho zpomalovat.
7.3.2015 18:54 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Sice reaguji mimo tvůj komentář, ale skus jazyk ELM elm-lang.org. Jedná se o čistě funkcionální jazyk podobný Haskellu který se překládá do JS a má zabudovanou podporu pro reaktivní funkcionální programování. Takže nepotřebuje žádný měnitelný globální stav, a jdou v tom dělat interaktivní stránky a 3D hry. Škoda že nejsou kluci kolem Haskellu schopni něco podobného udělat i pro Haskell a furt se mordují s IO monádou ... a nebo aspoň uniqueness typy jako má Clean. Asi si budu muset ten svůj vysněný jazyk udělat sám
7.3.2015 20:01 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
a nebo aspoň uniqueness typy jako má Clean
V čem je to lepší než IO monáda?
7.3.2015 22:37 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
IO monáda je syntaktická metoda jak to všechno vochcat. Ona nedělá nic jiného než že potlačuje lenost dat, jejich neměnnost a taky pure paralelismus (on ani není možný pokud nechceme mít race conditions) a povoluje vedlejší efekty. Což znamená že funguje pouze jako takový vypínač mezi PURE a IMPURE světem. A to je blbě (protože potom většina real world programu je impure ...). Proto je Haskell implicitně čistě funkcionální. Nikoli čistě funkcionální. Uniquiness typování ale je skutečně referenčně transparentní, takže de klasicky využít s pure paralelismem. Bohužel ho má jen zanedbaný Clean. Další metodou jak zajistit čistotu jazyka je Reaktivní programování, které na měnitelné hodnoty kouká jako na funkce času. A ty sami o sobě jsou neměnné. Prostě je vyřešen problém s čistotou tak, že se přidá do hry parametr čas. Bohužel, tendle přístup má v dnešní době jen ELM, který je pro web, a není tak dopracovaný jako Haskell. A jako dárek do něj ňákej vocas dovlík IO monádu, asi se mu stýskalo ... Ono, je více metod jak dosáhnout čistě funkcionálního jazyka. Jednu mám i v hlavě (ale není z mé hlavy, našel sem ji na blogu jednoho už zapomenutého týpka kde ji prezentoval, byl ale za ni Haskellerama ukamenován ve jménu IO monády ...):

main :: [Message] -> [Message]

main msg = ...

Kde listy [Message] jsou nekonečné díky lenosti. A program přijímá skrz zprávy všechny změny z okolního světa, a sám odpovídá skrz nekonečný list zpráv runtime systému. Vlastně tak jako GC je nutno pro čistě funkcionální jazyky z toho důvodu že alokace paměti není referenčně transparentní (a persistentní datové struktury bez GC taky nejdou). Tak je třeba i IO přesunout do runtime systému, s vyšší úrovní abstrakce se prostě nepotřebné věci zanedbávají, v tomto případě ruční provádění IO.
7.3.2015 23:17 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Uniquiness typování ale je skutečně referenčně transparentní
Nerozumím, proč IO monáda není skutečně referenčně transparentní.
Uniquiness typování ale je skutečně referenčně transparentní, takže de klasicky využít s pure paralelismem.
Máte na mysli fakt, že IO monáda vynucuje lineární uspořádání akcí? Uspořádání akcí, sice jen částečné, vynucuje i uniqueness typování, ne?
Bohužel ho má jen zanedbaný Clean.
AFAIK má to ještě Mercury. Podobné chování pravděpodobně půjde zajistit i v jazycích s lineárními typy jako např. ATS.
Vlastně tak jako GC je nutno pro čistě funkcionální jazyky z toho důvodu že alokace paměti není referenčně transparentní
I v IO monádě nebo s uniqueness typováním můžete ručně alokovat i dealokovat paměť. Referenčně transparentní to není například v případě, kdy můžete pozorovat adresy objektů, ale s dostatečnými omezeními to může být referenčně transparentní.
7.3.2015 23:27 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
BTW, aby bylo zřejmé, o čem se bavím, tak: výraz e je referenčně transparentní, pokud mohu v každém programu nahradit libovolné výskyty e hodnotou e a chování programu se nezmění.
8.3.2015 08:35 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Odpovím na vše, žádný strach.

Další věc co mne na Haskellu dráždí je vysoké procentu evangelistů, kteří ve chvíli když si nějaký hříšník dovolí Haskell kritizovat okamžitě se hrne nebožáka upálit. Takový příklad, někde sem viděl žě ňáký týpek kritizoval Haskell proto že má jen rekurzi a že tím pádem sežere spoustu místa na stacku. Místo toho aby té nevědomé ovečce někdo řekl, že Haskell má i tail call rekurzi, bylo mu odpovězeno že Haskell žádný stack nemá, a že ho nepotřebuje žádný funkcionální jazyk a aby šel rači pryč. Super ne? A nebo jeden dobroděj prezentoval rychlost Haskellu, prý že je rychlejší jak C. No, v c programu měl pole o 1 000 000 prvcích a něco s nima vyváděl. V Haskellu udělal list s 1 000 0 asi tolika prvkama, dělal s nima to samí a nakonci vítězoslavně křičel že Haskell je prostě nejrychlejší. A to je proti prohlášení že Haskell nemá stack celkem ještě pohoda. A co teprve když se nějaký vyslanec ďábla odváží kritizovat IO monádu ... To je tanec ...

IO monáda není referenčně transparentní, diť je to logické ne. Koukni se

do-some-stupid-thing :: IO [Int] do-some-stupid-thing = horrorfull code here ...

Hezký co? No, a teď na to zkus aplikovat optimaliazační techniku "call once". Jako to call once je můj termínus technikus, sedí ale. Prostě, čistou funkci je třeba zavolat s konkrétními argumenty jen jednou, pak už jen dávat její výsledek opakovaně (cachovat její výsledek, kterej prostě nemůže být se stejnými argumenty jinej). V Haskellu se tadle technika používá pro všechny funkční volání uvnitř funkcí (s vyjímkou funkcí vracejících IO monádu), po opuštění funkce se ale cache vykopne (nechceme přece plýtvat pamětí žejo). No, a teď to zkus použít i na můj příklad, nebere žádný argumenty, takže o to snažší. Představ si že ta moje hrozná funkce bere data já nevím třeba ze serveru. No, a kdyby to byla referenčně transparentní funkce, nevadilo by ji jednou vyhodnotit a pak jen dávat její výsledek žejo? Hezký, tvůj program by se ale choval trošku jinak než jak bys očekával. Ono, při každém vyhodnocení tadle funkce vrací něco jiného ... prostě proto že není referenčně transparentní.

Linearita operací ... dyť vo tom sem nemluvil. To není nic špatného, funkční kompozice taky způsobuje linearitu uspořádání operací ... Nic nemůže být absolutně paralelní.

Á Mercury, zajímavé. Kouknu se, ale pochybuju že bude mít takový ekosystém jako Haskell, takže nezíská mou pozornost. Využití v real world projektech bude nízké, když nemá GUI toolkit, 3D API, networking ...

No anoooo, V referenčně transparentní IO monádě můžeme ručně alokovat paměť. OUCH. To je jak facka. Haskell by se obrátil v hrobě. To už je skoro jako ta anabáze se stackem... Ano, můžeme, pomocí IO monády můžeme dělat tolik nečistých vecí ... Ale alokace prostě NENÍ referenčně transparentní. Stejně tak dealokace. Ta také není referečně transparentní. Samozřejmě do nečistý IO monády to nacpad de (tam de nacpat všechno imperativní). A myslím že i musí, pokud chceme něco z Haskellu překlopit do Cčka. Což se hodí když portujeme imperativní knihovny do Haskellu. Opět, FFI má Haskell navržené blbě když vyžaduje nečistý kejkle. ELM má lepší přístup k FFI ...

A bez GC by nefungovali persistentní datové struktury ... cpát ruční alokaci paměti do funkcionálního jazyka je stejná bejkovina jako GC do OOP.
8.3.2015 10:22 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
No, a kdyby to byla referenčně transparentní funkce, nevadilo by ji jednou vyhodnotit a pak jen dávat její výsledek žejo? Hezký, tvůj program by se ale choval trošku jinak než jak bys očekával. Ono, při každém vyhodnocení tadle funkce vrací něco jiného
Právě, že ne. Ta funkce vrací při každém vyhodnocení to samé, a to hodnotu typu IO [Int].

IO [Int] můžeme chápat jako popis akcí, co se mají stát. A sám o sobě je takový popis referenčně transparentní – popis žádné vedlejší efekty nedělá.
8.3.2015 10:53 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
A přesně todle tvrzení zabije každou diskuzi na téma "IO monáda je impure". Ono, hezký, je to zpráva co se má udělat, nic víc. Ale tu zprávu naneštěstí vyhodnotí monadické operátory >> a >>=. Které už jsou impure, v kódu společně s pattern matchingem a funkcema seq a pseq vynucují okamžitou exekuci. Takže žádné spojování správ a poslání do runtimu se nekoná jak rádi IO evangelisté křičí. Ano, sama o sobě je IO monáda nevinná. Bohužel sama o sobě je k ničemu. Něco ji musí rozhoupat k akce ... a runtime to není, je to nejbližší operátor >> nebo >>= ...
8.3.2015 11:36 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Ale tu zprávu naneštěstí vyhodnotí monadické operátory >> a >>=.
Tyto operátory nic nevyhodnocují. Můžeme si představit, že to vyhodnocuje jakýsi interpretr, k němuž nemáte přístup, používáte-li Safe Haskell, nebo máte přístup přes unsafePerformIO apod., pokud nepoužíváte Safe Haskell.
Něco ji musí rozhoupat k akce ... a runtime to není, je to nejbližší operátor >> nebo >>=
Můžete si zkusit, že >> nic takového nedělá, například vyhodnocení výrazu
(putStrLn "A" >> putStrLn "B") `seq` 4
nezpůsobí žádný vedlejší efekt, a to i přesto, že se putStrLn "A" >> putStrLn "B" vyhodnocuje do slabé hlavní normální formy.
8.3.2015 15:14 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Samozřejmě že

(putStrLn "A" >> putStrLn "B") `seq` 4

vrátí 4. Funkce seq má typ (a -> b -> b) což znamená že když dáme na první místo IO objekt a na druhý cokoli jiného krom jiného IO objektu, vznikne nám strašná chyba. IO objekt unikne do čistého kódu a bude vyhodnocen!! V čistém kódu platí úplně jiná pravidla, funkce se volají v jiném pořadí než byly napsaný, pokud se volají vůbec, vyhodnocují se taky všelijak, někdy víckrát, někdy jen jednou. Prostě kdyby pomocí funkce seq bylo možno vyhodnotit IO objekt a pak v klídku pokračovat v čistém kódu, nic by nefungovalo tak jak má. Proto je tam zadrátovaná ochrana, a IO objekt se prostě ignoruje a zahodí. Pro "vyhodnocení" IO objektů slouží >> a >>=.

Ono, ve skutečnosti, operátory >> a >>= nic nevyhodnocují, je to ale pěkné a snadné si to představovat. Lépe se poté akceptuje víra že IO monáda je Pure. IO monáda je vlastně jen tuple s obsaženým fake členem, který zajišťuje, aby kompiler nepřerovnal ňák blbě volání funkcí vracejících IO (jinak než jsme napsali). Operátor >> pak jen zřetězuje nečistá volání a >>= napojuje na nečistý kód čistý kód. Toť vše, žádné interpretry v pozadí neexistují, a jejich představování je skutečně záležitost víry. Stejně jako čistota IO. Sem se teď koukal na stránky Haskellu, a maj je nový ... když sem uviděl to tvrzení pod nadpisem "Purely functional", chtělo se mi rozplakat a poslat jim tam ukázku "čistého" Haskellu kterou sem právě dopsal. Prej že všechny výrazy nemůžou měnit proměnný. A co je kurva IORef, nebo TVar, nebo Chan a nebo další ze zástupu měnitelných datových struktur !!! Takový ty keci o čistotě sou lži, ve chvíli kdy mám funkci která vrací svou návratovou hodnotou hovno ale Chanellem (poslaným v argumentu!!) šupá data do mateřského vlákna, je mi blivno, to nemůže zdraví člověk nazvat PURE!

Ale na to mi evangelista odpoví, "Ale IORef se přece nemění ne? :) Furt je to ta samá reference :) Tak vidíš že sem měl pravdu ... je to čistý :)" ... Jo, svůj obsah ale mění ... a vo to de.
8.3.2015 16:09 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Takový ty keci o čistotě sou lži, ve chvíli kdy mám funkci která vrací svou návratovou hodnotou hovno ale Chanellem (poslaným v argumentu!!) šupá data do mateřského vlákna, je mi blivno, to nemůže zdraví člověk nazvat PURE!
Definice: Funkce f je pure, pokud je výraz "f a1 an" referenčně transparentní pro libovolné referenčně transparentní a1an.

Podle této definice, jsou funkce v Haskellu pure. Nevidím tedy žádný problém.

Například i funkce
function f() {
  var u = 10;
  u += 10;
  return u;
}
je pure a nevadí ani to, že uvnitř mění proměnnou u.
Ono, ve skutečnosti, operátory >> a >>= nic nevyhodnocují, je to ale pěkné a snadné si to představovat.
Podle mě to právě není dobrá a ani přesná představa (viz ten můj příklad). Lepší a přesnější je právě ta představa, kterou nabízím já, a to IO jako volná monáda + interpretr. To, že to GHC implementuje jinak, není příliš podstatné, když se to chová stejně.

Ve scalaz se to například implementuje skutečně jako volná monáda + interpretr – viz Task ze scalaz.
8.3.2015 18:11 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Smíchaný jabka s hruškama. Tvůj příklad jsou state threads. To je bublina měnitelného stavu, zamčená do monády aby neunikla do zbytku čistého kódu. Tyto bubliny měnitelného stavu lze dávat kamkoli do čistého kódu. Pokud neznáš, koukni se na STRef nebo ňák tak. Ano, state thread je jako celek z venku plně pure, protože nemůže komunikovat se světem, může ale u sebe vevnitř měnit data.

IO monáda může komunikovat se světem, takže není zvenku čistá. Tot vše, jakákoli představa interpretru je mimo.

Definice referenční transparentnosti: Funkce bere vstupní data pouze ze svých argumentů, a svůj výstup posílá pouze skrz svou návratovou hodnotu. Tečka.

Jakákoli funkce která tyto podmínky nesplňuje není pure. Funkce vracející IO monádu tyto podmínky nesplňují, takže nejsou čisté. Hotovo.
8.3.2015 19:08 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Jakákoli funkce která tyto podmínky nesplňuje není pure. Funkce vracející IO monádu tyto podmínky nesplňují, takže nejsou čisté. Hotovo.
Splňují, už jsme to tu řešili.

Např. putStrLn bere řetězec a vrací IO (), to je vše, žádný side effect nedělá, je to tedy čistá funkce.

(Problém může nastat jedině s funkcemi, které uvnitř používají unsafePerformIO apod. – např. readFile.)
IO monáda může komunikovat se světem, takže není zvenku čistá.
Vy nemáte žádný runIO, který by ji spustil, takže pro vás je čistá.

Pokud jste například v jazyce s eager vyhodnocováním, tak i následující funkce je čistá
type foo

let f (x : foo) = printf "foo"
Důvodem je, že ji nikdy nemůžete zavolat, protože nejde zkonstruovat hodnotu typu foo. (V Haskellu má každý typ hodnotu bottom, takže tam bych tu funkci ještě musel udělat striktní v 1. argumentu.)
8.3.2015 21:43 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Marné ale normální v komunitě Haskellu. Haskell pojde díky tomu zástupu evangelistů kteří nestrpí, aby se jazyk vyvinul dál a poučil ze svých chyb ... Nevadí, bude nahrazen, jen co vznikne funkcionální jazyk s podobnou platformou jako má Haskell (a že ji má úžasnou, to se musí nechat). Prostě ti to nejde vysvětlit, co se dá dělat. Kdybych měl zdraví, a neměl sem v jednom oku hrozivě naběhlou žílu, napsal bych tady ukázkovej kód, a schválně bych se zeptal: Pure || Impure $ a pokusil se udělat ještě jeden round ve snaze tě přesvědčit. Nevadí, třeba zejtra.
8.3.2015 23:02 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Nezlob se, myslim, ze to uplne nechapes a Radek to rika spravne, zejmena kdyz pise, ze si muzes IO monadu predstavit jako funkci vracejici popis (zase funkci) toho, co se ma udelat. No a pro tytez argumenty ta funkce vraci to same.

Neni mi uplne jasne, o co ti jde. Funkcionalni programovani je jen matematicky konstrukt, ktery se snazi (jistym zpusobem) usnadnit programovani. Ale realny svet je nakonec imperativni (masivne paralelni s mnoha stavy), takze se to nekde musi prevest. Vyhoda je, ze ten prevod dela pocitac, takze v tom nedela chyby jako clovek.
Lidstvo má již jen 11 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte hnutí Limity jsme my!
9.3.2015 16:55 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Ne, nejenže se nepletu, ale bohužel (ano bohužel, rád bych se pletl a používal jazyk snů) ty a tobě podobní ano. Ono, to s tou čistotou IO je něco jako pověst, 100 lidí má 100 vysvětlení proč je vlastně IO monáda čistá. Někdo odpoví na otázku "Funkce vracející IO jsou nečisté?" něco ve stylu "NE, funkce nedělají side efekty, pouze akce maj vedlejší efekty!". Někdo se utěšuje tím, že to sou zprávy, jiný tím že to pro jistotu nejsou ani funkce ale akce (a tím pádem je Haskell pak 1000% referenčně transparentní žejo) a další pak třeba tím že to je ňákej interpretr. A pak chudák praktik, mimo bezpečný svět teorie má v Haskellu data races když nepoužije zamykatelný měnitelný reference při multithredingu ... Nechci už nikdy po svých zkušenostech něco slyšet o tom že je IO monáda pure. Není. A evangelisté s těma svýma pohádkama si budu říkat furt sví voloviny, a pohřbívat Haskell a povědomí o tom, co to vlastně je Funkcionální paradigma.

Poznámka pro neznalé: Hlavní výhoda funkcionálního paradigmatu je ta, že umožňuje teoreticky implicitní paralelismus bez nutnosti paměť zamykat. Protože data se nikdy v referenčně transparentním jazyku nemění.

Takto sem to napsal aby to docvaklo. "Zamykatelná měnitelná reference"

Ale ELM vypadá hezky. Žádný měnitelný srágory, skutečně plně funkcionální jazyk. Škoda že se překládá do JS ... Dodnes se ptám proč není po 10 letech postavena v Haskellu platforma na funkcionálně reaktivním stylu ... proč
9.3.2015 17:52 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Poznámka pro neznalé: Hlavní výhoda funkcionálního paradigmatu je ta, že umožňuje teoreticky implicitní paralelismus bez nutnosti paměť zamykat. Protože data se nikdy v referenčně transparentním jazyku nemění.
Bezpečný implicitní paralelismus bez zamykání umožňují i jazyky, kde se data mění. Podívejte se třeba na jazyk ParaSail.

Cituji ze stránek jazyka:
Every ParaSail expression is defined to have parallel evaluation semantics. That is, given a ParaSail expression like F(X) + G(Y), the language rules ensure that it is safe to evaluate F(X) and G(Y) in parallel. The compiler makes the decision based on complexity or other criteria whether a given computation should be created as a potentially parallel activity. An underlying scheduler then maps these potentially parallel activities to particular processing resources, by default using a work-stealing approach, which provides load balancing across processors while also providing good locality of reference and minimal cache contention.
9.3.2015 18:45 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Zajímavé, hmm. Na ten jazyk se někdy kouknu blíže. Ono, je tam napsáno bez explicitního zamykání (na stránkách) ... Kompiler prostě sám přijde na to, co chce zamykat a co ne podle toho jak si to přerovná. Pokud máš objekt který mění stav, a chceš ho číst, či ho modifikovat, vždy ho musíš zamknout, jinak se ti taky může (nemusí, ale je to ruská ruleta) změnit pod rukama. A každé zamykání je velký overhead, čím víc vláken máš, tím větší.
9.3.2015 19:25 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Kompiler prostě sám přijde na to, co chce zamykat a co ne podle toho jak si to přerovná.
Pokud tomu dobře rozumím, tak se zamykají pouze objekty označené jako konkurentní (pomocí klíčového slova concurrent), které obsahují metody označené pomocí locked nebo queued – to jsou také místa, kde je paralelismus nedeterministický.

Ostatní věci se nezamykají a paralelismus je deterministický (nebo žádný, pokud si kompilátor myslí, že to nejde bezpečně paralelizovat). Pomocí || jde požádat o explicitní paralelismus.

Například výraz
X := 3 || X := 5
se nepřeloží.
Pokud máš objekt který mění stav, a chceš ho číst, či ho modifikovat, vždy ho musíš zamknout, jinak se ti taky může (nemusí, ale je to ruská ruleta) změnit pod rukama.
Například u indexovatelných objektů je schopen rozpoznat, zda přistupujete k disjunktním částem, takže žádné zamykání není třeba. Tohle je vidět na paralelním Quicksortu (In-Place version of Quicksort – slajd 59).
10.3.2015 11:03 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Neříkám že ten jazyk je špatný, má zabudovanou podporu pro paralelismus a lockovani skutečně tak málo paměti, kolik de, takže může mít větší efektivitu, než kdyby to člověk zamykal sám. Čistě funkionalni jazyk ale nepotřebuje žádné lockovani. To je jeho síla.
10.3.2015 11:20 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Čistě funkionalni jazyk ale nepotřebuje žádné lockovani. To je jeho síla.
Tohle pak ještě umí synchronní jazyky jako např. Esterel nebo ReactiveML.

Nicméně aplikace těchto jazyků je poměrně specifická.
10.3.2015 11:22 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
V těchto jazycích však paralelismus není implicitní.
10.3.2015 20:51 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Hele, co sem si všim tak tydle jazyky sou taky reaktivní a čarujou se signálama. A to FRP (funkcionálně reaktivní programování) taky, to na nich stojí. Ale víc nevím o těhle jazycích (spíš paradigmatu ... se to podobá různým jazykům na návrh obvodů). Jak je to vlastně u nich vnitřně řešený? Řekl bych že maj taky immutable data, ale nevím, jen se ptám.

Jo, a implicitní paralelismus (takovej kterej bude "funkční", tj nesežere víc výkonu než samotná aplikace) bohužel nemá žádný jazyk dneška. Architektury dnešní doby to nedovolují, takže FP je mimo zájem prostě proto, že nepřidává krom toho že je kód pěkný, krátký, čitelný, rychle napsatelný bohužel nic. A ještě taky dost deterministický, pokud tam teda není zavlečen měnitelný stav. Jako že je (ahoj Haskelle :( ).
11.3.2015 00:23 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Jak je to vlastně u nich vnitřně řešený?
Třeba ReactiveML se kompiluje do OCamlu a OCaml paralelismus nepodporuje (může běžet nejvýše 1 vlákno). Všechno se tedy vykonává sekvenčně a implementace může provádět a provádí mutaci dat.
11.3.2015 19:01 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Samozřejmě, pokud program běží na jednom vláknu, lockování odpadá. Pak ale ztrácí paralelismus svoji hlavní sílu.
10.3.2015 06:46 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Hm, pripada mi, ze to co chces je tak trochu nemozne. Nakonec bude muset tvuj program interagovat s vnejsim svetem, ktery nebude soucasti modelu, na kterem je postaveny, a tam pak bude vzdycky hrozit race condition, pokud se to explicitne nezamkne. Haskell a IO monada tohle odsouva trochu dal, ze sdilene pameti nekam do sdilenych dat na disku apod. Proste, prijde mi, ze implicitni paralelismus vyzaduje uzavreny svet a ten mas malokdy.
Hlavní výhoda funkcionálního paradigmatu
O tom mam trochu pochybnosti, treba klasicky clanek "Why functional programming matters" spis mluvi o vetsi modularnosti. A i jine prezentace co jsem videl si predevsim pochvaluji typovy system a kontrolu chyb.
Lidstvo má již jen 11 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte hnutí Limity jsme my!
10.3.2015 15:02 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Dosáhnout čistoty je možné. Uniquiness typování je jedna z cest. Reaktivni FP je druhá cesta. Oboje je vyzkoušené a plně čisté. To znamená, žádný side efekty a mutable paměť. IO je jen syntakticky konstrukt na vynuceni sekvenčnosti, a informováni kompileru, že tady už není čistý kód. Pouze takový switch. IO nikam problémy neodsouva, na žádnej disk. Moje race condition byla ve sdílený mutable paměti. Kdyby IO měla state na disku, bylo by to fakt pomalí.

Typový systém je fajn, maj ho ale i imperativni jazyky ... Modularita, fajn, OOP je taky modulární ... Místo jen přebírání cizích myšlenek doporučuji i myslet, popřípadě přečíst těch cizích myšlenek hodně... Neber si to osobně, nechci na tebe útočit, je to jenom konstatování mého pocitu
11.3.2015 07:55 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Místo jen přebírání cizích myšlenek doporučuji i myslet, popřípadě přečíst těch cizích myšlenek hodně
Mozna by pomohlo, kdyby ses vic rozepsal (jaky presne jsi mel problem a jak to treba FRP resi) nez si jen stezoval na to, jak jsou vsichni hlupaci a nechapou FP. Ono bys totiz pri tom vysvetlovani treba prisel na to, ze tvuj oblibeny pristup ma uplne stejne "mouchy" jako ty ostatni, akorat je to schovane nekde jinde.
Lidstvo má již jen 11 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte hnutí Limity jsme my!
11.3.2015 19:18 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
No, představ si velkej program s GUI výstupem a velkým globálním stavem. O ten stav se dělí event handlery GUI a vlákna vytvořený pomoc forkIO ("pure" IO ... pche). No, aby to fungovalo, musíš bohužel udělat globální stav měnitelný. A pokud ho nebudeš atomicky zamykat, tak se o něj vlákna a handlery porvou a vznikne data race. Což je přesně ten typ bugu, který v pure FP jazyce není. A jak to řeší FRP? Jednoduše, znáš Verilog a podobný jazyky na návrh FPGA? Ty jsou postavený na signálech a paralelním zpracování všeho. FRP taky. Vstup do programu je dán skrz porty generující signál. Výstup programu je vyveden skrz porty opačné do který sou zavedeny taktéž signály. Signály tvoří páteř programu. Fígl je v tom, že signál lze brát jako stream něměnných hodnot. V jeden okamžik má tak jeden konrétní signál konstantní a immutable hodnotu. Takže náš program je naprogramován tak, že pracuje s jednou imutable hodnotou signálu v čase t. Ostatní neuvažujeme, pouze pokryjeme všechny možné stavy kterých může signál dosáhnout. Ve chvíli kdy se signál změní, vytvoří se vlastně další větev exekuce, s opět neměnnými daty, a všechny funkce napojené na daný signál se zavolají znovu, a jejich výstup spadne do výstupních portů, a runtime system poté zajistí vykonání dané IO operace, která ale žádným způsobem nezasáhne do našeho programu, protože nezmění jeho stav. Stav je díky FRP možné uchovat, a dokonce se nemusí měnit. Stav tam totiž není nic jiného než jen další signál... :) ukázka plně pure programu bez měnitelného stavu. http://people.cs.umass.edu/~jcollard/elmtris/. No, a teď to zkus udělat v Haskellu a nesmíš použít žádný měnitelný reference ....
12.3.2015 09:22 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Hm. Prijde mi, ze vychazis z toho, ze mas globalni stav, a ten asi pak nekde zamykat musis. Pokud je FRP reseni, nechapu, proc by jsi nemohl to same FRP delat i v Haskellu.

Ono ja uz asi chapu, v cem je tvuj problem - v predstave, ze zamykani (tedy "pesimisticky" paralelismus) je vzdycky spatne. Ono totiz nekdy to muze byt i uzitecne. Tady je priklad:

Dejme tomu, ze mam dva paralelni vypocty, A a B, ktere ale pak prochazeji skrze nejaky dalsi mechanismus C, ktery je dava dohromady. Pokud vysledek A dopadne jistym zpusobem, zjisti se, ze B se musi od te chvile pocitat jinak. Kdybychom zamykali na mechanismu C, prijde vypocet A a bude blokovat vypocet B. Takze pokud se zjisti, ze B se melo pocitat jinak, to puvodni B se vubec nebude pocitat (a to je vyhoda - usetri se energie). V optimistickem pripade (treba s FRP) bychom spocitali soucasne A i B a puvodni vypocet B pak proste zahodili na zaklade toho, jak dopadlo A.

Ja proste mam za to, ze hlavni problem v tom FRP bude v tom, jak vlastne resit situace, kdy dva signaly prijdou soucasne do stejne operace, a jejich poradi ma vliv na vysledek. V FPGA to dela hardware - napriklad hodinovy synchronni signal. Prijde mi, ze ve FRP se to odsouva az nekam nakonec, a tudiz se potencialne duplikuje usili neco vypocitat (viz priklad vys).
Lidstvo má již jen 11 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte hnutí Limity jsme my!
Josef Kufner avatar 12.3.2015 10:04 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Pokud by k zahazování nedocházelo příliš často a rychlost výpočtu byla přínosnější než trocha energie, bylo by výhodnější použít optimistický přístup.

Pokud by byl dostatek energie a vycházelo to nastejno, mohl bys spustit všechny tři výpočty současně a pak s dle výsledku jednoho vybrat jeden z těch ostatních dvou, tedy jeden by se zahodil vždy. Docela si to dovedu představit u real-time řízení, kde by nebyl čas na provedení druhého výpočtu po zjištění, že první je na nic, nebo po zjištění, který je potřeba.
Hello world ! Segmentation fault (core dumped)
12.3.2015 10:46 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Proti tomu nic nemam, jen si nejsem jisty, jak moc lze ten optimismus skalovat, a prijde mi, ze FRP (nebo pristup co popisuje Kvetinac) se ho snazi naskalovat tak nejak na cely program, a tudiz potencialne zahazuje hodne velke vypocty.

Trochu se obavam, ze se to sice zdanlive zparalelizuje, ale fakticky se tam dodaji zbytecne vypocty, takze celkovy efekt bude nulovy az zaporny.

Nemyslim si, ze to ma dobre univerzalni reseni. Vede to na otazku, co kdy vyhodnotit, a to asi neni obecne resitelna uloha.
Lidstvo má již jen 11 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte hnutí Limity jsme my!
12.3.2015 16:55 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Abych to uved na pravou míru. Já popisuju pouze FRP, není to z mé hlavy. Pouze sem to objevil a učarovalo mi to, a tak držím smutek za Haskell který se FRP asi bojí jak čert kříže, jinak by už přepisovali STD knihovnu.

Ktý neefektivitě výpočtů. Musím vás všechny hoši zklamat, ale v dnešní době prostě není plně FRP (tím plně myslím i s podporou paralelismu + kompilovaný) jazyk, takže není na čem vyzkoušet jeho rychlost. Toť vše. Hádat se jestli to je nebo není rychlejší je bohužel nyní plonkové. Teoreticky je to mnohem rychlejší v silně paralelním prostředí. Pomalí naopak v málo paralelním prostředí. Ale konkrétní měření nebylo a chvilku ještě nebude udělaný. V dnešní době je FRP jazyk jedině ELM. A nebo o jiném nevím. ELM se ale překládá do javascriptu. A ačkoli dneska už javascript v prohlížeči podporuje paralelismus, ELM ho nemá implementovaný. Takže smůla. Nejde nic měřit. Nehledě na to že javascript to rychlostně zabíjí.

Závěr? V dnešní době se vyplatí lockovat, protože standardně více jak 8 exekučních vláken dnešní domácí počítače nemají. Až bude standard 1000, bude to jiná káva, a lockování bude nereálný.

Příklady máme z reality. Velké superpočítače s kopou jader mají paměť rozdělenou tak, že každé jádro a nebo skupinka jader má sdílenou paměť do které nemůžou přistupovat ostatní jádra. Tím je výrazně zmenšen overhead lockování. To že je to pak chuťovka v C++ či jiném imperativním jazyce programovat je jiná.

Díky pure FP by ale nebylo nutno todle vyvádět. Prostě by se napsal program, který by sám běžel na všech jádrech a bez lockování. Bez bugů. A bez větší námahy.

Je nabíledni otázka. Pokud to tak je, proč to už nebylo uvedeno do praxe a vyzkoušeno? Hmm. Neznám na 100% odpověď. Můj dojem ale je, že FP programátorů je málo. A pure FP takřka žádní. Schválně si zkuste ELM. Uvidíte že ty programy vypadají absolutně jinak než imperativní. Vypadají (a chovají se) skutečně funkcionálně. Díky nedostatku lidí pak vývoj na poli plně pure FP jazyků moc nepokročil. Aspoň za minulých 15 let se nic velkého nestalo ...

Ono, proč by taky. Stačí když funkce realizující IO a dělající vedlejší efekty přejmenujeme na akce. A pak můžeme hrdině křičet "máme pure FP jazyk, každá funkce je pure !!!". Ty kdo se odvážej něco namítat horou argumentů utlučeme, a ... konec no. Máme pure FP jazyk a nemáme. A nikam víc neprorazí, protože nemá výhody pure FP jazyků. Hloupá situace.
12.3.2015 21:11 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
To o cem mluvis mi zni jako Erlang. A ten uz vyzkouseny byl.

Ono je hlavne potreba zkousnout fakt, ze popularita programovacich jazyku (a dalsich technologii) se neridi jenom jejich kvalitou, ale casto jinymi vecmi (treba modou) a v podstate je velkym dilem nahodna.
Lidstvo má již jen 11 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte hnutí Limity jsme my!
13.3.2015 09:30 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Erlang se ani nesnaží vypadat pure. Takže ne. A navíc Erlang je interpretovany a dynamicky typovany, takže rychlost je ubohá. Velmi špatný příklad ...
12.3.2015 12:09 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
FRP jde použít v haskellu, má to ale dva háčky. První. Haskell nemá žádné FRP knihovny realizující IO. Tak má ... , ale bohužel nepoužitelné ... Nevyvíjí se a mají velmi omezené schopnosti. A blbou dokumentaci. Druhý problém. Haskell nemá podporu FRP v runtime. A to je špatné, protože FRP sebou přináší pár problémů, které bez optimalizace způsobují velké zpomalení.

Bohužel, real world program potřebuje stav. To je nevyhnutelné.

Když signali přijdou ve stejnou chvíli, nic se neděje, nic se nemusí počítat dvakrát. ..

Samozřejmě, nutnost počítat vše bez feedbacku, zdali je to třeba je naky výkon, který je vyplitvany. Je ale otázkou, co je náročnější, synchronizace paměti, a nebo potencionálně zbytečné výpočty. V případě málo jader je plýtvání lock free přístup, v případě velkého množství jader je to ale opačně, protože lockovani je pak neskutečně drahé. A navíc lock free kód je rychleji a snadněji napsaný. A bez bugu jako je data race.
12.3.2015 21:18 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Haskell nemá žádné FRP knihovny realizující IO.
Hm, kdyz nad tim tak premyslim, neni mi moc jasne, co by jsi chtel paralelizovat na I/O. Bud potrebujes zapisovat na stejny soubor/zarizeni, a pak se nejake contention nevyhnes. Nebo budes zapisovat na ruzna zarizeni a pak nemusis nic zamykat.
V případě málo jader je plýtvání lock free přístup, v případě velkého množství jader je to ale opačně, protože lockovani je pak neskutečně drahé.
Nebudes v pripade vice jader take zahazovat vice vypoctu, a nula od nuly pojde?
Lidstvo má již jen 11 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte hnutí Limity jsme my!
12.3.2015 22:08 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
No, všechno IO nejde paralelizovat. Já sem však měl na mysli optimalizaci IO, nikoli jeho paralelizaci.

Ne. Proč bych měl? Normálně se tam žádné výpočty nezahazují. Proč by měli? Vstup je množina signálů, se signálama pracujeme pomocí transformačních operátorů které generují další signály až nakonec větší či menší množství signálu než bylo na vstupu spadne do výstupních portů. To, že většina hodnot je třeba nám jasně už ukázal Haskell. Call-by-need právě pracuje s tím, že odstraňuje volání funkcí které produkují hodnoty které nepotřebujeme. Bohužel potřebujeme valnou většinu, a tak lenost přináší jen výhodu v nekonečných datových strukturách a nekonečné použitelné rekurzy, popřípadě v ušetřené paměti díky tomu že se k datům dá přistupovat jako ke streamu. Procesorový čas lazy evaluation neušetří žádný (s vyjímkou potlačení neefektivnosti FP paradigmatu v některých případech). Proto nemám dojem že by bylo nutno provádět nějaké velké množství zbytečných operací když 90% z nich potřebujeme jistě. A nakonec, co nám brání vymyslet nový typ evaluace vycházející z optimistic evaluation, a hodnoty které jsou často nepoužité nevykonávat paralelně ale strčit do thunku? Nic. A že by thunky potřebovaly zamykat? Ne. GHC to vyřešilo pomocí lazy blackhoolingu.
12.3.2015 23:05 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Normálně se tam žádné výpočty nezahazují. Proč by měli?
Zahazují se, když např. začnete jeden thunk vyhodnocovat paralelně ve více vláknech.
13.3.2015 09:25 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
To je ale způsobeno lazy evaluaci. Nikoli FRP.
12.3.2015 20:26 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
tvuj oblibeny pristup ma uplne stejne "mouchy" jako ty ostatni, akorat je to schovane nekde jinde.
Presne tak. Dokud neuvidim ze to lide pouzivaji a jsou s tim produktivnejsi, tak tomu neuverim. U FP evangelistu jde casto o to, ze se na to nedivaji pragmaticky, ale ideologicky / pocitove, proste se jim libi ta myslenka, prijde jim to krasne ciste.

Pripomina mi to esej o Lispu od Paula Grahama. Motivovala me k tomu, abych se jeden Lisp naucil, ale casem jsem dosel k tomu, ze ta esej je v podstate bullshit.
12.3.2015 20:58 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Všechno má své mouchy bohužel :( U FRP se zatím nemůžeme o moc nevýhodách poučit, protože nikdo nebyl schopen po 15 letech udělat pořádný kompilovaný FRP jazyk s podporou paralelismu pro normální použití. Jedno je nyní jisté, runtime musí silně optimalizovat IO. V ELMu je klasický výstup (2D) plně optimalizovaný, takže zpomalení není znát. 3D knihovna vnitřně využívající webGL ale není optimalizovaná, a je to pomalí jak prase. Proč? No, nevím jestli s tebou sem řešil knihovnu React. Jak po každé změně dělá znova GUI. Tak bohužel stejně je to i u FRP IO. S každým cyklem signálů se znova vytvoří GUI. A pokud se pak výstup neřeší tak, jak ho řeší React, je to pomalí až běda. Takže ňáký výkonnostní overhead tady je (ale opravdu malí -> sám se divím) i přes optimalizace. V silně paralelním prostředí by se to ale ztratilo.
12.3.2015 21:46 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Silne paralelni prostredi - no to je zase vec ke ktere jsem hodne skepticky. Mozna tu o tom byla diskuze, necetl jsem vsechno, myslim zes sam rikal ze se soucasnymi procesory nelze FP kod dobre paralelizovat.

Souhlas s Linusem: The whole "let's parallelize" thing is a huge waste of everybody's time.

Prijde mi, ze se ti libi ta myslenka paralelizace samotna, ale jak velky je realny prinos pro uzivatele?
12.3.2015 22:11 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
V dnešní době malí bohůmžel. Architektura to nedovoluje. A přijde ti to správně, miluju tu myšlenku paralelizace.
12.3.2015 21:18 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Ktery Lisp?

Jinak treba s Haskellem pry realne lide produktivnejsi jsou.. Ale musi se to umet dobre vyuzit, neni to uplne trivialni.
Lidstvo má již jen 11 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte hnutí Limity jsme my!
12.3.2015 21:39 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Clojure. Pokud si dobre vzpominam, nejvic mi vadilo ze nejde psat tak srozumitelny kod jako v jinych dynamickych jazycich (jako Python).
12.3.2015 22:13 Květináč
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Na Clojure mi vadí, že vyhazuje Java exceptions ... aspoň si mohli pohrát a zabalit je do kabátku Clojure, a přidat ještě metadata o části kódu která tu exception vyhodila. Takhle aby se člověk z NULL exception posral.
8.3.2015 12:04 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Ono, je více metod jak dosáhnout čistě funkcionálního jazyka.
Ano, třeba Idris má knihovnu effects a něco podobného někdo naportoval (v rámci možností) i pro Haskell.

Mj. dřívější IO v Idrisu nebyla referenčně transparentní, ale to byl bug, který je již opraven.
7.3.2015 12:39 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Taky moje prvni reakce byla, ze to musi byt strasne pomaly. Ale rychlost je naopak jedna z hlavnich prednosti Reactu, alespon ve srovnani s konkurenci (Angular, Ember).
Je otázkou, jak to srovnání provádíte.

Když máte nějakou zanořenou komponentu, tak při její aktualizaci v Reactu generujete a porovnáváte virtuální DOM minimálně pro všechny její předky (potřebujete přegenerovat uzly na cestě z kořene virtuálního domu až do aktualizované komponenty; odbočky z této cesty ne, když vhodně použijete shouldComponentUpdate).

Zatímco v Angularu můžete onu komponentu přímo nabindovat na část modelu a změna modelu změní pouze tu komponentu – nijak se to nedotkne jejích předků.
7.3.2015 13:12 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Sam jsem to neporovnaval, ale obcas jsem to cetl jako duvod, proc lide presli z Angularu na React taky se mi libila tahle ukazka: https://www.youtube.com/watch?v=z5e7kWSHWTg&index=11&list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr (cas 5:00, angular uprostred, react vpravo).

Pokud se nastavi komponente novy stav (napr. v reakci na mouse over), tak se pregeneruje jenom ta komponenta, rodic ne.

Komponentu jde oznacit jako "pure" (http://facebook.github.io/react/docs/pure-render-mixin.html) - to vlastne nastavi defaultni shouldComponentUpdate a update se provede jenom pri zmene stavu.

A samotne vygenerovani komponenty je pry radove rychlejsi nez zmena DOMu.
7.3.2015 00:17 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Kategoricka tvrzeni jsou zlo. Skutecnost je trchu slozitejsi. Mutable state je v nekterych situacich to nejlepsi reseni.
9.3.2015 12:58 x
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Vlakna jako takova zlo nejsou. Za vetsinu spatneho muze mutable state.
shared mutable state. There, I fixed it for you. Lokální měnitelný stav je OK.
9.3.2015 23:17 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Sdileny stav je taky nekdy ok. Jednou jsem delal mapovou app, jedno vlakno stahovalo mapovy dlazdice z internetu, jedno je nacitalo z cache na disku a jedno je zobrazovalo. Nejdriv jsem to chtel resit posilanim zprav, ale nakonec jsem tam pridal i sdileny stav. Posilani zprav je nekdy vhodne, nekdy ne. Stejne to vidim s funkcionalnim, objektovym, imperativnim a dalsim programovanim
7.3.2015 05:28 Kvakor
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Ale v odkazovaném článku autor netvrdí, že vlákna jsou špatná, jen se mu nelíbí, že jsou nedeterministiká. U přirozeně nedeterministikých případů (servery a databáze zpracovávající spoustu požadavků paralelně) to za problém nepovažuje, ale nelíbí se mu to u programů, které by se měly chovat zcela deterministicky. Kritizuje přístup, kdy se determinismus vynucuje tím, že se vybudují dodatečné mechanizmy nad přirozeně nedeterministickými vlákny, a navrhuje, aby místo nich byly použity metody, které jsou deterministické už od začátku.

Osobně si myslím, že v mnoha případech je naprosto jedno, pokud se program chová nedeterministicky, pokud vypodukuje deterministický výsledek (vyjímkou jsou třeba hard-realitme programy). Také si myslím, že běžné synchroznizační primitva tu nejsou od toho, aby násilně vynucovaly na vláknech determinismus (což povede k deadlockům), ale aby zabránily stavům, které sice mohou nastat jen vyjímečně, ale jejich následky by byly katastrofální (i když i tady existují vyjímky u programů typu producent-konzument, kde vlákno na "rychlejší straně" tráví většinu času v zamknutém stavu spaním). Když je třeba synchronicita, měla by být řešena spíš dobře navrženými daty (typu RCU) než kódem se spoustou "obezliček".

Mimo toho, v případechech jako GUI není zas tak nutná absolutní konzistence zobrazovaného a skutečného vnitřního stavu (opět s vyjímkou hard-realtime), stačí, aby byl stav konzistení naprostou většinu času a okamžiky nekonzistence byly natolik krátké, že by si jich uživatel stejně nevšimnul (tj. přístup ve stylu Worse is better). Uživatelům se sice nelíbní, když se jim věci "mění pod rukama", ale mnohem více se jim nelíbí, když prostředí nereaguje vůbec na nic a často pak reagují tak, že stav ještě zhoršují (nejhorší je to asi u webových aplikací).
bambas avatar 9.3.2015 11:20 bambas | skóre: 20 | blog: bambasovo
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Tak jeste je moznost v C# pouzit Parallel tasks, ktere se v pripade prikladu v blogu jevi jako vyhodnejsi. Ovsem jsou narocnejsi na obsluhu vyjimek :)
9.3.2015 13:02 x
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Proč tedy asynchronní kód nevypadá stejně jako synchronní a proč tam kompilátor nebo interpretr automaticky nedoplní awaity?
A jak pozná, že to má udělat? V C# z návratového typu, dejme tomu, ale ostatní zmiňované jazyky jsou dynamicky typované, takže to může udělat buďto vždycky (overhead jako prase), nebo nikdy (a nechat to na programátorovi).

Já bych async/await vyčítal spíš to, že nejde rozumně dělat promise pipelining.
9.3.2015 15:25 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
ale ostatní zmiňované jazyky jsou dynamicky typované, takže to může udělat buďto vždycky (overhead jako prase)
Pozná to za běhu, že se podívá, co funkce vrátila (např. jestli má vrácený objekt určitou metodu). Myslíte, že to je velký overhead?
9.3.2015 20:50 x
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
await se typicky implementuje jako nějaká syntaktická transformace, takže ano, myslím, že to je velký overhead. Dělat to za běhu by bylo ještě horší.
9.3.2015 21:05 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
await se typicky implementuje jako nějaká syntaktická transformace
Syntaktická transformace je jedna z možností, kterou např. používá C#. VC++ to dělá jinak, používá fibers (viz Async-Await in C++, část A kind of magic…), a podobně to může dělat virtuální stroj pro dynamicky typovaný jazyk.

9.3.2015 21:14 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Je možné, že některé VM jazyků s generátory už něco podobného umí.
10.3.2015 12:00 x
Rozbalit Rozbalit vše Re: async a await je krok špatným směrem
Zajímavé. Ten overhead nejsem schopný posoudit, ale nižší asi bude. Ale jsem si celkem jistý, že připojit za každé volání funkce podmínku a případné vytvoření fiber s příslušnou "kontinuací" by u jazyků, kde se dbá na výkon, stejně neprošlo. I když by se asi dalo spekulativně optimalizovat.

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.