Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Názory k článku
Funkce v programovacím jazyku Lua - uzávěry

Vuk
Vuk (neregistrovaný)
7. 4. 2009 9:26 Nový

Uzávěry v Pythonu a jinde

celé vlákno
Jak to je s Pythonem? Tam přece uzávěry rozumně implementované nejsou, ten příklad by v Pythonu vůbec nefungoval, uniká mi něco? A propos, co měl být ten čtvrtý jazyk v seznamu JavaScript, Python, Python či některé dialekty Lispu? (A s tím Lispem - měl jsem dojem, že Emacs-Lisp je v tomhle ohledu exot, že to většina ostatních Lispů dělá "pořádně", ale přehled o tom mám jen nevalný.)
Pavel Tišnovský aura:98
7. 4. 2009 11:31 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
sorry, patřil tam Perl :-) V Pythonu se to dělá trošku přes ruku, zkusím splácat nějaký příklad.
ava
ava (neregistrovaný)
7. 4. 2009 12:43 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
No, python ma to omezeni ze do promenne v nadrazenem kontextu nelze priradit, ale jinak ji lze normalne pouzivat.
#!/usr/bin/python

def generateClosure():
    start = [] 
    def function(): 
        start.append('X')
        print start
    return function

f1 = generateClosure()
f2 = generateClosure()
 
f1(); f1(); f1(); f1()
f2(); f2(); f2(); f2()

vypise

['X']
['X', 'X']
['X', 'X', 'X']
['X', 'X', 'X', 'X']
['X']
['X', 'X']
['X', 'X', 'X']
['X', 'X', 'X', 'X']
V praxi se s timto omezenim da bez problemu zit.
Inkvizitor
Inkvizitor (neregistrovaný)
7. 4. 2009 13:20 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
On ten příklad je taky docela prasárna. Podle mě má uzávěr význam při konstrukci callbacků apod. a obecně tam, kde chceme do funkce uzavřít v runtime HODNOTU nějakého parametru. Kdybych chtěl v Pythonu dělat něco podobného jako v uvedeném příkladu, nepoužiju uzávěr, ale generátor nebo funktor. Funkce obecně nemá co sahat vně své definice a rozhodně tam nemá co měnit.
hyperion
hyperion (neregistrovaný)
7. 4. 2009 13:31 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
no, kdyz se pomoci uzaveru vytvari objektovy system, tak se proste nekdy musi sahnout mimo funkci (resp. nestaci jen jeji parametry a navratove hodnoty). A pokud se chceme vyhnout globalnim parametrum (a to vetsinou chceme :-), tak se nabizi prave uzavery. On i ten generator je v podstate uzaver ne? (IMHO-nejsem pythonista)
Inkvizitor
Inkvizitor (neregistrovaný)
7. 4. 2009 13:44 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
No, minimálně se dá jako uzávěr chápat, resp. já bych ho popsal jako třídu, do níž nalijeme parametry při vytvoření a pak voláme opakovaně "svázanou metodu" next() a "svázaná metoda" tvoří uzávěr nad self. Pokud se podobný mechanismus použije někde dole, dejme tomu k vytvoření objektového systému, tak mi to samozřejmě nevadí.
Inkvizitor
Inkvizitor (neregistrovaný)
7. 4. 2009 13:45 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
Samozřejmě, že se vytváří instance třídy, pro upřesnění.
Pichi aura:75
7. 4. 2009 15:24 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
Ano, to co se dělá ve funkcionálních jazycích elegantně pomocí uzávěr jde v OOP vždy komplikovaně převést na objekt viz anonymní třídy v Javě. Mimochodem uzávěra je obvykle implementována právě něčím co se nápadně podobá objektu s jednou metodou. Jenže uzávěry jsou řádově jednodušší na používání a flexibilnější.
Inkvizitor
Inkvizitor (neregistrovaný)
7. 4. 2009 20:34 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
1. OK, tak sem s nějakým užitečným příkladem, který nelze například v Pythonu (o Pythonu jsme se bavili původně) řešit jinak než uzávěrem (jednoduché vytváření parametrizovaných callbacků nemyslím, to považuju za užitečnou výjimku) řešit jinak a lépe nebo srovnatelně dobře.


2. Java má ten problém, že nutí uživatele vytvářet třídy i tam, kam se absolutně nehodí. Na tom se shodneme.

3. Jednodušší na používání asi často jsou, ale to neznamená je vhodné je často používat. Aby byl kód dobře čitelný, je vhodné jasně popsat vstupy a výstupy. K popisu vstupů logicky patří hlavička funkce, možné výstupy se často zjistí taky v hlavičce (alespoň typ návratové hodnoty). Sahat mimo funkci, ať už jde o globální proměnné nebo jiný nelokální prostor vždycky znamená zavádění chaosu do rozhraní funkce a k tomu by měl být safra dobrý důvod (viz bod 1).
Pichi aura:75
7. 4. 2009 23:11 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
ad 1. Aha, takže callbacky jsou výjimka, která se nepočítá. Když k tomu přidám map nebo grep (filtr), tak to se asi počítat taky nebude. Složitější příklady funkcí vyšších řádů zavrhneme rovnou.

ad 3. A ono je někde zakázáno dokumentovat uzávěry? To se ke mě nedoneslo.
Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 0:43 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
1. Callbacky jsou výjimka, která se počítá, jinak bych je přece neuváděl. map() a filter() chcete srovnávat s tím příkladem v článku? A z hlediska použití, nebo implementace?

3. Zakázáno to jistě není. Přesto si myslím, že rozhraní funkce by mělo být uvedeno v hlavičce a co se týče parametrů, je tomu tak vždy. Zda bude dokumentace každé proměnné z vnějšku uzávěru v kódu obsažena a hlavně to, zda ta dokumentace zůstane platná i po každé změně v tom uzávěru, je otázka. Větší problém ale vidím v tom, že na tu vnější proměnnou může sahat i kdokoliv jiný a dělat si s ní, co se mu zamane. V takovém případě ta dokumentace té funkce samotné nebude moc platná.
uživatel si přál zůstat v anonymitě
8. 4. 2009 1:11 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
"1. Callbacky jsou výjimka, která se počítá, jinak bych je přece neuváděl. map() a filter() chcete srovnávat s tím příkladem v článku? A z hlediska použití, nebo implementace?"

Tak dobře, třeba jiný příklad. CL-PPCRE je lispová knihovna, která implementuje regulární výrazy. Přesto, že je psaná v Lispu, je chvílemi rychlejší než implementace regulárních výrazů v Perlu (která je v Cčku, ale je nutno přiznat, že lépe zvládá některé okrajové případy - resp. případy, které by okrajové být měly). Kompiluje regulární výraz do stromu uzávěrů, který se zavolá se vstupními daty a běží pekelně rychle. S objekty a metodami by to asi tak dobře nešlo.

CL-PPCRE je v zásadě kombinátorová knihovna s předřazeným parserem. Viděl jsem i jiné podobné, třeba jednu pěknou XML knihovnu ve Scheme. Poměrně abstraktní, ale hezky to korespondovalo s doménou dotyčného problému. Tak nějak mi přijde, že použít místo toho ty pythoní konstrukce by bylo právě jako použít if a goto. (Jak přesně se v Pythonu parciálně aplikuje syntaxe? Nejde to, že? Aha!) Mimochodem, kombinátorové knihovny už lezou i do Pythonu. (PyParsing, třeba...)

Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 9:11 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
No tak tohle jsou zajímavé příklady. Takové věci se pro Python obyčejně programují v C (resp. v jiných jazycích, které kompilují do nativního kódu, jako Pyrex nebo OCaml), což má samozřejmě i svoje nevýhody. Ty knihovny neznám, takže nemohu posoudit, nakolik to hezky koresponduje s doménou problému, ale klidně to může být možné. Každopádně tohle je hodně nízkoúrovňová práce, takže pokud je alternativou nějaká C knihovna, tak proč ne.

Co je parciální aplikace syntaxe a proč by měla zajímat programátora v Pythonu? Pokud jde o tzv. currying, doporučuji podívat se na standardní modul functools, konkrétně na funkci partial(). To je koneckonců i lepší náhrada uzávěrů v některých případech (parametrizované callbacky).
Pichi aura:75
8. 4. 2009 10:59 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
... Ty knihovny neznám, takže nemohu posoudit, nakolik to hezky koresponduje s doménou problému, ...
... Implementace korutin v Pythonu existují také, ikdyž nevím, nakolik se dají srovnat s možnostmi Lua...
... Co a jak byste měl uvádět v Lua Vám předepisovat nebudu, tento jazyk neznám a je to Vaše věc...
"Neznám, nemohu posoudit, nevím, neznám" - toho by jste se asi měl držet. Když nevím, neznám a nemohu posoudit, tak nevyvozuji závěry a nepoučuji ostatní. Namístě by bylo začít třeba tímhle: Structure and Interpretation of Computer Programs aspoň první dvě kapitoly. Je to učivo prvního ročníku na MITu. Opírat svoje přesvědčení o neznalost je totiž přinejmenším pochybné.
Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 12:32 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
1. Je lepší přiznat neznalost, tam kde je. Vy tady naprosto demagogicky ukazujete na věci, jejichž neznalost se NAPROSTO NETÝKÁ mého původního příspěvku.

2. Nepřišel jsem poučovat jiné, ale diskutovat (to znamená i zkorigovat svoje názory, pokud se mýlím). Což jste možná nepochopil, stejně jako nechápete nebo nechcete chápat, co je slušná diskuse.

3. Za odkaz na text děkuji, ale raději bych fakt viděl nějaký praktický příklad. Ten jsem od Vás zatím neviděl, samé arogantní příspěvky a jinak nic (kromě tohohle odkazu, samozřejmě). Takhle působíte sice jako všeználek, ale s mizerným přínosem.
Pichi aura:75
8. 4. 2009 13:18 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
A v jakém jazyce je chcete? Perl, Lua, Scheme, Erlang?
Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 14:39 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
No tak mohu-li si vybrat z hlediska mého zájmu, preferoval bych ten Erlang. Ale nejvíc mě zajímá, nakolik je to řešení náročné na realizaci jinými předměty a jak je na tom z hlediska využití v praxi. Takže pokud bude nějaký jazyk v tomto lépe než jiné, budu rád, když použijete ten.
Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 21:29 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
Namísto "předměty" mělo být "prostředky", ale to je doufám jasné.
uživatel si přál zůstat v anonymitě
7. 4. 2009 23:24 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
1. Python je jazyk, který univerzální a flexibilní mechanismus uzávěrů nahradil půltuctem specializovaných konstrukcí. (Kupříkladu iterace: cyklus for, iterátorové a generátorové výrazy; parametrizovaný sort: předání pojmenované funkce nebo polofunkční lambda (povolené jen výrazy), datová abstrakce: objektový systém s neměnnou sémantikou ... atd.) Opravdu čekáte, že příkladů, kdy je (polofunkční) pythoní lambda lepší než jiná pythoní konstrukce, naleznete hodně?

Mimochodem, není ten "funktor" v Pythonu jen "anonymní uzávěr" se složitou syntaxí (protože se musí definovat třída a konstruktor)? To by právě možná byl docela dobrý příklad toho, kdy je uzávěr lepší. :-)

3. Mezi metodou objektu sahající na atributy objektu a mezi funkcí sahající na bindingy se scopem širším než tělo její funkce v podstatě není žádný rozdíl. :-) Obojí představuje "šahání jinam než dovnitř funkce" a v obou případech je dotyčný binding vytvořen jinde než v těle funkce a jindy než při jejím volání. To je mimochodem důvod, proč se lexikální scope tolik ujal: Je mnohem čitelnější (je statický) než dynamický scope, vlastně je triviálně pochopitelný a intiutivní.
Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 0:30 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
1. Ano, nahradil low-level flexibilní mechanismus půltuctem specializovaných konstrukcí, které vedou k vysoké čitelnosti programů v tomto jazyce napsaných. Stejně jako Pascal "kdovíproč" zavedl cykly for, while a until, přestože si mohl v klidu vystačit s flexibilní dvojicí if a goto. Já čekám, že mi někdo ukáže příklad třeba i s plnofunkční lambdou, který nelze v Pythonu s pomocí toho půltuctu konstrukcí vyřešit stejně dobře.

Ten uzávěr bude někdy lepší a jindy ne. V tom příkladu z článku bych jednoznačně preferoval generátor.

3. V Pythonu je sahání na atributy objektu krystalicky jasné - vždycky předtím musím napsat self. (v Ruby se dá použít zavináč). U každé proměnné v uzávěru musím naopak přemýšlet, kde se vlastně vzala a proč. To mi přijde podstatně horší.
uživatel si přál zůstat v anonymitě
8. 4. 2009 0:52 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno

Každá liška chválí svůj ocas. :-) Na tom není nic špatného, nicméně přirovnání s if a goto není moc na místě. if a goto jsou na "ose programovacích jazyků" na straně Turingova stroje, a musí se od nich jít "doprava" směrem k lambda kalkulu. Uzávěr je na straně lambda kalkulu, a dá se od něj jít jen "doleva" směrem k Turingovu stroji. Nicméně je mnohem mocnější, protože pomocí if a goto se vyšší řídicí struktury a abstrakce jako iterátory, funkce a podobně dělají mnohem hůře (preprocesorem? to už je vlastně kompilátor, že...), zatímco druhým směrem je to IMHO o dost jednodušší (viz Smalltalk).

A ještě bych rád upozornil, že ty pythoní konstrukce se do Lua dají dostat celkem snadno - pokud o ně stojíte -, zatímco s dohackováním tail callů a korutin à la Lua do Pythonu bych to viděl tak trošku bídně.

Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 1:25 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
Pozor na to, já jsem nechtěl říci, že Python je dokonalý, ikdyž to díky tomu, že některé konkrétní vlastnosti hájím nebo na nich ukazuju, proč si myslím, že něco považuju za lepší než něco jiného. Pythonu by jistě šlo spoustu věcí i vytknout. Funkci lze pomocí goto nasimulovat celkem snadno - například explicitním použitím "zásobníku" a "speciálních registrů" implementovaných pomocí globálních proměnných. Jasně že to bude vypadat dost blbě, ale to je jiná věc. Podobně s iterátory - tam to bude s globálními proměnnými naopak "krásná" obdoba implementace iterátoru pomocí podobné techniky, jako je ta použitá v článku.

Já klidně věřím, že v Lua lze všechny možné konstrukce (tedy i ty pythonní) vcelku snadno implementovat, problém ale vidím v tom, že to je nové a nové vynalézání kola, přičemž to kolo není standardizované, takže se při každém setkání s ním musím přesvědčit, že to je skutečně to kolo, které znám. Ale to je samozřejmě obecný problém a je otázkou míry, co má být součástí jazyka.

Tail call je v Pythonu samozřejmě problém, ikdyž se naimplementovat dá, byť ne moc optimálně ani elegantně, třeba takto:

http://lambda-the-ultimate.org/node/1331#comment-15165

Implementace korutin v Pythonu existují také, ikdyž nevím, nakolik se dají srovnat s možnostmi Lua.
uživatel si přál zůstat v anonymitě
8. 4. 2009 3:12 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
V současném Pythonu jsou korutiny omezeny jen na jediný stack frame. To je dáno i tím, že Python odvozuje skutečnost, zda funkce je nebo není generátor, z toho, zda se v ní vyskytuje nebo nevyskytuje klíčové slovo yield, a ten yield pak funguje jen "o úroveň výš". To je sice tzv. "primitivní, leč účinné" a hezky to řeší jednoduché případy, ale zase to bourá možnost nějak rozumně yieldovat z funkcí volaných v generátoru (pak je tu ten idiom "probublávání yieldu", ale to je právě ta ošklivost).
Ksl
Ksl (neregistrovaný)
7. 4. 2009 23:09 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
"Funkce obecně nemá co sahat vně své definice a rozhodně tam nemá co měnit."

V jazycích, ve kterých jsou *všechny* funkce first-class values, a tedy de facto proměnné s hodnotou typu function, je nesahání na proměnné se scopem širším než tělo funkce poměrně špatně realizovatelné. Nechcete doufám tvrdit, že v Lua bych uvnitř funkce, která používá funkci print(), měl na začátku funkce uvádět něco jako 'local_require("print")' nebo tak nějak?
Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 0:37 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
Co a jak byste měl uvádět v Lua Vám předepisovat nebudu, tento jazyk neznám a je to Vaše věc. Funkce print() je sice dobrý příklad použití hodnoty z vnějšku, jenomže mně šlo hlavně o proměnné (což jsem, pravda, neuvedl) a zejména o jejich destruktivní změny. Funkce print() je neměnná a pokud se i ona chová "slušně" (tedy vypisuje text výhradně v závislosti na svých parametrech a nekouká po okolí, co tam ještě přidat), zůstane kód krásně srozumitelný.
Vuk
Vuk (neregistrovaný)
8. 4. 2009 10:32 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
Vy teda vlastně chcete programování bez vedlejších efektů, chápu to dobře? Proč ne, to je celkem sympatický fundamentalismus :) (A chcete-li být důsledný, i na ten print byste potřeboval například Haskellovské monády.)

Co se srozumitelnosti týká: pokud někdo zkusí napsat bez "plnofunkční lambdy" například už zmíněné kombinátory parserů, dopadne to strašně (alespoň já to zkusil v Javě, a strašně to dopadlo; nemyslím, že to je jen můj problém). Zatímco v plně funkcionálních jazycích je to průhledné (přinejmenším pro někoho, kdo je ten který jazyk zvyklý číst) a hlavně o řád jednodušší.
Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 12:36 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
Ano, tady jste uhodil hřebíček na hlavičku. Skutečně mně jde o minimalizaci kódu s vedlejšími efekty (resp. jeho uzavření do jasně ohraničených míst v kódu) a Haskell je jazyk, který pro to má lepší podporu než třeba Python. Za námět děkuji. ;)
Ondrej SanTiago Zajicek
Ondrej SanTiago Zajicek (neregistrovaný)
8. 4. 2009 22:15 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
> A s tím Lispem - měl jsem dojem, že Emacs-Lisp je v tomhle ohledu exot, že to většina ostatních Lispů dělá "pořádně", ale přehled o tom mám jen nevalný.)

AFAIK starsi Lispy mely obecne dynamickou platnost promennych, zatimco Common Lisp a Scheme maji lexikalni platnost promennych (a tedy plne closures).
Ondrej SanTiago Zajicek
Ondrej SanTiago Zajicek (neregistrovaný)
8. 4. 2009 22:16 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
> zatimco Common Lisp a Scheme

(Coz jsou dnes asi nejrozsirenejsi dialekty Lispu.)
hyperion
hyperion (neregistrovaný)
9. 4. 2009 8:19 Nový

Re: Uzávěry v Pythonu a jinde

celé vlákno
i Logo se oznacuje jako dialekt Lispu, ale syntakticky jde uz o dost odlisny jazyk
David Štancl
7. 4. 2009 13:03 Nový

Chybka?

celé vlákno
Jestli jsem to dobře pochopil, pak by v první části nemělo být
"function jmeno(parametry) ... end je pouze syntaktickým cukrem ekvivalentním k zápisu promenna = function(parametry) ... end"
ale
"function jmeno(parametry) ... end je pouze syntaktickým cukrem ekvivalentním k zápisu jmeno = function(parametry) ... end"
(místo promenna je jmeno).
Pavel Tišnovský aura:98
7. 4. 2009 22:35 Nový

Re: Chybka?

celé vlákno
jasne, je to tak, diky za upozorneni, opravime to.
Trm
Trm (neregistrovaný)
8. 4. 2009 22:53 Nový

zabalte to

celé vlákno
Pane Tisnovsky, kdy jste psal super clanky, ale mam pocit, ze by bylo nacase to zabalit.
Perly typu ,,tyto jazyky tedy nemají speciální syntaxi pro třídy a objekty'' asi do zlateho fondu nikdo neda.
Inkvizitor
Inkvizitor (neregistrovaný)
8. 4. 2009 23:21 Nový

Re: zabalte to

celé vlákno
Možná mě tu zase někdo označí za blbce, ale co je na tom výroku špatně?
hyperion
hyperion (neregistrovaný)
9. 4. 2009 8:16 Nový

Re: zabalte to

celé vlákno
ty jsi asi cetl jen perex clanku ne? Musi mit tedy funkcionalni jazyky specialni syntaxi pro tridy a objekty nebo ne?
Pavel Tišnovský aura:98
9. 4. 2009 15:42 Nový

Re: zabalte to

celé vlákno
Hmm, to stejné jsem se dnes dozvěděl z jiné strany. Tak díky...
Inkvizitor
Inkvizitor (neregistrovaný)
9. 4. 2009 18:25 Nový

Re: zabalte to

celé vlákno
Nevím, jestli to rozhodnutí záleží na nějakém "hlasování", ale za sebe musím říct, že by mě to velice mrzelo. Podobně kvalitních autorů tu mnoho není a ti dobří obyčejně píší až žalostně málo článků.

Takže -1 ;-)
Pavel Tišnovský aura:98
9. 4. 2009 19:24 Nový

Re: zabalte to

celé vlákno
nene, to se vubec netykalo clanku na Rootu, zabalili jsme to jinde :-(
Zasílat nově přidané příspěvky e-mailem