Zobrazit příspěvky

Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.


Příspěvky - Ink

Stran: 1 ... 37 38 [39] 40 41 ... 43
571
/dev/null / Re:Těžké OOP problémy
« kdy: 12. 11. 2019, 07:13:51 »
cili (tak jako vetsina vyrazu prirozeneho jazyka) i "funkcionalni jazyk" je proste fuzzy pojem. Pro nekoho je funkcionalni jenom Haskell a par jazyku, o kterych nikdy nikdo normalni neslysel, pro nekoho je funkcionalni jazyk i Javascript :)

Proto podle mě má smysl hejtovat FP jako koncept (tedy pure FP), stejně jako OOP jako koncept a neřešit jednotlivé jazyky nebo když už, jenom v rámci demonstrace obecného problému. Něco jako "FP má problém navázat čisté funkce na reálný svět s jeho změnami v čase".

572
/dev/null / Re:Těžké OOP problémy
« kdy: 10. 11. 2019, 14:35:03 »
Ono obecně Go je hodně slabý pro vytváření jakýchkoli abstrakcí. Tenhle tvůj příklad by mě až tak netrápil. Daleko víc mě děsí situace, kde prostě z principu potřebuješ přijímat hodně různých typů, nedejmatkopřírodo i uživatelských, jako třeba u logování. Když člověk koukne na API https://godoc.org/go.uber.org/zap je mu zle... Tohle snad vyřeší generika plánovaná pro 2.0, pokud je zas nevymyslí nějakým "invenčně jednoduchým" způsobem ;)

Jinak když koukneš na https://github.com/ksimka/go-is-not-good najdeš tam spooooustu daleko zásadnějších problémů. Osobně jsem dost zvědavej, kolik z nich a jakým způsobem ve dvojce vyřeší.

Dík za odkazy, je to síla. Ten můj příklad s operátory byl hlavně míněn jako podpora mému tvrzení, že Go je spíš snaha o evoluci C než o přepsání/napravení C++ a že se návrháři vydali stejnými blátivými cestičkami jako návrháři Javy. Tímto za mě téma Go je docela vyčerpáno a můžeme se vrátit třeba k hejtování OOP.

573
/dev/null / Re:Těžké OOP problémy
« kdy: 10. 11. 2019, 07:24:58 »
No je to opět otázka míry. Pokud někdo vymyslí v dnešní době jazyk, v němž jeden číselný typ sčítáme pomocí infixového operátoru a u druhého se musí použít funkce typu add() protože proto, je to IMO dost podivné, to se dá těžko okecat nějakou ortogonalitou, když trpí konzistence.
To ale nemluvis o Go, ne? Nepamatuju se, ze bych potkal funkci add().

Go ma bambilion problemu, o tom me vubec nemusis presvedcovat, sam si u nej casto rvu vlasy. Treba reseni enumu pres iota a neschopnost kompileru zkontrolovat vycerpavajicnost jejich zpracovani, to je vylozene na pet let na tvrdo :) Jak rikam, Rust je mi sympatictejsi.

Koukám třeba sem: https://golang.org/pkg/math/big/#pkg-examples - konkrétně u příkladu Fibonacci:

Kód: [Vybrat]
// Compute the next Fibonacci number, storing it in a.
a.Add(a, b)

Dobré psycho. Ale to není všechno, z jiného příkladu:

Kód: [Vybrat]
return term.Add(term, frac)

Abych si mohl sečíst 2 čísla typu BigNum, musím si:

1. Vytvořit obě čísla pomocí new()
2. Naplnit si je nějakou Set* metodou
3. Sečíst si je in-place do nějaké proměnné

Když tuhle operaci chci udělat ve funkci a ty dvě čísla si tam pošlu jako parametry a vrátit výsledek, mám dvě možnosti:

a) Použít jako "receiver" jeden z parametrů - pak se ale nejenom vrátí jeho hodnota, nýbrž se změní i obsah proměnné, kterou jsem si poslal přes parametr
b) Vyrobit si ve volané funkci dočasnou proměnnou, použít ji jako "receiver" a vrátit tu

No a když to spletu (když ta funkce je netriviální), chyba je na světě. Určitě je ale možné, že něco přehlížím a že existuje idiomatický způsob, jak to napsat hezky a bez rizika podobných chyb.

574
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 21:34:59 »
Mimochodem, jeste k tomuhle, kdyz uz jsme beztak v offtopicu jako prase :) Ta motivace neni uplne "svazovat programatora", ale spis zvolit jenom ty featury, ktere jsou navzajem ortogonalni. A zaroven jenom ty featury, na kterych se vsichni tri autori jednomyslne shodnou. Oboji mi prijde jako prevelice rozumny kriterium. A jestli Rust zacne nejak vyrazne bobtnat, tak jim da vyvoj za pravdu...

No je to opět otázka míry. Pokud někdo vymyslí v dnešní době jazyk, v němž jeden číselný typ sčítáme pomocí infixového operátoru a u druhého se musí použít funkce typu add() protože proto, je to IMO dost podivné, to se dá těžko okecat nějakou ortogonalitou, když trpí konzistence.

A teď ses dopustil docela zajímavého faulu - jestliže někdo polévku přesolí, nedá to zapravdu někomu, kdo raději vůbec nesolí. Chybu udělali oba, pravdu měl někdo třetí, kdo solí akorát.

575
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 20:08:32 »
Že je Rust "přepis C++"? No a? To je Go taky a autoři zvolili ("rozvolněné") CSP.

Já jsem si vždycky myslel, že Go je spíš snaha o evoluci C - něco jako Java, ale od lidí, kteří nesnášejí OOP, ale sdílejí názor, že jazyk má být "hloupý" (svazovat programátora v maximální snesitelné míře).

Ty důvody, proč zvolili await, můžou být různé, klidně i netechnické - třeba to, že async/await prostě zná a chápe (ať už to znamená cokoli) víc lidí.

Určitě.

Nebo by důvod mohl být třeba ten, že async/await se asi dá implementovat tak, aby byl zaručeně korektní - protože má menší míru volnosti a tím i větší kontrolu nad tím, co se spustí kdy. U CSP (i toho "rozvolněného" ve stylu Go) si člověk musí víc lámat hlavu třeba s tím, v jakém okamžiku má kontexty přepínat. Rust moc neznám, tím míň nějaký jeho internals, takže třeba autoři došli k názoru, že se jim tohle prostě nechce řešit (nebo to dost dobře ani nejde). To nevím. Ale je mi to líto, že se vydali touhle cestou.

Snad jsou k nalezení diskuse ohledně použití jiného podobného modelu. Nic moc rozumného jsem nenašel, pořád předpokládám, že základ je v tom, že to do filosofie a vnitřností Rustu nezapadá.

576
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 20:02:35 »
Že je Rust "přepis C++"? No a? To je Go taky a autoři zvolili ("rozvolněné") CSP.

Já jsem si vždycky myslel, že Go je spíš snaha o evoluci C - něco jako Java, ale od lidí, kteří nesnášejí OOP, ale sdílejí názor, že jazyk má být "hloupý" (svazovat programátora v maximální snesitelné míře).

Ty důvody, proč zvolili await, můžou být různé, klidně i netechnické - třeba to, že async/await prostě zná a chápe (ať už to znamená cokoli) víc lidí.

Určitě.

Nebo by důvod mohl být třeba ten, že async/await se asi dá implementovat tak, aby byl zaručeně korektní - protože má menší míru volnosti a tím i větší kontrolu nad tím, co se spustí kdy. U CSP (i toho "rozvolněného" ve stylu Go) si člověk musí víc lámat hlavu třeba s tím, v jakém okamžiku má kontexty přepínat. Rust moc neznám, tím míň nějaký jeho internals, takže třeba autoři došli k názoru, že se jim tohle prostě nechce řešit (nebo to dost dobře ani nejde). To nevím. Ale je mi to líto, že se vydali touhle cestou.

Snad jsou diskuse ohledně použití jiného podobného modelu. Nic moc rozumného jsem nenašel, pořád předpokládám, že základ je v tom, že to do filosofie a vnitřností Rustu nezapadá.

577
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 14:00:31 »
V tom je ten vtip - Rust není magický jazyk, nedělá žádné legrácky typu GC a automatickou paralelizaci.
To je právě docela škoda, protože ta asynchronicita je pak tak trochu jenom šidítko... V praxi to má oproti sekvenčnímu kódu přínos velký, ale menší než by na dnešních multiprocesorových strojích mít mohlo. Model založený na CSP, který má Erlang (a do menší míry i Go) škáluje na multiprocesoru sám o sobě, bez potřeby jakékoliv magie a často fakt lineárně [1].

No a s tím sleepem a joinem je zrovna pár hodin starý dotaz a vysvětlení na Redditu: https://www.reddit.com/r/rust/comments/dtp6z7/what_can_i_actually_do_with_the_new_async_fn/
A je to tady! Tohle je bohužel úplně geniální ilustrace přesně toho, o čem jsem mluvil. Přesně tohle se mi stalo, když jsem poprvé zkoušel async v Pythonu: byv odchován systémy s oddělenými stacky, naběhl jsem si přesně stejně, protože mi vůbec nepřišlo na mysl, že v async/await světě tenhle červenomodrý[2] problém existuje - ze svého světa jsem ho vůbec neznal.

No jenže Rust není Erlang ani Go, je to snaha přepsat C++ (nízkoúrovňový jazyk a jeho zero cost abstractions). Já jsem poměrně skálopevně přesvědčený, že autoři Rustu ty věci dělají tak dobře, jak je v jejich silách a vůbec si nemyslím, že by byli hloupí a nějaké zjevné lepší cesty k implementaci nějaké vlastnosti jim unikaly. Skoro mi přijde, že Ti je líto, že Rust je Rust a ne něco jiného a u Idrise, na kterého jsem reagoval hlavně, nevím na čem jsem, protože nic konkrétního nenapsal.

Rust není jazyk pro úplně každého a úplně na všechno, pokud se mi zrovna hodí něco, co on dobře umí, použiju ho a kde to dře, tam ho nepoužiju. A jelikož futures a async/await ve stabilním toolchainu odemykají cestu k použití aplikací a knihoven, které řeší zcela konkrétní problémy a to (podle všeho) docela slušně a dosud fungovaly jenom v unstable, budu šťastný jako blecha, protože mi to dává šanci se něco nového naučit a případně něco vytvořit. Good luck w/ Go/Erlang/whatever. A hezkou sobotu.

578
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 13:19:40 »
Koukám právě narvali async/await do Rustu. To je fakt mor.
To je smutný. Zrovna od Rustu bych čekal, že se omezí na CSP. Třeba vtáhne Actix do standardní knihovny nebo tak něco.

Rust pořádně neznám, takže neumím posoudit implementaci, ale pokud by to ve finále vedlo ke stejnýmu zmatku jako kdysi v Pythonu - pro každou knihovnu bude x verzí, jedna sync, jedna nad Actix, jedna nad Tokio a pak ještě jedna s async/await, přičemž každá jinak zabugovaná, tak by to byl teda fakt smutný příběh jinak moc pěkného jazyka...
Shit happens. Taky bych býval čekal, že to nezasviní blbostma.

To si fakt, projednou, nedokážete připustit, že třeba někdo ví víc než Vy a má dobrý důvod do Rustu ten async/await přidat?

Opravdu jste studovali, co všechno s tím vyřeší, co se tím zjednoduší, jestli se opravdu budou muset dělat (v Rustu, neřeším jiné jazyky) všechny knihovny dvakrát, jestli to opravdu musí přidávat bugy, nebo jenom tak bručíte, protože jste něco holt nečekali a nejde Vám to pod fousy?

579
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 12:29:39 »
No a s tím sleepem a joinem je zrovna pár hodin starý dotaz a vysvětlení na Redditu: https://www.reddit.com/r/rust/comments/dtp6z7/what_can_i_actually_do_with_the_new_async_fn/

580
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 12:20:45 »
Máš na mysli paralelní polling, něco jako https://docs.rs/futures/0.3.1/futures/macro.join.html ? Nebo něco komplikovanějšího? V téhle problematice nemám zkušenosti.
Napadají mě minimálně dva rozdílné způsoby, jak by se to dalo implementovat:

1. Promisy běží (potenciálně) skutečně paralelně, každý (potenciálně) na svém jádře

2. Promisy jsou odstartované "zaráz" (rychle po sobě), ale paralelně běží jenom operace "mimo jazyk" (typicky IO)

To první je asi jasný. To druhý je jenom "jakože paralelní" v JS stylu. Od serializovaných awaitů by se to poznalo tak, že
Kód: [Vybrat]
await sleep(1)
await sleep(1)
await sleep(1)
by netrvalo ~ tři sekundy, ale ~ jednu.

To druhé v JS jde implementovat, ale musí se to (AFAIK) udělat ručně přes Promise.all()

V tom je ten vtip - Rust není magický jazyk, nedělá žádné legrácky typu GC a automatickou paralelizaci. Programátor v Rustu by vždycky měl rozumět tomu, co dělá, když překročí hranice, kompilátor ho pošle k šípku a pak se dotyčný musí zamyslet a konflikt představ vyřešit. Třeba si vem takový Rayon - na první pohled to vypadá jako velká magie, která vyřeší něco za Tebe, on skutečně leccos umí díky možnostem, které Rust a jeho typový systém umožňuje, jenže pak zjistíš, že pro paralelní iterátor buďto musíš použít nějakou kolekci, kterou Rayon podporuje nebo si budeš muset naimplementovat příslušný trait nebo se na to (jako já, když jsem si s tím hrál) vykašleš úplně a prostě si uděláš vlastní paralelní iterátor, který si synchronizaci řeší sám. To není moc těžké, ale musíš u toho přemýšlet a narazíš pak (jako já) třeba na to, že objekt má delší životnost, než ses domníval a najednou se výpočet provádí de facto sekvenčně.

Proto bych osobně neočekával, že tohle Rust kdy bude dělat sám - můžeš mít simultánní polling, ale ty přesahy mezi vlákny si řešíš sám v nižší vrstvě. Nebo tam holt budeš mít nějaký objekt, který to bude umět řešit elegantně za Tebe oboje, ale zase budeš muset splnit nějaké podmínky na obou koncích - v té paralelní metodě pro multithread a v tom "klientu" v původním vláknu.

581
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 10:44:29 »
To je implementační detail bez jakéhokoliv dopadu na cokoliv, co jsem napsal.
BTW, kdybys chtěl nějaký větší rozdíl, tak největší, co mě napadá, je že await může být lazy nebo eager. Jak teď koukám, Rust má lazy. JS má eager (AFAIK).

Taky by šlo promisy z awaitů paralelizovat (k tomu právě směřovala ta moje testovací otázka). Jestli to nějaký jazyk skutečně dělá, to nevím. Obávám se, že spíš ne, protože v jazyce s mutable shared state by to bylo obtížné až nemožné udělat korektně.

Máš na mysli paralelní polling, něco jako https://docs.rs/futures/0.3.1/futures/macro.join.html ? Nebo něco komplikovanějšího? V téhle problematice nemám zkušenosti.

582
/dev/null / Re:Těžké OOP problémy
« kdy: 09. 11. 2019, 09:11:29 »
Koukám právě narvali async/await do Rustu. To je fakt mor.

Na tom "moru" vývojáři Rustu pracovali spoustu měsíců a komunita se na to dost těšila. Možná víš něco, co oni nevědí, ale žádné zděšení jsem nikdy na příslušných fórech nezaznamenal.

583
/dev/null / Re:Těžké OOP problémy
« kdy: 08. 11. 2019, 11:34:37 »
Dobře zvolená abstrakce naopak nevyžaduje, abys někam skákal, prostě o sobě říká, co dělá a typicky se o vnitřek zajímat vůbec nemusíš.
Nemusím se o vnitřek starat, pokud jsem si dostatečně jistý tím, 1. co je výsledkem její činnosti (pokud je to funkce) 2. že neobsahuje žádnou chybu.

Implementaci knihovních funkcí typu map budu prolízat až jako poslední, protože je nejmenší šance, že chyba bude právě v ní. Naopak konstrukce, které napsali kolegové před půl rokem a jsou v kódu použité jenom dvakrát, prolízt musím, protože pravděpodobnost chyby je veliká. V případě, že jsou srozumitelné a snadno zapamatovatelné, prolezu je jednou. Jinak je musím prolízat pořád dokola, protože prostě nejsem schopný si zapamatovat nebo vůbec pochopit, co mají dělat.

No a teď jsme myslím u toho - abstrakce jsou OK, když jsou dobře navržené a odladěné. Tudíž asi nechceme, aby je psal "kdokoli", ale pustíme na to člověka, který to umí, děláme review kódu a pak máme rozumnou jistotu, že ten vnitřek funguje a "pojídači koláčů" nasekají co nejméně chyb a ty jsou dobře viditelné. Je to jiný přístup, než když všichni "jedí z jedné mísy" - neříkám, že jediný možný, neříkám, že vždy optimální, ale podle mě dost užitečný a s úspěchem aplikovaný.

584
/dev/null / Re:Těžké OOP problémy
« kdy: 08. 11. 2019, 08:38:29 »
dobře zvolená a napsaná abstrakce kód nemůže znepřehlednit.
S tím bych nesouhlasil. Dokonce bych spíš tvrdil skoro opak: každá abstrakce z definice přidává další indirekci v tom smyslu, že když sleduju flow programu a narazím na abstrakci, musím odskočit jinam (do souboru, kde je ta abstrakce definovaná).

Jediné, co rozhoduje, je, jestli převáží nevýhody použití nebo nepoužití abstrakce. Což je typicky počet abstrakcí (jestli jsem schopen si je zapamatovat a ušetřit si tak odskoky) a jejich srozumitelnost (po jednom přečtení chápu smysl abstrakce, nedělám to tak, že sleduju jenom ten jeden průchod, který zrovna řeším).

Dobře zvolená abstrakce naopak nevyžaduje, abys někam skákal, prostě o sobě říká, co dělá a typicky se o vnitřek zajímat vůbec nemusíš. Co je abstrakce, je datová struktura abstrakce? Je bufferovaný soubor abstrakce, je check box abstrakce? Je volání dobře pojmenované funkce zbytečná překážka v čitelnosti kódu, když se to přece dá naprasit na jednom místě a překladač to snese? Proč používat map() a filter(), když všichni známe cyklus a taky funguje. Proč požívat cyklus, když máme goto...

585
/dev/null / Re:Těžké OOP problémy
« kdy: 08. 11. 2019, 08:17:30 »
Já bych taky doporučoval vystříhat se zobecňování.

Viděl jsem programy "lidí z praxe", kteří vystudovali jiný obor. Jakmile systém přesáhne určitou velikost, často nevědí moc co s tím, protože jim scházejí zkušenosti, nemají to osahané ani odkoukané. Programování je řemeslo úplně odlišné od jiných a jeho znalost nedá se nahradit ani selským rozumem ani vysokým IQ, vyjma prdlikání prográmků o pár tisících řádek. Mimochodem, lidé z jiných oborů, kteří mají ultravýkonný mozek, sice nevrství abstrakce, ale zase občas píší špagetový kód, ve kterém se vyznají přinejlepším oni sami a udržovatelnost je mizivá.

Co se týče "zbytečných" abstrakcí, je to otázka míry a odhadu. Kolikrát jsem zažil situaci, kdy kolegové tíhli k "custom" implementaci, pak se udělal jeden copy/paste, pak druhý, pak další a už to šlo tak nějak ze zvyku a když to po nich někdo přepíše, málem aby si za to dal facku, když "to přece takhle funguje" a "proč to neudělat zase tak, když máme dost jiné práce". Že se to pak další měsíce a roky s úspěchem dělá ponovu a co se řešilo kopírováním funkce o 100 řádcích nebo větší třídy, je teď na jedno volání, už nikdo nevidí, protože se to "teď dělá takhle, no". Nebo ty abstrakce daný tým znovupoužívá v dalších a dalších produktech, ale to už jaksi není vždycky vidět. No a navíc - dobře zvolená a napsaná abstrakce kód nemůže znepřehlednit. Naopak by měla vést k tomu, že se pořád dokola řeší pár řádek namísto špagetového monstra, kde "všechno souvisí se vším" a "nic není navíc".

Že je abstrakce nástroj, který může být použit špatně? Ale jistě, jako každý nástroj!

Stran: 1 ... 37 38 [39] 40 41 ... 43