Funkcionální jazyky.

filosof

Funkcionální jazyky.
« kdy: 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

Kód: [Vybrat]
(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

Kód: [Vybrat]
(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.


filosof

Re:Funkcionální jazyky.
« Odpověď #1 kdy: 17. 08. 2015, 21:57:04 »
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..

Kit

Re:Funkcionální jazyky.
« Odpověď #2 kdy: 17. 08. 2015, 22:24:03 »
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód
Kód: [Vybrat]
(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.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Funkcionální jazyky.
« Odpověď #3 kdy: 18. 08. 2015, 01:01:02 »
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód

Kód: [Vybrat]
(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.

k

Re:Funkcionální jazyky.
« Odpověď #4 kdy: 18. 08. 2015, 10:10:23 »
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.


Pavel Tisnovsky

Re:Funkcionální jazyky.
« Odpověď #5 kdy: 18. 08. 2015, 10:25:52 »
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód

Kód: [Vybrat]
(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.

Ivan Nový

Re:Funkcionální jazyky.
« Odpověď #6 kdy: 18. 08. 2015, 11:45:24 »
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á.

Re:Funkcionální jazyky.
« Odpověď #7 kdy: 18. 08. 2015, 12:04:28 »
Tak, tak, ten kod je vic lispovy nez funkcionalni.

Pavel Tisnovsky

Re:Funkcionální jazyky.
« Odpověď #8 kdy: 18. 08. 2015, 13:22:49 »
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)


--,_O_,--

Re:Funkcionální jazyky.
« Odpověď #9 kdy: 18. 08. 2015, 14:23:06 »
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód

Kód: [Vybrat]
(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

Kód: [Vybrat]
(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é.

Radek Miček

Re:Funkcionální jazyky.
« Odpověď #10 kdy: 18. 08. 2015, 14:42:51 »
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í.

meno

Re:Funkcionální jazyky.
« Odpověď #11 kdy: 18. 08. 2015, 15:36:23 »
Tak jsem se kouknul na Clojure zde ve tutoriálu od p. Tišnovského a při pohledu na první kód

Kód: [Vybrat]
(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

Kód: [Vybrat]
(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 :-)


Pavel Tisnovsky

Re:Funkcionální jazyky.
« Odpověď #12 kdy: 18. 08. 2015, 16:11:07 »
Taky by to slo napsat treba takto:
(forever (-> (read) (eval) (print)))

Jenze to by chtelo hned na zacatek vysvetlit -> (a mozna i to makro)

k

Re:Funkcionální jazyky.
« Odpověď #13 kdy: 18. 08. 2015, 16:23:30 »
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)) }

k

Re:Funkcionální jazyky.
« Odpověď #14 kdy: 18. 08. 2015, 16:24:06 »
Kód: [Vybrat]
for (;;) { print(eval(read)) }