Async + Immutable rubrika: Programování: Jiné

9 Taco
položil/-a 3.4.2015

Prosím, neřešte výraziva (callback nebo async, to je buřt) a doufám, že mi prominete (psuedo)haskellovskou syntax.

Mějme funkci sum, která bere parametr pole, a sečte prvky toho pole. Výsledek vyhazuje callbackem.

sum xs \x => print x

Předpokládejme, že prvky toho pole mají být funkce, vracející hodnoty v callbacku - asynchronně.
Takže něco jako:
xs = [ plus 1 2, plus 3 4, plus 5 6 ]
(funkce plus má tři argumenty, kde poslední je ten callback.)

Cíl je, naimplementovat funkci sum tak, aby byla i implementace immutable. (Žádné zvenčí huj, uvnitř fuj.) Také je důležité zachovat, aby se ty tři funkce plus opravdu volali asynchronně (tedy nepovažuji za řešení vnořit to do sebe a volat je postupně).
Funkci print neřešte.

Myslíte, že to jde? Napsali byste jak (zhruba)? Zajímala by mě i případná podpora jazyků, které to například umí by default (a splňují všechny ty podmínky).

Komentáře

  • Honza Břešťan : Nejsem si jisty, jestli to nejak pujde skloubit. V podstate souhlasim s maryem, ze bud jsou ty funkce volat sekvencne (pak je sice sum neblokujici, ale jednotlive funkce navzajem sekvencni), nebo jdou pouzit promises, ktere ale maji vnitrni stav. Nenapadaji me dalsi reseni, ktera by nemely jeden z tech problemu. Na druhou stranu bych se nebal "zvenci huj, uvnitr fuj", protoze na tomhle konceptu stoji spousta dulezitych abstrakci (mimojine samotna immutabilita na soucasnych pocitacovych architekturach). Dulezite je, aby to "fuj" neleakovalo ven, jinak by melo stacit, ze bude ten stav v sum (treba ty promises) izolovany, ne nutne immutable. 4.4.2015
  • Taco : No já to podezření mám také, ale přišlo mi to jako zajímavá otázka. A protože jsem nebyl schopen najít řešení, ptám se tady. Problém s tím "zvenčí huj, uvnitř fuj" v tomto případě znamená, že jej nebudu moct spustit (bez nějaké explicitní kontroly) paralelně na více vláknech. A to by byla škoda. 4.4.2015
  • Honza Břešťan : Tak az ted jsem plne pochopil zadani, sorry. Tohle immutable skoro urcite nepujde, protoze ten callback jednotlivych prvku pole nemuze delat nic jineho nez side effect. Reseni s promises mi prijde jako nejschudnejsi kompromis. Jsem zvedavy, jestli se objevi nejaka dalsi zajimava reseni. 4.4.2015
  • pussy : Nelze použít jazyk, jenž podporuje paralelní vyhodnocení (stačí paralelní pole)? 6.4.2015
  • Taco : @pussy: Klidně. Nějaký příklad? 6.4.2015
  • Carless : Není to náhodou Fork/Join? 29.4.2015
  • Taco : @Carless: To vypadá zajímavě, nastuduji. Díky. 29.4.2015
odkaz
5 Havri
odpověděl/-a 5.4.2015

Jak už bylo řečeno, v callbacku můžu udělat jedině vedlejší efekt, takže si nemyslím, že to nějak půjde. Leda s nějakým frameworkem, který mě od toho vedlejšího efektu odstíní, takže s přísliby by to mohlo vypadat takto (Funkce plus a sum budou vytvářet vždy nové přísliby, takže by to mělo také fungovat paralelně.):

var Promise = require('bluebird');
 
var plus = function(a, b) {
    console.log("I am trying to compute " + a + " + " + b);
    return new Promise(function(resolve) {
        setTimeout(function() {
            var result = a + b;
            console.log("Got it! It's " + result);
            resolve(result);
        }, Math.random() * 1000);
    });
};
 
var sum = function(xs) {
    return Promise.reduce(xs, function(prev, cur) {
        return cur + prev;
    }, 0);
}
 
sum([plus(1, 2), plus(3, 4), plus(5, 6)]).then(function(result) {
    console.log("sum: " + result);
});

Výstup, ať je vidět, že se to volá asynchronně:

I am trying to compute 1 + 2
I am trying to compute 3 + 4
I am trying to compute 5 + 6
Got it! It's 7
Got it! It's 3
Got it! It's 11
sum: 21

Nevidím v tom vnitřním stavu u příslibů problém, když půjdu u jakéhokoliv řešení dostatečně hluboko, tak nějaký vedlejší efekt najdu.

Komentáře

  • Taco : Takže odpověď zní, že to nejde? 28.4.2015

Pro zobrazení všech 4 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.