Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: filosof 17. 08. 2015, 21:52:37
-
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód
(loop [] (println (eval (read))) (recur))
mě hned napadlo, že je to nepřehledné, prostě na první pohled nevidíte, co je argument čeho.
Pak mě napadlo, že se to asi dá zapsat taky takhle
(loop []
(println
(eval
(read)
)
)
(recur)
)
V čem se to pak ale liší od tolik hejtovanýho callback hellu známýho třeba z Node.js?
Působí to na mě tak, že to může být fajn, když si člověk něco bastlí sám, ale v komplikovaným kódu někoho cizího
bude asi problém se vyznat.
-
Teď mě napadá, že to úplně CB Hell není, protože jako argumenty přímo nefigurují definice metod, ale i tak mi to příjde nepřehledné a takové akademické.
Sice je fajn, že napíšu jeden řádek kódu co dělá spoustu věcí, ale zase u toho člověk musí víc přemýšlet a ve výsledku časově to vyjde třeba nastejno, jako kdybych si IDE pro imperativní jazyk vybavil nějakýma šablonama, které se mi budou automaticky vkládat, třeba pro cykly apod..
-
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód
(loop [] (println (eval (read))) (recur))
mě hned napadlo, že je to nepřehledné, prostě na první pohled nevidíte, co je argument čeho.
V Lispu už je takový zvyk psát výraz na jeden řádek, pokud se na něj vejde. Zřejmě je to dáno tím, že se často ladí přímo v řádkovém editoru, do skriptu se pak dostanou jen odladěné řádky. Matamatické výrazy se také přece píší na jeden řádek.
-
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód
(loop [] (println (eval (read))) (recur))
mě hned napadlo, že je to nepřehledné, prostě na první pohled nevidíte, co je argument čeho.
- zvyk
- je třeba toho méně přečíst, aby si to pochopil
Sice je fajn, že napíšu jeden řádek kódu co dělá spoustu věcí, ale zase u toho člověk musí víc přemýšlet a ve výsledku časově to vyjde třeba nastejno
- No, já bych si troufl tvrdit, že nevyjde. V mnoha jazycích (java například) musíš napsat spoustu balastu, kterej zdržuje při psaní i při čtení. V clojure rovnou píšeš co to má být (názvy rutin) a jediný balast jsou závorky.
-
V čem se to pak ale liší od tolik hejtovanýho callback hellu známýho třeba z Node.js?
Liší se to tím, že tady se nejedná o žádné callbacky, ale rovnou výsledky funkcí jsou argumenty jiných funkcí.
Oproti tomu callback hell je k tomu, že funkce se dočasně pozastaví a pak pokračuje tím callbackem.
-
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód
(loop [] (println (eval (read))) (recur))
mě hned napadlo, že je to nepřehledné, prostě na první pohled nevidíte, co je argument čeho.
Ono to v praxi není tak hrozné, například se v Clojure dost využívají makra, takže se dá psát i while, pokud už ke smyčce dojde, což se v mém případě stane tak jedenkrát na tisíc řádků kódu (fakt to není až tak využívané jako v Javě). Navíc kód dokážou zpřehlednit threading makra, forma doto atd. Btw loop-recur jsem ještě nikdy v praxi nepoužil, vlastně ani klasickou (tail) rekurzi, navíc ten uvedený kód byl na téma REPL (z čeho ta zkratka vznikla atd.). Ovšem to nemění nic na tom, že přechod od imperativních jazyků s céčkovou syntaxí je zpočátku složitější, to je pravda.
-
Ad Pavel Tisnovský, funkcionální a pak se tam stejně nabastlí cykly, třídy a objekty, kusy kódu v jiném jazyku, například SQL a pod., protože to obecenstvo (praxe?) žádá.
-
Tak, tak, ten kod je vic lispovy nez funkcionalni.
-
Ad Pavel Tisnovský, funkcionální a pak se tam stejně nabastlí cykly, třídy a objekty, kusy kódu v jiném jazyku, například SQL a pod., protože to obecenstvo (praxe?) žádá.
Záleží na tom, co se programuje. Čistě funkcionální kód samozřejmě nemám (už jen kvůli I/O), ale Clojure k tomu dost brutálně vede, o dost víc, než klasické LISPy například. Teď se dívám na jeden produkční kód, kterej mám na cca 5000 řádků a z nefunkcionálních věcí je tam:
1) asi 10x doseq (tj. vlastně for-each)
2) I/O (logování)
3) DB I/O
4) asi jen 4x atomy (mutable proměnné, session)
-
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód
(loop [] (println (eval (read))) (recur))
mě hned napadlo, že je to nepřehledné, prostě na první pohled nevidíte, co je argument čeho.
Pak mě napadlo, že se to asi dá zapsat taky takhle
(loop []
(println
(eval
(read)
)
)
(recur)
)
V čem se to pak ale liší od tolik hejtovanýho callback hellu známýho třeba z Node.js?
Působí to na mě tak, že to může být fajn, když si člověk něco bastlí sám, ale v komplikovaným kódu někoho cizího
bude asi problém se vyznat.
Tak se správnými nástroji (emacs údajně něco má) to asi není až tak hrozné, jak se na první pohled zdá... ale třeba Haskell je mnohem přehlednější (jen je těžší se ho naučit) a i delší jednořádkové výrazy mohou být poměrně čitelné.
-
třeba Haskell je mnohem přehlednější (jen je těžší se ho naučit) a i delší jednořádkové výrazy mohou být poměrně čitelné.
Zkuste napsat analogický program v Haskellu.
Domnívám se, že jednoduchost souvisí s přehledností.
-
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód
(loop [] (println (eval (read))) (recur))
mě hned napadlo, že je to nepřehledné, prostě na první pohled nevidíte, co je argument čeho.
Pak mě napadlo, že se to asi dá zapsat taky takhle
(loop []
(println
(eval
(read)
)
)
(recur)
)
Ona ta prehlednost je dana hlavne zvykem. Kdybych vzal kus kodu napsany v clojure/lispu a kus analogickeho kodu napsany v cemkoliv jinem a ukazal to svy sestre tak neprecte ani jedno. Kdybych ji naucil lisp a ukazal ji kus kodu v jave, tak by ji prisla zase neprehledna ta java a naopak.
V čem se to pak ale liší od tolik hejtovanýho callback hellu známýho třeba z Node.js?
Působí to na mě tak, že to může být fajn, když si člověk něco bastlí sám, ale v komplikovaným kódu někoho cizího
bude asi problém se vyznat.
Lisi se to napriklad v tom, ze tam jediny callback neni. Proste se zavola read, ten neco vrati to se preda evalu, ten neco vrati a to se vytiskne. Samozrejme by jsi mohl si vyrobit promenou, zavolat read, navratovou hodnotu do toho ulozit, pak vzit tu promenou dat ji jako parametr evalu vysledek zase ulozit do dalsi promeny a ten nakonec predat printu. Jestli v tom vydis nejaky zlepseni, to uz je tvoje vec :-)
-
Taky by to slo napsat treba takto:
(forever (-> (read) (eval) (print)))
Jenze to by chtelo hned na zacatek vysvetlit -> (a mozna i to makro)
-
Taky by to slo napsat treba takto:
(forever (-> (read) (eval) (print)))
A je tohle ještě funkcionální ? To už je skoro jako klasika :-)
for (;;) { print(eval(read)) }
-
for (;;) { print(eval(read)) }
-
Mě napadlo, co kdyby se ty závorky barevně zvýraznily? Pak by to mohlo být čitelné i na jednom řádku. Stačilo by třeba 4-6 barev s tím, že s hlubším zanořováním by se barvy mohly cyklicky opakovat, to už by nevadilo. Třeba to některé editory dělají, nevím, v tomto jazyku sem nikdy nedělal.
A taky mi připadá ta první a poslední závorka jako zbytečná. Prostě zbytečně přezávorkováno.
-
Taky by to slo napsat treba takto:
(forever (-> (read) (eval) (print)))
A je tohle ještě funkcionální ? To už je skoro jako klasika :-)
for (;;) { print(eval(read)) }
Proc by nebylo :), forever je jen makro postaveny nad loop-recur, -> je taky makro (to ted z hlavy nedam, jak je interne delany).
-
třeba Haskell je mnohem přehlednější (jen je těžší se ho naučit) a i delší jednořádkové výrazy mohou být poměrně čitelné.
Zkuste napsat analogický program v Haskellu.
Domnívám se, že jednoduchost souvisí s přehledností.
input <- getContents
putStr (mojefunkce input)
{- příp.
(putStr.fce1.fce2.fce3) input
nebo
putStr $ fce1 someArg $ fce2 (dalsi argument...) input
-}
Ty složitější případy by v lispu vypadali asi takhle
println (fce1 (fce2 (fce3 (read))))
println (fce1 someArg (fce2 (dalsi argument...) (read)))
Což mi přehlednější nepřijde... jiná věc je, že v haskellu na to potřebujete IO, k čemuž nemáte vždy přímý přístup ale to je trochu jiná otázka.
-
Mě napadlo, co kdyby se ty závorky barevně zvýraznily? Pak by to mohlo být čitelné i na jednom řádku. Stačilo by třeba 4-6 barev s tím, že s hlubším zanořováním by se barvy mohly cyklicky opakovat, to už by nevadilo. Třeba to některé editory dělají, nevím, v tomto jazyku sem nikdy nedělal.
A taky mi připadá ta první a poslední závorka jako zbytečná. Prostě zbytečně přezávorkováno.
jasne, editory rainbow parenthesis umi a pouzivaji (bez toho by se skutecne psalo spatne).
http://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim-3-cast/#k03
-
Což mi přehlednější nepřijde... jiná věc je, že v haskellu na to potřebujete IO
Na to narážím - místo klasického skládání funkcí (.) budete potřebovat Kleisliho skládání (>=>), podobně ani použití eval (https://hackage.haskell.org/package/plugins-1.5.4.0/docs/System-Eval-Haskell.html) nebude tak jednoduché, když budete chtít výsledek vytisknout.
-
Proc by nebylo :), forever je jen makro postaveny nad loop-recur, -> je taky makro (to ted z hlavy nedam, jak je interne delany).
Tomu rozumím, nechce se Vám psát boilerplate nativně v Clojure tak to zmáknete pomocí maker jinak, až se to nebezpečně blíží imperativnímu programování :-) Mimochodem značné užívání maker obvykle značí nedokonalost jazyka, kdy programátor potřebuje víc než mu jazyk nabízí ;)
-
A taky mi připadá ta první a poslední závorka jako zbytečná. Prostě zbytečně přezávorkováno.
Nejsou zbytečné. Bez závorek je to odkaz na strom, se závorkami je to jeho vyhodnocení.
-
Proc by nebylo :), forever je jen makro postaveny nad loop-recur, -> je taky makro (to ted z hlavy nedam, jak je interne delany).
Tomu rozumím, nechce se Vám psát boilerplate nativně v Clojure tak to zmáknete pomocí maker jinak, až se to nebezpečně blíží imperativnímu programování :-) Mimochodem značné užívání maker obvykle značí nedokonalost jazyka, kdy programátor potřebuje víc než mu jazyk nabízí ;)
Ovšem nikoli v LISPovských jazycích, které s makry právě počítají :-) Co je velký problém - termín "makro" používají i céčkové jazyky na úplně jinou a mnohem primitivnější věc, takže to lidi mají zažité jako něco špinavého, hnusný hack, divné chybové hlášení atd. Jenže v homoikonickém jazyku tomu tak není, tam mají makra svůj význam právě pro rozšíření možností jazyka, pro tvorbu DSL apod.
-
A taky mi připadá ta první a poslední závorka jako zbytečná. Prostě zbytečně přezávorkováno.
Nejsou zbytečné. Bez závorek je to odkaz na strom, se závorkami je to jeho vyhodnocení.
Až takhle? Tak takový jazyk si odpustím.
-
Již je mi to jasné, jazyk sám o sobě umí málo a makra jsou přímo nutnost :)
-
Již je mi to jasné, jazyk sám o sobě umí málo a makra jsou přímo nutnost :)
Přesně tak :-)
[je dobré připomenout, že celý LISP je možné vytvořit jen ze čtyř funkcí a tří speciálních forem, to se potom polepí dohromady makry :D]
-
Což mi přehlednější nepřijde... jiná věc je, že v haskellu na to potřebujete IO
Na to narážím - místo klasického skládání funkcí (.) budete potřebovat Kleisliho skládání (>=>), podobně ani použití eval (https://hackage.haskell.org/package/plugins-1.5.4.0/docs/System-Eval-Haskell.html) nebude tak jednoduché, když budete chtít výsledek vytisknout.
No tak vždycky můžete použít IO monádu, ale třeba tak jak sem to napsal si můžete napsat libovolnou "pure" funkci [Char] -> [Char] a o IO se postará main... celkově složitostí jednoho konkrétním programu přehlednost jazyka nezměříte, zvlášť když jde o tak specifickou věc jako interpret daného jazyka. To by v tomhle případě byl nejpřehlednější bash.
-
Nejsou zbytečné. Bez závorek je to odkaz na strom, se závorkami je to jeho vyhodnocení.
Až takhle? Tak takový jazyk si odpustím.
Těch závorek není víc než v jiném jazyce. Srovnej: funkce(par1, par2)
a (funkce par1 par2)
- závorka navíc tam není a ještě ušetříš čárku.
-
Což mi přehlednější nepřijde... jiná věc je, že v haskellu na to potřebujete IO
Na to narážím - místo klasického skládání funkcí (.) budete potřebovat Kleisliho skládání (>=>), podobně ani použití eval (https://hackage.haskell.org/package/plugins-1.5.4.0/docs/System-Eval-Haskell.html) nebude tak jednoduché, když budete chtít výsledek vytisknout.
celkově složitostí jednoho konkrétním programu přehlednost jazyka nezměříte, zvlášť když jde o tak specifickou věc jako interpret daného jazyka.
Souhlasím. Nicméně, když se podíváte na kód, který dělá vedlejší efekty (např. práce s DB, grafická uživatelská rozhraní), tak IMO situace nebude o nic lepší.
-
Což mi přehlednější nepřijde... jiná věc je, že v haskellu na to potřebujete IO
Na to narážím - místo klasického skládání funkcí (.) budete potřebovat Kleisliho skládání (>=>), podobně ani použití eval (https://hackage.haskell.org/package/plugins-1.5.4.0/docs/System-Eval-Haskell.html) nebude tak jednoduché, když budete chtít výsledek vytisknout.
celkově složitostí jednoho konkrétním programu přehlednost jazyka nezměříte, zvlášť když jde o tak specifickou věc jako interpret daného jazyka.
Souhlasím. Nicméně, když se podíváte na kód, který dělá vedlejší efekty (např. práce s DB, grafická uživatelská rozhraní), tak IMO situace nebude o nic lepší.
Tak nikdo vám nebrání používat Haskell jako procedurální jazyk, jen se pak nemůžete tvářit, že ten kód je funkcionální jako v lispu.
Nejsou zbytečné. Bez závorek je to odkaz na strom, se závorkami je to jeho vyhodnocení.
Až takhle? Tak takový jazyk si odpustím.
Těch závorek není víc než v jiném jazyce. Srovnej: funkce(par1, par2)
a (funkce par1 par2)
- závorka navíc tam není a ještě ušetříš čárku.
Taky se u jazyků jako C dlouhý jednořádkový příšery moc často nepoužívaj. U Lispu to je to problém, protože to často ani jinak nejde.
-
Což mi přehlednější nepřijde... jiná věc je, že v haskellu na to potřebujete IO
Na to narážím - místo klasického skládání funkcí (.) budete potřebovat Kleisliho skládání (>=>), podobně ani použití eval (https://hackage.haskell.org/package/plugins-1.5.4.0/docs/System-Eval-Haskell.html) nebude tak jednoduché, když budete chtít výsledek vytisknout.
celkově složitostí jednoho konkrétním programu přehlednost jazyka nezměříte, zvlášť když jde o tak specifickou věc jako interpret daného jazyka.
Souhlasím. Nicméně, když se podíváte na kód, který dělá vedlejší efekty (např. práce s DB, grafická uživatelská rozhraní), tak IMO situace nebude o nic lepší.
Tak nikdo vám nebrání používat Haskell jako procedurální jazyk
Otázkou je, zda to momentálně jde lépe (tj., zda existují rozšířené a podporované knihovny)?
-
Otázkou je, zda to momentálně jde lépe (tj., zda existují rozšířené a podporované knihovny)?
Tak ono toho až tolik potřeba neni, funkcionální struktury pořád používat můžete a na flow control máte funkce/procedury.
-
Těch závorek není víc než v jiném jazyce. Srovnej: funkce(par1, par2)
a (funkce par1 par2)
- závorka navíc tam není a ještě ušetříš čárku.
Taky se u jazyků jako C dlouhý jednořádkový příšery moc často nepoužívaj. U Lispu to je to problém, protože to často ani jinak nejde.
To jako vážně? Málokdo v C/C++ dodržuje maximum 80 sloupců - alespoň podle toho, jaké zrůdy občas vidím. V Lispu je dlouhý zápis příznakem, že se taková funkce či makro má rozdělit. Kromě toho není problém lámat a odsazovat řádky téměř kdekoli a jakkoli - viz zápis v prvním příspěvku.
Programy v C/C++ mají v sobě hromady balastu. Když se ty závorky přepočítají, vychází to téměř stejně jako v Lispu. Jen jsou ty závorky v Lispu víc vidět.
-
Proc by nebylo :), forever je jen makro postaveny nad loop-recur, -> je taky makro (to ted z hlavy nedam, jak je interne delany).
Tomu rozumím, nechce se Vám psát boilerplate nativně v Clojure tak to zmáknete pomocí maker jinak, až se to nebezpečně blíží imperativnímu programování :-)
Ono by se nemělo jen tak říkat "ve funkcionálním programování nesmí být smyčky". To je sice pravda ve chvíli, kdy je tam nějaká řídicí proměnná (tedy mutable objekt) nebo něco podobného, ale proč ne u nekonečné smyčky, což přesně je REPL? Navíc ještě REPL není funkce, takže se těžko funkcionálně implementuje :D
-
je dobré připomenout, že celý LISP je možné vytvořit jen ze čtyř funkcí a tří speciálních forem, to se potom polepí dohromady makry :D
Je otázka, kde je ten správný poměr. Některé jazyky mají velmi mnoho jazykových konstrukcí (C++, Perl). Opačný extrém je asi ten Lisp. Taková Java je někde mezi tím resp. spíš směrem k Lispu – je to taky relativně jednoduchý jazyk s málo konstrukcemi (i když přibývají – např. lambdy v 8) a všechno ostatní se řeší ne makry, ale knihovnami, tzn. třídami a metodami. Což třeba mně osobně dost vyhovuje (mj. online dokumentace, skvělá podpora v IDE…). Stěžovat si na ukecanost Javy podle mého není moc na místě – stačí používat vhodné knihovny/frameworky nebo si rozvrhnout vlastní kód tak, abych nemusel opakovat stejné úkoly pořád dokola. Když to programátor neudělá, tak může psát stejně otrocký kód i v C++, Perlu, Lispu… a mít program na spoustu řádků, který se špatně udržuje.
-
To jako vážně? Málokdo v C/C++ dodržuje maximum 80 sloupců - alespoň podle toho, jaké zrůdy občas vidím. V Lispu je dlouhý zápis příznakem, že se taková funkce či makro má rozdělit. Kromě toho není problém lámat a odsazovat řádky téměř kdekoli a jakkoli - viz zápis v prvním příspěvku.
Programy v C/C++ mají v sobě hromady balastu. Když se ty závorky přepočítají, vychází to téměř stejně jako v Lispu. Jen jsou ty závorky v Lispu víc vidět.
...lepší výraz pro to co jsem myslel by asi byl "jednovýrazové". Přehlednost s jedním typem závorek vs 2-3 typy je diametrálně odlišná, navíc procedurální jazyky častěji dávají příkazy "pod sebe" (logicky i vizuálně), což s přehledností taky pomáhá. Lisp je možná přehlednější, než si spoustu lidí myslí, ale C-like jazyky jsou pořád přehlednější.
-
...lepší výraz pro to co jsem myslel by asi byl "jednovýrazové". Přehlednost s jedním typem závorek vs 2-3 typy je diametrálně odlišná, navíc procedurální jazyky častěji dávají příkazy "pod sebe" (logicky i vizuálně), což s přehledností taky pomáhá. Lisp je možná přehlednější, než si spoustu lidí myslí, ale C-like jazyky jsou pořád přehlednější.
V Lispu se příkazy také dávají "pod sebe". Jenže pokud jsou všechny funkce jednořádkové, odsazování ztrácí na významu.
Otázkou je, zda je přehlednější aplikace v Lispu na 5000 řádek nebo aplikace v C-like jazyku na 30000 řádek.
-
Stěžovat si na ukecanost Javy podle mého není moc na místě
Myslím, že to je na místě. Jednak programy v Javě obsahují zbytečný syntaktický balast (návod na jeho odstranění - viz prezentace C# light (http://www.slideshare.net/ScottWlaschin/c-light)). Dalším problémem je, že řada konceptů jde v Javě vyjádřit pouze značně složitě nebo vůbec - například asynchronní kód, modularita (kvůli tomu, že Java má pouze nominální podtypový polymorfismus) nebo binární metody (metoda má argument stejného typu jako this a platí to i v podtřídách; důsledkem je, že podtřídy nejsou nutně podtypy).
-
...lepší výraz pro to co jsem myslel by asi byl "jednovýrazové". Přehlednost s jedním typem závorek vs 2-3 typy je diametrálně odlišná, navíc procedurální jazyky častěji dávají příkazy "pod sebe" (logicky i vizuálně), což s přehledností taky pomáhá. Lisp je možná přehlednější, než si spoustu lidí myslí, ale C-like jazyky jsou pořád přehlednější.
Jenze v Clojure, o kterem je toto tema, se taky extenzivne pouzivaji tri typy zavorek (samozrejme pro jine ucely). S tou citelnosti si nejsem tak jisty, co je objektivne lepsi, zrovna C s milionem corner casu moc nevynika. To uz je lepsi porovnani napriklad s Pascalem ci Luou, kde jsou "prikazove zavorky".
Ale dulezitejsi je jina vec - hlavne uzaviraci zavorky jsou v podstate v LISPu/Clojure prakticky bezvyznamne, proto se taky davaji na stejny radek za posledni cast vyrazu, na rozdil od C/Javy, kde to lidi vetsinou mlati na nove radky (a proto maji taky vertikalni hustotu kodu dost mizernou, coz se jeste nasobi horsimi moznostmi refaktoringu). Taky jsem kdysi mel snahu psat v LISPu podobne jako v cecku (tj. neco jako navrhuje puvodni tazatel), ale je to skutecne blbost.
-
Jednak programy v Javě obsahují zbytečný syntaktický balast (návod na jeho odstranění - viz prezentace C# light (http://www.slideshare.net/ScottWlaschin/c-light))...
Zajímavá prezentace. Silně mi připomíná můj vlastní metajazyk, který jsem si napsal pro Vim a který mi napsaný text (ne nepodobný C# light) on-line překládá do konkrétního programovacího jazyka.
-
Jednak programy v Javě obsahují zbytečný syntaktický balast (návod na jeho odstranění - viz prezentace C# light (http://www.slideshare.net/ScottWlaschin/c-light))...
Zajímavá prezentace.
Tolik zbytečných slajdů (přes 70?) o zbytečnosti getterů/setterů/properties, to je opravdu výkon, čekal bych, že se tam dozvím něco zajímavějšího než mlácení slámy. Ale co taky čekat od lidí ze světa C#, že?
Silně mi připomíná můj vlastní metajazyk, který jsem si napsal pro Vim a který mi napsaný text (ne nepodobný C# light) on-line překládá do konkrétního programovacího jazyka.
Taky jsem o něčem takovém uvažoval, dokonce bych si rád napsal vlastní dokonalý jazyk, asi jako každý programátor :-) Ale zatím na to nedošlo.
Pro Javu existuje Lombok (https://projectlombok.org/), který ti psaní getterů/setterů a spousty dalších věcí ušetří (logovače, toString, líné gettery atd.).
-
Jednak programy v Javě obsahují zbytečný syntaktický balast (návod na jeho odstranění - viz prezentace C# light (http://www.slideshare.net/ScottWlaschin/c-light))...
Zajímavá prezentace.
Tolik zbytečných slajdů (přes 70?) o zbytečnosti getterů/setterů/properties, to je opravdu výkon, čekal bych, že se tam dozvím něco zajímavějšího než mlácení slámy. Ale co taky čekat od lidí ze světa C#, že?
Zhruba polovina těch věcí (ne-li víc) je v podstatě Groovy...
-
[je dobré připomenout, že celý LISP je možné vytvořit jen ze čtyř funkcí a tří speciálních forem, to se potom polepí dohromady makry :D]
To je jistě zábavné a rozumím Vám, ale v praxi se tento přístup neosvědčil, nýbrž čas od času se vezme oblíbená sada takovýchto maker a přetaví se do nového jazyka.
Stěžovat si na ukecanost Javy podle mého není moc na místě
Stěžovat si na ukecanost Javy je správné neboť je to pravda a všichni to ví, jazyk Java má od samého počátku několik vážných pochybení, naštěstí ne zas tak moc.
návod na jeho odstranění - viz prezentace C# light (http://www.slideshare.net/ScottWlaschin/c-light)
C# light je příznačné myšlení Hurvínků neprogramátorů co se ještě v životě nesetkali s reálným větším projektem a proto mají zdání že je toho v C# zbytečně mnoho. Připadá mi to jako když plavčík co byl nejdál v Tróji v ZOO vymýšlí plavidlo na cestu do Yokohamy.
Otázkou je, zda je přehlednější aplikace v Lispu na 5000 řádek nebo aplikace v C-like jazyku na 30000 řádek.
Je to dobrá otázka. To že nějaký jazyk spotřebuje méně řádek neznamená že bude přehlednější, není to samosebou. Namátkou Perl.
-
návod na jeho odstranění - viz prezentace C# light (http://www.slideshare.net/ScottWlaschin/c-light)
C# light je příznačné myšlení Hurvínků neprogramátorů co se ještě v životě nesetkali s reálným větším projektem a proto mají zdání že je toho v C# zbytečně mnoho.
C# 6 už tu cestu nastoupil a zdá se, že C# 7 v ní bude pokračovat (https://github.com/dotnet/roslyn/issues/2136). Například algebraické datové typy
abstract class Expr;
class X() : Expr;
class Const(double Value) : Expr;
class Add(Expr Left, Expr Right) : Expr;
class Mult(Expr Left, Expr Right) : Expr;
class Neg(Expr Value) : Expr;
nebo stručná syntax pro n-tice patří k velmi žádaným vylepšením.
Na druhé straně má C# podobné problémy s modularitou jako Java a nevypadá to, že by v blízké době zmizely (jsou dány běhovým prostředím).
-
C# light je příznačné myšlení Hurvínků neprogramátorů co se ještě v životě nesetkali s reálným větším projektem a proto mají zdání že je toho v C# zbytečně mnoho. Připadá mi to jako když plavčík co byl nejdál v Tróji v ZOO vymýšlí plavidlo na cestu do Yokohamy.
Sám seš Hurvínek. Podívej se na autora těch slajdů a pak třeba na autora http://fsharpforfunandprofit.com/ ty Hurvínku...
-
Tolik zbytečných slajdů (přes 70?) o zbytečnosti getterů/setterů/properties, to je opravdu výkon, čekal bych, že se tam dozvím něco zajímavějšího než mlácení slámy. Ale co taky čekat od lidí ze světa C#, že?
Prolistování těch slajdů mi zabralo méně času, než shlédnutí průměrného hollywoodského filmu, takže toho nelituji. Vlastně mi ani nevadilo, že se to týkalo C#, protože se to dá aplikovat i na Javu či PHP. Dobře jsem se zasmál, když jsem místo ":" uviděl "=". Jen aby to nevypadalo jako Python :)
Silně mi připomíná můj vlastní metajazyk, který jsem si napsal pro Vim a který mi napsaný text (ne nepodobný C# light) on-line překládá do konkrétního programovacího jazyka.
Taky jsem o něčem takovém uvažoval, dokonce bych si rád napsal vlastní dokonalý jazyk, asi jako každý programátor :-) Ale zatím na to nedošlo.
Zkusil jsem si už hodně svých "dokonalých jazyků", než jsem přišel k závěru, že nejlepší bude ho naučit svůj editor. I když bude ten metajazyk sebeošklivější, stále budu vidět na obrazovce výsledný kód a ušetří mi to hledání spousty zbytečných syntaktických chyb. Také ho mohu kdykoli modifikovat, aniž bych tím ohrozil dříve napsané aplikace.
Pro Javu existuje Lombok (https://projectlombok.org/), který ti psaní getterů/setterů a spousty dalších věcí ušetří (logovače, toString, líné gettery atd.).
Víš dobře, že getterům/setterům se vyhýbám. Jsou to jen berličky pro programátory, kteří neumí psát objektově. Makro pro metodu toString() mám přetíženo pro všechny mnou používané jazyky - stačí jen napsat ",S" a vygeneruje mi to kostru metody ve správné syntaxi. Na tom je vidět, kolik balastu v zápisu je. Jenže proč je tam ten balast? Aby se nám to dobře četlo. Pokud si někdo do programu narve hromadu zbytečných komentářů, tak se nemůže divit, že je stěží čitelný. I bez komentářů se program v Javě či PHP dá docela dobře číst.
V Lispu se komentáře dají rozumně psát pouze mezi funkcemi - i proto bývají užitečnější než v C-like jazycích, ve kterých ten syntaktický balast nese roli komentářů. Skutečné komentáře v C-like jazyku mají vlastně jen jednu roli: Ukazují, že zde je chyba, kterou je nutné opravit.
-
Tam jsou víceméně mírné vylepšení, ve těch slajdech jsou zásadní jiné věci.
Podívej se na autora těch slajdů
Po shlédnutí slajdů jsem si jist že to nikdy neudělám.
-
Tam jsou víceméně mírné vylepšení, ve těch slajdech jsou zásadní jiné věci.
Například?
-
Vy to nevidíte sám rovnou a musíte se ptát ? :o To jste mě tedy zklamal. Namátkou strany 20, 24, 28, 49
-
Vy to nevidíte sám rovnou a musíte se ptát ? :o To jste mě tedy zklamal. Namátkou strany 20, 24, 28, 49
Říkáte, že ve slajdech jsou zásadní jiné věci, ale dal jste odkaz na slajdy 20 a 24, které jsou součástí návrhu C# 7 - viz Proposal: Pattern matching and record types (https://github.com/dotnet/roslyn/issues/206). Dokonce změna ze slajdu 24 (primární konstruktor) byla původně plánována pro C# 6, ale nakonec byla odebrána (http://stackoverflow.com/questions/26915789/primary-constructors-no-longer-compile-in-vs2015).
-
Říkáte, že ve slajdech jsou zásadní jiné věci, ale dal jste odkaz na slajdy 20 a 24, které jsou součástí návrhu C# 7 - viz Proposal: Pattern matching and record types (https://github.com/dotnet/roslyn/issues/206). Dokonce změna ze slajdu 24 (primární konstruktor) byla původně plánována pro C# 6, ale nakonec byla odebrána (http://stackoverflow.com/questions/26915789/primary-constructors-no-longer-compile-in-vs2015).
Tak to mi uniklo to uznávám. Je vidět že se jim p. konstruktory ve C# 6 nezamlouvají, jak se dalo čekat a dali to k ledu.
-
Víš dobře, že getterům/setterům se vyhýbám. Jsou to jen berličky pro programátory, kteří neumí psát objektově.
Budeš řvát jak opařená kočka až jednou, za mnoho let zjistíš, že opravdově objektově je to právě s těmi gettery.
-
Víš dobře, že getterům/setterům se vyhýbám. Jsou to jen berličky pro programátory, kteří neumí psát objektově.
Budeš řvát jak opařená kočka až jednou, za mnoho let zjistíš, že opravdově objektově je to právě s těmi gettery.
Co je na getterech, setterech a public atributech tak opravdu objektového?
-
Co je na getterech, setterech a public atributech tak opravdu objektového?
To je porad dokola - je to moznost, jak zapouzdrit. Casto to neni dobry navrh ale samo o sobe to nic proti OOP neni.
-
Co je na getterech, setterech a public atributech tak opravdu objektového?
To je porad dokola - je to moznost, jak zapouzdrit. Casto to neni dobry navrh ale samo o sobe to nic proti OOP neni.
To je pořád dokola - nic z toho se nechová objektově. Copak se ptám psa, jak mám za něho štěkat? To je getter.
-
Co je na getterech, setterech a public atributech tak opravdu objektového?
Getter a setter jsou běžné metody objektu. Zakázat možnost z venku měnit členské proměnné přímo a donutit místo toho volat nějakou metodu je hlavní způsob jak udržet objekt v konzistentním stavu.
Jiná možnost je neustále při každé změně vyrábět novou instanci a řešit to v konstruktoru, to ale není vůbec praktické.
To je pořád dokola - nic z toho se nechová objektově. Copak se ptám psa, jak mám za něho štěkat? To je getter.
Psa se ptáš kolik má blech a zda má obojek nebo nemá. Štěkat zvládne sám.
-
Co je na getterech, setterech a public atributech tak opravdu objektového?
To je porad dokola - je to moznost, jak zapouzdrit. Casto to neni dobry navrh ale samo o sobe to nic proti OOP neni.
To je pořád dokola - nic z toho se nechová objektově. Copak se ptám psa, jak mám za něho štěkat? To je getter.
To je kravina. Getter je když se ptáš psa, jakou má barvu chlupů. Nebo jestli je mu zima. Nebo jestli má hlad. Prostě cokoliv, co ten pes z principu ví lépe než okolí. Schopnost štěkat není (nemusí být) getter.
-
uz je to tady, uz se to roztaci. jako kazdou stredu, jako kazdy patek.
http://i.imgur.com/LqAU25T.png
Kit, uz ste vymysleli priklady na vasu ohromnu architekturu? vase predosle priklady boli total fail.
-
debata sa opakuje, obrazky sa musia tiez
(http://i.imgur.com/LqAU25T.png)
-
Getter a setter jsou běžné metody objektu. Zakázat možnost z venku měnit členské proměnné přímo a donutit místo toho volat nějakou metodu je hlavní způsob jak udržet objekt v konzistentním stavu.
Jiná možnost je neustále při každé změně vyrábět novou instanci a řešit to v konstruktoru, to ale není vůbec praktické.
Problémem getterů a setterů je, že nejsou polymorfní. Pokud budu mít ve třídě Article metodu setTitle(), tak taková metoda se mi vůbec nehodí ve třídě Person či Store. Nemohu tedy použít stejné rozhraní.
To je pořád dokola - nic z toho se nechová objektově. Copak se ptám psa, jak mám za něho štěkat? To je getter.
Psa se ptáš kolik má blech a zda má obojek nebo nemá. Štěkat zvládne sám.
Hmm. A co mi ten pes odpoví na otázku, kolik má blech, když neumí mluvit? Proč bych se ho měl ptát, zda má obojek? To mi přece k ničemu není. Prostě ho připnu na vodítko. Pokud nemá obojek, vyhodí výjimku.
Nechme toho, bavíme se tu o funkcionálních jazycích.
-
Kit nepotřebuje Getter na zjištění barvy psa. Vytvoří si singleton factory, která dostane instanci psa a z databáze si vytáhne jeho barvu. Může to být krásně polymorfní, protože stejná metoda může jednou dostat psa a podruhé kočku. Dovnitř hodí nějaké mutexy, aby to bylo thread safe. Ukol byl splněn, škaredý Getter je pryč.
-
Problémem getterů a setterů je, že nejsou polymorfní. Pokud budu mít ve třídě Article metodu setTitle(), tak taková metoda se mi vůbec nehodí ve třídě Person či Store. Nemohu tedy použít stejné rozhraní.
Možná je to tím, že se OOP už delší dobu vyhýbám, ale tohle jsem teda vůbec nepochopil. Atricle, Person a Store by měli mít nějaké společné rozhraní? Jaké? Co mají společného? A jak ve vytvoření takového rozhraní vadí gettery/settery? Ne že bych to téma chtěl přiživovat, ale tohle konkrétně by mě zajímalo.
-
Getter a setter jsou běžné metody objektu. Zakázat možnost z venku měnit členské proměnné přímo a donutit místo toho volat nějakou metodu je hlavní způsob jak udržet objekt v konzistentním stavu.
Jiná možnost je neustále při každé změně vyrábět novou instanci a řešit to v konstruktoru, to ale není vůbec praktické.
Problémem getterů a setterů je, že nejsou polymorfní. Pokud budu mít ve třídě Article metodu setTitle(), tak taková metoda se mi vůbec nehodí ve třídě Person či Store. Nemohu tedy použít stejné rozhraní.
Což je jedině žádoucí. Article není Person, natož Store. Nejen, že nemůžeš použít stejné rozhranní, ale ani by tě to nemělo napadnout.
Psa se ptáš kolik má blech a zda má obojek nebo nemá. Štěkat zvládne sám.
Hmm. A co mi ten pes odpoví na otázku, kolik má blech, když neumí mluvit?
Sorry, ale to je demagogie nejhlubšího zrna. Chápu to tedy správně, že uznáváš, že máme pravdu? :-)
-
[je dobré připomenout, že celý LISP je možné vytvořit jen ze čtyř funkcí a tří speciálních forem, to se potom polepí dohromady makry :D]
To je jistě zábavné a rozumím Vám, ale v praxi se tento přístup neosvědčil, nýbrž čas od času se vezme oblíbená sada takovýchto maker a přetaví se do nového jazyka.
Osvědčil. Pouze pokud některé potřebné funkce vycházejí pomalé nebo je potřebné vytvořit ovladač pro nějaký HW, tak se přidají v C a stanou se součástí speciální verze Lispu pro nějaký konkrétní účel.
-
Problémem getterů a setterů je, že nejsou polymorfní. Pokud budu mít ve třídě Article metodu setTitle(), tak taková metoda se mi vůbec nehodí ve třídě Person či Store. Nemohu tedy použít stejné rozhraní.
Když jsou getter a setter normální metody, mohou (částečně) být virtuální/polymorfní. Minimálně můžete mít setTitle(string value) i setTitle(string value, int color) a můžete to v potomku přepsat jinak. Že je Vám setTitle v Person a Store k ničemu je v pořádku.
Hmm. A co mi ten pes odpoví na otázku, kolik má blech, když neumí mluvit? Proč bych se ho měl ptát, zda má obojek? To mi přece k ničemu není. Prostě ho připnu na vodítko. Pokud nemá obojek, vyhodí výjimku.
Nepotřebuji aby pes mluvil, potřebuji vědět jak moc akutní je shánět šampon na blechy. Na připínání vodítka bych ho napřed musel mít, půjdu tedy ke skříni a budu se ptát skříně zda k ní jde připnout obojek ? :) Ne nebudu, psa se zeptám zda má obojek a skříně se zeptám zda obsahuje vodítko.
-
Atricle, Person a Store by měli mít nějaké společné rozhraní? Jaké? Co mají společného? A jak ve vytvoření takového rozhraní vadí gettery/settery? Ne že bych to téma chtěl přiživovat, ale tohle konkrétně by mě zajímalo.
Například mohou sdílet rozhraní Presentable, což může nahradit všechny gettery jedinou metodou. Volající pak nemusí vůbec zkoumat, jak se ta metoda u konkrétní třídy jmenuje, ale použije vždy stejný název metody presentate(). Samozřejmě tohle použiji pouze pokud mi z nějakého důvodu nevyhovuje standardní metoda toString().
Ale už toho vážně nechávám, věnujme se funkcionálním jazykům.
-
Například mohou sdílet rozhraní Presentable, což může nahradit všechny gettery jedinou metodou. Volající pak nemusí vůbec zkoumat, jak se ta metoda u konkrétní třídy jmenuje, ale použije vždy stejný název metody presentate(). Samozřejmě tohle použiji pouze pokud mi z nějakého důvodu nevyhovuje standardní metoda toString().
Tak jistě, pes, auto, kosmická loď nebo špinavé spoďáry můžou mít společné rozhraní presentable. Bohužel už nevidíš nebo nechceš vidět, že je to návrh od základů špatný a řešení s gettery mnohem čistější.
-
Například mohou sdílet rozhraní Presentable
gettery a settery nějak zabraňují těmto třídám sdílet rozhraní Presentable a mít metodu presentate() ?
-
gettery a settery nějak zabraňují těmto třídám sdílet rozhraní Presentable a mít metodu presentate() ?
Přesně tohle právě nechápu. Stejně jako mám společný toString, tak můžu mít společný toHTML a gettery s tím nemají vůbec nic společného (ledaže by Kit chtěl říct, že používat getter je zlo a že se musí vždycky pokud to jde použít toString,toHTML,presentate - s čím snad ale nikdo nepolemizuje).
-
(ledaže by Kit chtěl říct, že používat getter je zlo a že se musí vždycky pokud to jde použít toString,toHTML,presentate - s čím snad ale nikdo nepolemizuje).
Jak zlo?
-
Jak zlo?
V tom smyslu, že když chci objekt odprezentovat v html, tak bych se ho neměl ptát na jeho properties a sám skládat prezentaci, ale měl bych ho nechat sama sebe odprezentovat. (Samozřejmě to neber doslovně, když mám třeba MVC, tak to tam bude třeba probíhat jinak, to je jasný. Každopádně nerozumím tomu, jak s tím gettery můžou souviset)
-
Přesně tohle právě nechápu. Stejně jako mám společný toString, tak můžu mít společný toHTML a gettery s tím nemají vůbec nic společného (ledaže by Kit chtěl říct, že používat getter je zlo a že se musí vždycky pokud to jde použít toString,toHTML,presentate - s čím snad ale nikdo nepolemizuje).
Asi tím chtěl vyjádřit, že getter a setter chce mít deklarován v nějakém společném předku, takže presentate je OK, setTitle ee protože je jenom na Article.
-
Jak zlo?
V tom smyslu, že když chci objekt odprezentovat v html, tak bych se ho neměl ptát na jeho properties a sám skládat prezentaci, ale měl bych ho nechat sama sebe odprezentovat. (Samozřejmě to neber doslovně, když mám třeba MVC, tak to tam bude třeba probíhat jinak, to je jasný. Každopádně nerozumím tomu, jak s tím gettery můžou souviset)
A když budu chtít, aby se mi ten objekt prezentoval v json, xml, pdf, ...?
Imho mi to s těmi gettery souvisí dost těsně, protože na to presentování budu používat nějaký jiný nástroj, kterému ten objekt předhodím. A ten bude reflexi toho objektu dělat pomocí getterů.
-
Říkám, nejsem žádný odborník na OOP, ber to tak pls.
A když budu chtít, aby se mi ten objekt prezentoval v json, xml, pdf, ...?
No tak budeš muset mít další protokoly (interfaces) s metodami toJSON, toXML, toPDF.
Imho mi to s těmi gettery souvisí dost těsně, protože na to presentování budu používat nějaký jiný nástroj, kterému ten objekt předhodím. A ten bude reflexi toho objektu dělat pomocí getterů.
To nejde napsat obecně. Nevím, jak bys mohl zobrazovat libovolný neznámý objekt. Leda přes nějaké rozhraní typu Person, kde budeš mít jistotu, že daný objekt umí odevzdat jméno, příjmení, adresu apod. a ty nějak zobrazíš. Ale to už není klasický getter, to je datové rozhraní.
Ale nehledej v tom žádnou vědu, prostě jsem chtěl říct, že otázka, jestli mám nebo nemá gettery nijak neovlivňuje otázku, jestli objekt splňuje nebo nesplňuje nějaký interface typu IsHTMLPresentable.
-
Říkám, nejsem žádný odborník na OOP, ber to tak pls.
Beru neboj.
A když budu chtít, aby se mi ten objekt prezentoval v json, xml, pdf, ...?
No tak budeš muset mít další protokoly (interfaces) s metodami toJSON, toXML, toPDF.
Upravování existujícího kódu. To není dobře.
Imho mi to s těmi gettery souvisí dost těsně, protože na to presentování budu používat nějaký jiný nástroj, kterému ten objekt předhodím. A ten bude reflexi toho objektu dělat pomocí getterů.
To nejde napsat obecně. Nevím, jak bys mohl zobrazovat libovolný neznámý objekt. Leda přes nějaké rozhraní typu Person, kde budeš mít jistotu, že daný objekt umí odevzdat jméno, příjmení, adresu apod. a ty nějak zobrazíš. Ale to už není klasický getter, to je datové rozhraní.
Ale nehledej v tom žádnou vědu, prostě jsem chtěl říct, že otázka, jestli mám nebo nemá gettery nijak neovlivňuje otázku, jestli objekt splňuje nebo nesplňuje nějaký interface typu IsHTMLPresentable.
Já bych to udělal pomocí tří rozhraní:
1. Entry - obsahuje vlastní objekt.
2. Formater - objekt získávající Entry a výsledek bude stream/string
3. Dump - objekt zastřešující vytisknutí libovolného objektu.
Takže třeba: objekt DumpJSON nakrmím formatery, a pak když budu chtít vytisknout Psa, tak se použije PesFormaterJSON.
-
Já bych to udělal pomocí tří rozhraní:
1. Entry - obsahuje vlastní objekt.
2. Formater - objekt získávající Entry a výsledek bude stream/string
3. Dump - objekt zastřešující vytisknutí libovolného objektu.
Takže třeba: objekt DumpJSON nakrmím formatery, a pak když budu chtít vytisknout Psa, tak se použije PesFormaterJSON.
Může být, o (ne)vhodnost nějakého OOP návrhu se rozhodně přít nebudu ;) Chápu, že v tomhle případě opravdu gettery potřebuješ (nebo použít frienda, což je ještě horší a navíc to jde jenom (?) pro C++).
Pocitově se mi to nelíbí proto, že ti tam vzniká jednoúčelová třída, která musí být napsaný přesně na míru třídě toho daného tisknutého objektu - např. když si vymyslíš novou třídu Mirek, musíš k ní vytvořit MirekFormatterJSON, která bude mít jedinou metodu formatToJSON, kterou bych daleko raději viděl v Mirkovi než kdekoli jinde, protože když bude jinde, zase musím vědět, že vůbec pro Mirka existuje, jak se jmenuje, horko těžko ho budu pro Mirka hledat automaticky... Nevím no, mně se to prostě pocitově (ne-odborně) nezdá :)
...a mám podezření, že se k tomuhle návrhu uchyluješ v podstatě jenom proto, že přemýšlíš v intencích jazyka, který neumožňuje bezbolestně rozšiřovat existující třídy[1], což by imho pořádný OOP jazyk umět měl ;)
[1] https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
-
děkuji kolegové, že jste mi připoměli proč oop nesnáším a proč mám rád haskell
-
děkuji kolegové, že jste mi připoměli proč oop nesnáším a proč mám rád haskell
Ano, ano, taky jsem se na to upomněl :)
-
Já bych to udělal pomocí tří rozhraní:
1. Entry - obsahuje vlastní objekt.
2. Formater - objekt získávající Entry a výsledek bude stream/string
3. Dump - objekt zastřešující vytisknutí libovolného objektu.
Takže třeba: objekt DumpJSON nakrmím formatery, a pak když budu chtít vytisknout Psa, tak se použije PesFormaterJSON.
Může být, o (ne)vhodnost nějakého OOP návrhu se rozhodně přít nebudu ;) Chápu, že v tomhle případě opravdu gettery potřebuješ (nebo použít frienda, což je ještě horší a navíc to jde jenom (?) pro C++).
Pocitově se mi to nelíbí proto, že ti tam vzniká jednoúčelová třída, která musí být napsaný přesně na míru třídě toho daného tisknutého objektu - např. když si vymyslíš novou třídu Mirek, musíš k ní vytvořit MirekFormatterJSON, která bude mít jedinou metodu formatToJSON, kterou bych daleko raději viděl v Mirkovi než kdekoli jinde, protože když bude jinde, zase musím vědět, že vůbec pro Mirka existuje, jak se jmenuje, horko těžko ho budu pro Mirka hledat automaticky... Nevím no, mně se to prostě pocitově (ne-odborně) nezdá :)
...a mám podezření, že se k tomuhle návrhu uchyluješ v podstatě jenom proto, že přemýšlíš v intencích jazyka, který neumožňuje bezbolestně rozšiřovat existující třídy[1], což by imho pořádný OOP jazyk umět měl ;)
[1] https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
Mno, ve skutečnosti se k tomu uchyluji proto, že:
1. Nesnáším velké třídy. Třída Mirek obsahující metody toJSON, toXML, toAnything mě děsí, a mám s tím zlé zkušenosti.
2. Jestli ten kód napíšu do jednoúčelové třídy, nebo to vlepím do existujícího objektu... tak to radši tu jednoúčelovku.
3. Čistě filozoficky objekt Máslo by neměl umět létat letadlem. (A přesto létá.)
4. Poslední dobou si hodně hraju na kontext. V jednom místě aplikace potřebuju specielní transformaci objektu. Když tuto transformaci zadrátuju do dotyčného objektu, tak to tím zveřejním, a budou to chtít používat všude. To je moc odvážné.
-
děkuji kolegové, že jste mi připoměli proč oop nesnáším a proč mám rád haskell
Ano, ano, taky jsem se na to upomněl :)
Co konkrétně? Já se z Haskellu hodně inspiruju, a jeho praktiky používám i v OOP.
-
3. Čistě filozoficky objekt Máslo by neměl umět létat letadlem. (A přesto létá.)
Čistě prakticky by bylo fajn umět jakoukoli operaci udělat s libovolným neznámým objektem, to je polymorfismus. Když ti dám objekt X, tak budeš zjišťovat reflexí, jaké je třídy, budeš se dívat do nějakého seznamu, jestli pro tu třídu máš formatter? No nevím :)
-
Co konkrétně? Já se z Haskellu hodně inspiruju, a jeho praktiky používám i v OOP.
Já jsem konkrétně dost vystřízlivěl z propagandy, že OOP odpovídá tomu, jak skutečně myslíme. Z toho tvrzení, že OOP-uvažování odpovídá přirozenému způsobu práce s pojmy (Sysel je Savec, Savec je Strunatec...). Když se koukneš na to, o čem jsme se bavili teď, co to má propánakrále společného s (nám) přirozeným způsobem uvažování?! :)
Ve finále mi přijde daleko přirozenější a přímočařejší uvažování funkcionální, kde je analogie výrobní linka: X jde dovnitř, Y jde ven. Toť vše ;)
-
děkuji kolegové, že jste mi připoměli proč oop nesnáším a proč mám rád haskell
Ano, ano, taky jsem se na to upomněl :)
Co konkrétně? Já se z Haskellu hodně inspiruju, a jeho praktiky používám i v OOP.
na filosofické úrovni bych řekl, že to je jednoduchost a přimočarost - program je tvořen funkcemi, které transformují jedny data na druhé, doslova takto
naproti tomu oop - "posílání zpráv objektů" - co to vlastně je? jistě víme jenom že konsensus neexistuje, patterrny... stav rozházený všude možně.. a tak
-
naproti tomu oop - "posílání zpráv objektů" - co to vlastně je? jistě víme jenom že konsensus neexistuje, patterrny... stav rozházený všude možně.. a tak
A tak to zas neee! Posílání zpráv je (může být) naprosto jasně definované a pokud skutečně funguje tak, jak se tváří, že funguje, je to ok (Erlang, Elixir). Problém dnešního OOP je mj. v tom, že vychází z logiky posílání zpráv a přitom žádné neposílá, jenom to neuměle kašíruje.
-
3. Čistě filozoficky objekt Máslo by neměl umět létat letadlem. (A přesto létá.)
Čistě prakticky by bylo fajn umět jakoukoli operaci udělat s libovolným neznámým objektem, to je polymorfismus. Když ti dám objekt X, tak budeš zjišťovat reflexí, jaké je třídy, budeš se dívat do nějakého seznamu, jestli pro tu třídu máš formatter? No nevím :)
Ano budu. To co popisuješ ty, je jako ukazovat na Máslo a říct: "padej do ledničky". Jako některá inteligentnější Másla to umí. Ale když koukám na našeho Psa, tak si říkám, že je někdy jednodužší ho tam dostat ručně (do boudy, do ledničky mu to de).
Mimochodem to s tou reflexí, to nemáš pravdu. Rozdíl mezi tím tvým a mým je pouze umístění. Stejně jako mě může scházet formater, tak tobě může ten objekt to které formátování neumět.
-
naproti tomu oop - "posílání zpráv objektů" - co to vlastně je? jistě víme jenom že konsensus neexistuje, patterrny... stav rozházený všude možně.. a tak
A tak to zas neee! Posílání zpráv je (může být) naprosto jasně definované a pokud skutečně funguje tak, jak se tváří, že funguje, je to ok (Erlang, Elixir). Problém dnešního OOP je mj. v tom, že vychází z logiky posílání zpráv a přitom žádné neposílá, jenom to neuměle kašíruje.
může, není, do teologie se (dneska večer) nepouštím
-
3. Čistě filozoficky objekt Máslo by neměl umět létat letadlem. (A přesto létá.)
Když ti dám objekt X, tak budeš zjišťovat reflexí, jaké je třídy, budeš se dívat do nějakého seznamu, jestli pro tu třídu máš formatter? No nevím :)
Nešlo by to řešit tak, že by se formatter do funkce předal společně s objektem X (to může udělat i kompilátor automaticky - v Haskellu se k tomu používají typové třídy, ve Scale implicity, v Rustu traity)?
-
Ano budu. To co popisuješ ty, je jako ukazovat na Máslo a říct: "padej do ledničky". Jako některá inteligentnější Másla to umí. Ale když koukám na našeho Psa, tak si říkám, že je někdy jednodužší ho tam dostat ručně (do boudy, do ledničky mu to de).
Jak jsem říkal, (už) nevěřím tomu, že OOP přímo souvisí s reálným světem a nevěřím argumentaci analogií z reálného světa. Kdybych si z toho chtěl dělat srandu (což vlastně chci! :)) ), tak lednička taky nefunguje tak, že když z ní chceš něco vzít, tak se staneš ledničkou, něco si tam vezmeš, pak se staneš zpátky BoneFlutem a juchů, máš to v ruce! A přitom přesně tohle vlákna v OOP dělají...
Mimochodem to s tou reflexí, to nemáš pravdu. Rozdíl mezi tím tvým a mým je pouze umístění. Stejně jako mě může scházet formater, tak tobě může ten objekt to které formátování neumět.
Ne. Pokud formátovací kód neexistuje, tak neexistuje, v tom se ta dvě řešení neliší a lišit nemůžou. Maximálně můžeš mít obecný formatter, ale to já taky (objekt metodu nepodporuje? Ok, tady je workaround...) Jediný skutečný rozdíl je přesně v tom, kde ten kód leží - já bych ho připlácl k datům, ty bys ho dal někam kdovíkam a pak ho při každé operaci horko těžko zase zpátky hledal. To mi prostě přijde zbytečný, nekoncepční a typicky OOP-přeplácaný. :) Ale už bych fakt tuhle věc opustil, není to důležitý ani jako offtopic :)
-
může, není, do teologie se (dneska večer) nepouštím
No právěže v Erlangu je definované naprosto přesně. Včetně toho, jak se to chová v konkurentním prostředí, jak se zprávy řadí, jak je možné je vybírat atd.atd. Proto na posílání zpráv není nic špatného, akorát musí být prostě implementované dobře.
Nešlo by to řešit tak, že by se formatter do funkce předal společně s objektem X (to může udělat i kompilátor automaticky - v Haskellu se k tomu používají typové třídy, ve Scale implicity, v Rustu traity)?
To asi nějak šlo, ale já právě mluvím o situaci, kdy ten formatter nemám. Např. deserializuju objekty ze souboru a chci do html vypsat jejich seznam. Čili pro každý objekt pak budu horko těžko hledat vhodný formatter. Haskell bych do toho netahal, já se vymezuju proti konkrétnímu řešení v konkrétním "mainstreamovém OOP".
-
Co konkrétně? Já se z Haskellu hodně inspiruju, a jeho praktiky používám i v OOP.
Já jsem konkrétně dost vystřízlivěl z propagandy, že OOP odpovídá tomu, jak skutečně myslíme. Z toho tvrzení, že OOP-uvažování odpovídá přirozenému způsobu práce s pojmy (Sysel je Savec, Savec je Strunatec...). Když se koukneš na to, o čem jsme se bavili teď, co to má propánakrále společného s (nám) přirozeným způsobem uvažování?! :)
Nedá mi to a připomenu dnes již starou polemiku mezi p. Viriusem a p.Čadou o tom, jak jsou na tom z hlediska třídního OOP třídy reálných a komplexních čísel. Vyplynulo z toho, že návrh OOP hierarchie není tak jednoduchý, jak by se mohlo zdát (a nepřímo vyplynula poučka, že dědičnost mnohdy přináší víc škody než užitku :D)
-
Ano budu. To co popisuješ ty, je jako ukazovat na Máslo a říct: "padej do ledničky". Jako některá inteligentnější Másla to umí. Ale když koukám na našeho Psa, tak si říkám, že je někdy jednodužší ho tam dostat ručně (do boudy, do ledničky mu to de).
Jak jsem říkal, (už) nevěřím tomu, že OOP přímo souvisí s reálným světem a nevěřím argumentaci analogií z reálného světa. Kdybych si z toho chtěl dělat srandu (což vlastně chci! :)) ), tak lednička taky nefunguje tak, že když z ní chceš něco vzít, tak se staneš ledničkou, něco si tam vezmeš, pak se staneš zpátky BoneFlutem a juchů, máš to v ruce! A přitom přesně tohle vlákna v OOP dělají...
Hmm, nezaměňuješ teď tak trochu teorii s realitou?
Neodvažuji se tvrdit, jak moc je OOP inspirovaný reálným světem, ale většina těch nekoncepčností IMHO vychází z toho, že si to ti programátoři (případně i jazyky jako takové) dělají tak trochu po svém.
Lednička funguje tak, jak bych to OOP čekal. Mám ledničku. Má zprávu put. Má zprávu takeOut. Přijímá libovolné objekty, které mají zprávy getSize, getWeight. Když chci něco dát do ledničky, musím na to použít nějaký manipulátor Hands.
Pokud nepřijde Kit, který zakazuje gettery, tak mě to celkem sedí.
To s tím stát se ledničkou je sice pravda, to ti neberu, ale dá se s tím žít. A bavíme se o OOP, ne o konkrétní implementaci nějakého jazyka.
Ne. Pokud formátovací kód neexistuje, tak neexistuje, v tom se ta dvě řešení neliší a lišit nemůžou. Maximálně můžeš mít obecný formatter, ale to já taky (objekt metodu nepodporuje? Ok, tady je workaround...) Jediný skutečný rozdíl je přesně v tom, kde ten kód leží - já bych ho připlácl k datům, ty bys ho dal někam kdovíkam a pak ho při každé operaci horko těžko zase zpátky hledal. To mi prostě přijde zbytečný, nekoncepční a typicky OOP-přeplácaný. :) Ale už bych fakt tuhle věc opustil, není to důležitý ani jako offtopic :)
No, já bych zase řekl, že právě tento způsob vůbec není klasicky OOP. To jsem si přinesl z Haskellu. Nechci aby ten formater používal kdekdo.
-
3. Čistě filozoficky objekt Máslo by neměl umět létat letadlem. (A přesto létá.)
Pro tu dobu se stává členem třídy Náklad a dědí její schopnost být přemisťován libovolným dopravním prostředkem.
Já také nesnáším OOP ;D
-
To asi nějak šlo, ale já právě mluvím o situaci, kdy ten formatter nemám. Např. deserializuju objekty ze souboru a chci do html vypsat jejich seznam. Čili pro každý objekt pak budu horko těžko hledat vhodný formatter.
A když by jsi ten formater měl součástí objektu, tak jsi na tom v čem líp?
-
Naštěstí mi nic z této (asi bambilionosmé debaty) debaty nemůže zkazit radost z toho, že už není 58 celsiusů ve stínu.
A chleba už stejně nebude stát 4.20,- a školství a zdravotnictví nebudou zadarmo ...
-
Co konkrétně? Já se z Haskellu hodně inspiruju, a jeho praktiky používám i v OOP.
Já jsem konkrétně dost vystřízlivěl z propagandy, že OOP odpovídá tomu, jak skutečně myslíme. Z toho tvrzení, že OOP-uvažování odpovídá přirozenému způsobu práce s pojmy (Sysel je Savec, Savec je Strunatec...). Když se koukneš na to, o čem jsme se bavili teď, co to má propánakrále společného s (nám) přirozeným způsobem uvažování?! :)
Nedá mi to a připomenu dnes již starou polemiku mezi p. Viriusem a p.Čadou o tom, jak jsou na tom z hlediska třídního OOP třídy reálných a komplexních čísel. Vyplynulo z toho, že návrh OOP hierarchie není tak jednoduchý, jak by se mohlo zdát (a nepřímo vyplynula poučka, že dědičnost mnohdy přináší víc škody než užitku :D)
Já jsem nejdříve nadšeně opustil OOP ve prospěch FP. Konkrétně Haskellu. Pak jsem zjistil, že Haskell je víc OOP než Java s C# dohromady, ale že používat čistě jen blbé přepravky mě nebaví.
Takže:
- nepoužívám dědičnost na reusable kódu
- nedělám velké objekty
- dělám anemické objekty a objekty chovající se jako konfigurovatelné funkce
- fakt modeluju realitu přesně jak v to ty nevěříš
Zatím mi to vychází.
-
PS: a hlavně bacha na getry, setry, retry ...
-
Nedá mi to a připomenu dnes již starou polemiku mezi p. Viriusem a p.Čadou o tom, jak jsou na tom z hlediska třídního OOP třídy reálných a komplexních čísel. Vyplynulo z toho, že návrh OOP hierarchie není tak jednoduchý, jak by se mohlo zdát
Jé, no to bylo svého času úplný programátorský porno :) Ale obsah už si dneska nepamatuju, natož tuhle konkrétní zápletku. Budu si to asi muset někdy ve vaně pro pobavení znovu přečíst :)) Akorát nevím, jak moc to ještě odpovídá dnešní situaci, minimálně Java asi od té doby nějaký vývoj prodělala...
(a nepřímo vyplynula poučka, že dědičnost mnohdy přináší víc škody než užitku :D)
Jj, to je jeden ze závěrů, které jsem si sám pro sebe taky udělal, jedna z těch ne-přirozeností je ta hierarchie. Přirozeně asi spíš přemýšlíme tak, že obecné pojmy sdružují jednotlivosti s nějakými společnými znaky, ale ne nutně ve formě hierarchie. Mj. proto mi začaly být daleko sympatičtejší jazyky založený na volně kombinovatelných rozhraních, založených jenom na společných vlastnostech a ničem jiném. Odpadá tím spousta z těch klasických neplodných nekonečných OOP sporů o ničem...
-
Nedá mi to a připomenu dnes již starou polemiku mezi p. Viriusem a p.Čadou o tom, jak jsou na tom z hlediska třídního OOP třídy reálných a komplexních čísel. Vyplynulo z toho, že návrh OOP hierarchie není tak jednoduchý, jak by se mohlo zdát
Jé, no to bylo svého času úplný programátorský porno :) Ale obsah už si dneska nepamatuju, natož tuhle konkrétní zápletku. Budu si to asi muset někdy ve vaně pro pobavení znovu přečíst :)) Akorát nevím, jak moc to ještě odpovídá dnešní situaci, minimálně Java asi od té doby nějaký vývoj prodělala...
Tady, ale je nutné za domácí úlohu spustit cstocs :-) http://www.tutok.sk/nezmar/files/silnekafe.html
(osobně bych řekl, že vývojem prošel i autor té polemiky, přecejen z toho strašně čouhalo C++ :D)
-
To s tím stát se ledničkou je sice pravda, to ti neberu, ale dá se s tím žít. A bavíme se o OOP, ne o konkrétní implementaci nějakého jazyka.
No jo, jenže obecně se o OOP prakticky bavit nedá, protože ho různé jazyky implementují radikálně jinak a design se pak těm vlastnostem implementace až nehezky moc přizpůsobuje...
No, já bych zase řekl, že právě tento způsob vůbec není klasicky OOP. To jsem si přinesl z Haskellu. Nechci aby ten formater používal kdekdo.
Myslel jsem, že klasicky OOP je ten guláš, co tam pak vzniká.
-
děkuji kolegové, že jste mi připoměli proč oop nesnáším a proč mám rád haskell
Klídek, problém má jenom Kit, ostatní to zvládají :) Buď se udělá společný předek s virtuální metodou TransformToJSON() nebo objekt implementuje interface s TransformToJSON() nebo se to nouzově dolepí procedurálně přes gettery a settery:
JSON TransformObjectToJSON(object obj)
{
if (obj.type == Article) return TransformArticleToJSON(Article(obj))
elseif (obj.type == Person) return TransformPersonToJSON(Person(obj))
elseif (obj.type == Store) return TransformStoreToJSON(Store(obj))
else throw error('not supported');
}
OOP odpovídá tomu, jak skutečně myslíme.
naproti tomu oop - "posílání zpráv objektů"
OOP nikdy nebylo o myšlení, o reálném světě a ani o posílání zpráv objektům, tohle vždycky tvrdilo jen pár pomatených akademiků, konzultantů a spisovatelů. OOP bylo prezentováno jako kolekce dat a metod na jejich manipulaci, killer features byly dědičnost a zapouzdření. Lidé očekávající myšlení a reálný svět proto nevyhnutelně museli být zklamáni neb to tam opravdu není, reklamace u pomatenců, ne u OOP ;)
-
OOP nikdy nebylo o myšlení, o reálném světě a ani o posílání zpráv objektům,tohle vždycky tvrdilo jen pár pomatených akademiků
Už je to tu opět? "Pomatení akademici" jako např. Alan Kay?
The big idea is "messaging" - that is what the kernal of Smalltalk/Squeak is all about
http://c2.com/cgi/wiki?AlanKayOnMessaging
(nechci se k tomu vracet, byla tu o tom dlouhá debata, pokud jsi ji nečetl, najdi si ji v archivu)
... o reálném světě ...
U tohodle vycházím ze dvou věcí:
1. snad každá učebnice OOP uvádí příklady z reálného světa jako právě třeba to Člověk-Savec-Strunatec - a dost často se tam najde dovětek typu "vidíte, přesně takhle o tom přece normálně uvažujete!" - ano, u Člověk-Savec-Strunatec to funguje. U Žárovka-Světlo taky. Ale jakmile začne člověk řešit skutečný program v reálném nasazení, nebo si aspoň přečte pár debat o takových problémech, zjistí, že OOP se až podezřele často zabývá samo sebou místo problému, který je k řešení...
2. velice často se v debatách o tom, jestli nějaký návrh je nebo není vhodný, argumentuje analogiemi z reálného světa. Jako například že máslo nelétá nebo psa se na nic neptáme. Čili tam lidi zjevně analogii minimálně nevědomě očekávají, jinak by je nenapadlo takhle argumentovat. Nikdo nezdůvodňuje statiku domu tím, že mu tohle řešení víc připomíná zmrzlinu, takže je lepší.
(lehce si z toho dělám srandu, to je doufám poznat)
-
U tohodle vycházím ze dvou věcí:
1. snad každá učebnice OOP uvádí příklady z reálného světa jako právě třeba to Člověk-Savec-Strunatec - a dost často se tam najde dovětek typu "vidíte, přesně takhle o tom přece normálně uvažujete!" - ano, u Člověk-Savec-Strunatec to funguje. U Žárovka-Světlo taky. Ale jakmile začne člověk řešit skutečný program v reálném nasazení, nebo si aspoň přečte pár debat o takových problémech, zjistí, že OOP se až podezřele často zabývá samo sebou místo problému, který je k řešení...
2. velice často se v debatách o tom, jestli nějaký návrh je nebo není vhodný, argumentuje analogiemi z reálného světa. Jako například že máslo nelétá nebo psa se na nic neptáme. Čili tam lidi zjevně analogii minimálně nevědomě očekávají, jinak by je nenapadlo takhle argumentovat. Nikdo nezdůvodňuje statiku domu tím, že mu tohle řešení víc připomíná zmrzlinu, takže je lepší.
(lehce si z toho dělám srandu, to je doufám poznat)
No já nevím. Já jsem o Člověku jako o Savci, natož Strunatci uvažoval naposled na základce. Čímž si tak nějak nenápadně přihřívám polívčičku, že dědění u OOP nemám rád.
Myslím si, že OOP je o analogiích z reálného světa. Hlavně o modelování.
A příklad s učebnicemi je poněkud nešťastný. Papír snese všechno.
-
Jakékoli analogie fungují jen ve velmi omezeném měřítku, já by jsem je sem vůbec netahal.
Dědičnost, gettery a settery, interface ... jsou věci, které se prostě mají používat s mírou. Není problém napsat OOP humus, kde vše implementuje interface, a má na každé property setter s getterem. Krásnou ukázkou jsou korporátní Java sw, kde platí programátory od řádky kódu - viz stará klasika
https://gist.github.com/ghoseb/25049
-
Co konkrétně? Já se z Haskellu hodně inspiruju, a jeho praktiky používám i v OOP.
Já jsem konkrétně dost vystřízlivěl z propagandy, že OOP odpovídá tomu, jak skutečně myslíme. Z toho tvrzení, že OOP-uvažování odpovídá přirozenému způsobu práce s pojmy (Sysel je Savec, Savec je Strunatec...). Když se koukneš na to, o čem jsme se bavili teď, co to má propánakrále společného s (nám) přirozeným způsobem uvažování?! :)
Nedá mi to a připomenu dnes již starou polemiku mezi p. Viriusem a p.Čadou o tom, jak jsou na tom z hlediska třídního OOP třídy reálných a komplexních čísel. Vyplynulo z toho, že návrh OOP hierarchie není tak jednoduchý, jak by se mohlo zdát (a nepřímo vyplynula poučka, že dědičnost mnohdy přináší víc škody než užitku :D)
Čada je ObjC fanatik, doporučuju najít si diskuze, kde tvrdí, že jmenné prostory a šablony (resp. generics) jsou na nic. Taky někde "dokazoval", že dispatch v ObjC je rychlejší než v C++. To už hraničí s debilitou (mohu-li použít jeho styl vyjadřování v diskuzích). Nicméně dědičnost je v OOP skutečně zlo, i když do tohoto vlákna to asi nepatří.
-
Okrajový smalltalk si necháme na jindy. Vycházím ze situace OOP v současných mainstream jazycích.
1. snad každá učebnice OOP uvádí příklady z reálného světa jako právě třeba to Člověk-Savec-Strunatec
No tak takové učebnice asi jsou špatné když popisují OOP blbě, za to však nemůže OOP ale ty učebnice :) Původně se OOP vysvětlovalo na věcech jako obecný Stream, MemoryStream, FileStream, kde byl smysl, přínos a limity OOP očividné a všem to bylo jasné. Jakmile pomatenci začali OOP zneužívat na modelování reálného světa tak to nutně muselo skončit obrovským průšvihem, protože OOP na to nikdy nebylo stavěné a také se tak stalo :) Čili problémem není OOP, ale nerealistická očekávání od OOP, OOP je mírná evoluce procedurálního programování, žádný megahyperzázrak, spasení lidstva a záchrana Pandy Velké :)
-
Okrajový smalltalk si necháme na jindy. Vycházím ze situace OOP v současných mainstream jazycích.
Reagoval jsem na to, že jsi napsal "OOP nikdy nebylo o ...". Na začátku bylo o posílání zpráv, byla to jeho klíčová myšlenka.
-
Reagoval jsem na to, že jsi napsal "OOP nikdy nebylo o ...". Na začátku bylo o posílání zpráv, byla to jeho klíčová myšlenka.
V době zavádění OOP do mainstream praxe se tato myšlenka již nezmiňovala a hlavně neaplikovala. Pro mainstream OOP proto nikdy nebylo o ...
Z hlediska archeologie samozřejmě máte pravdu Vy, časově první byla zaniklá kultura kolem firmy Xerox :)
-
Reagoval jsem na to, že jsi napsal "OOP nikdy nebylo o ...". Na začátku bylo o posílání zpráv, byla to jeho klíčová myšlenka.
V době zavádění OOP do mainstream praxe se tato myšlenka již nezmiňovala a hlavně neaplikovala. Pro mainstream OOP proto nikdy nebylo o ...
Z hlediska archeologie samozřejmě máte pravdu Vy, časově první byla zaniklá kultura kolem firmy Xerox :)
ObjC je vosk?
-
...Jakmile pomatenci začali OOP zneužívat na modelování reálného světa tak to nutně muselo skončit obrovským průšvihem, protože OOP na to nikdy nebylo stavěné a také se tak stalo :) Čili problémem není OOP, ale nerealistická očekávání od OOP, OOP je mírná evoluce procedurálního programování, žádný megahyperzázrak, spasení lidstva a záchrana Pandy Velké :)
Tak, a ještě horší situace nastává, když se OOP (resp. OOP se třídami) začne násilím roubovat na jiná paradigmata. Už jsem vidět šílené (relační) DB schéma navržené "objektově", to byl dobrej humus. Asi 300 tabulek pro zcela jednoduchej use case atd. atd. Jen proto, že se někdo od Javy nechtěl "špinit" s SQL :-)
-
V době zavádění OOP do mainstream praxe se tato myšlenka již nezmiňovala a hlavně neaplikovala.
A to je přesně důvod, proč je OOP tam, kde je. Je to jako bys řekl "Jo, historicky jakýsi akademický magor vymyslel potrubí s dírou, ale při zavádění do praxe se prosadily plné trubky" :)
P.S. nemáš pravdu, že se ta myšlenka nezmiňuje. Zmiňuje se pořád. Viz např. http://stackoverflow.com/questions/2347973/how-exactly-do-objects-communicate-with-each-other-by-passing-messages Q.E.D.
-
A to je přesně důvod, proč je OOP tam, kde je.
Technicky je mainstream OOP slabší než mohlo být, to je jasné. Tristní stav kolem OOP je především díky produkci akademických magorů a za to OOP opravdu nemůže.
Viz právě uvedený link na stackoverflow, stačilo podle pravdy říct že na posílání zpráv objektům se mainstream vys***, na Wikipedii jsou bajky a hotovo :)
Tak, a ještě horší situace nastává, když se OOP (resp. OOP se třídami) začne násilím roubovat na jiná paradigmata.
No to je pak peklo :)
-
Tristní stav kolem OOP je především díky produkci akademických magorů a za to OOP opravdu nemůže.
OOP z principu nemůže moci za nic, protože to není nic jiného než čistě abstraktní koncept, který nikam nechodí, nic nikomu neříká a žádný software nepíše. Pokud se budeme bavit o tom, kdo za co může, tak to můžou být buď návrháři jazyka, implementátoři, investor/vlastník_práv nebo uživatelská obec.
A pokud tvrdíš, že za něco můžou akademici, tak by bylo dobré to pojmenovat konkrétně. Já mám třeba neodolatelný dojem, že na vině jsou především implementátoři, kteří původní dobře (vy)myšlený koncept pomocí nevhodných rozhodnutí dovedli do slepé uličky. A jedna z těch věcí je zapomenutí na důležitost konceptu asynchronního a snadno dynamicky dispatchovatelného zasílání zpráv. Což se neprojevilo na jednojádrových strojích, ale dneska je to slepá ulička plná upírů, vampírů, mutexů, locků, deadlocků a jiných strašáků. Druhá chyba bylo přehnané zdůrazňování dědičnosti, čímž se OOP dostalo do situace, kdy jenom nekonečně řeší problémy, které si samo nadrobilo a víc než řešení problému připomíná hádky o to, která křesťanská sekta jsou ti praví křesťané.
Nic z toho není dílem akademiků. Naopak když to akademici viděli, rozpracovali spoustu jiných cest, kterýma je možný se vydat a který těmihle neduhy netrpí (čímž netvrdím, že nemají jiné). Včetně třeba variací na původní koncept, který "reálné OOP"* zprofanovalo do nepoužitelnosti - jako třeba agenti, actor model apod., což v principu není nic jiného, než "původní OOP".
* podle vzoru "reálný socialismus"
-
Tomu rozumím, já ale celou dobu píšu o něčem jiném :) Problémem není technická nedokonalost implementace OOP ale přehnaná očekávání od implementace OOP. Dokud někteří akademikové a další verbež nezačali v souvislosti s OOP produkovat sra*** o modelování reálného světa, zasílání zpráv a další, byl svět v pořádku, všichni věděli že mainstream OOP je pouhá mírná evoluce procedurálního programování ;)
Asynchronní dynamický message dispatch má svoje určité výhody a svoje určité nevýhody, ani tohle není konečné spasení světa :) Probereme to jindy.
-
Tomu rozumím, já ale celou dobu píšu o něčem jiném :) Problémem není technická nedokonalost implementace OOP ale přehnaná očekávání od implementace OOP. Dokud někteří akademikové a další verbež nezačali v souvislosti s OOP produkovat sra*** o modelování reálného světa, zasílání zpráv a další, byl svět v pořádku, všichni věděli že mainstream OOP je pouhá mírná evoluce procedurálního programování ;)
Ve vší úctě :), tohle je totální krávovina, co jsi napsal.
-
...Jakmile pomatenci začali OOP zneužívat na modelování reálného světa tak to nutně muselo skončit obrovským průšvihem, protože OOP na to nikdy nebylo stavěné a také se tak stalo :) Čili problémem není OOP, ale nerealistická očekávání od OOP, OOP je mírná evoluce procedurálního programování, žádný megahyperzázrak, spasení lidstva a záchrana Pandy Velké :)
Tak, a ještě horší situace nastává, když se OOP (resp. OOP se třídami) začne násilím roubovat na jiná paradigmata. Už jsem vidět šílené (relační) DB schéma navržené "objektově", to byl dobrej humus. Asi 300 tabulek pro zcela jednoduchej use case atd. atd. Jen proto, že se někdo od Javy nechtěl "špinit" s SQL :-)
Jo, bohužel tohle je tragická realita - kolikrát nechápu, kde se v systému objevují stovky tabulek, a proč dotazy obsahují desítky joinů - a pak ORMka dávají logiku - při silně neprakticky navrženém schématu databáze se fakt SQLka píší špatně - a potřebujete ORMko, jinak se z toho zblázníte. Při návrhu relační databáze je potřeba zapomenout na dědičnost - jinak je to neštěstí.
-
Tomu rozumím, já ale celou dobu píšu o něčem jiném :) Problémem není technická nedokonalost implementace OOP ale přehnaná očekávání od implementace OOP. Dokud někteří akademikové a další verbež nezačali v souvislosti s OOP produkovat sra*** o modelování reálného světa, zasílání zpráv a další, byl svět v pořádku, všichni věděli že mainstream OOP je pouhá mírná evoluce procedurálního programování ;)
ehm... Ta mírná evoluce procedurálního programování přišla až podstatně později než to původní OOP se zprávama. Ale chápu. Nadávat na akademiky a jinou verbež je jednodušší než se vzdělávat.
-
A co konkrétně je špatné na té dědičnosti, kdy si prostě nějakou funkcionalitu, co je společná pro víc třd, vyčlením do zvláštní třídy a pak si ji podědím? Jak jinak by jste tohle chtěli třeba řešit (a lépe).
-
A co konkrétně je špatné na té dědičnosti, kdy si prostě nějakou funkcionalitu, co je společná pro víc třd, vyčlením do zvláštní třídy a pak si ji podědím? Jak jinak by jste tohle chtěli třeba řešit (a lépe).
Nechceš na to založit separé vlákno? Už jsme to tady tím OOP zaplevelili až hanba :)
-
A co konkrétně je špatné na té dědičnosti, kdy si prostě nějakou funkcionalitu, co je společná pro víc třd, vyčlením do zvláštní třídy a pak si ji podědím? Jak jinak by jste tohle chtěli třeba řešit (a lépe).
Nechceš na to založit separé vlákno? Už jsme to tady tím OOP zaplevelili až hanba :)
... a nazvat ho "Programovací jazyky budoucnosti (funkcionální a OOP), zdělání (VŠ) je k ničemu", zdá se že tato při themata vždy organicky zkonvergují do jednoho spletence vláken. ;D :P
-
ehm... Ta mírná evoluce procedurálního programování přišla až podstatně později než to původní OOP se zprávama. Ale chápu. Nadávat na akademiky a jinou verbež je jednodušší než se vzdělávat.
Nechápete, přišel jste pozdě :) Nadává se magorům co kolekci dat a metod spojují s modelováním reálného světa a zasíláním zpráv.
Vzdělání do kolekce dat a metod asynchronní message dispatch nepřidá, tím není dotčena důležitost vzdělání.
-
zdělání (VŠ) je k ničemu", zdá se že tato při themata vždy organicky zkonvergují do jednoho spletence vláken. ;D :P
tím není dotčena důležitost vzdělání.
TALL KNIGHT: Now he's said the word!
-
A co konkrétně je špatné na té dědičnosti, kdy si prostě nějakou funkcionalitu, co je společná pro víc třd, vyčlením do zvláštní třídy a pak si ji podědím? Jak jinak by jste tohle chtěli třeba řešit (a lépe).
Nechceš na to založit separé vlákno? Už jsme to tady tím OOP zaplevelili až hanba :)
... a nazvat ho "Programovací jazyky budoucnosti (funkcionální a OOP), zdělání (VŠ) je k ničemu", zdá se že tato při themata vždy organicky zkonvergují do jednoho spletence vláken. ;D :P
To je tím, že tomu skoro nikdo nerozumí. Jak potvrdili v jednom psychologickém experimentu, podprůměrně inteligentní přeceňují své znalosti, kdežto ti inteligentní je naopak podceňují. Proto tolik vláken "VŠ je k ničemu".
-
Proto tolik vláken "VŠ je k ničemu".
TALL KNIGHT: Stop saying the word!