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

JSH

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #150 kdy: 23. 03. 2016, 21:18:45 »
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.
Takhle se ale funkce v FP nechovají. Tam je jejich působnost omezená jen na to, co dostanou jako parametry.


Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #151 kdy: 23. 03. 2016, 21:28:14 »
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ší.

Clovece, ty musis byt umelecky projekt ztohoven.

v

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #152 kdy: 23. 03. 2016, 21:33:27 »
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ší.
třída "používá" jenom své předky?

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #153 kdy: 23. 03. 2016, 21:58:13 »
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ší.
třída "používá" jenom své předky?

Prakticky ano, když pošlete zprávu do nějakého objektu, neovlivní to objekt, který zprávu vyslal, třída z jiného objektu převezme jen stav, který umí zpracovat, cokoliv jiného vyvolá chybu.

V FP při řetězení funkcí map, filter, reduce chyba častěji než u OOP projde do dalšího kroku, asi tak, jako když na montážním pásu, kde montují automobily, zapomenou namontovat kliku u dveří. V jednom kontextu to vadit nebude, v jiném ano.

JSH

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #154 kdy: 23. 03. 2016, 22:05:22 »
Prakticky ano, když pošlete zprávu do nějakého objektu, neovlivní to objekt, který zprávu vyslal, třída z jiného objektu převezme jen stav, který umí zpracovat, cokoliv jiného vyvolá chybu.

V FP při řetězení funkcí map, filter, reduce chyba častěji než u OOP projde do dalšího kroku, asi tak, jako když na montážním pásu, kde montují automobily, zapomenou namontovat kliku u dveří. V jednom kontextu to vadit nebude, v jiném ano.
To už jsou tak vágní žvásty, že už to dokonce přestává být i špatně.


v

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #155 kdy: 23. 03. 2016, 22:12:01 »
Prakticky ano, když pošlete zprávu do nějakého objektu, neovlivní to objekt, který zprávu vyslal, třída z jiného objektu převezme jen stav, který umí zpracovat, cokoliv jiného vyvolá chybu.

V FP při řetězení funkcí map, filter, reduce chyba častěji než u OOP projde do dalšího kroku, asi tak, jako když na montážním pásu, kde montují automobily, zapomenou namontovat kliku u dveří. V jednom kontextu to vadit nebude, v jiném ano.
To už jsou tak vágní žvásty, že už to dokonce přestává být i špatně.
http://rationalwiki.org/wiki/Fractal_wrongness

v

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #156 kdy: 23. 03. 2016, 22:15:49 »

Prakticky ano, když pošlete zprávu do nějakého objektu, neovlivní to objekt, který zprávu vyslal, třída z jiného objektu převezme jen stav, který umí zpracovat, cokoliv jiného vyvolá chybu.
tak např. musí třída dědit od třídy string aby ji mohla "použít"?

V FP při řetězení funkcí map, filter, reduce chyba častěji než u OOP projde do dalšího kroku, asi tak, jako když na montážním pásu, kde montují automobily, zapomenou namontovat kliku u dveří. V jednom kontextu to vadit nebude, v jiném ano.
z čeho odvozujete, že k tomu dojde častěji? v praktickém FP může i funkce vyvolat výjimku, kde se to liší od praktického OOP?

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #157 kdy: 23. 03. 2016, 22:25:23 »
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
To není specifikum FP.

a to se uhlídat nedá
Ale dá, existují na to různé přístupy, například testování. (Předpokládám, že narážíte na situaci, kdy někdo změní chování funkce.)
A opět, to není specifikum FP. V OOP je to taky, a mnohem horší, protože se tam toho musí hlídat mnohem více.

protože nikde nemáte uschovanou definici závislostí
máme, jmenuje se to closure

což u OOP koncetptu existuje (dědičnost, privátní proměnné).
což nesouvisí se závislostmi, ale s mutabilitou.

Pracně se to bude pak přepisovat do tříd, aby se alespoň rámcově vědělo, co s čím souvisí.
Blbé je, že čím více a více získávám zkušeností z praxe, tím více OOP ohejbám do FP. Takže vaše odvážné tvrzení nemohu potvrdit.

Mimochodem nejsou třídy jako třídy, viz Haskell :-P

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #158 kdy: 23. 03. 2016, 22:31:55 »
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ší.
To je divný, nic z toho nepozoruji.

to která funkce uvnitř používá kterou funkci není nějak explicitně zaznamenáno
Hele, uvědomujete si, že základem FP je imutabilita, tudíž řešit něco takového je prostě absurdně zbytečné?

Když umíte tak šikovně popsat katastrofické scénáře které díky FP proběhnou, uveďte alespoň nějaký příklad toho, kdy by vámi uváděný problém mohl vzniknout.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #159 kdy: 23. 03. 2016, 22:39:26 »
Prakticky ano, když pošlete zprávu do nějakého objektu, neovlivní to objekt, který zprávu vyslal
Tak pokud ta zpráva nevrací výsledek (u klasických OOP jazyků věc nevýdaná), tak máte pravdu.
Stejně jako funkce, která je volána jinou funkcí není ovlivněná volanou funkcí.

třída z jiného objektu převezme jen stav, který umí zpracovat, cokoliv jiného vyvolá chybu.
ve FP je to stejné, funkce převezme jen parametry které umí zpracovat, cokoliv jiného vyvolá chybu.

A?

V FP při řetězení funkcí map, filter, reduce chyba častěji než u OOP projde do dalšího kroku, asi tak, jako když na montážním pásu, kde montují automobily, zapomenou namontovat kliku u dveří. V jednom kontextu to vadit nebude, v jiném ano.
Nedovedu si představit, proč by tento problém nemohl vzniknout při zřetězení objektů.

atarist

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #160 kdy: 23. 03. 2016, 22:39:57 »
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ší.

Nevim, jak je to mozny, ale vzdycky podle Tveho slohu po max. deseti slovech poznam, ze jsi to psal ty :)

Pavel Tisnovsky

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #161 kdy: 23. 03. 2016, 22:51:16 »
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 je ale úplně stejné (vlastně horší) v třídním i netřídním OOP že? Když mě někdo pod rukama změní dejme tomu String.substring tak, že se specifikují znaky od-do "včetně" (ne "kromě" u horního indexu), tak to prostě rozhodí veškerej kód, který počítá s původním chováním. Potom to buď mám pokryté testy nebo nemám, ale to není závislé na paradigmatu (u FP to však je samozřejmě jednodušší).

Btw sice uznávám, že Lisp a Scheme nejsou čisté FP jazyky, ale projekty v nich existují, a mnohé z nich *běží* delší dobu, než je životnost mnohých dnešních OOP jazyků.

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #162 kdy: 23. 03. 2016, 23:22:58 »
Ale použijete-li v rámci nějaké funkce jinou funkci, už na tom kontextu záleží
Ne, nezáleží na kontextu, nemaťme pojmy. Funkce f aplikovaná kdekoli na stejné argumenty dává stejný výsledek. To je princip FP a jeho hlavní deviza. U různých FP jazyků je to různě striktně dodržováno, ale v principu se to dodržuje všude, kde není pádný důvod to nedodržovat.

, 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
Neexistuje. V OOP nikde nemáte mapu, že metoda M1 objektu O1 používá metodu M4 objektu 04, pokud si ji nějakým spešl toolem nevygenerujete z AST.

Vezměte si libovolný středně velký OOP projekt určený pro jednovláknový běh, na pět náhodně vybraných míst dejte nějaký ten skok do jiného vlákna a celé to pusťte na sto vláknech. Jestli dokážete předem přesně identifikovat místa, na kterých může dojít k nějakému problému, tak jste buď geniální, nebo lžete. Spíš ale lžete :) Abyste to udělal, musíte ten kód kompletně projít, analyzovat si stromy volání a pravděpodobný výsledek bude, že všechno v důsledku volá všechno, takže problém může nastat kdekoli.

Čili u OOP i FP máme jeden společný pseudoproblém "když změním chování fce, tak se změní chování fce" a navíc má OOP jeden megaproblém, na který se v praxi naráží.

Erlangovský program můžu spustit na kolika chci vláknech a nestane se vůbec nic. Protože neexistuje způsob, jak by si procesy mohly do stavů šahat. Prostě není. Funkce přijímají data a vrací data, sdílená data neexistují (kromě databáze) a s procesy se komunikuje výhradně zprávami.

Ale co z nějakého FP projektu bude po 10 letech, to si ani nechci představovat.
To není potřeba si představovat, stačí se podívat na ejabberd. Je z něj po (více než) deseti letech jeden z nejúspěšnějších jabber serverů (ne-li úplně nejúspěšnější).

Pavel Tisnovsky

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #163 kdy: 24. 03. 2016, 00:01:24 »

To není potřeba si představovat, stačí se podívat na ejabberd. Je z něj po (více než) deseti letech jeden z nejúspěšnějších jabber serverů (ne-li úplně nejúspěšnější).

Z komercnich veci pak napriklad ITA, ti maji codebase starou dvacet let, stale upravuji, stale funguji (neni to ciste FP, stejne jako naprosta vetsina  OOP kodu neni ciste OOP).

Ivan Nový

Re:Rust vs. C++ (funkcionální vs. OOP)
« Odpověď #164 kdy: 24. 03. 2016, 08:10:21 »

To není potřeba si představovat, stačí se podívat na ejabberd. Je z něj po (více než) deseti letech jeden z nejúspěšnějších jabber serverů (ne-li úplně nejúspěšnější).

Z komercnich veci pak napriklad ITA, ti maji codebase starou dvacet let, stale upravuji, stale funguji (neni to ciste FP, stejne jako naprosta vetsina  OOP kodu neni ciste OOP).

Ano, ale to je aplikační doména, která je dostatečně abstraktní na to, aby to šlo naprogramovat elegantně. Je to svět sám pro sebe, vytvořený tvůrci toho projektu. Zajímavé bude sledovat, jak se to osvědčí v prostředí modelování reálných firemních procesů a nelogických požadavků na úpravy, mimo logiku aplikace, které v tomto prostředí běžně vznikají.

Osobně proti FP nic nemám, celkem mi toto paradigma vyhovuje, ale pořádek v kódu bych si od něj automaticky nesliboval. Samozřejmě nejlepší na něm je vazba na teorii kategorií.