Vzdelávací program o písaní v programovacích jazykoch. Akýkoľvek jazyk - Prečo dynamické písanie? Mém dynamického písania

Všetko je veľmi jednoduché. Je to ako rozdiel medzi hotelom a súkromným bytom.

V byte žijú iba tí, ktorí sú tam zaregistrovaní. Ak v ňom, povedzme, žije rodina Sidorovcov, potom rodina Pupkinovcov preňho nebude môcť žiť. Petya Sidorov môže zároveň žiť v tomto byte, potom sa tam môže presťahovať Grisha Sidorov (niekedy tam dokonca môžu bývať súčasne - to je pole). Toto je statické písanie.

Rodina Sidorovcov môže v hoteli bývať jednorazovo. Aj tam nie je vždy potrebné, aby sa zaregistrovali. Potom odídu a Pupkins sa tam presťahujú. A potom Kuznecovovci. A potom niekto ďalší. Toto je dynamické písanie.

Keď sa vrátime k programovaniu, prvý prípad (statické písanie) sa vyskytuje povedzme v jazykoch C, C ++, C #, Java a ďalších. Pred prvým priradením variabilná hodnota Mali by ste povedať, čo tam budete ukladať: celé čísla, čísla s pohyblivou rádovou čiarkou, reťazce atď. ( v tomto byte budú bývať Sidorovci). Dynamické písanie to naopak nevyžaduje. V čase priradenia hodnoty súčasne priraďujete premennej jej typ ( Vasya Pupkin z rodiny Pupkinovcov teraz žije v tejto hotelovej izbe). Nájdeme ho v jazykoch ako PHP, Python a JavaScript.

Oba prístupy majú svoje výhody a nevýhody. Ktorý z nich je lepší alebo horší, závisí od riešených úloh. Viac podrobností nájdete, povedzme, na Wikipédii.

pri statickom písaní presne poznáte typ premennej v čase písania programu a vyvíjania algoritmu a zohľadnite to. tí. ak ste povedali, že premenná G je štvorbajtové celé číslo bez znamienka, potom v algoritme bude vždy presne štvorbajtové celé číslo bez znamienka (ak niečo, potom ho musíte explicitne previesť alebo vedieť, ako ho prekladač prevádza na určitý rozsah situácií, ale v zásade, ak existuje nesúlad typov, je to chyba algoritmu a kompilátor vás na to aspoň upozorní), pri statickom nemôžete zadať reťazec „Vasya-blázon“ do počtu a ďalších kontroly pred použitím premennej na „existuje číslo“ nie sú povinné, vykonáte všetku správnosť údajov v čase ich zadania do programu alebo podľa požiadaviek samotného algoritmu.

pri dynamickom písaní vám typ tej istej premennej vo všeobecnom prípade nie je známy a môže sa zmeniť už počas vykonávania programu, a to vezmete do úvahy, nikto vás nevaruje pred potenciálnou chybou algoritmu v dôsledku nesúlad typu (pri vývoji algoritmu ste predpokladali, že v G je celé číslo a používateľ zadal povedzme číslo s pohyblivou rádovou čiarkou alebo ešte horšie reťazec alebo povedzme, že po aritmetickej operácii bolo namiesto čísla s pohyblivou rádovou čiarkou celé číslo, a v nasledujúcom kroku sa pokúsite použiť bitové operácie ...), na druhej strane sa nemusíte trápiť s mnohými drobnosťami.

Tento článok obsahuje nevyhnutné minimum vecí, ktoré by ste mali vedieť o písaní, aby ste dynamické písanie nenazvali zlom, Lisp bez jazyka a C ako silne písaný jazyk.

V. plná verzia Nachádza Detailný popis všetkých typov písania, doplnených príkladmi kódu, odkazmi na obľúbené programovacie jazyky a ilustračnými obrázkami.

Odporúčam najskôr prečítať krátku verziu článku a potom, ak je to žiaduce, plnú verziu.

Krátka verzia

Programovaním sa programovacie jazyky zvyčajne delia na dva veľké tábory - typové a netypové (bez typov). Prvý z nich zahŕňa napríklad C, Python, Scala, PHP a Lua, zatiaľ čo druhý obsahuje montážny jazyk, Forth a Brainfuck.

Pretože „písanie bez typu“ je vo svojej podstate také jednoduché ako korek, nie je ďalej rozdelené na žiadne iné typy. Jazyky sú však rozdelené do niekoľkých prekrývajúcich sa kategórií:

  • Statické / dynamické písanie. Statický je definovaný skutočnosťou, že konečné typy premenných a funkcií sú nastavené v čase kompilácie. Títo. už si kompilátor je 100% istý, ktorý typ je kde. Pri dynamickom písaní sa všetky typy zisťujú za behu.

    Príklady:
    Statický: C, Java, C #;
    Dynamické: Python, JavaScript, Ruby.

  • Silné / slabé písanie (niekedy sa tiež hovorí, že je silné / slabé). Silné písanie vyniká, pretože jazyk neumožňuje miešanie výrazov Rôzne druhy a nevykonáva automatické implicitné prevody, napríklad množinu nemožno odpočítať od reťazca. Slabo napísané jazyky vykonávajú mnoho implicitných konverzií automaticky, aj keď môže dôjsť k strate presnosti alebo nejednoznačnosti.

    Príklady:
    Silné: Java, Python, Haskell, Lisp;
    Slabé: C, JavaScript, Visual Basic, PHP.

  • Explicitné / implicitné písanie. Explicitne napísané jazyky sa líšia v tom, že typ nových premenných / funkcií / ich argumentov musí byť špecifikovaný výslovne. Preto jazyky s implicitným typovaním posúvajú túto úlohu na prekladač / tlmočník.

    Príklady:
    Explicitné: C ++, D, C #
    Implicitné: PHP, Lua, JavaScript

Je tiež potrebné poznamenať, že všetky tieto kategórie sa prekrývajú, napríklad jazyk C má statické slabé explicitné písanie a Jazyk Python- dynamický silný implicitný.

Neexistujú však žiadne jazyky so statickým a dynamickým písaním súčasne. Hoci bežím dopredu, poviem, že tu ležím - skutočne existujú, ale o tom neskôr.

Podrobná verzia

Ak sa vám skrátená verzia nezdala dostačujúca, dobre. Niet divu, že som napísal podrobne? Hlavná vec je, že do krátkej verzie bolo jednoducho nemožné zmestiť všetky užitočné a zaujímavé informácie a podrobná informácia by bola pravdepodobne príliš dlhá na to, aby si ju každý prečítal bez namáhania.

Beztypové písanie

V programovacích jazykoch bez jazyka sú všetky entity považované za jednoducho sekvencie bitov rôznych dĺžok.

Beztypové písanie je zvyčajne vlastné jazykom nízkej úrovne (montážny jazyk, Forth) a ezoterike (Brainfuck, HQ9, Piet). Spolu so svojimi nevýhodami má však aj niekoľko výhod.

Výhody
  • Umožňuje písanie na extrémne nízkej úrovni a prekladač / tlmočník nebude zasahovať do žiadnej kontroly typu. Môžete slobodne vykonávať akékoľvek operácie s akýmkoľvek druhom údajov.
  • Výsledný kód je zvyčajne efektívnejší.
  • Transparentnosť pokynov. So znalosťou jazyka spravidla nie je pochýb o tom, že ten alebo onen kód je.
nevýhody
  • Zložitosť. Často je potrebné reprezentovať komplexné hodnoty, ako sú zoznamy, reťazce alebo štruktúry. To môže byť nepohodlné.
  • Nedostatok kontrol. Akékoľvek nezmyselné akcie, ako napríklad odčítanie ukazovateľa na poli od symbolu, sa budú považovať za úplne normálne, čo je plné jemných chýb.
  • Nízka úroveň abstrakcie. Práca s akýmkoľvek komplexným dátovým typom sa nelíši od práce s číslami, čo samozrejme spôsobí mnoho ťažkostí.
Silné beztypové písanie?

Áno, to existuje. Napríklad v montážnom jazyku (pre architektúru x86 / x86-64, iné nepoznám) nemôžete zostaviť program, ak sa pokúsite načítať údaje z registra rax (64 bitov) do registra cx (16 bitov) ).

mov cx, eax; chyba času montáže

Ukazuje sa teda, že v assembleri stále existuje písanie? Verím, že tieto kontroly nestačia. A váš názor, samozrejme, závisí len od vás.

Statické verzus dynamické písanie

Hlavnou vecou, ​​ktorá odlišuje statické písanie od dynamického, je to, že všetky kontroly typu sa vykonávajú v čase kompilácie, nie v čase spustenia.

Niektorí ľudia si môžu myslieť, že statické písanie je príliš obmedzené (v skutočnosti je, ale pomocou niektorých techník sa ho už dávno zbavilo). Pre niektorých sú dynamicky písané jazyky hra s ohňom, ale aké sú vlastnosti, ktorými sa odlišujú? Majú oba druhy šancu existencie? Ak nie, prečo existuje mnoho staticky aj dynamicky typovaných jazykov?

Poďme na to.

Výhody statického písania
  • Kontroly typu sa vykonávajú iba raz, v čase kompilácie. To znamená, že nebudeme musieť neustále zisťovať, či sa pokúšame rozdeliť číslo reťazcom (a buď hodiť chybu alebo vykonať konverziu).
  • Rýchlosť vykonávania. Z predchádzajúceho bodu je zrejmé, že staticky napísané jazyky sú takmer vždy rýchlejšie ako dynamicky písané.
  • Za určitých dodatočných podmienok vám to umožní odhaliť potenciálne chyby už vo fáze kompilácie.
Výhody dynamického písania
  • Jednoduchosť vytvárania univerzálnych zbierok je zväzkom všetkého a všetkého (taká potreba vzniká len zriedka, ale keď nastane dynamické písanie, pomôže).
  • Pohodlie popisu generalizovaných algoritmov (napríklad triedenie poľa, ktoré bude fungovať nielen v zozname celých čísel, ale aj v zozname skutočných čísel a dokonca aj v zozname reťazcov).
  • Ľahko sa učí - dynamicky písané jazyky sú zvyčajne veľmi dobré na začiatku programovania.

Zovšeobecnené programovanie

Dobre, najdôležitejším argumentom pre dynamické písanie je jednoduchosť popisu generických algoritmov. Predstavme si problém - potrebujeme funkciu na vyhľadávanie vo viacerých poliach (alebo zoznamoch) - pole celých čísel, pole reals a pole znakov.

Ako to ideme riesit? Vyriešime to na 3 rôzne jazyky: jeden dynamicky napísaný a dva staticky napísané.

Algoritmus vyhľadávania, ktorý použijem, je jedným z najjednoduchších - hrubou silou. Funkcia prijme požadovaný prvok, samotné pole (alebo zoznam) a vráti index prvku, alebo, ak sa prvok nenájde, (-1).

Dynamické riešenie (Python):

Def find (required_element, list): for (index, element) in enumerate (list): if element == required_element: return index return (-1)

Ako vidíte, všetko je jednoduché a neexistujú žiadne problémy s tým, že zoznam môže obsahovať aspoň čísla, dokonca aj zoznamy, aj keď neexistujú žiadne ďalšie polia. Veľmi dobre. Pokračujme a vyriešime rovnaký problém v C!

Statický roztok (C):

Nepodpísané int find_int (int required_element, int array, unsigned int size) (pre (unsigned int i = 0; i< size; ++i) if (required_element == array[i]) return i; return (-1); } unsigned int find_float(float required_element, float array, unsigned int size) { for (unsigned int i = 0; i < size; ++i) if (required_element == array[i]) return i; return (-1); } unsigned int find_char(char required_element, char array, unsigned int size) { for (unsigned int i = 0; i < size; ++i) if (required_element == array[i]) return i; return (-1); }

Každá funkcia je individuálne podobná verzii Python, ale prečo existujú tri? Naozaj statické programovanie zlyhalo?

Áno a nie. Existuje niekoľko programovacích techník, z ktorých jednu teraz zvážime. Hovorí sa mu generické programovanie a jazyk C ++ to celkom dobre podporuje. Pozrime sa na novú verziu:

Statické riešenie (generické programovanie, C ++):

Predloha nepodpísané int nájsť (T required_element, std :: vector pole) (pre (bez znamienka int i = 0; i< array.size(); ++i) if (required_element == array[i]) return i; return (-1); }

Dobre! Nevyzerá to oveľa komplikovanejšie ako verzia Python a nemusí veľa písať. Okrem toho sme dostali implementáciu pre všetky polia, nielen pre riešenie problémov potrebné tri!

Zdá sa, že táto verzia je presne to, čo potrebujete - získavame výhody statického písania a niektoré výhody dynamického písania.

Je skvelé, že je to dokonca možné, ale mohlo to byť ešte lepšie. Po prvé, generické programovanie môže byť pohodlnejšie a krásnejšie (napríklad v jazyku Haskell). Za druhé, okrem generického programovania môžete použiť aj polymorfizmus (výsledok bude horší), preťaženie funkcií (podobne) alebo makrá.

Statická dynamika

Malo by sa tiež spomenúť, že mnoho statických jazykov umožňuje dynamické písanie, napríklad:

  • C # podporuje dynamický pseudo-typ.
  • F # podporuje syntaktický cukor vo forme? Operátora, ktorý je možné použiť na simuláciu dynamického písania.
  • Haskell - dynamické písanie zabezpečuje modul Data.Dynamic.
  • Delphi - prostredníctvom špeciálneho typu Variant.

Niektoré dynamicky písané jazyky vám tiež umožňujú využiť výhody statického písania:

  • Bežné deklarácie typu Lisp.
  • Perl - od verzie 5.6 skôr obmedzený.

Silné a slabé písanie

Silne napísané jazyky neumožňujú miešať vo výrazoch entity rôznych typov a nevykonávajú žiadne automatické prevody. Hovorí sa im aj „silne napísané jazyky“. Anglický výraz pre toto je silné písanie.

Slabo napísané jazyky, naopak, robia všetko pre to, aby programátor zmiešal rôzne typy v jednom výraze a samotný kompilátor privedie všetko k jednému typu. Hovorí sa im aj „voľne písané jazyky“. Anglický výraz pre to znamená slabé písanie.

Slabé písanie je často zamieňané s dynamickým typovaním, čo je úplne nesprávne. Dynamicky písaný jazyk môže byť napísaný slabo aj silne.

Málokto však pripisuje dôležitosť prísnosti písania. Často sa tvrdí, že ak je jazyk staticky napísaný, môžete zachytiť veľa potenciálnych chýb pri kompilácii. Klamú vám!

Jazyk musí mať zároveň silné písanie. Skutočne, ak kompilátor namiesto nahlásenia chyby jednoducho pridá reťazec k číslu, alebo ešte horšie, odčíta iné od jedného poľa, na čo nám je dobré, že všetky „kontroly typu“ sú v čase kompilácie? To je pravda - slabé statické písanie je ešte horšie ako silné dynamické písanie! (To je môj názor)

Nemá teda slabé písanie vôbec žiadne výhody? Môže to vyzerať takto, ale hoci som horlivým zástancom silného písania, musím súhlasiť s tým, že slabý má aj výhody.

Chcete vedieť ktoré?

Výhody silného písania
  • Spoľahlivosť - namiesto nesprávneho správania dostanete výnimku alebo chybu kompilácie.
  • Rýchlosť- namiesto skrytých konverzií, ktoré môžu byť pri drahom písaní poriadne drahé, ich musíte napísať vyslovene, vďaka čomu programátor aspoň vie, že tento kúsok kódu môže byť pomalý.
  • Pochopenie práce programu - opäť, namiesto implicitnej konverzie typu, programátor píše všetko sám, čo znamená, že zhruba chápe, že porovnanie reťazca a čísla sa nedeje samé a nie mágiou.
  • Istota - keď píšete konverzie ručne, presne viete, na čo a na čo konvertujete. Tiež vždy pochopíte, že takéto transformácie môžu viesť k strate presnosti a k ​​nesprávnym výsledkom.
Výhody slabého písania
  • Jednoduché použitie zmiešaných výrazov (napríklad z celých čísel a reálnych čísel).
  • Abstrakcia od písania a sústredenie sa na úlohu.
  • Stručnosť záznamu.

Dobre, prišli sme na to, ukazuje sa, že slabé písanie má aj výhody! Existujú spôsoby, ako preniesť výhody slabého písania na silné písanie?

Ukázalo sa, že sú dokonca dve.

Implicitná konverzia typu, v jednoznačných situáciách a bez straty údajov

Uh ... Celkom dlhý bod. Dovoľte mi to skrátiť na „obmedzenú implicitnú konverziu“ Čo teda znamená jednoznačná situácia a strata údajov?

Jednoznačná situácia je transformácia alebo operácia, v ktorej je entita okamžite zrozumiteľná. Napríklad sčítanie dvoch čísel je jednoznačná situácia. A prevádzanie čísla na pole nie je (možno sa vytvorí pole jedného prvku, možno pole s takouto dĺžkou, štandardne vyplnené prvkami alebo sa možno číslo skonvertuje na reťazec a potom na pole znakov).

Strata údajov je ešte jednoduchšia. Ak sa transformujeme Reálne číslo 3,5 na celé číslo - prídeme o niektoré údaje (v skutočnosti je táto operácia tiež nejednoznačná - ako sa bude zaokrúhľovať? Hore? Dole? Vyradenie zlomkovej časti?).

Nejednoznačné transformácie a stratové transformácie sú veľmi, veľmi zlé. V programovaní nie je nič horšie ako toto.

Ak mi neveríte, naučte sa jazyk PL / I, alebo dokonca len hľadajte jeho špecifikáciu. Má pravidlá pre prevod medzi VŠETKÝMI typmi údajov! Je to jednoducho peklo!

Dobre, spomeňme si na obmedzenú implicitnú konverziu. Existujú také jazyky? Áno, napríklad v Pascale môžete previesť celé číslo na skutočné číslo, ale nie naopak. Podobné mechanizmy existujú aj v jazykoch C #, Groovy a Common Lisp.

Dobre, povedal som, že stále existuje spôsob, ako získať niekoľko výhod slabého písania v silnom jazyku. A áno, je a nazýva sa konštruktívny polymorfizmus.

Vysvetlím to na príklade nádherného jazyka Haskell.

Polymorfné konštruktéry sú výsledkom pozorovania, že pri použití numerických literálov sú najčastejšie potrebné bezpečné implicitné konverzie.

Napríklad vo výraze pi + 1 nechcete písať pi + 1,0 alebo pi + float (1). Chcel by som napísať iba pi + 1!

A to sa robí v Haskelli, pretože doslovná 1 nemá žiadny konkrétny typ. Nie je ani celý, ani skutočný, ani zložitý. Je to len číslo!

Výsledkom je, že pri písaní súčtu jednoduchej funkcie xy, vynásobením všetkých čísel od x do y (s prírastkom 1), dostaneme niekoľko verzií naraz - súčet pre celé čísla, súčet pre reálne, súčet pre racionálne, súčet pre komplexné čísla , a dokonca súčet pre všetky tie číselné typy, ktoré ste sami definovali.

Táto technika samozrejme šetrí iba pri použití zmiešaných výrazov s číselnými literálmi, a to je len špička ľadovca.

Môžeme teda povedať, že najlepším riešením by bolo balansovať na pokraji, medzi silným a slabým písaním. Zatiaľ však žiadny jazyk nie je v dokonalej rovnováhe, takže sa skôr prikláňam k silne napísaným jazykom (ako je Haskell, Java, C #, Python), než k jazykom slabo napísaným (ako C, JavaScript, Lua, PHP) .

Explicitné a implicitné písanie

Výslovne zadaný jazyk predpokladá, že programátor musí špecifikovať typy všetkých premenných a funkcií, ktoré deklaruje. Anglický výraz pre toto je explicitné písanie.

Implicitne napísaný jazyk vás naopak pozýva na to, aby ste zabudli na typy a preniesli úlohu odvodenia typu na prekladač alebo tlmočník. Anglický výraz pre toto je implicitné písanie.

Najprv sa môžete rozhodnúť, že implicitné písanie je ekvivalentom dynamického písania a explicitné písanie je ekvivalentné statickému, ale neskôr uvidíme, že to tak nie je.

Existujú výhody pre každý typ a opäť existujú ich kombinácie a existujú jazyky, ktoré podporujú obe metódy?

Výhody explicitného písania
  • Prítomnosť podpisu pre každú funkciu (napríklad int add (int, int)) vám umožňuje ľahko určiť, čo funkcia robí.
  • Programátor ihneď napíše, aký typ hodnoty je možné uložiť do konkrétnej premennej, čím odpadá potreba zapamätať si to.
Výhody implicitného písania
  • Skratka pre def add (x, y) je zreteľne kratšia ako int add (int x, int y).
  • Odolnosť voči zmenám. Ak napríklad dočasná premenná vo funkcii bola rovnakého typu ako vstupný argument, potom v výslovne napísanom jazyku, keď sa zmení typ vstupného argumentu, bude potrebné zmeniť aj typ dočasnej premennej.

Dobre, vidíte, že oba prístupy majú klady a zápory (kto čakal niečo iné?), Poďme teda hľadať spôsoby, ako tieto dva skombinovať!

Explicitné písanie podľa výberu

Existujú jazyky s implicitným typovaním a s možnosťou špecifikovať typ hodnôt, ak je to potrebné. Prekladač automaticky odvodí skutočný typ výrazu. Jeden z týchto jazykov je Haskell, dovoľte mi pre jednoduchosť uviesť jednoduchý príklad:

Bez explicitnej indikácie typu add (x, y) = x + y - Explicitná indikácia typu add :: (Integer, Integer) -> Integer add (x, y) = x + y

Poznámka: Zámerne som použil neskúsenú funkciu a tiež som úmyselne napísal súkromný podpis namiesto všeobecnejšieho doplnku :: (Číslo a) -> a -> a -> a, pretože chcel ukázať myšlienku bez vysvetlenia syntaxe Haskella „a.

HM. Ako vidíme, je veľmi pekný a krátky. Záznam funkcie trvá iba 18 znakov na jednom riadku vrátane medzier!

Automatické odvodenie typu je však ošemetná vec a dokonca aj v chladnom jazyku, akým je Haskell, niekedy zlyhá. (ako príklad možno uviesť obmedzenie monomorfizmu)

Existujú jazyky, ktoré sú predvolene napísané a ktoré sú implicitne napísané podľa potreby? Kon
navždy.

Voliteľné implicitné písanie

Nový jazykový štandard C ++ s názvom C ++ 11 (predtým C ++ 0x) zaviedol kľúčové slovo auto, aby kompilátor vyvodil typ na základe kontextu:

Porovnajme: // Ručná špecifikácia nepodpísaného typu int a = 5; bez znamienka int b = a + 3; // Automatické odvodenie nepodpísaného typu int a = 5; auto b = a + 3;

Nie zlé. Rekord sa ale veľmi nezmenšil. Pozrime sa na príklad s iterátormi (ak nerozumiete, nebojte sa, hlavnou vecou je poznamenať, že záznam je vďaka automatickému výstupu výrazne znížený):

// Ručná špecifikácia typu std :: vector vec = randomVector (30); for (std :: vector :: const_iterator it = vec.cbegin (); ...) (...) // Automatické odvodenie typu auto vec = randomVector (tridsať); pre (auto it = vec.cbegin (); ...) (...)

Wow! Toto je skratka. Dobre, ale môžete urobiť niečo v duchu Haskella, kde bude typ návratu závisieť od typov argumentov?

A opäť je odpoveď áno, ďakujem kľúčové slovo decltype kombinovaný s auto:

// Ručná špecifikácia typu int delenie (int x, int y) (...) // Automatické delenie typu automatické delenie (int x, int y) -> typ deklinácie (x / y) (...)

Môže sa zdať, že je tento zápis veľmi dobrý, ale v kombinácii s generickým programovaním (šablóny / generiká), implicitné písanie alebo automatické odvodenie typu robí zázraky.

Niektoré programovacie jazyky podľa tejto klasifikácie

Dám krátky zoznam obľúbených jazykov a napíšem, ako sú zaradené do jednotlivých kategórií „písania na stroji“.

JavaScript - Dynamický / Slabý / Implicitný Ruby - Dynamický / Silný / Implicitný Python - Dynamický / Silný / Implicitný Java - Statický / Silný / Explicitný PHP - Dynamický / Slabý / Implicitný C - Statický / Slabý / Explicitný C ++ - Statický / Semi- Silné / Explicitné Perl - Dynamické / Slabé / Implicitné Cieľ - C - Statické / Slabé / Explicitné C # - Statické / Silné / Explicitné Haskell - Statické / Silné / Implicitné Common Lisp - Dynamické / Silné / Implicitné

Možno som sa niekde mýlil, najmä s CL, PHP a Obj -C, ak máte na nejaký jazyk iný názor - napíšte do komentárov.

  • Dynamické písanie je technika široko používaná v programovacích jazykoch a špecifikačných jazykoch, v ktorej je premenná priradená k typu v okamihu priradenia hodnoty, a nie v okamihu deklarovania premennej. V rôznych častiach programu teda rovnaká premenná môže nadobúdať hodnoty rôznych typov. Príklady dynamicky typovaných jazykov sú Smalltalk, Python, Objective-C, Ruby, PHP, Perl, JavaScript, Lisp, xBase, Erlang, Visual Basic.

    Opačnou technikou je statické písanie.

    V niektorých jazykoch so slabým dynamickým typovaním je problém s porovnávaním hodnôt, napríklad PHP má porovnávacie operácie "==", "! =" And "===", "! ==", kde druhý dvojica operácií tiež porovnáva hodnoty a typy premenných. Operácia "===" platí iba v prípade úplnej zhody, na rozdiel od "==", ktorá považuje nasledujúci výraz za pravdivý: (1 == "1"). Treba poznamenať, že to nie je problém dynamického písania vo všeobecnosti, ale konkrétnych programovacích jazykov.

Súvisiace koncepty

Programovací jazyk je formálny jazyk určený na písanie počítačové programy... Programovací jazyk definuje súbor lexikálnych, syntaktických a sémantických pravidiel, ktoré definujú vzhľad programy a akcie, ktoré bude exekútor (spravidla počítač) vykonávať pod jeho kontrolou.

Syntaktický cukor v programovacom jazyku sú syntaktické vlastnosti, ktorých použitie neovplyvňuje správanie programu, ale robí používanie jazyka pre ľudí pohodlnejším.

Vlastnosť je spôsob prístupu k vnútornému stavu objektu, ktorý napodobňuje premennú určitého typu. Prístup k vlastnosti objektu vyzerá rovnako ako prístup k štruktúrovanému poľu (v štruktúrovanom programovaní), ale v skutočnosti sa implementuje prostredníctvom volania funkcie. Keď sa pokúsite nastaviť hodnotu tejto vlastnosti, zavolá sa jedna metóda a keď sa pokúsite získať hodnotu tejto vlastnosti, zavolá sa iná metóda.

Extended Backus - Naur Form (EBNF) je formálny systém definície syntaxe, v ktorom sú niektoré syntaktické kategórie postupne definované prostredníctvom iných. Používa sa na opis bezkontextových formálnych gramatík. Navrhol Niklaus Wirth. Jedná sa o rozšírené spracovanie foriem Backus - Naur, ktoré sa líši od BNF v „priestrannejších“ prevedeniach, čo umožňuje s rovnakou expresívnou schopnosťou zjednodušiť ...

Aplikačné programovanie je typom deklaratívneho programovania, v ktorom písanie programu spočíva v systematickom aplikovaní jedného objektu na druhý. Výsledkom takejto aplikácie je opäť predmet, ktorý sa môže zúčastňovať aplikácií ako v úlohe funkcie, tak v úlohe argumentu a pod. Vďaka tomu je záznam programu matematicky jasný. Skutočnosť, že funkcia je označená výrazom, naznačuje možnosť použitia hodnôt -funkcií - funkčných ...

Reťazcový programovací jazyk je programovací jazyk založený na koncepte, že zreťazenie dvoch častí kódu vyjadruje ich zloženie. V takom jazyku je široko používaná implicitná indikácia funkčných argumentov (pozri nezmyselné programovanie), nové funkcie sú definované ako skladba funkcií a namiesto aplikácie sa používa zreťazenie. Tento prístup je v kontraste k aplikačnému programovaniu.

Premenná je atribút fyzického alebo abstraktného systému, ktorý môže meniť jeho spravidla číselnú hodnotu. Pojem premenná je široko používaný v oblastiach ako matematika, veda, strojárstvo a programovanie. Medzi príklady premenných patrí: teplota vzduchu, funkčný parameter a ďalšie.

Syntaktická analýza (alebo syntaktická analýza, jarg. Analýza ← angl. Parsing) v lingvistike a informatike je proces porovnávania lineárnej postupnosti lexém (slov, tokenov) prirodzeného alebo formálneho jazyka s jeho formálnou gramatikou. Výsledkom je zvyčajne syntaktický strom (syntaktický strom). Obvykle sa používa v spojení s lexikálnou analýzou.

Generalizovaný algebraický dátový typ (GADT) je jedným z typov algebraických dátových typov, ktoré sa vyznačujú tým, že jeho konštruktéri môžu vracať hodnoty, ktoré s ním nie sú spojené. Navrhnuté pod vplyvom práce na induktívnych rodinách medzi výskumníkmi závislých typov.

Sémantika v programovaní je disciplína, ktorá študuje formalizáciu významov konštrukcií programovacích jazykov konštruovaním ich formálnych matematických modelov. Na stavbu takýchto modelov je možné použiť rôzne prostriedky, napríklad matematickú logiku, λ-počet, teóriu množín, teóriu kategórií, teóriu modelov, univerzálnu algebru. Formalizáciu sémantiky programovacieho jazyka je možné použiť na opis jazyka, na definovanie vlastností jazyka ...

Objektovo orientované programovanie (OOP) je metodika programovania založená na reprezentácii programu ako súboru objektov, z ktorých každý je inštanciou určitej triedy a triedy tvoria hierarchiu dedičnosti.

Dynamická premenná - premenná v programe, umiestnite do Náhodný vstup do pamäťe podľa ktorého je alokovaný počas vykonávania programu. V skutočnosti je to časť pamäte pridelená systémom programu na konkrétne účely, keď je program spustený. Tým sa líši od globálnej statickej premennej - časti pamäte pridelenej systémom programu na konkrétne účely pred spustením programu. Dynamická premenná je jednou z tried variabilných pamätí.

Tento článok obsahuje nevyhnutné minimum vecí, ktoré by ste mali vedieť o písaní, aby ste dynamické písanie nenazvali zlom, Lisp bez jazyka a C ako silne písaný jazyk.

Plná verzia obsahuje podrobný popis všetkých typov písania, doplnený o príklady kódu, odkazy na obľúbené programovacie jazyky a ilustračné obrázky.

Odporúčam najskôr prečítať krátku verziu článku a potom, ak je to žiaduce, plnú verziu.

Krátka verzia

Programovaním sa programovacie jazyky zvyčajne delia na dva veľké tábory - typové a netypové (bez typov). Prvý z nich zahŕňa napríklad C, Python, Scala, PHP a Lua, zatiaľ čo druhý obsahuje montážny jazyk, Forth a Brainfuck.

Pretože „písanie bez typu“ je vo svojej podstate také jednoduché ako korek, nie je ďalej rozdelené na žiadne iné typy. Jazyky sú však rozdelené do niekoľkých prekrývajúcich sa kategórií:

  • Statické / dynamické písanie. Statický je definovaný skutočnosťou, že konečné typy premenných a funkcií sú nastavené v čase kompilácie. Títo. už si kompilátor je 100% istý, ktorý typ je kde. Pri dynamickom písaní sa všetky typy zisťujú za behu.

    Príklady:
    Statický: C, Java, C #;
    Dynamické: Python, JavaScript, Ruby.

  • Silné / slabé písanie (niekedy sa tiež hovorí, že je silné / slabé). Silné písanie sa vyznačuje tým, že jazyk neumožňuje miešanie rôznych typov vo výrazoch a nevykonáva automatické implicitné prevody, napríklad nemôžete odčítať množinu od reťazca. Slabo napísané jazyky vykonávajú mnoho implicitných konverzií automaticky, aj keď môže dôjsť k strate presnosti alebo nejednoznačnosti.

    Príklady:
    Silné: Java, Python, Haskell, Lisp;
    Slabé: C, JavaScript, Visual Basic, PHP.

  • Explicitné / implicitné písanie. Explicitne napísané jazyky sa líšia v tom, že typ nových premenných / funkcií / ich argumentov musí byť špecifikovaný výslovne. Preto jazyky s implicitným typovaním posúvajú túto úlohu na prekladač / tlmočník.

    Príklady:
    Explicitné: C ++, D, C #
    Implicitné: PHP, Lua, JavaScript

Je tiež potrebné poznamenať, že všetky tieto kategórie sa prekrývajú, napríklad C má statické slabé explicitné písanie a Python má dynamické silné implicitné písanie.

Neexistujú však žiadne jazyky so statickým a dynamickým písaním súčasne. Hoci bežím dopredu, poviem, že tu ležím - skutočne existujú, ale o tom neskôr.

Podrobná verzia

Ak sa vám skrátená verzia nezdala dostačujúca, dobre. Niet divu, že som napísal podrobne? Hlavná vec je, že do krátkej verzie bolo jednoducho nemožné zmestiť všetky užitočné a zaujímavé informácie a podrobná informácia by bola pravdepodobne príliš dlhá na to, aby si ju každý prečítal bez namáhania.

Beztypové písanie

V programovacích jazykoch bez jazyka sú všetky entity považované za jednoducho sekvencie bitov rôznych dĺžok.

Beztypové písanie je zvyčajne vlastné jazykom nízkej úrovne (montážny jazyk, Forth) a ezoterike (Brainfuck, HQ9, Piet). Spolu so svojimi nevýhodami má však aj niekoľko výhod.

Výhody
  • Umožňuje písanie na extrémne nízkej úrovni a prekladač / tlmočník nebude zasahovať do žiadnej kontroly typu. Môžete slobodne vykonávať akékoľvek operácie s akýmkoľvek druhom údajov.
  • Výsledný kód je zvyčajne efektívnejší.
  • Transparentnosť pokynov. So znalosťou jazyka spravidla nie je pochýb o tom, že ten alebo onen kód je.
nevýhody
  • Zložitosť. Často je potrebné reprezentovať komplexné hodnoty, ako sú zoznamy, reťazce alebo štruktúry. To môže byť nepohodlné.
  • Nedostatok kontrol. Akékoľvek nezmyselné akcie, ako napríklad odčítanie ukazovateľa na poli od symbolu, sa budú považovať za úplne normálne, čo je plné jemných chýb.
  • Nízka úroveň abstrakcie. Práca s akýmkoľvek komplexným dátovým typom sa nelíši od práce s číslami, čo samozrejme spôsobí mnoho ťažkostí.
Silné beztypové písanie?

Áno, to existuje. Napríklad v montážnom jazyku (pre architektúru x86 / x86-64, iné nepoznám) nemôžete zostaviť program, ak sa pokúsite načítať údaje z registra rax (64 bitov) do registra cx (16 bitov) ).

mov cx, eax; chyba času montáže

Ukazuje sa teda, že v assembleri stále existuje písanie? Verím, že tieto kontroly nestačia. A váš názor, samozrejme, závisí len od vás.

Statické verzus dynamické písanie

Hlavnou vecou, ​​ktorá odlišuje statické písanie od dynamického, je to, že všetky kontroly typu sa vykonávajú v čase kompilácie, nie v čase spustenia.

Niektorí ľudia si môžu myslieť, že statické písanie je príliš obmedzené (v skutočnosti je, ale pomocou niektorých techník sa ho už dávno zbavilo). Pre niektorých sú dynamicky písané jazyky hra s ohňom, ale aké sú vlastnosti, ktorými sa odlišujú? Majú oba druhy šancu existencie? Ak nie, prečo existuje mnoho staticky aj dynamicky typovaných jazykov?

Poďme na to.

Výhody statického písania
  • Kontroly typu sa vykonávajú iba raz, v čase kompilácie. To znamená, že nebudeme musieť neustále zisťovať, či sa pokúšame rozdeliť číslo reťazcom (a buď hodiť chybu alebo vykonať konverziu).
  • Rýchlosť vykonávania. Z predchádzajúceho bodu je zrejmé, že staticky napísané jazyky sú takmer vždy rýchlejšie ako dynamicky písané.
  • Za určitých dodatočných podmienok vám to umožní odhaliť potenciálne chyby už vo fáze kompilácie.
Výhody dynamického písania
  • Jednoduchosť vytvárania univerzálnych zbierok je zväzkom všetkého a všetkého (taká potreba vzniká len zriedka, ale keď nastane dynamické písanie, pomôže).
  • Pohodlie popisu generalizovaných algoritmov (napríklad triedenie poľa, ktoré bude fungovať nielen v zozname celých čísel, ale aj v zozname skutočných čísel a dokonca aj v zozname reťazcov).
  • Ľahko sa učí - dynamicky písané jazyky sú zvyčajne veľmi dobré na začiatku programovania.

Zovšeobecnené programovanie

Dobre, najdôležitejším argumentom pre dynamické písanie je jednoduchosť popisu generických algoritmov. Predstavme si problém - potrebujeme funkciu na vyhľadávanie vo viacerých poliach (alebo zoznamoch) - pole celých čísel, pole reals a pole znakov.

Ako to ideme riesit? Vyriešme to v 3 rôznych jazykoch: v jednom s dynamickým písaním a v dvoch so statickým písaním.

Algoritmus vyhľadávania, ktorý použijem, je jedným z najjednoduchších - hrubou silou. Funkcia prijme požadovaný prvok, samotné pole (alebo zoznam) a vráti index prvku, alebo, ak sa prvok nenájde, (-1).

Dynamické riešenie (Python):

Def find (required_element, list): for (index, element) in enumerate (list): if element == required_element: return index return (-1)

Ako vidíte, všetko je jednoduché a neexistujú žiadne problémy s tým, že zoznam môže obsahovať aspoň čísla, dokonca aj zoznamy, aj keď neexistujú žiadne ďalšie polia. Veľmi dobre. Pokračujme a vyriešime rovnaký problém v C!

Statický roztok (C):

Nepodpísané int find_int (int required_element, int array, unsigned int size) (pre (unsigned int i = 0; i< size; ++i) if (required_element == array[i]) return i; return (-1); } unsigned int find_float(float required_element, float array, unsigned int size) { for (unsigned int i = 0; i < size; ++i) if (required_element == array[i]) return i; return (-1); } unsigned int find_char(char required_element, char array, unsigned int size) { for (unsigned int i = 0; i < size; ++i) if (required_element == array[i]) return i; return (-1); }

Každá funkcia je individuálne podobná verzii Python, ale prečo existujú tri? Naozaj statické programovanie zlyhalo?

Áno a nie. Existuje niekoľko programovacích techník, z ktorých jednu teraz zvážime. Hovorí sa mu generické programovanie a jazyk C ++ to celkom dobre podporuje. Pozrime sa na novú verziu:

Statické riešenie (generické programovanie, C ++):

Predloha nepodpísané int nájsť (T required_element, std :: vector pole) (pre (bez znamienka int i = 0; i< array.size(); ++i) if (required_element == array[i]) return i; return (-1); }

Dobre! Nevyzerá to oveľa komplikovanejšie ako verzia Python a nemusí veľa písať. Okrem toho sme dostali implementáciu pre všetky polia, nielen pre riešenie problémov potrebné tri!

Zdá sa, že táto verzia je presne to, čo potrebujete - získavame výhody statického písania a niektoré výhody dynamického písania.

Je skvelé, že je to dokonca možné, ale mohlo to byť ešte lepšie. Po prvé, generické programovanie môže byť pohodlnejšie a krásnejšie (napríklad v jazyku Haskell). Za druhé, okrem generického programovania môžete použiť aj polymorfizmus (výsledok bude horší), preťaženie funkcií (podobne) alebo makrá.

Statická dynamika

Malo by sa tiež spomenúť, že mnoho statických jazykov umožňuje dynamické písanie, napríklad:

  • C # podporuje dynamický pseudo-typ.
  • F # podporuje syntaktický cukor vo forme? Operátora, ktorý je možné použiť na simuláciu dynamického písania.
  • Haskell - dynamické písanie zabezpečuje modul Data.Dynamic.
  • Delphi - prostredníctvom špeciálneho typu Variant.

Niektoré dynamicky písané jazyky vám tiež umožňujú využiť výhody statického písania:

  • Bežné deklarácie typu Lisp.
  • Perl - od verzie 5.6 skôr obmedzený.

Silné a slabé písanie

Silne napísané jazyky neumožňujú miešať vo výrazoch entity rôznych typov a nevykonávajú žiadne automatické prevody. Hovorí sa im aj „silne napísané jazyky“. Anglický výraz pre toto je silné písanie.

Slabo napísané jazyky, naopak, robia všetko pre to, aby programátor zmiešal rôzne typy v jednom výraze a samotný kompilátor privedie všetko k jednému typu. Hovorí sa im aj „voľne písané jazyky“. Anglický výraz pre to znamená slabé písanie.

Slabé písanie je často zamieňané s dynamickým typovaním, čo je úplne nesprávne. Dynamicky písaný jazyk môže byť napísaný slabo aj silne.

Málokto však pripisuje dôležitosť prísnosti písania. Často sa tvrdí, že ak je jazyk staticky napísaný, môžete zachytiť veľa potenciálnych chýb pri kompilácii. Klamú vám!

Jazyk musí mať zároveň silné písanie. Skutočne, ak kompilátor namiesto nahlásenia chyby jednoducho pridá reťazec k číslu, alebo ešte horšie, odčíta iné od jedného poľa, na čo nám je dobré, že všetky „kontroly typu“ sú v čase kompilácie? To je pravda - slabé statické písanie je ešte horšie ako silné dynamické písanie! (To je môj názor)

Nemá teda slabé písanie vôbec žiadne výhody? Môže to vyzerať takto, ale hoci som horlivým zástancom silného písania, musím súhlasiť s tým, že slabý má aj výhody.

Chcete vedieť ktoré?

Výhody silného písania
  • Spoľahlivosť - namiesto nesprávneho správania dostanete výnimku alebo chybu kompilácie.
  • Rýchlosť- namiesto skrytých konverzií, ktoré môžu byť pri drahom písaní poriadne drahé, ich musíte napísať vyslovene, vďaka čomu programátor aspoň vie, že tento kúsok kódu môže byť pomalý.
  • Pochopenie práce programu - opäť, namiesto implicitnej konverzie typu, programátor píše všetko sám, čo znamená, že zhruba chápe, že porovnanie reťazca a čísla sa nedeje samé a nie mágiou.
  • Istota - keď píšete konverzie ručne, presne viete, na čo a na čo konvertujete. Tiež vždy pochopíte, že takéto transformácie môžu viesť k strate presnosti a k ​​nesprávnym výsledkom.
Výhody slabého písania
  • Jednoduché použitie zmiešaných výrazov (napríklad z celých čísel a reálnych čísel).
  • Abstrakcia od písania a sústredenie sa na úlohu.
  • Stručnosť záznamu.

Dobre, prišli sme na to, ukazuje sa, že slabé písanie má aj výhody! Existujú spôsoby, ako preniesť výhody slabého písania na silné písanie?

Ukázalo sa, že sú dokonca dve.

Implicitná konverzia typu, v jednoznačných situáciách a bez straty údajov

Uh ... Celkom dlhý bod. Dovoľte mi to skrátiť na „obmedzenú implicitnú konverziu“ Čo teda znamená jednoznačná situácia a strata údajov?

Jednoznačná situácia je transformácia alebo operácia, v ktorej je entita okamžite zrozumiteľná. Napríklad sčítanie dvoch čísel je jednoznačná situácia. A prevádzanie čísla na pole nie je (možno sa vytvorí pole jedného prvku, možno pole s takouto dĺžkou, štandardne vyplnené prvkami alebo sa možno číslo skonvertuje na reťazec a potom na pole znakov).

Strata údajov je ešte jednoduchšia. Ak konvertujeme skutočné číslo 3,5 na celé číslo, prídeme o časť údajov (v skutočnosti je táto operácia tiež nejednoznačná - ako sa bude zaokrúhľovať? Hore? Dole? Vyradenie zlomkovej časti?).

Nejednoznačné transformácie a stratové transformácie sú veľmi, veľmi zlé. V programovaní nie je nič horšie ako toto.

Ak mi neveríte, naučte sa jazyk PL / I, alebo dokonca len hľadajte jeho špecifikáciu. Má pravidlá pre prevod medzi VŠETKÝMI typmi údajov! Je to jednoducho peklo!

Dobre, spomeňme si na obmedzenú implicitnú konverziu. Existujú také jazyky? Áno, napríklad v Pascale môžete previesť celé číslo na skutočné číslo, ale nie naopak. Podobné mechanizmy existujú aj v jazykoch C #, Groovy a Common Lisp.

Dobre, povedal som, že stále existuje spôsob, ako získať niekoľko výhod slabého písania v silnom jazyku. A áno, je a nazýva sa konštruktívny polymorfizmus.

Vysvetlím to na príklade nádherného jazyka Haskell.

Polymorfné konštruktéry sú výsledkom pozorovania, že pri použití numerických literálov sú najčastejšie potrebné bezpečné implicitné konverzie.

Napríklad vo výraze pi + 1 nechcete písať pi + 1,0 alebo pi + float (1). Chcel by som napísať iba pi + 1!

A to sa robí v Haskelli, pretože doslovná 1 nemá žiadny konkrétny typ. Nie je ani celý, ani skutočný, ani zložitý. Je to len číslo!

Výsledkom je, že pri písaní súčtu jednoduchej funkcie xy, vynásobením všetkých čísel od x do y (s prírastkom 1), dostaneme niekoľko verzií naraz - súčet pre celé čísla, súčet pre reálne, súčet pre racionálne, súčet pre komplexné čísla , a dokonca súčet pre všetky tie číselné typy, ktoré ste sami definovali.

Táto technika samozrejme šetrí iba pri použití zmiešaných výrazov s číselnými literálmi, a to je len špička ľadovca.

Môžeme teda povedať, že najlepším riešením by bolo balansovať na pokraji, medzi silným a slabým písaním. Zatiaľ však žiadny jazyk nie je v dokonalej rovnováhe, takže sa skôr prikláňam k silne napísaným jazykom (ako je Haskell, Java, C #, Python), než k jazykom slabo napísaným (ako C, JavaScript, Lua, PHP) .

Explicitné a implicitné písanie

Výslovne zadaný jazyk predpokladá, že programátor musí špecifikovať typy všetkých premenných a funkcií, ktoré deklaruje. Anglický výraz pre toto je explicitné písanie.

Implicitne napísaný jazyk vás naopak pozýva na to, aby ste zabudli na typy a preniesli úlohu odvodenia typu na prekladač alebo tlmočník. Anglický výraz pre toto je implicitné písanie.

Najprv sa môžete rozhodnúť, že implicitné písanie je ekvivalentom dynamického písania a explicitné písanie je ekvivalentné statickému, ale neskôr uvidíme, že to tak nie je.

Existujú výhody pre každý typ a opäť existujú ich kombinácie a existujú jazyky, ktoré podporujú obe metódy?

Výhody explicitného písania
  • Prítomnosť podpisu pre každú funkciu (napríklad int add (int, int)) vám umožňuje ľahko určiť, čo funkcia robí.
  • Programátor ihneď napíše, aký typ hodnoty je možné uložiť do konkrétnej premennej, čím odpadá potreba zapamätať si to.
Výhody implicitného písania
  • Skratka pre def add (x, y) je zreteľne kratšia ako int add (int x, int y).
  • Odolnosť voči zmenám. Ak napríklad dočasná premenná vo funkcii bola rovnakého typu ako vstupný argument, potom v výslovne napísanom jazyku, keď sa zmení typ vstupného argumentu, bude potrebné zmeniť aj typ dočasnej premennej.

Dobre, vidíte, že oba prístupy majú klady a zápory (kto čakal niečo iné?), Poďme teda hľadať spôsoby, ako tieto dva skombinovať!

Explicitné písanie podľa výberu

Existujú jazyky s implicitným typovaním a s možnosťou špecifikovať typ hodnôt, ak je to potrebné. Prekladač automaticky odvodí skutočný typ výrazu. Jeden z týchto jazykov je Haskell, dovoľte mi pre jednoduchosť uviesť jednoduchý príklad:

Bez explicitnej indikácie typu add (x, y) = x + y - Explicitná indikácia typu add :: (Integer, Integer) -> Integer add (x, y) = x + y

Poznámka: Zámerne som použil neskúsenú funkciu a tiež som úmyselne napísal súkromný podpis namiesto všeobecnejšieho doplnku :: (Číslo a) -> a -> a -> a, pretože chcel ukázať myšlienku bez vysvetlenia syntaxe Haskella „a.

HM. Ako vidíme, je veľmi pekný a krátky. Záznam funkcie trvá iba 18 znakov na jednom riadku vrátane medzier!

Automatické odvodenie typu je však ošemetná vec a dokonca aj v chladnom jazyku, akým je Haskell, niekedy zlyhá. (ako príklad možno uviesť obmedzenie monomorfizmu)

Existujú jazyky, ktoré sú predvolene napísané a ktoré sú implicitne napísané podľa potreby? Kon
navždy.

Voliteľné implicitné písanie

Nový jazykový štandard C ++ s názvom C ++ 11 (predtým C ++ 0x) zaviedol kľúčové slovo auto, aby kompilátor vyvodil typ na základe kontextu:

Porovnajme: // Ručná špecifikácia nepodpísaného typu int a = 5; bez znamienka int b = a + 3; // Automatické odvodenie nepodpísaného typu int a = 5; auto b = a + 3;

Nie zlé. Rekord sa ale veľmi nezmenšil. Pozrime sa na príklad s iterátormi (ak nerozumiete, nebojte sa, hlavnou vecou je poznamenať, že záznam je vďaka automatickému výstupu výrazne znížený):

// Ručná špecifikácia typu std :: vector vec = randomVector (30); for (std :: vector :: const_iterator it = vec.cbegin (); ...) (...) // Automatické odvodenie typu auto vec = randomVector (tridsať); pre (auto it = vec.cbegin (); ...) (...)

Wow! Toto je skratka. Dobre, ale môžete urobiť niečo v duchu Haskella, kde bude typ návratu závisieť od typov argumentov?

Odpoveď je opäť áno, vďaka kľúčovému slovu decltype v kombinácii s automatom:

// Ručná špecifikácia typu int delenie (int x, int y) (...) // Automatické delenie typu automatické delenie (int x, int y) -> typ deklinácie (x / y) (...)

Môže sa zdať, že je tento zápis veľmi dobrý, ale v kombinácii s generickým programovaním (šablóny / generiká), implicitné písanie alebo automatické odvodenie typu robí zázraky.

Niektoré programovacie jazyky podľa tejto klasifikácie

Dám krátky zoznam obľúbených jazykov a napíšem, ako sú zaradené do jednotlivých kategórií „písania na stroji“.

JavaScript - Dynamický / Slabý / Implicitný Ruby - Dynamický / Silný / Implicitný Python - Dynamický / Silný / Implicitný Java - Statický / Silný / Explicitný PHP - Dynamický / Slabý / Implicitný C - Statický / Slabý / Explicitný C ++ - Statický / Semi- Silné / Explicitné Perl - Dynamické / Slabé / Implicitné Cieľ - C - Statické / Slabé / Explicitné C # - Statické / Silné / Explicitné Haskell - Statické / Silné / Implicitné Common Lisp - Dynamické / Silné / Implicitné

Možno som sa niekde mýlil, najmä s CL, PHP a Obj -C, ak máte na nejaký jazyk iný názor - napíšte do komentárov.

Záver

OK. Čoskoro bude svetlo a mám pocit, že k písaniu nie je viac čo povedať. Ach ako? Je téma bez dna? Zostalo veľa nevypovedaného? Podeľte sa o užitočné informácie v komentároch.