Rust vs. C++ (funkcionální vs. OOP)

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #135 kdy: 23. 03. 2016, 09:12:41 »
Jestli to nebude tím, že v FP se vytváří výhradně nové projekty a vše je nové, svěží a čisté. Po pár letech provozu projektu to takové nebude.
RabbitMQ je devět let starý, CouchDB 11 let, Ejabberd 14 let. Nezaznamenal jsem, že by si někdo stěžoval na codebase.

Jinak FP taky obsahuje dědičnost, negativní důsledky dědičnosti v FP představuje použití funkce uvnitř funkce.
To je asi tak jako bys řekl, že v autě je taky dědičnost a tou dědičností je šaltrpáka. Proč mást pojmy? Dědičnost je dědičnost a v FP není.

Změní-li se chování té vnitřní funkce rozhodí to ne zcela odvoditelným způsobem chování jiných funkcí. Což taky zatemňuje. Závislosti mezi funkcemi jsou taky časem hodně složité a dostatečně temné.
Pokud mám funkci add(a,b) a "+" v ní přepíšu na "-", tak se ten program samozřejmě rozbije. Proti špatně napsanému kódu mě žádné paradigma neochrání. Výhoda FP je v tom, že ty funkce bývají tak jednoduché a dobře definované, že je jasné, jestli dělají co mají nebo nedělají. U Haskellu pak mám navíc silný typový systém, který spoustu chyb odhalí.

Zamotané závislosti je samozřejmě možné napsat v jakémkoliv jazyce. Rozdíl je v tom, že v OOP se tomu prakticky nedá vyhnout, zatímco v FP se člověk musí docela snažit, aby způsobil nějaký problém. Klíčem ke guláši nejsou funkce a jejich volání, ale STAV a jeho nepřehledné změny. A v FP je stav vždycky dobře izolovaný - z principu, vynuceného jazykem, který se nedá porušit i kdyby člověk chtěl.


Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #136 kdy: 23. 03. 2016, 19:32:26 »
Jestli to nebude tím, že v FP se vytváří výhradně nové projekty a vše je nové, svěží a čisté. Po pár letech provozu projektu to takové nebude.
RabbitMQ je devět let starý, CouchDB 11 let, Ejabberd 14 let. Nezaznamenal jsem, že by si někdo stěžoval na codebase.

Jinak FP taky obsahuje dědičnost, negativní důsledky dědičnosti v FP představuje použití funkce uvnitř funkce.
To je asi tak jako bys řekl, že v autě je taky dědičnost a tou dědičností je šaltrpáka. Proč mást pojmy? Dědičnost je dědičnost a v FP není.

Změní-li se chování té vnitřní funkce rozhodí to ne zcela odvoditelným způsobem chování jiných funkcí. Což taky zatemňuje. Závislosti mezi funkcemi jsou taky časem hodně složité a dostatečně temné.
Pokud mám funkci add(a,b) a "+" v ní přepíšu na "-", tak se ten program samozřejmě rozbije. Proti špatně napsanému kódu mě žádné paradigma neochrání. Výhoda FP je v tom, že ty funkce bývají tak jednoduché a dobře definované, že je jasné, jestli dělají co mají nebo nedělají. U Haskellu pak mám navíc silný typový systém, který spoustu chyb odhalí.

Zamotané závislosti je samozřejmě možné napsat v jakémkoliv jazyce. Rozdíl je v tom, že v OOP se tomu prakticky nedá vyhnout, zatímco v FP se člověk musí docela snažit, aby způsobil nějaký problém. Klíčem ke guláši nejsou funkce a jejich volání, ale STAV a jeho nepřehledné změny. A v FP je stav vždycky dobře izolovaný - z principu, vynuceného jazykem, který se nedá porušit i kdyby člověk chtěl.
Nemáte funkce a + b, ale funkci pocet_vyr_skladem_bez_obratu_var_3(sklad, bez_obratu_od, min_cena, max_cena), která vznikla z funkce poc_vyr_bez_obratu_var_2(sklad) pomocí filtru. A je použita na mnoha místech v aplikaci v různých více méně nespecifikovaných kontextech. Odvozeno z ní je dalších x funkcí, které vznikaly v průběhu 10 let. A to je budoucnost FP, no a nebo ještě horší varianta, každý programátor co na projektu kdy pracoval, si vytvořil tuto funkci vlastní :-)))

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #137 kdy: 23. 03. 2016, 19:34:50 »
Nemáte funkce a + b, ale funkci pocet_vyr_skladem_bez_obratu_var_3(sklad, bez_obratu_od, min_cena, max_cena), která vznikla z funkce poc_vyr_bez_obratu_var_2(sklad) pomocí filtru. A je použita na mnoha místech v aplikaci v různých více méně nespecifikovaných kontextech. Odvozeno z ní je dalších x funkcí, které vznikaly v průběhu 10 let. A to je budoucnost FP, no a nebo ještě horší varianta, každý programátor co na projektu kdy pracoval, si vytvořil tuto funkci vlastní :-)))
To je ale naprosto v pořádku. Funkci +/2 mám taky na spoustě míst v programu. Protože na všech těch místech dělá to, co tam dělat má. Hezké je na tom právě to, že na kontextu nezáleží a záležet nesmí.

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #138 kdy: 23. 03. 2016, 20:31:06 »
Nemáte funkce a + b, ale funkci pocet_vyr_skladem_bez_obratu_var_3(sklad, bez_obratu_od, min_cena, max_cena), která vznikla z funkce poc_vyr_bez_obratu_var_2(sklad) pomocí filtru. A je použita na mnoha místech v aplikaci v různých více méně nespecifikovaných kontextech. Odvozeno z ní je dalších x funkcí, které vznikaly v průběhu 10 let. A to je budoucnost FP, no a nebo ještě horší varianta, každý programátor co na projektu kdy pracoval, si vytvořil tuto funkci vlastní :-)))
To je ale naprosto v pořádku. Funkci +/2 mám taky na spoustě míst v programu. Protože na všech těch místech dělá to, co tam dělat má. Hezké je na tom právě to, že na kontextu nezáleží a záležet nesmí.
Ale použijete-li v rámci nějaké funkce jinou funkci, už na tom kontextu záleží, už to samo o sobě vytváří závislost, změnou té vnitřní funkce dojde ke změně chování té vnější funkce, a to se uhlídat nedá, protože nikde nemáte uschovanou definici závislostí, což u OOP koncetptu existuje (dědičnost, privátní proměnné). Takže ano, na malé projekty s omezenou dobou životnosti může být FP přínosem. Ale co z nějakého FP projektu bude po 10 letech, to si ani nechci představovat. Pracně se to bude pak přepisovat do tříd, aby se alespoň rámcově vědělo, co s čím souvisí. FP je samo o sobě nevýhodné, ale nutné v paralelním prostředí, kdy je potřeba dosáhnout stavu, aby přirozeně vznikaly bloky kódu, jejichž provádění je na sobě časově nezávislé. A k tomu se FP naopak hodí.

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #139 kdy: 23. 03. 2016, 20:43:20 »
Jak se budou chovat rozsáhlé FP aplikace po mnohaletém provozu? V časově neurčitých intervalech budou kolabovat jako celek po malé úpravě, která se projeví se zpožděním, díky provázaným funkcím, se chyba bude rychle šířit aplikací a bude téměř neidentifikovatelná.


Kit

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #140 kdy: 23. 03. 2016, 20:45:09 »
... Pracně se to bude pak přepisovat do tříd, aby se alespoň rámcově vědělo, co s čím souvisí. FP je samo o sobě nevýhodné, ale nutné v paralelním prostředí, kdy je potřeba dosáhnout stavu, aby přirozeně vznikaly bloky kódu, jejichž provádění je na sobě časově nezávislé. A k tomu se FP naopak hodí.

Proč přepisovat do tříd? Pro udržení pořádku stačí použít namespaces.

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #141 kdy: 23. 03. 2016, 20:47:48 »
Nemáte funkce a + b, ale funkci pocet_vyr_skladem_bez_obratu_var_3(sklad, bez_obratu_od, min_cena, max_cena), která vznikla z funkce poc_vyr_bez_obratu_var_2(sklad) pomocí filtru. A je použita na mnoha místech v aplikaci v různých více méně nespecifikovaných kontextech. Odvozeno z ní je dalších x funkcí, které vznikaly v průběhu 10 let. A to je budoucnost FP, no a nebo ještě horší varianta, každý programátor co na projektu kdy pracoval, si vytvořil tuto funkci vlastní :-)))
To je ale naprosto v pořádku. Funkci +/2 mám taky na spoustě míst v programu. Protože na všech těch místech dělá to, co tam dělat má. Hezké je na tom právě to, že na kontextu nezáleží a záležet nesmí.
Ale použijete-li v rámci nějaké funkce jinou funkci, už na tom kontextu záleží, už to samo o sobě vytváří závislost, změnou té vnitřní funkce dojde ke změně chování té vnější funkce, a to se uhlídat nedá, protože nikde nemáte uschovanou definici závislostí, což u OOP koncetptu existuje (dědičnost, privátní proměnné). Takže ano, na malé projekty s omezenou dobou životnosti může být FP přínosem. Ale co z nějakého FP projektu bude po 10 letech, to si ani nechci představovat. Pracně se to bude pak přepisovat do tříd, aby se alespoň rámcově vědělo, co s čím souvisí. FP je samo o sobě nevýhodné, ale nutné v paralelním prostředí, kdy je potřeba dosáhnout stavu, aby přirozeně vznikaly bloky kódu, jejichž provádění je na sobě časově nezávislé. A k tomu se FP naopak hodí.
To by platilo za předpokladu, že disponujete nějakým metajazykem, který je schopen jednoznačně a přesně posat sémantický obsah funkce, u + se vám to podaří, ale u funkcí se sémantickými přesahy to možné nebude. Každý člověk bude mít vlastní představu o tom, co dělají a nebo by měly dělat.

Kit

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #142 kdy: 23. 03. 2016, 20:50:28 »
Jak se budou chovat rozsáhlé FP aplikace po mnohaletém provozu? V časově neurčitých intervalech budou kolabovat jako celek po malé úpravě, která se projeví se zpožděním, díky provázaným funkcím, se chyba bude rychle šířit aplikací a bude téměř neidentifikovatelná.

Totéž platí i pro OOP. Opět se dostáváme k tomu, že když je programátor prase, tak zašmodrchá OOP i FP.

Kit

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #143 kdy: 23. 03. 2016, 20:54:20 »
To by platilo za předpokladu, že disponujete nějakým metajazykem, který je schopen jednoznačně a přesně posat sémantický obsah funkce, u + se vám to podaří, ale u funkcí se sémantickými přesahy to možné nebude. Každý člověk bude mít vlastní představu o tom, co dělají a nebo by měly dělat.

On snad někdo programuje nesémanticky? Sémantika se obvykle dává do názvu namespace+funkce.

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #144 kdy: 23. 03. 2016, 20:57:17 »
... Pracně se to bude pak přepisovat do tříd, aby se alespoň rámcově vědělo, co s čím souvisí. FP je samo o sobě nevýhodné, ale nutné v paralelním prostředí, kdy je potřeba dosáhnout stavu, aby přirozeně vznikaly bloky kódu, jejichž provádění je na sobě časově nezávislé. A k tomu se FP naopak hodí.

Proč přepisovat do tříd? Pro udržení pořádku stačí použít namespaces.
Nestačí. a je to nepraktické, povede to k zápisům:
let m = (sklad.brno.koje.zasuvka.mnozstvi.sum(id=11) - sklad.praha.koje.zasuvka.mnosztvi.sum(id=11)) * cenik.nakupni.(id=11, kat=katalog.filter(podminka.cenik.obdobi(12))) :-)))

JSH

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #145 kdy: 23. 03. 2016, 20:57:42 »
Nemáte funkce a + b, ale funkci pocet_vyr_skladem_bez_obratu_var_3(sklad, bez_obratu_od, min_cena, max_cena), která vznikla z funkce poc_vyr_bez_obratu_var_2(sklad) pomocí filtru. A je použita na mnoha místech v aplikaci v různých více méně nespecifikovaných kontextech. Odvozeno z ní je dalších x funkcí, které vznikaly v průběhu 10 let. A to je budoucnost FP, no a nebo ještě horší varianta, každý programátor co na projektu kdy pracoval, si vytvořil tuto funkci vlastní :-)))
To je ale naprosto v pořádku. Funkci +/2 mám taky na spoustě míst v programu. Protože na všech těch místech dělá to, co tam dělat má. Hezké je na tom právě to, že na kontextu nezáleží a záležet nesmí.
Ale použijete-li v rámci nějaké funkce jinou funkci, už na tom kontextu záleží, už to samo o sobě vytváří závislost, změnou té vnitřní funkce dojde ke změně chování té vnější funkce, a to se uhlídat nedá, protože nikde nemáte uschovanou definici závislostí, což u OOP koncetptu existuje (dědičnost, privátní proměnné). Takže ano, na malé projekty s omezenou dobou životnosti může být FP přínosem. Ale co z nějakého FP projektu bude po 10 letech, to si ani nechci představovat. Pracně se to bude pak přepisovat do tříd, aby se alespoň rámcově vědělo, co s čím souvisí. FP je samo o sobě nevýhodné, ale nutné v paralelním prostředí, kdy je potřeba dosáhnout stavu, aby přirozeně vznikaly bloky kódu, jejichž provádění je na sobě časově nezávislé. A k tomu se FP naopak hodí.
Tohle ale přece není vůbec kritika omezená na FP. Naprosto stejně může někdo rozbít vnitřnosti nějaké třídy a rozbije tím i třídy, které je používají. V jakémkoliv paradigmatu se to rozbije úplně stejně. Tomuhle dokážou zabránit třeba unittesty, ale ty zase nejsou nijak omezené na použité paradigma.

Uchází mi něco?

JSH

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #146 kdy: 23. 03. 2016, 21:03:42 »
Nestačí. a je to nepraktické, povede to k zápisům:
let m = (sklad.brno.koje.zasuvka.mnozstvi.sum(id=11) - sklad.praha.koje.zasuvka.mnosztvi.sum(id=11)) * cenik.nakupni.(id=11, kat=katalog.filter(podminka.cenik.obdobi(12))) :-)))
Začínám mít nepříjemný popis, že si pod funkcionálním programováním představujete nějaký špagetový procedurální zprasek, který mimochodem používá funkce. Jinak nechápu, proč sem taháte takovouhle zběsilost. U FP to ani neleželo.

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #147 kdy: 23. 03. 2016, 21:03:52 »
To by platilo za předpokladu, že disponujete nějakým metajazykem, který je schopen jednoznačně a přesně posat sémantický obsah funkce, u + se vám to podaří, ale u funkcí se sémantickými přesahy to možné nebude. Každý člověk bude mít vlastní představu o tom, co dělají a nebo by měly dělat.

On snad někdo programuje nesémanticky? Sémantika se obvykle dává do názvu namespace+funkce.
No malý problém je v tom, že dva lidé se málokdy shodnou na sémantickém obsahu čehokoliv. Takže těžko dohlédnou důsledky jen malé změny, nějaké funkce. U OOP u metody alespoň víte, na jaký objekt je její platnost omezena, její sémantika je fixována na objekt, naproti tomu funkce se může v aplikaci vyskytovat kdekoliv, a co je horší, v kontextech s rozdílným či jen posunutým sémantickým obsahem. Když funkci upravíte tak, aby vyhovola jednomu, vzdálí se od druhého, to naruší rovnováhu a vzniknou chyby, které budete jen těžko hledat.

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #148 kdy: 23. 03. 2016, 21:06:18 »
Jak se budou chovat rozsáhlé FP aplikace po mnohaletém provozu? V časově neurčitých intervalech budou kolabovat jako celek po malé úpravě, která se projeví se zpožděním, díky provázaným funkcím, se chyba bude rychle šířit aplikací a bude téměř neidentifikovatelná.

Totéž platí i pro OOP. Opět se dostáváme k tomu, že když je programátor prase, tak zašmodrchá OOP i FP.
Ano, samozřejmě, žádné samospásné koncepty neexistují.

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #149 kdy: 23. 03. 2016, 21:10:22 »
Nemáte funkce a + b, ale funkci pocet_vyr_skladem_bez_obratu_var_3(sklad, bez_obratu_od, min_cena, max_cena), která vznikla z funkce poc_vyr_bez_obratu_var_2(sklad) pomocí filtru. A je použita na mnoha místech v aplikaci v různých více méně nespecifikovaných kontextech. Odvozeno z ní je dalších x funkcí, které vznikaly v průběhu 10 let. A to je budoucnost FP, no a nebo ještě horší varianta, každý programátor co na projektu kdy pracoval, si vytvořil tuto funkci vlastní :-)))
To je ale naprosto v pořádku. Funkci +/2 mám taky na spoustě míst v programu. Protože na všech těch místech dělá to, co tam dělat má. Hezké je na tom právě to, že na kontextu nezáleží a záležet nesmí.
Ale použijete-li v rámci nějaké funkce jinou funkci, už na tom kontextu záleží, už to samo o sobě vytváří závislost, změnou té vnitřní funkce dojde ke změně chování té vnější funkce, a to se uhlídat nedá, protože nikde nemáte uschovanou definici závislostí, což u OOP koncetptu existuje (dědičnost, privátní proměnné). Takže ano, na malé projekty s omezenou dobou životnosti může být FP přínosem. Ale co z nějakého FP projektu bude po 10 letech, to si ani nechci představovat. Pracně se to bude pak přepisovat do tříd, aby se alespoň rámcově vědělo, co s čím souvisí. FP je samo o sobě nevýhodné, ale nutné v paralelním prostředí, kdy je potřeba dosáhnout stavu, aby přirozeně vznikaly bloky kódu, jejichž provádění je na sobě časově nezávislé. A k tomu se FP naopak hodí.
Tohle ale přece není vůbec kritika omezená na FP. Naprosto stejně může někdo rozbít vnitřnosti nějaké třídy a rozbije tím i třídy, které je používají. V jakémkoliv paradigmatu se to rozbije úplně stejně. Tomuhle dokážou zabránit třeba unittesty, ale ty zase nejsou nijak omezené na použité paradigma.

Uchází mi něco?
Rozsah škod u FP bude ale větší právě proto, že funkce nejsou vázány na nějaký pevně daný kontext, není zachován řetěz dědičnosti, to která funkce uvnitř používá kterou funkci není nějak explicitně zaznamenáno, spontánně vzniklé struktury závislostí budou daleko složitější.