Dědičnost dnes

balki

Re:Dědičnost dnes
« Odpověď #570 kdy: 30. 01. 2017, 09:11:15 »
To je uz ina vec, ze c++ nema tolke moznosti reflexie a nie je dynamicky typovany. Skratka stale zahmlievate fakt, ze posielanie messagov je analogia k volaniu metod. Pokial si spominam, neexistujuci selector je tiez len dalsi pripad selectoru.  Takze nie je potrebne to ponimat ako magiu.

Stranou: By mě zajímalo, kdo vymyslel ten termín "dynamicky typovaný". Je to hovadina. 1. čisté OP typy nemá, takže buďto je třídovaný, nebo má prototypy. 2. Nic se nikde netypuje/netříduje, objektu přijde zpráva a objekt zná/nezná. Nic dalšího tam není, žádné škatulkování.

K věci: Toto vlákno neslouží k vysvětlování základů pure object programming, to by se dalo dělat donekonečna, obzvláště v případě, že si to někdo ani nechce nechat vysvětlit. Obraťte se na literaturu nějakých smalltalkařů (ne javařů!), najdete v ní nejspíš i provedení zasílání zpráv virtuálním počítačem.

Nuda, operujete tu s terminom "ciste oop", ani poriadne neviete podlozit, co to je. Termin dynamicky typovany je oproti roznym "pozdnim vazbam" a podobnym laxne definovanym frikulinstinam bezne zauzivana terminologia.  Tu je clanok z root https://www.root.cz/clanky/staticka-dynamicka-typova-kontrola/.  Tu je wikipedia  https://en.wikipedia.org/wiki/Type_system. Literaturu smalltalkarov som cital v ramci studia, ale iba seriozne publikacie.


SB

Re:Dědičnost dnes
« Odpověď #571 kdy: 30. 01. 2017, 09:23:05 »
Jak vis, ze nerozumi OOP? Zato vime, ze ty neznas FP.. Me prijde, ze tak trochu popiras, ze by sly veci delat lepe.
...
Jadro Armstrongova argumentu je v tom, ze michani funkci a dat neni dobry napad. A s tim bych souhlasil, vede to k problemum. Chces poprit, ze to vede k problemum? Klasicky priklad je trida matice a vektor, ktery se treba v C++ resi pres spratelene tridy.

Ono ostatne i existence mnoha "design patterns" naznacuje, ze takova ta originalni predstava OOP, ze lze pomoci trid modelovat domenove objekty, tak docela nevysla.

Jeho odpovědi nedávají smysl, se slávou to nemá co dělat. Koncept rozdělení dat a funkcí jsem pochopil, neměnitelné stavy dosud neviděl. To tvrdíte vy.
Matici a vektor rozepište.
Možná by bylo vhodné připomenout nevýhody rozdělení ve FP.
V čem spočívá ta chyba tříd?

SB

Re:Dědičnost dnes
« Odpověď #572 kdy: 30. 01. 2017, 09:48:03 »
Každopádně důsledkem je, že vnitřně je modul sice immutable, ale navenek (a to mě v interakci s ostatními zajímá) pochopitelně mutable.
Tady nebezpečně motáš pojmy. Mutabilita se týká dat. Co je "mutabilita modulu", to bysme si museli nějak zadefinovat, jinak to bude plácání o koze a o voze :)

Tohle by bylo třeba dořešit, protože tu vznikl dojem, že FP je tak nějak celé immutable, což mi bylo hned od začátku jasné, že je to hovadina. Proto jsem se ptal, jak přechází systém (jako celek) mezi stavy.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Dědičnost dnes
« Odpověď #573 kdy: 30. 01. 2017, 09:50:55 »
Každopádně důsledkem je, že vnitřně je modul sice immutable, ale navenek (a to mě v interakci s ostatními zajímá) pochopitelně mutable.
Tady nebezpečně motáš pojmy. Mutabilita se týká dat. Co je "mutabilita modulu", to bysme si museli nějak zadefinovat, jinak to bude plácání o koze a o voze :)

Tohle by bylo třeba dořešit, protože tu vznikl dojem, že FP je tak nějak celé immutable, což mi bylo hned od začátku jasné, že je to hovadina. Proto jsem se ptal, jak přechází systém (jako celek) mezi stavy.
Čisté FP je immutable.

SB

Re:Dědičnost dnes
« Odpověď #574 kdy: 30. 01. 2017, 09:51:52 »
Jde, ale je to míň praktické - musím pro každé volání rezervovat thread/process. Proto je defaultní asynchronnost lepší, protože asynchronní je prostě asynchronní a pokud chci blokovat, tak blokuju přímo ve vlákně volajícího, něpotřebuju nic "navíc".
To není tak úplně pravda, stačí jen vytvořit/přepnout kontext, podobně jako v Go, kde klidně může běžet plně asynchronní program na jednom vlákně. V C by se to dělalo typicky přes ucontext. Pak se dá snadno napsat kupříkladu něco jako node.js bez callbacků.

To samé mě napadlo - jestliže mám asynchronně bezpečný model, můžu pro spouštění zpracování fronty (bez ohledu na její implementaci) jednotlivých objektů/aktorů používal libovolný počet (1-n) vláken přepínáním kontextu.


Kiwi

Re:Dědičnost dnes
« Odpověď #575 kdy: 30. 01. 2017, 09:52:23 »
Rozhodně. Jenže na tom taky OOP založeno není, ačkoli si to většina lidí zblbnutých javským a cépluspluskovým pojetím myslí. Objektový program jsou škatulky, které si vzájemně vyměňují zprávy, a pochopení tohoto konceptu zpráv je naprosto klíčové k správnému pochopení celého objektového programování, protože právě v tom vězí celá ta síla a tvárnost.
No právě. Jenže většina těch nesmyslných nekonečných debat "o OOP" jsou právě debaty o tom co je "správné" dědit z čeho a jestli je "správné" mít k atributům accessory... Prostě nudné, zbytečné pseudoproblémy, které vnějšího pozorovatele vedou k úvaze, jestli (takhle chápané) OOP víc problémů nepřináší, než jich řeší...

Když to celé někdo (autoři C++, autoři Javy) nesprávně pochopili a nesprávně implementovali, tak je taková úvaha správná. Jenže to se pak nebavíme o objektovém, ale o jakémsi podtřídně-typovém programování.

Pak nám ovšem vyvstává otázka, jestli neexistují jiné, "neobjektové" způsoby modelování, které problém neřeší elegantněji

Možná jo, i když za těch 30 let, co se motám kolem počítačů, už na žádné zázračné stříbrné kulky, co dokážou skolit každý problém jedinou ranou, fakt věřit nezačnu. Jednu nesnáz vyřeší, další dvě způsobí. Ale když už porovnávat a vylepšovat, tak pro boha ne s javským (nebo nedej bože dokonce C++kovým), ale se smalltalkovským pojetí OOP. Pak totiž třeba přijdeš na to, že všechny ty pseudoproblémy OOP jsou ve skutečnosti problémy Javy nebo C++ a jejich podtřídně-typového programování, ale ne samotného objektového programování, s nímž mají společnou vážně jen možnost odvozovat podtřídy.

Re:Dědičnost dnes
« Odpověď #576 kdy: 30. 01. 2017, 10:22:33 »
Tohle by bylo třeba dořešit, protože tu vznikl dojem, že FP je tak nějak celé immutable, což mi bylo hned od začátku jasné, že je to hovadina. Proto jsem se ptal, jak přechází systém (jako celek) mezi stavy.
"Tak nějak celé immutable" nevím, co znamená. V čistém FP jsou data immutable a ohledně fcí platí referenční transparentnost. Tyhle dvě věci asi celkem stačí na popis toho, o co jde, víc není potřeba říkat.

Jak (čistě funkcionální) celej přechází mezi stavy už tady bylo řečeno víckrát: "uvnitř jazyka" nic nikam nepřechází, protože celý systém je de facto čistě statický. To, co nějak mění stav, je runtime (na základě těch statických instrukcí).

Re:Dědičnost dnes
« Odpověď #577 kdy: 30. 01. 2017, 10:23:28 »
Možná jo, i když za těch 30 let, co se motám kolem počítačů, už na žádné zázračné stříbrné kulky, co dokážou skolit každý problém jedinou ranou, fakt věřit nezačnu. Jednu nesnáz vyřeší, další dvě způsobí. Ale když už porovnávat a vylepšovat, tak pro boha ne s javským (nebo nedej bože dokonce C++kovým), ale se smalltalkovským pojetí OOP. Pak totiž třeba přijdeš na to, že všechny ty pseudoproblémy OOP jsou ve skutečnosti problémy Javy nebo C++ a jejich podtřídně-typového programování, ale ne samotného objektového programování, s nímž mají společnou vážně jen možnost odvozovat podtřídy.
Naprostý souhlas, v tomhle nejsme v žádném sporu.

ava

Re:Dědičnost dnes
« Odpověď #578 kdy: 30. 01. 2017, 10:24:06 »
JS, poprosim k Vasim tvrdeniam literaturu. Funkcionalne programovanie je momentalne moje hobby, a rad by som si teda precital.
  • o tom, ako je enkapsulacia zbytocna
  • ako robi FP zo vzorov trivialne veci, co nemaju pomenovanie
  • ako robia abstrakcie funkcionalneho programovania objektove abstrakcie zbytocnymi

Potom budem schopny polemizovat, lebo zatial nechapem suvislosti.

Dakujem :)

Ahoj,
mrkni na přednášku https://www.youtube.com/watch?v=Rmer37g9AZM , mohlo by to být pro tebe zajímavé.

SB

Re:Dědičnost dnes
« Odpověď #579 kdy: 30. 01. 2017, 10:56:12 »

Objection 1: OOP oproti FP "data" a "funkce" spojuje z jednoduchého důvodu, a to, že data bez funkcí jsou k ničemu stejně tak jako funkce bez dat, přičemž funkce jsou vytvořeny pro daná data (to nevylučuje práci s obecnými daty jako v FP!). Myšlenka nutnosti nespojovat funkce a data jen z důvodu, že se jedná o jiné kategorie, je neopodstatněná (to ale neznamená, že to nejde).
Tam jde myslím spíš o to, že OOP svazuje konkrétní fce s konkrétními ("svými") daty a tím komplikuje (záměrně - a podle některých chybně) přístup k datům jinými fcemi.

Stupidní příklad: fce List.reverse(list) může fungovat nad listem čehokoli, protože o položkách nic nepředpokládá. Vesele teda jednou jedinou funkcí otáčím listy zákazníků, faktur i planet sluneční soustavy. Když chci totéž udělat u OOP, tak mi tenhle jeden problém exploduje do tisíce dalších: asi teda chci nějaké rozhraní IReversable, nebo chci nějak data zpřístupnit? Nebo pro každý objekt úplně nezávisle napíšu tutéž fci o.reverse()? Co je správně? Co je antipattern? Co porušuje zapouzdření? Neměl by objekt PlanetList dědit z List? No jo, ale já potřebuju, aby dědil z PlanetsOfSolarSystem. Co s tím? Vícenásobná dědičnost? Ale ne, to je fuj. atd.atd.atd. Armstrong tvrdí (nemusíš s ním souhlasit, ale myslím, že to nemůžeš jenom tak šmahem odbýt), že kdybys ty data nesvázal s konkrétními, předem danými funkcemi, měl bys míň problémů.

...


Myslím, že jste si na ony připomínky odpověděl sám - všechna použití, co jste uvedl, jsou použití seznamu (List), a proto budou mít též jeho vlastnosti - je-li něčeho řada a je třeba jí otočit pořadí, téměř jistě se bavíme o seznamu, který toto již dávno umí. Je-li třeba použít jiný než obecný seznam (a to je otázka!), vždy jej lze specializovat, případně (u vaší obavy) při různých speciálních vlastnostech složit a zvláštnosti doplnit. Ani trait na to není třeba (osobně bych to ani nedělal). List JE ubiquitous a obecný, není třeba jej implementovat opakovaně na mnoha místech pomocí sady funkcí, pod kterou stejně bude ležet nějaká datová struktura seznamu.
Možná jste zvolil nevhodný příklad, nebo vyrábíte problém, kde není. To je můj názor, neberte to jako boj. ;)

Re:Dědičnost dnes
« Odpověď #580 kdy: 30. 01. 2017, 10:58:56 »
Myslím, že jste si na ony připomínky odpověděl sám - všechna použití, co jste uvedl, jsou použití seznamu (List), a proto budou mít též jeho vlastnosti - je-li něčeho řada a je třeba jí otočit pořadí, téměř jistě se bavíme o seznamu, který toto již dávno umí. Je-li třeba použít jiný než obecný seznam (a to je otázka!), vždy jej lze specializovat, případně (u vaší obavy) při různých speciálních vlastnostech složit a zvláštnosti doplnit. Ani trait na to není třeba (osobně bych to ani nedělal). List JE ubiquitous a obecný, není třeba jej implementovat opakovaně na mnoha místech pomocí sady funkcí, pod kterou stejně bude ležet nějaká datová struktura seznamu.
Možná jste zvolil nevhodný příklad, nebo vyrábíte problém, kde není. To je můj názor, neberte to jako boj. ;)
Podstata je v tom, že když se programátor v záchvatu oop-vitosti rozhodne ten list uvnitř objektu skrýt, tak na něm ten reverse neudělám.

SB

Re:Dědičnost dnes
« Odpověď #581 kdy: 30. 01. 2017, 11:49:11 »
Jak funguje třeba funkce Map.put? Vytvoří kopii celé původní mapy nebo na ní odkáže?
Já vlastně ani nevím a je mi to jedno ;) Dležitý je, že starou i novou mapu můžu pořád někam předávat  a nemusím se bát, že by mi je někdo změnil. Jestli to vnitřně nějaká data sdílí (předpokládám že jo), je mi jako programátorovi šuma fuk, mě zajímají ty vnější garance.

Zde pořád nějak nevidím tu výhodu FP od OOP (teď nemám na mysli optimalizaci a paralelizaci, ale model) - když potřebuju objekt immutable, udělám si ho, když ne, nic mě nenutí. Rozhoduju se dle použití.

Re:Dědičnost dnes
« Odpověď #582 kdy: 30. 01. 2017, 11:56:09 »
Zde pořád nějak nevidím tu výhodu FP od OOP (teď nemám na mysli optimalizaci a paralelizaci, ale model) - když potřebuju objekt immutable, udělám si ho, když ne, nic mě nenutí. Rozhoduju se dle použití.
Jedna z výhod je nabíledni: pokud si můžu vybrat, potom o výsledku neexistuje žádná garance.

Pokud jsou data zaručeně imutabilní => mám garanci, že obsahují jenom backward reference (nemůžou tam z principu být cykly) => můžu mít např. výrazně efektivnější GC.

Můžu si vybrat => garance není => musím počítat s nejhorší variantou => v nejhorším případě jsem si vybral imutabilitu a přesto z ní nemůžu těžit.

SB

Re:Dědičnost dnes
« Odpověď #583 kdy: 30. 01. 2017, 12:16:33 »
Popravdě, aniž bych si to zkusil napsat mě teď od židle nenapadá, v čem že je u matic a vektorů problém. Mohl bys naznačit?
...
Mame operaci nasobeni matice a vektoru - patri do tridy matice, nebo do tridy vektor? A pokud si jednu vybereme, jak se dostaneme k prvkum te druhe? (Samozrejme, muzeme modelovat oboji jako matici, ale pak jsme se ponekud vyhnuli tomu skryvani.)

Jiny priklad. Mame tridu matice, a ta ma nejake metody. Potrebuji spocitat permanent, ale na to tam metoda neni. Jak to implementovat, aniz bych nemel pristup k vnitrnostem te tridy matice?
...

Nebo obecne, vezmi si jakykoli algoritmus. Je existence toho algoritmu vlastnosti objektu, s kterymi pracuje? Je treba moznost vypoctu maximalniho toku vlastnosti elektricke site? Zda se mi, ze ne. Jenze ten algoritmus typicky o tech objektech neco predpoklada a potrebuje k nim pristupovat. Takze pro implementaci toho algoritmu neni lhostejne, jaka je vnitrni struktura tech objektu.

Jsou situace, kde OOP funguje pomerne dobre - treba GUI. Protoze na to v naivni implementaci zadny algoritmus nepotrebujes. Tam pokud spolu veci nejak musi interagovat, tak maji spolecneho predka (treba Widget). OOP je proste postavene na nejake analogii s realnym svetem, ktery tak nejak prirozene delime do objektu, a prisuzujeme jim duvod, proc neco delaji. Ale to je do jiste miry dost nepresny popis reality a na mnoho problemu selhava.

Citace
To se ale týká právě těch jazyků typu C++ či Java, v nichž se pomocí design patterns dohání ta jejich objektová polovičatost.

Ano, zajima me to v Jave, to je kanonicky pripad jazyka, co pouzivaji zastanci OOP. Ale klidne muzes naznacit, jak bys to resil ve Smalltalku; pochybuji, ze pujde o skutecne skryvani dat.

Ufff, to je hukot...

Matici je možno modelovat vektory, pak půjde o skládání!!! Dědičnost tu nemá co pohledávat! Nebo je možno matici modelovat bez vektorů, aniž by to mělo vliv na funkcionalitu. Provedení je ponecháno na soudruhovi.
K čemu je mi matice či vektor, do kterého nevidím?!!! Neboli asi budou immutable, ale není důvod, aby jejich hodnoty nebyly viditelné!

Chybí metoda? Je několik možností:
1. Specializace: vytvořit podtřídu - její zvláštností je, že umí něco navíc. V pořádku.
2. Extended method (u některých jazyků).
3. V Smalltalku: třídy (i z jiných balíčků) je možno běžně rozšiřovat o vlastní metody (ve svých balíčcích), takže stačí doplnit.
4. Skládání: Vyrobím objekt, který bude obsahovat původní matici (její vytvoření ap.), a doplním jej o požadovanou metodu. V jazyku s pozdní vazbou (Smalltalk, ...) to mám o to jednodušší, že na předelegování metod seru a vyřeším je jedním vrzem přeposláním zprávy z doesNotUnderstand (to kdyby někdo potřeboval vědět, na co že ta hovadina je).
5. Vždy (jako všude jinde) můžu třídu vyrobit znovu, nechci-li použít něco existujícího.

Opět snadná uchopitelnost OOP v GUI, protože to jde vidět?

Takže opět a pořád dokola: Chyba není v OOP, ale v znalosti jeho použití.

SB

Re:Dědičnost dnes
« Odpověď #584 kdy: 30. 01. 2017, 12:21:55 »
...Ale ten standard povědomí o OOP, který nastavilo především C++, je prostě k zblití...

Jinak řečeno se jedná o únos termínu OOP.