Byla vydána nová major verze 5.0.0 svobodného multiplatformního nástroje BleachBit (GitHub, Wikipedie) určeného především k efektivnímu čištění disku od nepotřebných souborů.
Na čem pracují vývojáři webového prohlížeče Ladybird (GitHub)? Byl publikován přehled vývoje za duben (YouTube).
Provozovatel čínské sociální sítě TikTok dostal v Evropské unii pokutu 530 milionů eur (13,2 miliardy Kč) za nedostatky při ochraně osobních údajů. Ve svém oznámení to dnes uvedla irská Komise pro ochranu údajů (DPC), která jedná jménem EU. Zároveň TikToku nařídila, že pokud správu dat neuvede do šesti měsíců do souladu s požadavky, musí přestat posílat data o unijních uživatelích do Číny. TikTok uvedl, že se proti rozhodnutí odvolá.
Společnost JetBrains uvolnila Mellum, tj. svůj velký jazykový model (LLM) pro vývojáře, jako open source. Mellum podporuje programovací jazyky Java, Kotlin, Python, Go, PHP, C, C++, C#, JavaScript, TypeScript, CSS, HTML, Rust a Ruby.
Vývojáři Kali Linuxu upozorňují na nový klíč pro podepisování balíčků. K původnímu klíči ztratili přístup.
V březnu loňského roku přestal být Redis svobodný. Společnost Redis Labs jej přelicencovala z licence BSD na nesvobodné licence Redis Source Available License (RSALv2) a Server Side Public License (SSPLv1). Hned o pár dní později vznikly svobodné forky Redisu s názvy Valkey a Redict. Dnes bylo oznámeno, že Redis je opět svobodný. S nejnovější verzí 8 je k dispozici také pod licencí AGPLv3.
Oficiální ceny Raspberry Pi Compute Modulů 4 klesly o 5 dolarů (4 GB varianty), respektive o 10 dolarů (8 GB varianty).
Byla vydána beta verze openSUSE Leap 16. Ve výchozím nastavení s novým instalátorem Agama.
Devadesátková hra Brány Skeldalu prošla portací a je dostupná na platformě Steam. Vyšel i parádní blog autora o portaci na moderní systémy a platformy včetně Linuxu.
Lidi dělají divné věci. Například spouští Linux v Excelu. Využít je emulátor RISC-V mini-rv32ima sestavený jako knihovna DLL, která je volaná z makra VBA (Visual Basic for Applications).
Byla vydána verze 7.0.0 skriptovacího jazyka PHP používaného zejména k vývoji dynamických webových stránek. Nejnovější větev PHP přináší novou verzi Zend Enginu, řadu vylepšení a nových vlastností. Dle oznámení může být PHP 7 až dvakrát rychlejší než PHP 5.6 a má výrazně nižší paměťové nároky. K dispozici je příručka pro přechod z PHP 5.6.x na PHP 7.0.x.
Tiskni
Sdílej:
jaké praktické a výkonnostní výhody má PHP nad Pythonem?Za sebe: nenašel jsem pro Python něco, co by dělalo FastCGI server, a umožnilo do existujících HTML stránek vložit krátký snippet Pythoního kódu, prostě stejně jako PHP:
<?python print("Hello world") ?>
. Když se někde zeptám, tak mi všichni začnou říkat, že Python ví lépe než já co chci, tedy že potřebuji komplexní šablonovací systém, a že nepotřebuji webserver, protože Python má přece vestavěný, a že každá stránka má mít vlastní rezidentní proces, který jí bude dělat webserver.
/var/www/doména/cesta
), přečte ho a vrazí do template. S tím by se dalo žít, ale 1) neumím z templaty vypsat generický výpis (print() píše samozřejmě do konzole), 2) odpověď to pošle až celou najednou po tom, co je template hotová. Takže nedokážu implementovat partial content.
Takže nedokážu implementovat partial content.Nejmenuje se to takhle. Use-cases:
multipart/x-mixed-replace
, a pak mu postupně posílám ty sekce.Na prúdové spracovanie ja dobré tornado / cyclone.
neumím z templaty vypsat generický výpis (print() píše samozřejmě do konzole)Budeš si muset print() redefinovat tak, aby psal do té templaty. Když se kouknu na zdroják, tak se tomu předává jakýsi _stdout parametr, zkus schválně co se stane, když do něj zapíšeš. Netvrdím ale, že to půjde, ostatně je to SimpleTemplate. V tomhle ohledu by možná bylo lepší použít nějakou z alternativ, jako třeba zmiňovaná jinja2 (tam by to podle rychlého googlení mělo jít přes Custom Filters).
Takže nedokážu implementovat partial content.V bottle je objekt response. Pro inspiraci viz toto: Is it possible to use gzip compression with Server-Sent Events (SSE)?
Simplehttpserver mě napadl, jako první řešení toho, jak docílit, aby mi HTTP server interpretoval <?Python print("hello") ?> jako pythonovský kód.Ale ten SimpleHTTPServer jenom servíruje soubory, interpretaci bych si musel napsat.
Jinak na CGI řešení s Pythonem je celá řada projektíčků.Já chtěl FastCGI, protože a) bych si musel napsat parser (což by nebylo tak těžké), b) bych musel nějak vyřešit, aby se při každém requestu nespouštěl nový pythoní interpret. Pro Apache existuje mod_python, ale já na většině serverů nemám Apache. Asi budu reverzovat ten mod_python, jak udělat, aby to nespouštělo nový interpret při každém požadavku.
Vůbec jsem si nevšimnul, že by si Jenda na něco stěžoval.Viz:
Když se někde zeptám, tak mi všichni začnou říkat, že Python ví lépe než já co chci, tedy že potřebuji komplexní šablonovací systémNa což jsi mu řekl, ať si implementuje šablonovací systém.
a že nepotřebuji webserver, protože Python má přece vestavěnýA pak mu doporučil vestavěný simplehttpserver.
A nemůže být info o 7 řádcích kódu vysvětlení, proč mu lidi doporučují embeded server?Došlo mi, že by mi bylo asi fuk, jestli to je webserver nebo fastcgi server (jen nevím, jestli u webserveru umí lighttpd a Apache chunked jak jsem psal výše). Jenže druhý problém je, že ani to řešení s webserverem nedělá to, co jsem požadoval.
Jinak o Pythonu a FastCGI se dá něco najít. Nakolik je to použitelné netuším.Ani jeden z těch návodů nesplňuje mé původní požadavky, jedná se o separátně běžící konkrétní aplikaci. Nemohu mít pro každý skript spuštěný proces. Tímto způsobem by to šlo leda že bych spustil toto a to by byl parser, který by dělal eval() dalších souborů. Přijde mi to přes ruku, ale v Pythonu se mi programuje o tolik líp než v PHP, že to asi zkusím.
Ani jeden z těch návodů nesplňuje mé původní požadavky, jedná se o separátně běžící konkrétní aplikaci. Nemohu mít pro každý skript spuštěný proces.Zkoušel jsi ten bottle? Ten má FastCGI rozhraní, přes které se umí připojit na „velké“ servery jako nginx, ale umí běžet i jako docela postačující server (běží na tom třeba moje stránky).
Tímto způsobem by to šlo leda že bych spustil toto a to by byl parser, který by dělal eval() dalších souborů. Přijde mi to přes ruku, ale v Pythonu se mi programuje o tolik líp než v PHP, že to asi zkusím.Prostě přečteš soubor, který přišel v URL, spustíš nad ním template engine a vrátíš zbytek. Asi by nebylo od věci to napsat jako framework, když je po tom taková poptávka. Píšu si do todo.
spustíš nad ním template engineTo mi právě nejde, protože to čeká, až template engine doběhne, a pak to teprve vrátí výsledek.
Asi by nebylo od věci to napsat jako framework, když je po tom taková poptávka.Nevím o nikom jiném než jsem já, kdo by to chtěl.
Nevím o nikom jiném než jsem já, kdo by to chtěl.Kdysi jsem to chtěl taky, tak jsem googlil a našel jsem docela hodně stackoverflow threadů, kde to lidi taky poptávají.
To mi právě nejde, protože to čeká, až template engine doběhne, a pak to teprve vrátí výsledek.Aha. Tak tohle se bude řešit docela blbě. Jediné, co mě napadá je nedělat to v template engine, protože fakt nevím o žádném, který by umožňoval proudové renderování (ale v tomhle nejsem zrovna dvakrát odborník, mirec dělá weby, tak možná bude vědět víc).
Jinja2 má TemplateStream.
Mimochodem v PHP je webserver na 0 nebo 1 řádek kódu, podle toho, jak to počítáš (php -S).Imho nemá smysl srovnávat jazyk s modulem pro apache. V PHP jako jazyku taky webserver nebude žádná slává. V PHP jako frameworku je to o něčem jiném, ale to pro python taky.
Tyhle embedded webservery mají ale problém v tom, že nemají žádné pokročilejší konfigurační volby, takže jim člověk stejně musí předřadit „skutečný“ webserver.Já konkrétně používám bottle přímo jako webserver s backendem paste (zajišťuje multithreading).
Možná je to tím, že v Pythonu lze udělat webserver na 7 řádek kódu a pak už si můžete parsovat vaše soubory jak je libo. https://docs.python.org/2/library/simplehttpserver.htmlA dalších kdovíkolik řádek musím vymyslet, aby mi můj současný webserver při požadavku na soubor.py tento přesměroval na tento pythoní server a ten běžel ve správném adresáři (v tom, ve kterém je ten soubor).
V časech kompilovaných CGI scriptů bylo PHP docela šikovným nástrojem.Mně by nevadilo, kdyby se to kompilovalo, kompilaci si naskriptuju.
Nějak jsem neměl sílu snášet ty přešlapy, když se PHP snažilo vyrůst z (Private Home Page) někam dál.Já nerozporuji, že PHP jako jazyk stojí za prd.
Chybí-li vám hosting pro PythonNechybí, všechno mi běží na serverech, kde mám roota, takže si můžu cokoli nainstalovat a nastavit.
Ale pokud vím, tak smyslem FastCGI (kterým jsem před lety pythoní aplikace mimochodem běžně deployoval) je právě rezidentní proces pro každý jednotlivý web (nikoli stránku).Ne tak docela. Navíc ještě řeší, zda ten proces musí běžet a jestli není lepší ho vypnout a spustit něco jiného. Navíc je tam takový drobný rozdíl v sémantice, kdy jednotlivé požadavky jsou pořád velmi izolované (až na nějaké to kešování). FastCGI je jen optimalizace obyčejného CGI, kde to je nový proces pro každý požadavek. Oproti tomu při trvale běžícím procesu se zachovává kontext mezi požadavky. Kdyby Python měl něco jako PHP-FPM a bylo to běžně podporované na webhostinzích, bylo by to úplně o něčem jiném.
FastCGI je jen optimalizace obyčejného CGI, kde to je nový proces pro každý požadavek.
Nový proces (tj. fork()
) není až takový problém - a nový proces pro každý request může vznikat i u FastCGI (spíš by mne překvapilo, kdyby to nebyla většinová implementace). Podstatným problémem klasického CGI je ten execve()
, který u klasického CGI následuje.
execve()
jde hlavně o spojení k databázi, otevřené logy, načítání konfigurace a podobné inicializační věci, které trvají dlouho a které kvůli execve()
neumí CGI uchovat mezi požadavky.
https://www.phusionpassenger.com/library/walkthroughs/start/python.html
https://www.phusionpassenger.com/library/walkthroughs/basics/python/
https://www.phusionpassenger.com/library/walkthroughs/deploy/python/
Ako človek, ktorý prešiel z PHP na django môžem povedať jedinú výhodu PHP - podpora hostingov. Čo sa týka výkonu python je prakticky rovnako výkonný ako node.js (ak sa použije pypy). Django je kapitola sama o sebe, výkon šablónovacieho systému je žalostný, ale dá sa ľahko vymeniť za jinja2.
ty se koukám prostě nechceš učit nicVážně? Kde na to koukáš? Taky bych se rád podíval *odloží self handbook a napjatě čeká*.konzerva, v IT tě to brzy zabije
Vážne žiadne zrýchlenia? Jazyk, ktorý má 68 funkcií (pre porovnanie PHP má vyše 6000) potrebuje fakt orezávať zbytočnosti?
Já bych prosil nějakou studii dokazující, že statický typový systém vede na vyšší produktivitu, protože zatím veškeré mé desetileté programátorské zkušenosti ukazují pravý opakŽádnou nemám. Nicméně nepodporuje mé tvrzení skutečnost, že Python přidal syntax pro typové anotace? Dále, když máte bohatý statický typový systém s dobrou typovou inferencí, může vám IDE vypomoci při tvorbě kódu a při orientaci v kódu, aniž by to znamenalo znepřehlednění programu typovými anotacemi. V tzv. dynamicky typovaných jazycích máte sice větší volnost (například lze manipulovat s třídami za běhu), ale je tam větší riziko, že IDE těmto obratům neporozumí a nijak vám nepomůže.
Kromě toho, typový systém brání některým chybám, na něž v tzv. dynamicky typovaných jazycích přijdete až za běhuAno, to uznávám.
– tím se vývoj zrychluje.Neuznávám, že se tím vývoj zrychluje, protože stejně musím psát testy tak, jako tak.
Neuznávám, že se tím vývoj zrychluje, protože stejně musím psát testy tak, jako tak.Někdy stačí psát testů méně, protože může nastat méně situací (typy zamezí vzniku některých situací).
Žádnou nemám. Nicméně nepodporuje mé tvrzení skutečnost, že Python přidal syntax pro typové anotace?Ne, to fakt nepodporuje. Do pythonu to bylo přidané po 26 letech spokojeného fungování hlavně kvůli „bezpečnosti“ a nápovědám funkcí v IDE (místo v docstringu to teď bude oblejzat definici funkce, třikrát hurá). Produktivitu jsem fakt nikde v diskuzích kolem toho, ani v PEPu neviděl.
Dále, když máte bohatý statický typový systém s dobrou typovou inferencí, může vám IDE vypomoci při tvorbě kódu a při orientaci v kódu, aniž by to znamenalo znepřehlednění programu typovými anotacemi.Imho je nutné rozlišovat taky silné a slabé typové systémy. Python používá silné typování (objekt nikdy nemění typ) s dynamickými typy proměnných (proměnná může ukazovat na objekty libovolného typu a na co ukazuje lze později změnit). IDE pro python existují a fungují stejně dobře, jako třeba pro javu (viz pycharm). „Problém“ byl u funkcí, kde IDE může zkoušet odvodit podle kódu funkce co všechno lze do ní dát, a co už vyhodí výjimku. Běžně se to psalo do docstringů, teď se to bude moct volitelně psát kolem. Osobně v tom nevidím žádnou silnou výhodu a kdyby bylo na mě, tak bych tam tuhle featuru nepřidával, protože to kurví duck typing a původní ideu OOP, ve prospěch javovin.
IDE pro python existují a fungují stejně dobře, jako třeba pro javu (viz pycharm).Fungují dobře jen v případě, pokud je kód velmi jednoduchý nebo pokud mají speciální podporu pro použité knihovny (což platí jen pro značně rozšířené knihovny – pro ostatní knihovny máte smůlu). Například můžete zkusit napsat kód, který modifikuje nějaké třídy za běhu (třeba přidává nebo mění metody) a pozorovat, jak se s tím různá IDE vyrovnají. Jinak řečeno, když v těch jazycích píšete jako v Javě, tak IDE fungují dobře. Když, ale začnete využívat skutečnost, že třídy jsou obyčejné hodnoty, a měnit je za běhu (čímž někdy lze ušetřit velké množství kódu), tak většina IDE selže.
„Problém“ byl u funkcí, kde IDE může zkoušet odvodit podle kódu funkce co všechno lze do ní dát, a co už vyhodí výjimku.BTW tohle odvozování začne být problematické, když analyzovaná funkce bere jinou funkci jako argument nebo když chcete odvozovat generické typy.
Fungují dobře jen v případě, pokud je kód velmi jednoduchý nebo pokud mají speciální podporu pro použité knihovny (což platí jen pro značně rozšířené knihovny – pro ostatní knihovny máte smůlu). Například můžete zkusit napsat kód, který modifikuje nějaké třídy za běhu (třeba přidává nebo mění metody) a pozorovat, jak se s tím různá IDE vyrovnají.S tímhle kódem si samozřejmě neporadí. Naštěstí něco takového jsem zatím nikdy nebyl nucen dělat a pokud bych byl, asi bych si našel lepší abstrakci.
Jinak řečeno, když v těch jazycích píšete jako v Javě, tak IDE fungují dobře. Když, ale začnete využívat skutečnost, že třídy jsou obyčejné hodnoty, a měnit je za běhu (čímž někdy lze ušetřit velké množství kódu), tak většina IDE selže.Já si pořád nějak neumím představit use-case, kde bych je skutečně potřeboval měnit. Například v pythonu není problém si napsat proxy objekt, který bude odchytávat cally, což imho hodně těhle tlaků odstraňuje.
BTW tohle odvozování začne být problematické, když analyzovaná funkce bere jinou funkci jako argument nebo když chcete odvozovat generické typy.Ano. To ale bude i s type hintingem, ne?
Já si pořád nějak neumím představit use-case, kde bych je skutečně potřeboval měnit.Například vygenerovat nějaký boilerplate kód? Nedělá to například SQLAlchemy? Dokumentace uvádí příklad
class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) fullname = Column(String) password = Column(String)a píše
Declarative replaces all the Column objects with special Python accessors known as descriptors; this is a process known as instrumentation. The “instrumented” mapped class will provide us with the means to refer to our table in a SQL context as well as to persist and load the values of columns from the database.
Ano. To ale bude i s type hintingem, ne?Typová inference dokáže odvodit typy pro dostatečně omezený typový systém (například jako OCaml).
Osobně v tom nevidím žádnou silnou výhodu a kdyby bylo na mě, tak bych tam tuhle featuru nepřidával, protože to kurví duck typing a původní ideu OOP, ve prospěch javovin.Docela by mě zajímala nějaká obhajoba duck-typingu. Podle mého je to prasečina největší. Hlavní důvod, proč Python nemusím.
Moc nechapu tyhle vyroky typu, python by byl super, kdyby... Od toho mas jine jazyky, netreba kurvit python.No, já zase nechápu tohle vkládání výroků, které dotyčný neřekl, a pak ho za to urážet.
Docela by mě zajímala nějaká obhajoba duck-typingu.To je těžké. Prostě na to nemám motivaci. Za sebe můžu říct, že jsem to pochopil ve chvíli, kdy jsem se naučil základy Smalltalku, i když předtím jsem to samozřejmě pár let používal v pythonu. Prostě tak bylo OOP myšleno, předtím, než ho znásilnili a naroubovali na silně typované imperativní jazyky, s ducktypingem počítalo a byl jednou z hlavních výhod. Když došlo k chybě, tak program nespadl, ale zastavil se na debuggeru, kterým bylo možné upravit chybný kód pro všechny běžící instance a pak dál pokračovat v běhu.
class BombTicker: def run(self): pass class Car: def run(self): pass def fire(a): a.run() xs.append(Car()) xs.append(BombTicker()) fire(rand(xs))
Jinak duck typing imho začne dávat smysl hlavně ve chvíli, kdy člověk programuje alespoň trochu funkcionálně, spolu s používáním closures a list comprehensions / generator expressions.No jako Haskellista si dovolím zásadně nesouhlasit. Mě duck-typing nedává smysl v ničem. Jaká by měla být jeho výhoda? Zkus to prosím nějak shrnout. (Mě nenapadá žádná, ale jsem samozřejmě zaujatý.) Teď z fleku mě napadá další nevýhoda: Chybu se dozvím nejenom až za běhu, ale až dost pozdě, až v okamžiku, kdy se runtime pokouší dobouchat na neexistující metodu, což je někde hluboko uvnitř střev, kde to vůbec neznám.
Chápu. Takže smysl těch interfaců přesouváš do názvů těch metod, to by teoreticky mohlo fungovat.Já rozhodně nejsem proti interfacům. Naopak model založený na traitsech/mixinech mi přijde lepší, než vícenásobná dědičnost.
Mě duck-typing nedává smysl v ničem. Jaká by měla být jeho výhoda? Zkus to prosím nějak shrnout. (Mě nenapadá žádná, ale jsem samozřejmě zaujatý.)V tom že kód pak může být univerzální a využívat výhod existence zapouzdření? Speciálně u metod aplikujících nějaké operace na data dodaná v sekvenci to může dávat smysl.
Chybu se dozvím nejenom až za běhu, ale až dost pozdě, až v okamžiku, kdy se runtime pokouší dobouchat na neexistující metodu, což je někde hluboko uvnitř střev, kde to vůbec neznám.Ano. Proto je dobrým zvykem psát testy, které bys stejně musel psát tak jako tak.
Proto je dobrým zvykem psát testy, které bys stejně musel psát tak jako tak.BTW dobrým zvykem je také dodržovat princip DRY, což testy porušují (stejně jako typy). Lepší by bylo psát jen jedno (buď testy, nebo program, nebo typy), ideálně to, co je v daném případě nejjednodušší.
Testy jen obtížně budou pokrývat vše.Proč ne? Já používám modul na coverage, který mi řekne, co mám pokryté a co ne. Obecně se nesetkávám s chybami tohohle typu, ale spíš s logickými chybami v návrhu. A od těch mi nepomůžou ani testy, ani typy.
int32
, tak otestovat cca 4 mld. hodnot (v podstatě provést model checking).
Ta sama vetev kodu ti muze spadnout treba v zavislosti na tom, jestli funkce dostane jako parametr integer nebo string. Na tyhle veci je code coverage z principu nedostatecne.Vyvolání výjimky v tomhle případě není chyba, ale žádaná vlastnost.
Podobny problem panuje i u vetsiny staticky typovanych jazyku - vetev funguje pro vetsinu integeru, ale ne pro nulu (protoze deli nulou).Ano. Stará moudrost praví, že všechny hodnoty by se měly testovat na krajní meze datových typů a nulu. Ne vždy je to ale časově možné.
Vyvolání výjimky v tomhle případě není chyba, ale žádaná vlastnost.Zadana vlastnost je, aby se takto nekorektni program nedostal do produkce, resp. ani do faze manualniho testovani. Unit testy u teto tridy problemu pomuzou nekdy, staticke typovani vzdy.
Ano. Stará moudrost praví, že všechny hodnoty by se měly testovat na krajní meze datových typů a nulu. Ne vždy je to ale časově možné.Tohle je trivialni priklad, ne vzdy jsou potencialne problematicke hodnoty na prvni pohled videt. Zrovna vcera jsem videl algoritmus, ktery selhaval na hodnotach delitelnych 100 :) V jazyce jako Agda tohle ani testovat nemusis, protoze jazyk samotny ti nedovoli delit promennou o ktere jsi nedokazal, ze nemuze byt nulou (opet trivialni priklad, funguje to ale obecne).
mame tu ve jmenovateli nulu, ale to nevadi, misto nuly muzeme dat jednicku, to je take male cislo...v prirodnich vedach by to nefungovalo, ale v ekonomii, astrologii a podobnych pavedach je to skutecne jedno :) BTW ad AI: doufam ze bude zakazana :)
BTW ad AI: doufam ze bude zakazana :)To imho z dlouhodobého hlediska nejde. Červená královna tě donutí jí mít a používat, neboť jinak budeš nahrazen těmi, kdo jí mají. Ať už z ekonomických, či silových důvodů. Je to stejné, jako kdyby někdo před 30 lety chtěl podnikat v oboru informací a nesnášel počítače. Tenkrát to ještě chvíli mohlo vypadat jako že to třeba snad možná půjde bez nich, ale dnes byli prostě vytlačeni a zapomenuti.
no ja si spis myslim, ze kdo bude pouzivat AI, bude nahrazen tou AI... takze ti rozumnejsi budou bojovat proti AI cizi, treba z cinyZ čistě dlouhodobého hlediska evolučních tlaků je to imho nevyhnutelné a stejně, jako lidi nahradili třeba neandrtálce se dá s jistotou počítat, že jednou něco nahradí náš druh. Otázkou je, jestli to bude nahrazení ve smyslu vyhlazení a zaujetí místa, nebo postupného fůzování, až nebude rozdíl mezi jedním a druhým, či postupnou evolucí, kdy se třeba lidstvo plynule přejde do něčeho jiného.
Tolik potíží s tou nulou, a přitom stačilo se dohodnout, že dělení nulou je kladné nekonečnoA proč ne záporné nekonečno? Myslím, že by obojí akorát udělalo hromadu bordelu a přibylo by v matematických větách pár zcela nečekaných výjimek.
Jsem zvědavý, kde bude programování za 20..40..60 let jestli už to nebude víc o AI a genetických algoritmech, které si s tím naším přehazováním dat z hromádky na hromádku poradí na úrovni strojového jazyka lépe než my.K tomu mi právě pomocí těch typů směřujeme. Zatímco Python jde opačnou cestou.
K tomu mi právě pomocí těch typů směřujeme. Zatímco Python jde opačnou cestou.Ono je celkově docela zajímavé, jak moc jsou jazyky, které to přehání s typy nepoužívané. Nedávno jsem se o tom bavil s kamarádem na IRC, že jsem vlastně nikdy neviděl nic napsaného v třeba v haskellu. Jinak já nemám nic proti typům, ani statickému typování. Imho to má svojí doménu a u některých typů software si to neumím představit bez nich. Co mi vadí jsou lidi, kteří se to snaží roubovat do pythonu.
xmonadNeznám a nepoužívám. Popravdě jediný program, který jsem kdy v haskellu použil byla obluda a to se skoro nedá počítat, protože jsem to stáhl jen ze zvědavosti. Fakt by mě zajímalo, proč se v tom prakticky neprogramuje, když je to tady už takové desítky let. Jakože vážně, nepomlouvám - proč se v tom skoro nic nepíše?
Jsem zvědavý, kde bude programování za 20..40..60 let jestli už to nebude víc o AI a genetických algoritmech, které si s tím naším přehazováním dat z hromádky na hromádku poradí na úrovni strojového jazyka lépe než my.Všichni používáme hory abstrakce nad strojovým kódem. Jenže do vzniku generických umělých inteligencí vždy bude ten který program limitovat množství informace, kterou ho musíš popsat. I kdyby to bylo v úplně přirozeném jazyce. Ostatně programátoři dnes dělají přesně tohle - píší (různě volnou) formální specifikaci toho, co zadavatel chce. Vrstvy software pod tím z toho pak dělají funkční kód. Jinak tuším že hned druhý MLMU talk byl o tom, jak algoritmy pěstují algoritmy, co hledají závislosti v big datech. Bohužel z toho není video, ale bylo to dost zajímavé.
Zadana vlastnost je, aby se takto nekorektni program nedostal do produkce, resp. ani do faze manualniho testovani. Unit testy u teto tridy problemu pomuzou nekdy, staticke typovani vzdy.Žádaná vlastnost je, aby funkce na nedefinované vstupy reagovala výjimkou (v pythonu).
V jazyce jako Agda tohle ani testovat nemusis, protoze jazyk samotny ti nedovoli delit promennou o ktere jsi nedokazal, ze nemuze byt nulou (opet trivialni priklad, funguje to ale obecne).Jak to funguje s uživatelskými vstupy? Jak dokážeš, že uživatel nikdy nezadá nulu, nebo že nula nikdy nebude v souboru, nepřijde po síti, ..?
Na produkci?Zadana vlastnost je, aby se takto nekorektni program nedostal do produkce, resp. ani do faze manualniho testovani. Unit testy u teto tridy problemu pomuzou nekdy, staticke typovani vzdy.Žádaná vlastnost je, aby funkce na nedefinované vstupy reagovala výjimkou (v pythonu).
Odmítne ji, pomocíV jazyce jako Agda tohle ani testovat nemusis, protoze jazyk samotny ti nedovoli delit promennou o ktere jsi nedokazal, ze nemuze byt nulou (opet trivialni priklad, funguje to ale obecne).Jak to funguje s uživatelskými vstupy? Jak dokážeš, že uživatel nikdy nezadá nulu, nebo že nula nikdy nebude v souboru, nepřijde po síti, ..?
if a = 0 then .. else ..
(tedy takto bych to dělal v Haskellu).
Na produkci?Takhle prostě dynamické jazyky fungují a součástí práce programátora je postarat se, aby byl kód otestovaný dost na to, aby měl jistotu, že tam nikde nechtěné typy nepolezou a že aplikace umí případnou chybu zpracovat.
Odmítne ji, pomocí if a = 0 then .. else .. (tedy takto bych to dělal v Haskellu).To ale není formální důkaz, ne?
Spolu se semantikou jazyka to postacuje jako dukaz, ze a nemuze mit nikdy ve vetvi else hodnotu 0.Odmítne ji, pomocí if a = 0 then .. else .. (tedy takto bych to dělal v Haskellu).To ale není formální důkaz, ne?
Soucasti prace programatora je tim padem dokazat nemozneJak to? Když programuji nějakou aplikaci, tak snad vím, co mi do ní leze, ne? Uživatel nemá možnost volit typy, jen jejich hodnoty. Tohle mi přijde jako taková ta javovská logika, kde se lidi chovají k dalším programátorům jako k nekompetentním uživatelům, přitom jsou to právě a jedině oni, kdo jediný může reagovat na chyby, ne kód knihoven, ten může jen říct, že se mu něco nelíbí. Silné typování neumožňuje nic víc, než kódu knihoven říct, že poměrně malý subset situací se mu asi možná (jen na základě předpokládaného typu!) nelíbí už během parsování. Funkce knihoven jsou pro mě z tohohle hlediska úplně stejné, jako kdybych pracoval se vzdáleným API - prostě musím počítat, že přijímají jen něco a můžou vyhazovat výjimky, které bych měl zpracovat. Vážně, tady se z toho dělá kdovíjaké drama, ale takhle to prostě funguje a funguje to dost spolehlivě na to, aby se to vyplatilo používat všude možně, včetně třeba velkých firem (hint: google, seznam). Dokonce se nebojím říct, že naprostá majorita webových aplikací je psaná přesně takhle a apokalypsa se nekoná. Jeden si skoro říká, jak vůbec je možné napsat řádek kódu bez silného typování, když by to mělo vést ke konci světa.
Což platí jen o write-only jazycích, což asi o Pythonu říct nechceš.Soucasti prace programatora je tim padem dokazat nemozneJak to? Když programuji nějakou aplikaci, tak snad vím, co mi do ní leze, ne?
Uživatel nemá možnost volit typy, jen jejich hodnoty. Tohle mi přijde jako taková ta javovská logika, kde se lidi chovají k dalším programátorům jako k nekompetentním uživatelům, přitom jsou to právě a jedině oni, kdo jediný může reagovat na chyby, ne kód knihoven, ten může jen říct, že se mu něco nelíbí.Ale uživatel, a programátor uživatel nějaké knihovny je opravdu v roli absolutního idiota. Protože čím více se musí s kódem seznamovat, tím je to dražší.
Silné typování neumožňuje nic víc, než kódu knihoven říct, že poměrně malý subset situací se mu asi možná (jen na základě předpokládaného typu!) nelíbí už během parsování.Jenže v tom je ta pointa. Do čím méně stavů může funkci uživatel dostat, tím lépe se s ní pracuje. Protože prostě člověk má omezenou kapacitu pojmout celej ten graf, který to volání funkcí vytváří. A tak vznikají boje mezi tím, aby funkce měla co nejméně stavů, a tím, aby byla co nejobecnější. Haskell má problém IMHO až v okamžiku mutability. Proto není tak oblíbený. Python mi přijde že pro samou obecnost neposkytuje žádné záruky. Což přináší důsledky které můžou být více či méně zásadní.
Což platí jen o write-only jazycích, což asi o Pythonu říct nechceš.Stejně jako bude v jiných jazycích programátor zodpovědný za to, že nemixuje typy špatným způsobem.
Ale uživatel, a programátor uživatel nějaké knihovny je opravdu v roli absolutního idiota. Protože čím více se musí s kódem seznamovat, tím je to dražší.Proč by se měl seznamovat s kódem? Stačí mu přečíst si docstring. Jinak tohle je asi to, kde se naše filosofie rozcházejí. Moje zkušenost mi ukázala, že v takových jazycích trávím čas věcmi, které pro samotný projekt vůbec nejsou podstatné. Má to další sympatickou vlastnost; všemožné design patterny jsou v pythonu prakticky neexistující, protože když člověk pochopí filosofii jazyka, tak je to triviální a často na jeden řádek, místo aby psal všemožné abstraktní továrny továren.
Proč by se měl seznamovat s kódem? Stačí mu přečíst si docstring.Tak tohle me uprimne rozesmalo. Docstringy (resp. obecne dokumentace rozhrani metod/trid) jsou velmi casto zastarale, vetsinou nekompletni (nespecifikuji ruzne corner casy) a nikdy tak exaktni jako formalni, automaticky verifikovatelny typovy kod. Lidsky jazyk neni staveny na preciznost a formalnost, coz usti v to, ze komentar je do velke miry viceznacny/nepresny. Zkratka receno, komentare casto lzou, staticke typy ne. V praxi se na komentare metod nespoleham, ale da se z nich vycist naopak to, co formalne zapsat nejde - kontext, motivace atp.
... protože když člověk pochopí filosofii jazyka, tak je to triviální a často na jeden řádek, místo aby psal všemožné abstraktní továrny továrenPripadne to muze byt i tim, ze clovek nechape vyznam a vhodne pouziti abstraktni tovarny.
Tak tohle me uprimne rozesmalo. Docstringy (resp. obecne dokumentace rozhrani metod/trid) jsou velmi casto zastarale, vetsinou nekompletni (nespecifikuji ruzne corner casy) a nikdy tak exaktni jako formalni, automaticky verifikovatelny typovy kod.Ano, nic takového jsem ale ani netvrdil. Zastaralé můžou být asi stejně, jako všechno ostatní, od typů po samotná těla funkce.
Zkratka receno, komentare casto lzou, staticke typy ne.Statické typy v tomhle lžou úplně stejně, jako dynamické - nezaručují, že nedojde k vyvolání výjimky v runtime při nějakém „corner case“. Tohle asi může zajistit formální verifikace, ale kolik takového kódu v praxi vzniká?
Pripadne to muze byt i tim, ze clovek nechape vyznam a vhodne pouziti abstraktni tovarny.Když se nad tím tak zamyslím, tak je to v podstatě metodika vytvořená k boji s typovým systémem, aby se v tom daly dělat věci, které jdou dělat v dynamických jazycích úplně přirozeně.
Zastaralé můžou být asi stejně, jako všechno ostatní, od typů po samotná těla funkce.To mas nejake popletene - kod je vzdy "source of truth". Z principu nemuze byt zastaraly, na rozdil od komentare.
To neni pravda - to, co typovy system treba Javy dokaze vyjadrit, tak v tom proste nelze. Pokud ma metoda v Jave jako navratovy typ String, tak proste nic jineho vratit nemuze. Pokud ma Python funkce v docstringu napsane, ze vraci string, tak ve skutecnosti muze vratit cokoliv. Neco jineho je, ze expresivita typovych systemu jazyku jako C# a Java je omezena - spousta veci v nich nejde vyjadrit. To se ale zlepsuje s Haskellem, Scalou, Ceylonem az treba k Idrisu, kde je to dovedene do (obtizne pouzitelneho) extremu. Stale je to ale radove lepsi nez treba u Pythonu.Zkratka receno, komentare casto lzou, staticke typy ne.Statické typy v tomhle lžou úplně stejně, jako dynamické - nezaručují, že nedojde k vyvolání výjimky v runtime při nějakém „corner case“. Tohle asi může zajistit formální verifikace, ale kolik takového kódu v praxi vzniká?
Když se nad tím tak zamyslím, tak je to v podstatě metodika vytvořená k boji s typovým systémem, aby se v tom daly dělat věci, které jdou dělat v dynamických jazycích úplně přirozeně.
To mas nejake popletene - kod je vzdy "source of truth". Z principu nemuze byt zastaraly, na rozdil od komentare.To teda může. Podstatné není co je v kódu, ale jak se má program chovat podle specifikace. Když se chová jinak než je žádáno, není v kódu zdroj pravdy, ale bug. Nehledě na to, že různé části projektu můžou mít různá očekávání a pak musíš rozhodnout, které z nich je správné.
Pokud ma metoda v Jave jako navratovy typ String, tak proste nic jineho vratit nemuze.Ehm, výjimku? Není tam taky náhodou
null
, který se dá vracet místo libovolných referencí? A co NaN?
Pokud ma Python funkce v docstringu napsane, ze vraci string, tak ve skutecnosti muze vratit cokoliv.Ano, to je pravda. Je věcí cti autora, aby takové věci nedělal.
To teda může. Podstatné není co je v kódu, ale jak se má program chovat podle specifikace. Když se chová jinak než je žádáno, není v kódu zdroj pravdy, ale bug.Tahle otazka uz presahuje do filozofie (nominalismus/realismus)
Ehm, výjimku? Není tam taky náhodou null, který se dá vracet místo libovolných referencí? A co NaN?Java ma checked exceptions, interface je musi deklarovat. Unchecked exceptions se deklarovat nemusi, ale taky se *nemaji* osetrovat, takze jejich ne-deklarace moc nevadi. Jinak vyjimka se nevraci, ale haze ... Null je zvlastni pripad, castecne je povazovany za hodnotu vsech typu (jde assignovat do vsech typu), castecne ne (null instanceof Cokoli vraci false). Nicmene tohle je blbost Javy, novejsi jazyky to maji poresene daleko lip (napr. Ceylon). NaN je instance Double/Float, resp. hodnota primitivnich typu double/float.
Ano, to je pravda. Je věcí cti autora, aby takové věci nedělal.To je ten obecny problem s Pythonem a podobnymi jazyky. Vsechno je na autorovi.
Mne je vcelku jedno, co dana metoda slibuje - primarne me zajima, co skutecne dela.A jak ti v tomhle pomůžou typy? Pořád nemáš vůbec tušení, co metoda skutečně dělá, jen co přijímá za typ (ne data, to bys musel přidat kontrakty) a co za typ vrací.
To je ten obecny problem s Pythonem a podobnymi jazyky. Vsechno je na autorovi.Jak jsem psal; testy ti to pomohou ověřit (pro určitý subset dat). V podstatě se na ně lze dívat jako na (neformální) verifikaci, že program v daných rozmezích dělá to co má. Teoreticky to sice nemá stejnou sílu, ale v praxi to často stačí.
A jak ti v tomhle pomůžou typy? Pořád nemáš vůbec tušení, co metoda skutečně dělá, jen co přijímá za typ (ne data, to bys musel přidat kontrakty) a co za typ vrací.Jak rikam, treba v Jave to neni zadna hitparada - signatura metody ti toho zas az tak moc nerekne (ale stale daleko vic nez v Pythonu). Staticke typy ti ale podobnym zpusobem pomuzou analyzovat i telo metody.
Jak jsem psal; testy ti to pomohou ověřit (pro určitý subset dat). V podstatě se na ně lze dívat jako na (neformální) verifikaci, že program v daných rozmezích dělá to co má. Teoreticky to sice nemá stejnou sílu, ale v praxi to často stačí.To ano. Mne na tom vadi primarne to, ze je to opet na prgaci, aby ty testy napsal a maintainoval - neco, co mas v jazyce se statickymi typy zadarmo. Prgac se pak muze soustredit na psani skutecnych testu, ne jen "chytacu typovych chyb". Nemam problem pouzit Python na nejake mensi projekty (coz obcas delam), ale nedokazu si jej moc predstavit v projektech napr. trvajicich 10 let s desitkami vyvojaru.
Pořád nemáš vůbec tušení, co metoda skutečně dělá, jen co přijímá za typ (ne data, to bys musel přidat kontrakty) a co za typ vrací.Typ může říci i něco o datech. Například, pokud existuje pouze jedna hodnota s daným typem. Nebo z parametricity například plyne (v jazyce bez vedlejších efektů, kde jsou funkce totální), co dělá funkce
S
typu: (A -> B -> C) -> (A -> B) -> A -> C
.
Jak už bylo zmíněno, existují systémy se závislými typy. Například v Idrisu jsem kdysi napsal testy takto:
test_parseLit_pos : so $ parseLit "c" == Right (MkLit Pos "c") test_parseLit_pos = ohTyp hodnoty
oh
je so True
. Typová kontrola tedy musí ověřit, že
typ so $ parseLit "c" == Right (MkLit Pos "c")
je shodný se so True
, tj. při typové kontrole se zavolá pasrseLit "c"
a ověří se rovnost s Right (MkLit Pos "c")
. Typ tedy říká i něco o datech funkce parseLit
.
val x = ("Scala", 1)tak
x(0)
resp. x(1)
se přeloží jako výrazy s typy String
resp. Int
a x(2)
se nepřeloží. Dále jsou na tom třeba postaveny kolekce s velikostí známou v době kompilace nebo rozšiřitelné záznamy (klíče jsou singleton typy – třeba řetězec title
má typ String("title")
).
To teda nemůže. Co je v kódu typem zajištěno, na to se dá spolehnout. A pak se můžeme hádat o tom, že manžer chtěl něco jiného, než co je naprogramováno. U pythonu je to o úroveň dál. Dohaduješ se s managerem o tom, co chtěl, a co si myslíš, že je naprogramováno. Python je o volnosti a o tom, že se spoléhá na programátory, dokumentaci, paměť. Protože na kód se v jeho případě spolehnout nedá. Věřím, že ta snadnost něco napsat je benefitem. Ale co údržba existujícího kódu? A čitelnost?To mas nejake popletene - kod je vzdy "source of truth". Z principu nemuze byt zastaraly, na rozdil od komentare.To teda může. Podstatné není co je v kódu, ale jak se má program chovat podle specifikace. Když se chová jinak než je žádáno, není v kódu zdroj pravdy, ale bug. Nehledě na to, že různé části projektu můžou mít různá očekávání a pak musíš rozhodnout, které z nich je správné.
To teda nemůže. Co je v kódu typem zajištěno, na to se dá spolehnout. A pak se můžeme hádat o tom, že manžer chtěl něco jiného, než co je naprogramováno. U pythonu je to o úroveň dál. Dohaduješ se s managerem o tom, co chtěl, a co si myslíš, že je naprogramováno.Manažera vůbec nebude zajímat, co je někde v kódu, ale (v lepším případě) co je ve smlouvě a hlavně jak se program skutečně chová. To jestli tam máš nebo nemáš typy bude to úplně poslední, co bude v tom sporu hrát roli.
Python je o volnosti a o tom, že se spoléhá na programátory, dokumentaci, paměť. Protože na kód se v jeho případě spolehnout nedá. Věřím, že ta snadnost něco napsat je benefitem. Ale co údržba existujícího kódu? A čitelnost?Z mé zkušenosti plyne, že dobrá, ba řekl bych i lepší než ve většině ostatních jazyků, se kterými jsem přišel do styku, ale to může být dáno nepoměrem jak moc jsem v nich dělal a jak moc dělám v pythonu.
from decimal import Decimal a = Decimal("1.15"); b = 0.555 a + b >>> TypeError: unsupported operand type(s) for +: 'Decimal' and 'float' float(a) + b >>> 1.705Tím, že si Python zvolil takovou míru kontroly, není ani lepší, ani horší, je takový. My lidé jsme různí (což je dobře). Vyhovuje nám různý způsob přemýšlení a komunikace s počítačem a můžeme být rádi, že tu máme různé jazyky s různými vlastnostmi. Pár možností, jak si v Pythonu zajistit vyšší míru "typové kontrolu": * Tam kde se mi v kódu motá moc podobných názvů proměnných různých typu si některé názvy prefixuji. Například slovníky d_nazev_promenne, dvourozměrný seznam l2l_nazev_promenne, slovník seznamů d2l_nazev_promenne a pod... * Když je to v nějakém místě důležité, je možné si vyhodit debug výjimku, předat jí locals() # seznam lokálních proměnných + případně parametr, kterým určím typ kontroly a proklepnout si ty proměnné, jestli je v nich to, co tam chci mít a ve správném rozsahu. Je to hezky DRY, nezaclání to v kódu, dá se to z jednoho místa zapnout/vypnout, dá se to pustit jen pro určité, aktuálně laděné úseky. * Udělat si svůj vlastní typ s typovou (případně i obsahovou) kontrolu při každé změně hodnoty. Pravdou je, že to na 90% věcí v podstatě není třeba. Osvětě a práci zdar.
Dokážu si představit mnohem propracovanější mechanismus typové a obsahové kontroly, kdy při deklaraci proměnné, nadefinuji rovnou i min / max / default / excluded hodnoty a kód hlídající, zda při každém zápisu do proměnné splňuje hodnota definované parametry.
Takovouhle nádstavbovou funkcionalitu si můžu vytvořit vlastním kódem, ale vždy to bude stát něco výkonu, při tom neustálém ověřování.
To je ale hodně zavádějící příklad, který se snaží vyvolat dojem, že typová kontrola je něco, co stojí prostředky. Pokud mám jazyk, kde má proměnná jasně deklarovaný typ, neznamená to, že by tato "typová kontrola" byla méně efektivní, ale přesně naopak. Kontrolu provede už překladač a za běhu je implementace výrazu a + b
naopak mnohem efektivnější než kdybych měl teprve v tom okamžiku řešit, co jsou a
a b
zač a co tedy vlastně znamená to "+
". (V případě virtuálních metod např. v C++ to bude trochu složitější, ale ani tak mne jasně deklarovaný typ nestojí nic navíc a obecně to naopak prostředky ušetří.)
Z mého pohledu, pokud nějaký jazyk podporuje víc než jeden datový typ, tak je tam vždy nějaká režie, která se týká typů.Pokud nějaký jazyk víc než jeden datový typ nepodporuje, tak je to kalkulačka nebo nějaký jednoduchý shell, podle toho, jestli je to typ číselný nebo textový. Navíc je otázka, koho ta drobná režie zajímá, když se týká například jen toho kompilátoru, to by se ta režie musela nějak vyčíslit.
Nesouhlasím s tím, že "...jasně deklarovaný typ nestojí nic navíc".
Ale ono to opravdu nestojí, naopak, je to efektivnější. Když v C mám
int a, b c; ... c = a + b
překladač hned ví, co to "+" znamená a generuje optimální kód, což většinou bude jedna instrukce, přinejhorším dvě až tři, když ty proměnné nebudou v registrech. V jakémkoli jazyce, kde bude muset program za běhu nejdřív zjistit, co jsou vlastně a
, b
a c
zač a podle toho použít příslušnou implementaci (nebo zpracovat chybu), to vždy bude méně efektivní.
#bytecode for: c = a + b LOAD_FAST (a) # Pushes a reference to the local co_varnames[var_num] onto the stack LOAD_FAST (b) # Pushes a reference to the local co_varnames[var_num] onto the stack BINARY_ADD # TOS = TOS1 + TOS STORE_FAST (c) # Stores TOS into the local co_varnames[var_num] A operace BINARY_ADD je v cpythonu takto: #from file: cpython/Python/ceval.c TARGET(BINARY_ADD) { PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { sum = unicode_concatenate(left, right, f, next_instr); /* unicode_concatenate consumed the ref to v */ } else { sum = PyNumber_Add(left, right); Py_DECREF(left); } Py_DECREF(right); SET_TOP(sum); if (sum == NULL) goto error; DISPATCH(); }Takže ano, je tam režie na to, že se nezná typ proměnných "a" a "b", ale ten luxus, že tím mohu sečíst cokoliv co má nadefinováno, že lze sečíst a nemusím řešit, zda zrovna pracuji s řetězci, unicode, slovníky, vlastními typy..., to mi stojí za to. Nejde o to, že bych jednou funkcí chtěl obsluhoval práci s různými typy najednou, to je spíš výjimečné, ale že se díky této vlastnosti Pythonu pohybuji v jiné vrstvě abstrakce, tak jak mi to vyhovuje. No a pokud zrovna tuhle část potřebuji zrychlit, mám k tomu dost prostředků jak toho docílit.
Děje se toho krapet víc. Například vám tam vzniká nová proměnná. Je třeba pro ni alokovat místo v paměti, což, pokud program nemá už dopředu zajištěno, vyžaduje komunikaci se systémem.
Nic takového se neděje. Zkuste si přeložit
int f(int a, int b) { int c = a + b; return c; }
Výsledek bude vypadat takto:
0000000000000000 <f>: 0: 8d 04 37 lea (%rdi,%rsi,1),%eax 3: c3 retq
Kde vidíte komunikaci se systémem? Pokud by lokálních proměnných bylo tolik, že by se do registrů nevešly, bude veškerá "alokace paměti" spočívat v jednom "sub %rsp, ...
" (jednom na funkci, ne jednom na proměnnou) a přístup k nim bude jen o malinko komplikovanější. Podobně pokud by šlo o globální proměnné, bude se provádět jedna alokace při spuštění programu.
A teď si zkuste představit, jak oproti tomu bude vypadat kód odpovídající těm fragmentům, které jste napsal pro python.
Ano. Techniky z dynamicky typovaných jazyků jde totiž použít i ve staticky typovaných jazycích s bohatšími typovými systémy (např. Scala a její trait Dynamic) – naopak to však neplatí.Proč to naopak neplatí?
3
může mít typ Int
nebo Int @@ Zakaznik
(pro id zákazníka) nebo Int(3)
a chování funkcí se může měnit v závislosti na typu.
Jiným příkladem je odvozování funkcionality v době kompilace na základě typů: Součástí knihoven a vašeho programu jsou pravidla, jak z určitých funkcionalit poskládat jiné funkcionality. Když pro určitý typ kompilátor potřebuje určitou funkcionalitu, tak zkusí použít pravidla a funkcionalitu odvodit. To by šlo dělat i za běhu pomocí tagů, ale bylo by to nepraktické, neboť odvození může trvat dlouho.
Shodneme se na tom, že použití datového typu slovník s unicode řetězci, bude vyžadovat režii na ošetření vstupních hodnot a na práci s ním?
To ano. Problém ale vidím v tom, že pokud v případě pythonu tyhle věci budete chtít implementovat nativně v pythonu a nezadrátujete je přímo do jazyka (což je cesta, kterou se na začátku vydalo PHP), bude ta režie pořád podstatně větší - právě proto, že ty elementární operace budou oproti programu napsanému v C podstatně méně efektivní. Totéž platí i pro ty ostatní příklady, jako je kontrola mezí.
Proto bych pro takové účely daleko raději použil C++, u kterého můžu příslušnou knihovnu napsat přímo v něm a získat jak pohodlnost vyjadřovacích prostředků, tak efektivitu velmi blízkou implementaci v C. (Tedy kdybych to opravdu potřeboval psát sám a nešlo využít už hotových součástí standardní C++ knihovny.)
Takže ano, je tam režie na to, že se nezná typ proměnných "a" a "b", ale ten luxus, že tím mohu sečíst cokoliv co má nadefinováno, že lze sečíst a nemusím řešit, zda zrovna pracuji s řetězci, unicode, slovníky, vlastními typy..., to mi stojí za to.Nechcete doufám trvrdit, že toto v staticky typovaných jazycích nelze, že ne? Proč mám dojem, že tu Pythonisti vymýšlení problémy, které nejsou. Proč prostě nemůžete jednoduše a jasně vysvětlit proč Python nepoužívá statickou typovou kontrolu? V čem duck-typing přináší výhodu? Beru jako odpověď i: "prostě proto", případně "nebaví nás psát typové deklarace raději to zapíšem do testů". A abych byl (na rozdíl od místních) poctivý, tak zatím se mi z Bystroushaáka podařilo vymlátit dvě výhody: 1. kratší zápis 2. je zde jistá šance, že se autor trefí do názvu metody, a nebudu muset dělat přemapování. Co dál?
Nemusim premyslet, zda funkci davam seznam, tuple atd.Pokud je například v té funkci
x + [2]
a vy jako x
předáte tuple, tak se to bude chovat jinak, než když předáte seznam. Takže to řešit musíte.
nikdy jsem nepochopil, jak to vubec nekdo muze takto pouzivat a resit, zda mu to nahodou nepretece, to bych nedelal nic jinehoNěkdy je modulární aritmetika užitečná. Nicméně bych ji rovněž nedával jako defaultní.
Pokud je například v té funkci x + [2] a vy jako x předáte tuple, tak se to bude chovat jinak, než když předáte seznam. Takže to řešit musíte.kdyby byly v prdeli ryby... vetsinou nic takoveho ve funkcich nemam a pokud budu z nejakeho duvodu mit, tak to holt resit budu muset. ale v 99%+ pripadu to resit nemusim. stejne tak funkce ze standardni knihovny a vetsiny dalsich knihoven, co bezne pouzivam
Někdy je modulární aritmetika užitečná. Nicméně bych ji rovněž nedával jako defaultní.v podstate me nenapada pripad, kdy bych si byl jisty, ze mi int32 nebo 64 staci - predpokladam, ze je na to v c a spol nejaka knihovna, ale ve vysledku by to znamenalo, ze bych bezne ceckove scitani intu nikdy nepouzil
vetsinou nic takoveho ve funkcich nemamNo vidiš to. V mém případě je něco takového dobře dvě chyby z pěti.
Je to proste mnohem rychlejsi a jednodussi. Pisu jen to, co je nutne psat. Proto napisu totez desetkrat rychleji.A to je tedy všechno, jo? Já jen pro pořádek.
Nemusim premyslet, zda funkci davam seznam, tuple atd.Ano, to jsem psal. To já v haskellu, v javě, v c# taky ne. A co?
Kdyz sectu dva kladne inty, nemuze se mi stat, ze dostanu zaporne cislo, jako treba v cecku (nikdy jsem nepochopil, jak to vubec nekdo muze takto pouzivat a resit, zda mu to nahodou nepretece, to bych nedelal nic jineho).Tak porovnávat to zrovna s typy v céčku je docela sprostý, ti povim. To si moc nezafrajeřil. Když sečtu dva inty v Haskellu tak se mi taky nestane, že bych dostal záporné číslo.
Asi chvíli převezmu štafetový kolík :) Když se dobrá snaha, osvětlit některé mýty zvrtne, vypadají Pythonisti jako fanatici. Re. Python nemá typy.: To je jako co za zkratku? Dokonce i typ má svůj typ "type(type)"A k čemu ten Python ty typy vlastně má?
Python nemá typy. To má nějaké důsledky. V praxi to možná nevadí (to mě nezajímalo), ale s těma typama sis naběhl sám.Python právě má typy. Je to silně typovaný jazyky a úplně všechno v něm má typ, který se po vytvoření nikdy nedá změnit (narozdíl od třeba javascriptu). Proměnné jsou ovšem jen reference na tyhle objekty a jako takové můžou ukazovat na objekty libovolných typů a reference později měnit.
Python nemá typy.Hmm, tak to asi píšu v něčem jiném, dík za poučení.
To understand it, it helps to know that the notion of "type" was invented in the 1930s, in the context of lambda calculus (in fact, even earlier, in the context of set theory). Since then, a whole branch of computational logic has emerged that is known as "type theory". Programming language theory is based on these foundations. And in all these mathematical contexts, "type" has a particular, well-established meaning. The terminology "dynamic typing" was invented much later -- and it is a contradiction in terms in the face of the common mathematical use of the word "type". For example, here is the definition of "type system" that Benjamin Pierce uses in his standard text book Types and Programming Languages: A type system is a tractable syntactic method for proving the absence of certain program behaviors by classifying phrases according to the kinds of values they compute. He also remarks: The word “static” is sometimes added explicitly--we speak of a “statically typed programming language,” for example--to distinguish the sorts of compile-time analyses we are considering here from the dynamic or latent typing found in languages such as Scheme (Sussman and Steele, 1975; Kelsey, Clinger, and Rees, 1998; Dybvig, 1996), where run-time type tags are used to distinguish different kinds of structures in the heap. Terms like “dynamically typed” are arguably misnomers and should probably be replaced by “dynamically checked,” but the usage is standard. Most people working in the field seem to be sharing this point of view.
V pythonu jsou imho úplně stejné typy, jako všude jinde, ale nejsou vázané na proměnnou, ale k objektům.Což je právě úplně jiné. Ve staticky typovaných jazycích je typ v podstatě jen výrok o nějakém výrazu (například po vyhodnocení vyjde celé číslo; nebo výraz jde vyhodnotit ve dvou krocích – což je třeba užitečné, když pomocí typového systému chcete kontrolovat časovou složitost). Zatímco v Pythonu je to jakýsi tag, který je součástí hodnot (nikoliv výrazů). Java má třeba oboje. Typ může být například
List<String>
a odpovídající tag jen List
(protože tagy v Javě neumí reprezentovat generika). Ale obecně mezi typem a tagem nemusí být žádný vztah.
Typy ve staticky typovaných jazycích přiřazují nějaká pravidla odvozovacího systému a tato pravidla často dovolují přiřadit i nekonečně mnoho typů naráz. Například hodnota pes
může mít typy Pes
i Zvíře
i Object
zatímco tag bude vždy Pes
.
Ve staticky typovaných jazycích je typ v podstatě jen výrok o nějakém výrazu (například po vyhodnocení vyjde celé číslo; nebo výraz jde vyhodnotit ve dvou krocích – což je třeba užitečné, když pomocí typového systému chcete kontrolovat časovou složitost).Prisne vzato oba dva mluvite trochu o necem jinem, proto si IMHO nemuzete rozumet. Ty evidentne chapes "typ" vcetne "typoveho systemu". Bystroushak IMHO chape typ jako pouhe "pojmenovani" pro "mnozinu hodnot", z ktere dana hodnota pochazi... a staci mu to.
a = 1; type(a) >>> <type 'int'> dir(a) ['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real'] b = "1"; type(b) >>> <type 'str'> dir(b) ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']?
Ale v takovém případě ten typ je jen taková nálepka, a k ničemu praktickému to není. Prostě stačí, když udělám obecný objekt, a pak mu přidám všechny ty metody, co má int a vznikne mi int, správně? To je ostatně princip duck-typingu.Špatně. Nevznikne ti int, vznikne ti něco, co se chová jako int a všechny funkce s tím mohou pracovat jako s intem, ale int to není. Jsou jazyky, které typy vůbec nemají (třeba self, kde je všechno prototype-based), kde by se takový kód dal považovat za int, python to ale není. Imho je to dané tím, že používá class-based OOP, které si bez typů neumím představit.
pod tvym "nemit typy" si predstavuju, ze si vsechna cisla budou rovnyNe, oni si nebudou rovny, protože int je struktura implementující __int__, zatímco float je struktura implementující __float__ (zjednodušuji, přirozeně).
vyuzivam to neustaleJak to tvoje využívám to neustále v praxi funguje? Pomocí funkcí type() a isinstance() ?
>>> a = Decimal(1)/10 >>> b = 1/10 >>> a == b False >>> type(a) <class 'decimal.Decimal'> >>> type(b) <class 'float'> >>>jestli te nechapu, zkus to vice polopaticky, jsem jen biolog, a navic jsem blond :)
Všimni si prosím na co se ptám. Pokud má Python duck-typing, k čemu má typy? K čemu jsou dobré?Jsi trol, nebo jen nečteš co píšu?
Imho je to dané tím, že používá class-based OOP, které si bez typů neumím představit.
Vysvětli mi posím v čem vidíš souvislost mezi class-based OOP a tím, že třída plně se chovající jako int ve skutečnosti intem není?Protože není ve stromu tříd pod intem? Nemá dědičnost? Když změním za běhu definici intu, tak se nezmění, protože na něj není nijak navázaná?
Ale že je to udělané jen kůli MonkeyPatchingu...No, a takhle vznikají pověry.
Tak to nebude pověra, že jo, když to nedokážeš vysvětlit.Tak já jsem snad tvůrce jazyka, nebo proč bych měl mít vysvětlení na otázky typu „a proč?“? Problém s předchozím tvrzením mám, že jsi z toho udělal jediný důvod. Je to prostě jen jeden z mnoha.
3. Jinak jsou typy použity jako značky (atribut {}.__class__), značky vytvářejí strom, dá se na ně dotazovat, ale žádný další význam nemaj.A co dědičnost? Polymorfizmus? Statické proměnné a vůbec celé class-based OOP?
4. A trochu hejt: díky pythonu mají někteří lidé velice zkreslené představy, co to je typování, a statická typová kontrola zvláště.Já bych řekl, že mám docela dobrou představu o tom co jsou a jak fungují běžné statické typové systémy, asi tak na úroveň, že bych dokázal vytvořit kompilátor pro takový jazyk. Tuhle diskuzi jsem ale vedl se třemi lidmi najednou a bylo krapet těžké udržet focus vlákna pro každého zvlášť a ještě při tom vysvětlovat/obhajovat python a jeho typový systém. Diskuze pro mě ale byla i tak přínosná, i když stále vůbec nejsem přesvědčen, že statické typování nějak zvyšuje produktivitu. Stále se domnívám na základě vlastních zkušeností, že je to přesně naopak, rozhodně co se týče produktivity ve smyslu rychlosti vytvoření programu (=psaní kódu a vymýšlení architektury). S čím souhlasím je, že typy redukují určitý druh chyb, nikoliv však chyby všechny. U kritického software (nemocnice, řídící systémy letadel a tak dále) si to taky nedokáži představit v čistém pythonu a určitě bych tam buď chtěl statické typování, nebo úplně jinou architekturu (posílání zpráv, formální verifikace, nebo něco úplně jiného).
Žádný další důvod se mi z vás nedaří vymlátit. Takže to vypadá, že není.Tak to nebude pověra, že jo, když to nedokážeš vysvětlit.Tak já jsem snad tvůrce jazyka, nebo proč bych měl mít vysvětlení na otázky typu „a proč?“? Problém s předchozím tvrzením mám, že jsi z toho udělal jediný důvod. Je to prostě jen jeden z mnoha.
No, co s tím? K tomu typy nepotřebuješ. Ale aby zase někdo nenabyl dojmu, že jsem vůči Pythonu nějak zaujatý: Python má dva obrovské benefity: 1. Je extrémně dynamický (to, že i třída je first-class object je naprosto fantastické). 2. Syntax suggar a s tím související dobře navržené názvosloví, způsoby použití etc. Jsou jazyky, které jsou mnohem čistěji navržené při zachování stejné dynamičnosti (Lua), nebo mají lepší práci s typy, třídami, a rozhraními (třeba PHP), nebo jsou bezpečnější a znovupožitelnější (Java). V ničem z toho Python nijak neexceluje. V čem je naopak naprosto perfektní je dynamičnost a čitelnost zkloubená dohromady.3. Jinak jsou typy použity jako značky (atribut {}.__class__), značky vytvářejí strom, dá se na ně dotazovat, ale žádný další význam nemaj.A co dědičnost? Polymorfizmus? Statické proměnné a vůbec celé class-based OOP?
Žádný další důvod se mi z vás nedaří vymlátit. Takže to vypadá, že není.To je jako přijít na poštu a chtít po nich jízdenku na vlak, a když ti jí neprodají, tak usoudit, že vlaky neexistují.
No, co s tím? K tomu typy nepotřebuješ.Nepotřebuješ v tom smyslu, že když je nebudeš mít přímo v jazyce, tak je musíš emulovat knihovnou (protože skáčeš k závěrům, tak radši zdůrazňuji: tohle nic neříká o tom, že se nemůžeš vzdát class-based OOP a fungovat úplně bez typů).
Prostě nesouhlasím s tvejma tvrzeníma - je to hřích?Hřích? Co jsme, náboženský kroužek?
Akceptoval jsem, že ty si pod typy něco představuješ, a pokusil se naladit na tvojí vlnu. Nechceš to taky zkusit? :-PNa internetu bývá zvykem při nesouhlasu argumentovat. To jsem udělal, nedošlo k tomu ale z tvé strany. Když něco říkáš, říkáš to jako obecně platné tvrzení, nikoliv podmíněné tvrzení (to musíš napsat "imho", "afaik", "já si myslím" a ideálně i proč), či argumenty podložený názor (to musíš uvést ty argumenty). Nevadí mi to v principu, ale vadí mi to, když diskutuješ se mnou. Například teď pořád tvrdíš, že k class-based OOP nepotřebuješ typy, nijak to nedokládáš argumenty a požaduješ po mě, abych .. co vlastně?
To přirovnání neberu.Na tom není co brát. Python tu nikdo z nás nevymyslel, ani nenavrhl, všechny informace o jeho typovém systému jsou z naší strany jen domněnky, či zprostředkované dojmy. Pokud chceš skutečně vědět proč (což je tvá původní otázka), napiš autorovi, je stále naživu, těší se dobrému zdraví a odpovídá na emaily. Nikdo z téhle diskuze nebude nikdy relevantním zdrojem informací na otázky typu „proč to tak je“, protože nikdo z nás u toho nebyl. Těžko můžeš z naší neochoty spekulovat o otázkách „proč to tak je“ vyvozovat důvody, proč to tak skutečně je, protože to spolu vůbec nesouvisí - tímhle způsobem můžeš odvodit libovolnou (nesmyslnou) teorii.
Napadlo tě někdy, že si myslím přesně to samé já o tobě? Já předkládám argumenty všude, tvé nějak moc nevidím, a když náhodou ano, a když jsou poněkud zavádějící a já tě na to upozorním, tak se začneš rozčilovat... Samozřejmě je všechno IMHO, a AFAIK, a "Já si myslím". Jsme v nějakým babinci, že slušní na sebe být nemusíme, ale tahat za slovíčka je dobrým zvykem? Ty tvrdíš, že "Problém s předchozím tvrzením mám, že jsi z toho udělal jediný důvod. Je to prostě jen jeden z mnoha." a když se tě tedy zeptáš na ty další důvody, tak ticho... a vysmíváš se mi přirovnáním s poštou. A nakonec tady šermuješ prohlášením, že na internetu je zvykem argumentovat. Myslím, že na takovouhle argumentaci fakt nejsem zvědavej.Akceptoval jsem, že ty si pod typy něco představuješ, a pokusil se naladit na tvojí vlnu. Nechceš to taky zkusit? :-PNa internetu bývá zvykem při nesouhlasu argumentovat. To jsem udělal, nedošlo k tomu ale z tvé strany. Když něco říkáš, říkáš to jako obecně platné tvrzení, nikoliv podmíněné tvrzení (to musíš napsat "imho", "afaik", "já si myslím" a ideálně i proč), či argumenty podložený názor (to musíš uvést ty argumenty). Nevadí mi to v principu, ale vadí mi to, když diskutuješ se mnou. Například teď pořád tvrdíš, že k class-based OOP nepotřebuješ typy, nijak to nedokládáš argumenty a požaduješ po mě, abych .. co vlastně?
A trochu hejt: díky pythonu mají někteří lidé velice zkreslené představy, co to je typování, a statická typová kontrola zvláště.Jak může Python zkreslit představy o statické typové kontrole, to je mi záhadou.
Možná se blýská na lepší časy. Když už máme i ten interpret Pythonu v JavaScriptu. http://www.brython.infoTen máme už dlouho, psal jsem tu o něm blog už v roce 2013. Jinak mimochodem ho teď používám v jedné zakázce.
Python je krasne citelny na urovni par desitek radku v par metodach. Ne ve velkych projektech.Related: Size Doesn’t Matter.
Takže, čte se to dobře, ale raději to napíšu znovu??Musíš číst všechno. I to, že jsem na třísté řádce... Ano, pak zkousnu svou hrdost, a napíšu to znova pomocí knihoven které už znám. Což je přesně ten blbej efekt, který mi tak vadí. K tomu zbytku, co píšeš: Ano, za tuto vlastnost Javy, PHP, Haskellu, C# jsem také vděčen. No a?
Já tomu prostě nevěřímOK.
Doslova veškeré mé zkušenosti mluví proti tomuPopisuji jen mé zkušenosti, nic víc, nic méně. Beru si tedy z toho, že ty máš opačné. OK.
Popisuji jen mé zkušenosti, nic víc, nic méně. Beru si tedy z toho, že ty máš opačné. OK.No a proto bych právě rád viděl ty ukázky.
Předpokládám, že do takového neblahého stavu se ten program nedostal kvůli vlastnostem jazyka.Ačkoliv to vůbec nesouvisí s mojím příspěvkem, toto je docela zajímavá poznámka. Když porovnám Haskell a Python, pokud v Pythonu začnu prasit, tak budu mět okamžitě problém s kolegy. V Haskellu, když začnu prasit, tak pokud se mi kód podaří přeložit, tak mi kolegové začnou nadávat až v okamžiku, kdy můj kód budou muset refaktorovat. Dokavad ho mají jen používat, tak jsem v klidu. Samozřejmě tato tolerance se týká jen střev. API funkcí a knihoven neokecám ani v jednom.
Neco podobneho obcas slycham: "Ja pas v aute nepouzivam ... ridim opatrne a nejaky blbec v aute me muze zabit s pasem i bez pasu".Ono je docela paradoxní, že zrovna smalltalk se používal a stále ještě používá pro spoustu industry grade software. Mimo jiné třeba v bankovnictví, ale viděl jsem použití i ve francouzské armádě. Jak si to vysvětluješ?
Related: Size Doesn’t Matter.Related: https://www.reddit.com/r/programming/comments/3xm490/why_java_tales_from_a_python_convert/ (ta diskuze, ne článek)
Opět zaměňuješ příčinu a následek. Dávej si na to prosím pozor.Na produkci?Takhle prostě dynamické jazyky fungují a součástí práce programátora je postarat se, aby byl kód otestovaný dost na to, aby měl jistotu, že tam nikde nechtěné typy nepolezou a že aplikace umí případnou chybu zpracovat.
Já používám modul na coverage, který mi řekne, co mám pokryté a co ne.To ti žádný program neřekne.
Lepší by bylo psát jen jedno (buď testy, nebo program, nebo typy), ideálně to, co je v daném případě nejjednodušší.To by se mi líbilo, ale neumím si to představit v praxi.
To by se mi líbilo, ale neumím si to představit v praxi.Z typů vygenerovat program je úloha pro automatické dokazování (například v intuicionistické logice – viz třeba djinn). Z testů vygenerovat program: na jedné konferenci letos byly hned dva příspěvky, které se tím zabývaly. V podstatě se zvolila "míra složitosti programu" a hledal se program v dané míře nejjednodušší, který projde testy.
Z typů vygenerovat program je úloha pro automatické dokazování (například v intuicionistické logice – viz třeba djinn).To jsem viděl, ale imho to chce docela množství práce zas někde jinde.
Sorry, ale to vůbec není specifikum duck-typingu. Univerzální funkce umí Haskell parádně a navíc s jistotou, kterou mu dodají typy. V Javě to jde taky (například Iterable). V PHP taky (Traversable). Mě to smysl vůbec nedává. Naopak, přijde mi ten kód nebezpečnej, protože absolutně netuším, co to udělá, na čem to chcípne.Mě duck-typing nedává smysl v ničem. Jaká by měla být jeho výhoda? Zkus to prosím nějak shrnout. (Mě nenapadá žádná, ale jsem samozřejmě zaujatý.)V tom že kód pak může být univerzální a využívat výhod existence zapouzdření? Speciálně u metod aplikujících nějaké operace na data dodaná v sekvenci to může dávat smysl.
No jistě, ale to neodpovídá na otázku, proč zvolit tento způsob, když nepřináší žádné výhody?Chybu se dozvím nejenom až za běhu, ale až dost pozdě, až v okamžiku, kdy se runtime pokouší dobouchat na neexistující metodu, což je někde hluboko uvnitř střev, kde to vůbec neznám.Ano. Proto je dobrým zvykem psát testy, které bys stejně musel psát tak jako tak.
Sorry, ale to vůbec není specifikum duck-typingu. Univerzální funkce umí Haskell parádně a navíc s jistotou, kterou mu dodají typy. V Javě to jde taky (například Iterable). V PHP taky (Traversable). Mě to smysl vůbec nedává. Naopak, přijde mi ten kód nebezpečnej, protože absolutně netuším, co to udělá, na čem to chcípne.Tím jsem nemyslel přijímat obecnou sekvenci, ale mít v sekvenci různé datové typy, nad kterými provádím konkrétní operaci. V případě interface by to předpokládalo, že všechny prvky v sekvenci mají společný interface, což nemusí být pravda. V případě vynucení interface to pak musíš řešit třeba konverzí. Ty jako programátor bys měl vědět, zda tam nějaká data patří, nebo ne a přijde mi neefektivní se o tom hádat se zabudovanými omezeními programovacího jazyka.
No jistě, ale to neodpovídá na otázku, proč zvolit tento způsob, když nepřináší žádné výhody?To je tvůj subjektivní pocit, u kterého si opravdu nejsem jistý, jestli mám motivaci ho vyvracet. Například deklarované nevýhody se můžou zdát značné, ale v praxi jsou docela zanedbatelné. Prostě se s nimi setkávám jen velmi zřídka.
Já jako programátor kolikrát nemusím ani tušit, jaká data tam patří. Typy mi to řeknou (plus pro typy). Já jako programátor se můžu seknout. A má zkušenost mi říká, že čím dřív se to dozvím, tím lépe pro mě. (Další plus pro typy.) Některé typové systémy umožňují více datových typů jako omezení genericity sekvence. Je fakt, že to zase neumí každý jazyk. Můžu taky argumentovat, že obvykle v té funkci vím, jaké typy (alespoň generické) mají být obsahem té sekvence. Takže tak nějak furt nevidím problém.Sorry, ale to vůbec není specifikum duck-typingu. Univerzální funkce umí Haskell parádně a navíc s jistotou, kterou mu dodají typy. V Javě to jde taky (například Iterable). V PHP taky (Traversable). Mě to smysl vůbec nedává. Naopak, přijde mi ten kód nebezpečnej, protože absolutně netuším, co to udělá, na čem to chcípne.Tím jsem nemyslel přijímat obecnou sekvenci, ale mít v sekvenci různé datové typy, nad kterými provádím konkrétní operaci. V případě interface by to předpokládalo, že všechny prvky v sekvenci mají společný interface, což nemusí být pravda. V případě vynucení interface to pak musíš řešit třeba konverzí. Ty jako programátor bys měl vědět, zda tam nějaká data patří, nebo ne a přijde mi neefektivní se o tom hádat se zabudovanými omezeními programovacího jazyka.
Deklarované nevýhody mohou být marginální, ok. Ale chtěl jsem vědět ty výhody. A koho se nejlépe zeptat, než zapáleného pythonisty. Ale když ti to nestojí za to, tak asi nebudou tak jasné. Tudíž můj pocit nebude zase tak subjektivní :-PNo jistě, ale to neodpovídá na otázku, proč zvolit tento způsob, když nepřináší žádné výhody?To je tvůj subjektivní pocit, u kterého si opravdu nejsem jistý, jestli mám motivaci ho vyvracet. Například deklarované nevýhody se můžou zdát značné, ale v praxi jsou docela zanedbatelné. Prostě se s nimi setkávám jen velmi zřídka.
Takže tak nějak furt nevidím problém.Představ si, že máš tři různé API. Každé z nich vrací jiný druh objektu, všechny mají property třeba .time(), ale jeden implemetuje rozhraní Timed, další RecordedTime a třetí neimplementuje žádné. A pak máš čtvrté API, které provede analýzu časů, ale přijímá pouze třídy s rozhraním TimedRecord. Tenhle bordel musíš celý nějak normalizovat a trávíš čas řešením kravin, místo algoritmem.
Ale chtěl jsem vědět ty výhody. A koho se nejlépe zeptat, než zapáleného pythonisty. Ale když ti to nestojí za to, tak asi nebudou tak jasné. Tudíž můj pocit nebude zase tak subjektivní :-PPls. Výhody jsem uvedl. Tobě se nezdají jako výhody. Samozřejmě, že bych ti mohl dokazovat, argumentovat a tak, ale imho je to prostě subjektivní záležitost. Svět není černobílý, věci mají své pro a proti a tobě se prostě některé proti zdají větší, než mě. Nechce se mi do toho ti to vyvracet. Byla by to zdlouhavá práce s nejistým výsledkem a nic z toho nemám, ani pocit, že to má smysl. Jinak nejsem zapálený pythonista, snažím se vidět i nevýhody a temné kouty. Dělám v něm od roku 2007, z toho poslední roky více/méně každý den, tak prostě vím, co v něm jsou skutečné potíže a co jen jako potíže (unicode pain třeba) připadá často lidem, kteří přichází z jiných jazyků. Částečně taky proto, že jsem někdy kolem 2011 taky dělal v silně typovaných jazycích (Java, C#, D) a měl jsem pocit, že python je nějak nahovno. Jednoho dne mi ale došlo, že prostě nemůžu argumentovat s produktivitou, kterou v něm mám vyšší, tak jsem přestal řešit zdánlivé problémy, které ve skutečnosti nemám.
Supr, tohle je hezký vysvětlení. A nebudu zde rozvádět, proč bych to dělal jinak, a proč si myslím, že by to bylo lepšíTakže tak nějak furt nevidím problém.Představ si, že máš tři různé API. Každé z nich vrací jiný druh objektu, všechny mají property třeba .time(), ale jeden implemetuje rozhraní Timed, další RecordedTime a třetí neimplementuje žádné. A pak máš čtvrté API, které provede analýzu časů, ale přijímá pouze třídy s rozhraním TimedRecord. Tenhle bordel musíš celý nějak normalizovat a trávíš čas řešením kravin, místo algoritmem.
Trochu mi křivdíš. Chtěl jsem slyšet výhody. O nevýhodách jsem se zmínil jen pro motivaci, nijak jsem to dále nerozpitvával. Maximálně jsem uváděl na pravou míru výhody, které ve skutečnosti, objektivně, nejsou výhodami duck-typingu.Ale chtěl jsem vědět ty výhody. A koho se nejlépe zeptat, než zapáleného pythonisty. Ale když ti to nestojí za to, tak asi nebudou tak jasné. Tudíž můj pocit nebude zase tak subjektivní :-PPls. Výhody jsem uvedl. Tobě se nezdají jako výhody. Samozřejmě, že bych ti mohl dokazovat, argumentovat a tak, ale imho je to prostě subjektivní záležitost. Svět není černobílý, věci mají své pro a proti a tobě se prostě některé proti zdají větší, než mě. Nechce se mi do toho ti to vyvracet. Byla by to zdlouhavá práce s nejistým výsledkem a nic z toho nemám, ani pocit, že to má smysl.
Nevýhodou statického typování je, že typy musí být všude, což zbytečně mnoho věcí komplikuje.Aby se typy nemusely explicitně psát, lze použít typovou inferenci. Pokud typový systém nedovede něco otypovat (například API knihovny z dynamicky typovaného jazyka nebo API knihovny z jazyka s jiným typovým systémem), lze zavést speciální typ (např.
dynamic
v C#), na nějž lze převést libovolné hodnoty a naopak on sám lze použít na místě libovolné hodnoty.
Když to není potřeba, typy být uvedeny nemusí a metoda může být použitelná s čímkoliv, což se hodí u obecných knihoven.Nedovedu si představit, proč byste metodu z obecné knihovny nechtěl otypovat. Většina metod nedokáže pracovat s libovolnou hodnotou – proč to tedy nepopsat v typu? A to platí dvojnásob, když ten typ ani nemusíte napsat explicitně.
Nedovedu si představit, proč byste metodu z obecné knihovny nechtěl otypovat. Většina metod nedokáže pracovat s libovolnou hodnotou – proč to tedy nepopsat v typu? A to platí dvojnásob, když ten typ ani nemusíte napsat explicitně.Většina funkcí dokáže pracovat s druhem hodnoty. Například libovolnou sekvencí. Pokud to ale omezím jen na pole, či tuple, tak už budu mít problém, když tomu budu předávat iterátory, nebo generátory, nebo třeba můj rekurzivní objekt s definovaným .__getitem__(). Ono to vypadá, jako dobrý nápad, protože je to volitelné, jenže jak znám javisty, tak přijdou do pythonu a budou javit na plné koule, výsledkem čehož jsou knihovny na dvě věci (na nic a na hovno, kdyby někdo nevěděl).
Většina funkcí dokáže pracovat s druhem hodnoty. Například libovolnou sekvencí.Na to přeci stačí rozhraní.
Například když se propojují dvě knihovny, každá trochu jinak napsaná.Jak ale v tomto případě pomůže, že tam ten typ (nebo rozhraní) nebude?
V praxi to tak prostě nebude, protože autor prostě nemá a ani nemůže mít představu, co tam cpát půjde a co ne.Autor třeba ví, jaká metoda se vždy zavolá. Typ, který řekne, že hodnota na vstupu tuto metodu nesmí nemít (povoleny jsou tedy hodnoty, které ji mají a hodnoty, o kterých se to neví), přeci nic nepokazí, ne?
Například co když jsou dva interface na syntaktické a funkcionální úrovni totožné, ale díky omezení jen na ten se kterým autor počítal tam ten druhý nejde nacpat? OOP prostě bylo od začátku (=smalltalk, ne java)Doporučuji jiný typový systém, než má Java. Třeba Scala nebo Typescript podporují strukturální podtypový polymorfismus. OCaml má řádkový polymorfimus.
OOP prostě bylo od začátku (=smalltalk, ne java) vytvářeno s ducktypingem v mysli mixování s typovými systémy tohle paradigma rozbíjí a ubírá tomu hodně na kráse a eleganci.Jsou typové systémy, jenž duck typing podporují.
Autor třeba ví, jaká metoda se vždy zavolá. Typ, který řekne, že hodnota na vstupu tuto metodu nesmí nemít (povoleny jsou tedy hodnoty, které ji mají a hodnoty, o kterých se to neví), přeci nic nepokazí, ne?No ale jak říkám, už třeba jen u sekvencí jde tohle velmi těžce. Protože sekvencí může být tuple, pole, slovník, iterátor, generátor, view, nebo třídy s definovaným iterátorem, nebo třídy s indexovacím a bool operátorem. Už jsem říkal, že python nemá interface, takže autor by tam musel vyjmenovat všechno tohle a stejně by pravděpodobně na něco zapomněl. Je to hned několik různých metod, které ale nemůže typovým systémem ověřovat (není možné kontrolovat existenci metod, to by musel dělat v kódu třídy). A co tím získáváme? Lepší nápovědu v IDE a (falešný*) pocit bezpečí? *Je to dynamický jazyk, stejně to tam někdo může vrazit dynamicky a pak to spadne až za běhu.
Je to hned několik různých metod, které ale nemůže typovým systémem ověřovat (není možné kontrolovat existenci metod, to by musel dělat v kódu třídy).Proč to nemohu typovým systéměm ověřovat? Pokud to dokážu popsat v dokumentaci v přirozeném jazyce, je velmi pravděpodobné, že to dokážu i formálně v nějaké logice, což už je v podstatě typový systém.
No ale jak říkám, už třeba jen u sekvencí jde tohle velmi těžce. Protože sekvencí může být tuple, pole, slovník, iterátor, generátor, view, nebo třídy s definovaným iterátorem, nebo třídy s indexovacím a bool operátorem. Už jsem říkal, že python nemá interface, takže autor by tam musel vyjmenovat všechno tohle a stejně by pravděpodobně na něco zapomněl.Typový systém může obsahovat typ
Sequence
, který pokryje všechny možnosti, jenž jste vyjmenoval.
Tuhle věc lze snadno zvládnout například ve Scale. Můžete si zavést typovou třídu Sequence
a pomocí implicitních maker vygenerovat instance ke všemu, co připomíná sekvenci (například pro všechny třídy, jenž mají určité metody).
a (falešný*) pocit bezpečí?To je podobné jako v ostatních staticky typovaných jazycích.
Proč to nemohu typovým systéměm ověřovat? Pokud to dokážu popsat v dokumentaci v přirozeném jazyce, je velmi pravděpodobné, že to dokážu i formálně v nějaké logice, což už je v podstatě typový systém.Ah, takhle. Myslel jsem že se stále bavíme o tom type hintingu v pythonu. Tam to není možné.
No ale jak říkám, už třeba jen u sekvencí jde tohle velmi těžce. Protože sekvencí může být tuple, pole, slovník, iterátor, generátor, view, nebo třídy s definovaným iterátorem, nebo třídy s indexovacím a bool operátorem.To je nějaká blbost ne? Sekvence je něčím definována. Tak třeba tím, že má metodu .__getitem__(). Takže prostě všechno to, co jsi vyjmenoval, tuple, slovník, iterátor, generátor a cokoliv nového, co si vymyslíš prostě musí definovat tuto funkci. To je všechno. Na tom není principielně žádný rozdíl. A nevím co brání tomu, aby se určil typ Sekvence, vynucující tuto funkci. Abychom se vyhli problémů s pochopením, má otázka směřuje na to, v čem přesně ten typ u těch sekvencí škodí, či brání. Ano, python nemá interface, to asi všichni víme. Ale co to přesně dokazuje?
To je nějaká blbost ne? Sekvence je něčím definována. Tak třeba tím, že má metodu .__getitem__(). Takže prostě všechno to, co jsi vyjmenoval, tuple, slovník, iterátor, generátor a cokoliv nového, co si vymyslíš prostě musí definovat tuto funkci. To je všechno. Na tom není principielně žádný rozdíl. A nevím co brání tomu, aby se určil typ Sekvence, vynucující tuto funkci.Jednak ti imho nestačí jen __getitem__(), ale potřebuješ i velikost. Iterátor má jen AFAIK jen next() a __iter__(), ne? No a pak potřebuješ při definici typu OR, tedy buď metodu getitem & spol, a/nebo next() a __iter__(). Když to uděláš přes dědičnost, tak to nebude OR, ale AND, tedy všechny tyhle metody najednou.
Ano, python nemá interface, to asi všichni víme. Ale co to přesně dokazuje?Pointa byla, že současný type hinting v pythonu ti AFAIK umožňuje kontrolovat jen, jestli jde o instanci nějakého konkrétního typu, ne jestli má ty a ony metody. A i kdyby ano, tak máš výčet metod delší, než samotnou deklaraci funkce.
Doporučuji jiný typový systém, než má Java. Třeba Scala nebo Typescript podporují strukturální podtypový polymorfismus. OCaml má řádkový polymorfimus.Neměl by si prosím tě nějaké hezké porovnání mezi těmi jednotlivými druhy typových systémů? Dost v tom plavu, a zajímaly by mě rozdíly. Praxy chápu, spíše mi jde o ty nuance.
porovname-li vyjadrovaci schopnosti jazykuAno, třeba v Pythonu můžete napsat
a = (1, [2, 3]) a[1] += [4]a hádat, co to dělá.
jakym problemum?Třeba, že ten kód mj. vyhazuje výjimku.
cemuz by ten tvuj typovy system nepomohl, spis naopakPomohl by tomu tím, že by některé nesmysly odhalil ještě před jejich vykonáním.
a[1] += [4]
znamená
a[1] = a[1] + [4]
Najskôr sa vykonáva pravá časť výrazu, ktorá je v poriadku. Python nerobí deep copy (čo je logické keďže názvy premenných sú len značky), takže aj bez vykonania priradenia sa obsah zmení.
Nikoliv (v tom vašem kódu se obsaha[1] += [4]znamená
a[1] = a[1] + [4]
a
nezmění). Správné vysvětlení je přímo ve FAQu. Je to ekvivalentní
result = a[1].__iadd__([4]) a[1] = result
smutne by bylo, kdyby ji nevyhazovalProč myslíte? Měnit seznam přeci normálně jde. Koneckonců výše zmíněný kód stačí přepsat
a = (1, [2, 3]) b = a[1] b += [4]a výjimka se nevyhodí.
a = (1, [2, 3]) a[1].__iadd__([4])
Takze to, ze je referencni implementace pythonu 3 o par procent pomalejsi mi fakt zily netrha a jsem radPorovnáváte rychlost různých algoritmů v různých jazycích nebo stejného algoritmu v různých jazycích?
Kdybychom měli zakázat všechny jazyky,Nikdo nic nezakazuje.
JJ, a to je ten problem. Jelikoz jsou to "ignoranti" a o modernim PHP nic nevedi :D. Ja jsem za kazde nove PHP rad. Jelikoz predstava ze nase aplikace musi bezet na PHP4 nebo treba i na PHP 5.2 me desi :D. Jinak pro vlastni projekty preferuji python, ale holt "musim" pracovat i v PHP.
Dneska neni problem v PHP psat prehledny a rychly kod.
Ano, to je pravda, ale bohuzel vychazej, takze opet koncim u toho ze jsem vlastne rad :). Samozrejme je skoda ze se na to nevykaslali uz driv a ja mel klid :). Ne ze bych stale nemel moznost zmenit praci a vyhnout se tomu, ale to by nebyla vyzva :D.