Računalniki Windows Internet

Izobraževalni program o tipkanju v programskih jezikih. Kateri koli jezik – zakaj je potrebno dinamično tipkanje? Močno in šibko tipkanje

Vse je zelo preprosto. To je kot razlika med hotelom in zasebnim stanovanjem.

V stanovanju živijo samo tisti, ki so tam prijavljeni. Če v njem živi, ​​recimo, družina Sidorov, potem družina Pupkin, za življenje, tam ne more živeti. Hkrati lahko Petya Sidorov živi v tem stanovanju, potem se Grisha Sidorov lahko preseli tja (včasih lahko celo živita tam hkrati - to je niz). To je statično tipkanje.

Družina Sidorov lahko živi v hotelu naenkrat. Tam se jim sploh ni treba vedno prijaviti. Potem bodo od tam odšli, Pupkinovi pa se bodo tja preselili. In potem Kuznecovi. In potem še nekdo drug. To je dinamično tipkanje.

Če se vrnemo k programiranju, potem prvi primer (statično tipkanje) najdemo recimo v jezikih C, C++, C#, Java in drugih. Preden spremenljivki prvič dodelite vrednost, morate povedati, kaj boste tja shranili: cela števila, števila s plavajočo vejico, nize itd. ( Sidorovi bodo živeli v tem stanovanju). Po drugi strani pa dinamično tipkanje tega ne zahteva. Ko dodelite vrednost, spremenljivki hkrati dodelite njen tip ( V tej hotelski sobi zdaj živi Vasya Pupkin iz družine Pupkin). To najdemo v jezikih, kot so PHP, Python in JavaScript.

Oba pristopa imata svoje prednosti in slabosti. Kateri je boljši ali slabši, je odvisno od težav, ki jih rešujemo. Več si lahko podrobneje preberete recimo na Wikipediji.

Pri statičnem tipkanju točno poznate vrsto spremenljivke v času pisanja programa in razvoja algoritma in to upoštevate. tiste. če ste rekli, da je spremenljivka G štiribajtno nepredznačeno celo število, potem bo v algoritmu vedno štiribajtno nepredznačeno celo število (če kaj, potem ga morate eksplicitno pretvoriti ali vedeti, kako ga prevajalec pretvori v določen vrsta situacij, vendar je v glavnem, če pride do neujemanja tipa, napaka v algoritmu in prevajalnik vas bo vsaj opozoril), pri statičnem nizu "Vasja norec" ne morete dati v številko in dodatna preverjanja pred uporabo spremenljivke za ugotavljanje "ali je tam številka" niso potrebna, vso pravilnost podatkov izvedete ob njihovem vnosu v program ali kot zahteva sam algoritem.

pri dinamičnem tipkanju vam tip iste spremenljivke praviloma ni znan in se lahko spremeni že med izvajanjem programa in to upoštevate, vas nihče ne bo opozoril na morebitno napako v algoritmu zaradi tipskega neujemanja (pri razvoju algoritma ste predvidevali, da je G celo število, uporabnik pa je vnesel, recimo, število s plavajočo vejico, ali še huje, niz, ali pa je recimo po aritmetični operaciji namesto celega števila prišlo do števila s plavajočo vejico , v naslednjem koraku pa boste poskusili uporabiti bitne operacije ...), po drugi strani pa vam ni treba skrbeti za veliko malenkosti.

Ta članek pojasnjuje razlike med statično tipkanimi in dinamično tipkanimi jeziki, preučuje koncepta "močnega" in "šibkega" tipkanja ter primerja moč sistemov tipkanja v različnih jezikih. V zadnjem času je prišlo do jasnega premika v smeri strožjih in močnejših sistemov tipkanja v programiranju, zato je pomembno razumeti, o čem govorimo, ko govorimo o vrstah in tipkanju.



Vrsta je zbirka možnih vrednosti. Celo število ima lahko vrednosti 0, 1, 2, 3 in tako naprej. Logična vrednost je lahko resnična ali napačna. Izmislite si lahko svojo lastno vrsto, na primer vrsto »High Five«, v kateri sta možni vrednosti »visoko« in »5« in nič drugega. To ni niz ali številka, je nova, ločena vrsta.


Statično tipizirani jeziki omejujejo vrste spremenljivk: programski jezik lahko na primer ve, da je x celo število. V tem primeru je programerju prepovedano narediti x = true, to bo napačna koda. Prevajalnik ga bo zavrnil prevesti, zato kode sploh ne bomo mogli zagnati. Drug statično tipiziran jezik ima lahko drugačne izrazne zmožnosti in noben od priljubljenih tipskih sistemov ne more izraziti našega tipa HighFive (vendar mnogi lahko izrazijo druge, bolj sofisticirane ideje).


Dinamično tipizirani jeziki označujejo vrednosti s tipi: jezik ve, da je 1 celo število, 2 je celo število, ne more pa vedeti, da spremenljivka x vedno vsebuje celo število.


Jezikovno izvajalno okolje preveri te oznake ob različnih časovnih točkah. Če poskušamo sešteti dve vrednosti, lahko preveri, ali sta številki, nizu ali nizu. Nato bo dodal te vrednosti, jih zlepil skupaj ali izdal napako, odvisno od vrste.

Statično tipkani jeziki

Statični jeziki preverijo vrste v programu med prevajanjem, preden se program zažene. Vsak program, v katerem tipi kršijo pravila jezika, se šteje za nepravilnega. Na primer, večina statičnih jezikov bo zavrnila izraz "a" + 1 (C je izjema od tega pravila). Prevajalnik ve, da je "a" niz in je 1 celo število in da + deluje le, če sta leva in desna stran istega tipa. Torej mu ni treba zagnati programa, da ugotovi, da obstaja težava. Vsak izraz v statično tipiziranem jeziku je posebne vrste, ki jo je mogoče določiti brez izvajanja kode.


Mnogi statično tipkani jeziki zahtevajo oznako tipa. Javna funkcija public int add(int x, int y) sprejme dve celi števili in vrne tretje celo število. Drugi statično tipkani jeziki lahko samodejno sklepajo o vrsti. Ista funkcija seštevanja v Haskell-u izgleda takole: seštej x y = x + y. Jeziku ne povemo tipov, vendar jih lahko ugotovi sam, ker ve, da + deluje samo na številih, zato morata biti x in y števili, zato funkcija dodajanja vzame dve števili kot argumenta.


To ne zmanjša "statične" narave sistema tipov. Haskellov tipski sistem je znan po tem, da je statičen, strog in zmogljiv, in Haskell je pred Javo na vseh teh frontah.

Dinamično tipkani jeziki

Dinamično vtipkani jeziki ne zahtevajo, da se tip določi, vendar ga sami ne definirajo. Vrste spremenljivk so neznane, dokler nimajo določenih vrednosti ob zagonu. Na primer funkcija v Pythonu


def f(x, y): vrni x + y

lahko sešteje dve celi števili, združuje nize, sezname in tako naprej, in ne moremo razumeti, kaj točno se dogaja, dokler ne zaženemo programa. Možno je, da bo funkcija f na neki točki poklicana z dvema nizoma, drugič pa z dvema številkama. V tem primeru bosta x in y vsebovala vrednosti različnih vrst ob različnih časih. Zato velja, da imajo vrednosti v dinamičnih jezikih tip, spremenljivke in funkcije pa ne. Vrednost 1 je vsekakor celo število, x in y pa sta lahko karkoli.

Primerjava

Večina dinamičnih jezikov bo povzročila napako, če so tipi uporabljeni nepravilno (JavaScript je opazna izjema; poskuša vrniti vrednost za kateri koli izraz, tudi če ni smiseln). Pri uporabi dinamično tipkanih jezikov lahko v produkcijskem okolju pride celo do preproste napake, kot je "a" + 1. Statični jeziki preprečujejo takšne napake, seveda pa je stopnja preprečevanja odvisna od moči sistema tipov.


Statični in dinamični jeziki so zgrajeni na bistveno različnih idejah o pravilnosti programa. V dinamičnem jeziku je "a" + 1 veljaven program: koda se bo zagnala in v izvajalnem okolju se bo pojavila napaka. Vendar pa je v večini statično tipkanih jezikov izraz "a" + 1 ni program: Ne bo se prevedel in ne bo deloval. To je napačna koda, tako kot niz naključnih znakov!&%^@*&%^@* je napačna koda. Ta dodatni koncept pravilnosti in nepravilnosti nima ekvivalenta v dinamičnih jezikih.

Močno in šibko tipkanje

Pojma "močan" in "šibek" sta zelo dvoumna. Tukaj je nekaj primerov njihove uporabe:

    Včasih "močan" pomeni "statičen".
    Preprosto je, vendar je bolje uporabiti izraz "statičen", ker ga večina ljudi uporablja in razume.

    Včasih "močan" pomeni "ne izvaja implicitne pretvorbe tipa".
    Na primer, JavaScript vam omogoča pisanje "a" + 1, kar lahko imenujemo "šibko tipkanje". Toda skoraj vsi jeziki zagotavljajo določeno raven implicitne pretvorbe, ki vam omogoča samodejno pretvorbo iz celih števil v števila s plavajočo vejico, kot je 1 + 1,1. V resnici večina ljudi uporablja besedo "močan" za določitev meje med sprejemljivo in nesprejemljivo konverzijo. Splošno sprejetih meja ni, vse so nenatančne in odvisne od mnenja posamezne osebe.

    Včasih "močan" pomeni, da je nemogoče zaobiti stroga pravila tipkanja v jeziku.

  • Včasih "močan" pomeni varen za spomin.
    C je primer jezika, ki ni varen glede pomnilnika. Če je xs niz štirih števil, potem bo C z veseljem izvedel xs ali xs in vrnil neko vrednost iz pomnilnika takoj za xs.

Ustavimo se. Evo, kako nekateri jeziki izpolnjujejo te definicije. Kot lahko vidite, je samo Haskell dosledno "močan" v vseh pogledih. Večina jezikov ni tako jasnih.



(»Kdaj kot« v stolpcu »Implicitne konverzije« pomeni, da je delitev med močnimi in šibkimi odvisna od tega, katere konverzije štejemo za sprejemljive).


Pogosto se izraza "močan" in "šibek" nanašata na nejasno kombinacijo različnih zgornjih definicij in drugih, ki tukaj niso prikazane. Zaradi vse te zmede sta besedi "močan" in "šibek" skoraj brez pomena. Ko želite uporabiti te izraze, je bolje opisati, kaj točno je mišljeno. Lahko bi na primer rekli, da "JavaScript vrne vrednost, ko je dodan niz s številko, Python pa vrne napako." V tem primeru ne bomo izgubljali energije, da bi se dogovorili o večpomenskih pomenih besede »močan«. Ali še huje: na koncu bomo imeli nerazrešene nesporazume zaradi terminologije.


Pojma »močan« in »šibek« na internetu so največkrat nejasna in slabo opredeljena mnenja določenih posameznikov. Uporabljajo se, da jezik imenujejo "slab" ali "dober", to mnenje pa se spremeni v tehnični žargon.



Strong Typing: Sistem tipkov, ki mi je všeč in mi je všeč.

Slabo tipkanje: sistem tipkanja, ki me moti ali mi ni všeč.

Postopno tipkanje

Ali je mogoče dinamičnim jezikom dodati statične tipe? V nekaterih primerih - da. V drugih je težko ali nemogoče. Najbolj očitna težava so eval in druge podobne lastnosti dinamičnih jezikov. Izvajanje 1 + eval("2") v Pythonu prinese 3. Toda kaj prinese 1 + eval(read_from_the_network())? Odvisno od tega, kaj je na spletu v času izvedbe. Če dobimo število, potem je izraz pravilen. Če je niz, potem ne. Pred zagonom ni mogoče vedeti, zato ni mogoče statično razčleniti vrste.


Nezadovoljiva rešitev v praksi je nastavitev izraza eval() na tip Any, ki je podoben Object v nekaterih objektno usmerjenih programskih jezikih ali vmesniku() v Go: to je tip, ki ga lahko zadovolji katera koli vrednost.


Vrednosti tipa Any so neomejene, zato zmožnost sistema tipa, da nam pomaga pri eval kodi, izgine. Jeziki, ki imajo sistem eval in tipski sistem, se morajo odpovedati tipski varnosti, kadar koli je uporabljen eval.


Nekateri jeziki imajo neobvezno ali postopno tipkanje: privzeto so dinamični, vendar omogočajo dodajanje nekaterih statičnih opomb. Python je nedavno dodal izbirne tipe; TypeScript je nadnabor JavaScripta, ki ima izbirne vrste; Flow izvaja statično analizo dobre stare kode JavaScript.


Ti jeziki zagotavljajo nekatere prednosti statičnega tipkanja, vendar nikoli ne bodo zagotovili absolutnih jamstev resnično statičnih jezikov. Nekatere funkcije bodo vnesene statično, nekatere pa dinamično. Programer se mora vedno zavedati razlike in biti pozoren nanjo.

Prevajanje statično tipizirane kode

Pri prevajanju statično vnesene kode se najprej preveri sintaksa, kot v vsakem prevajalniku. Nato se preverijo vrste. To pomeni, da se lahko statični jezik najprej pritoži zaradi ene sintaksne napake, potem ko jo popravi, pa se pritoži zaradi 100 tipkarskih napak. Popravek sintaksne napake ni ustvaril teh 100 tipkarskih napak. Prevajalnik preprosto ni mogel zaznati tipskih napak, dokler sintaksa ni bila popravljena.


Prevajalniki za statične jezike lahko običajno ustvarijo hitrejšo kodo kot prevajalniki za dinamične jezike. Na primer, če prevajalnik ve, da funkcija dodajanja sprejema cela števila, potem lahko uporabi izvorni ukaz ADD CPE-ja. Dinamični jezik bo med izvajanjem preveril vrsto in izbiral med različnimi funkcijami za dodajanje, odvisno od vrst (dodajanje celih števil ali plavajočih ali združevanje nizov ali morda seznamov?) ali se mora odločiti, da je prišlo do napake in se vrste ne ujemajo . Vsi ti pregledi zahtevajo čas. Dinamični jeziki uporabljajo različne trike za optimizacijo, kot je prevajanje JIT (pravočasno), kjer se koda znova prevede med izvajanjem, potem ko so pridobljene vse potrebne informacije o vrsti. Vendar se noben dinamični jezik ne more kosati s hitrostjo lepo napisane statične kode v jeziku, kot je Rust.

Argumenti za statične in dinamične tipe

Zagovorniki sistema statičnih tipov poudarjajo, da lahko brez sistema tipov preproste napake povzročijo težave v proizvodnji. To je seveda res. Vsakdo, ki je uporabljal dinamičen jezik, je to izkusil na lastni koži.


Zagovorniki dinamičnih jezikov poudarjajo, da se zdi, da je v takih jezikih lažje pisati kodo. To vsekakor velja za nekatere vrste kode, ki jo pišemo občasno, kot je koda eval. To je kontroverzna rešitev za redno delo in tukaj se je smiselno spomniti nejasne besede "enostavno". Rich Hickey je opravil odlično delo, ko je govoril o besedi "enostavno" in njeni povezavi z besedo "preprosto". Po ogledu tega poročila boste razumeli, da ni lahko pravilno uporabiti besede "enostavno". Pazite na "enostavno".


Prednosti in slabosti statičnih in dinamičnih sistemov tipkanja so še vedno slabo razumljene, vendar so vsekakor odvisne od jezika in specifičnega problema, ki ga rešujemo.


JavaScript poskuša nadaljevati, tudi če to pomeni nesmiselno pretvorbo (na primer "a" + 1, kar povzroči "a1"). Python po drugi strani poskuša biti konzervativen in pogosto vrne napake, kot v primeru "a" + 1 .


Obstajajo različni pristopi z različnimi stopnjami varnosti, vendar sta Python in JavaScript oba dinamično vtipkana jezika.



Haskell vam ne bo dovolil dodajanja celega števila in števila s plavajočo vrednostjo brez predhodne eksplicitne pretvorbe. C in Haskell sta kljub tako velikim razlikam statično tipkana.


Obstaja veliko različic dinamičnih in statičnih jezikov. Vsaka splošna izjava, kot je "statični jeziki so boljši od dinamičnih jezikov, ko gre za X", je skoraj zagotovljena neumnost. To morda drži v primeru določenih jezikov, vendar je potem bolje reči "Haskell je boljši od Pythona, ko gre za X."

Raznolikost sistemov statičnega tipkanja

Oglejmo si dva znana primera statično tipkanih jezikov: Go in Haskell. Sistem tipkanja Go nima generičnih tipov, tipov s "parametri" iz drugih tipov. Na primer, ustvarimo lahko lastno vrsto za sezname MyList, ki lahko shrani vse podatke, ki jih potrebujemo. Želimo, da bi lahko ustvarili MyList celih števil, MyList nizov in tako naprej, ne da bi spremenili izvorno kodo MyList. Prevajalnik mora paziti na tipkanje: če obstaja MyList celih števil in vanj pomotoma dodamo niz, mora prevajalnik zavrniti program.


Go je bil posebej zasnovan tako, da ne dovoli definiranja vrst, kot je MyList. Najboljše, kar lahko naredimo, je ustvariti MyList "praznih vmesnikov": MyList lahko vsebuje objekte, vendar prevajalnik preprosto ne pozna njihove vrste. Ko pridobimo objekte iz MyList, moramo prevajalniku povedati njihovo vrsto. Če rečemo "dobim niz", v resnici pa je vrednost število, potem bo prišlo do napake med izvajanjem, kot je to v primeru dinamičnih jezikov.


Go prav tako nima veliko drugih funkcij, ki jih najdemo v sodobnih statično tipkanih jezikih (ali celo nekaterih sistemih iz sedemdesetih let). Ustvarjalci programa Go so imeli svoje razloge za te odločitve, vendar se lahko mnenja zunanjih sodelavcev o tej zadevi včasih slišijo ostro.


Zdaj pa primerjajmo s Haskellom, ki ima zelo zmogljiv tipski sistem. Če nastavite vrsto na MyList, potem je vrsta »seznama številk« preprosto MyList Integer. Haskell nam bo preprečil nenamerno dodajanje niza na seznam in poskrbel, da elementa s seznama ne bomo vstavili v nizovno spremenljivko.


Haskell lahko izrazi veliko bolj zapletene ideje neposredno s tipi. Na primer, Num a => MyList a pomeni "Moj seznam vrednosti, ki pripadajo isti vrsti številk." Lahko bi bil seznam celih števil, lebdečih ali decimalnih mest s fiksno natančnostjo, vendar zagotovo nikoli ne bo seznam nizov, ki se preveri med prevajanjem.


Napišete lahko funkcijo dodajanja, ki deluje s katero koli številsko vrsto. Ta funkcija bo imela vrsto Num a => (a -> a -> a) . To pomeni:

  • a je lahko katera koli številska vrsta (Num a =>).
  • Funkcija sprejme dva argumenta tipa a in vrne tip a (a -> a -> a).

Zadnji primer. Če je tip funkcije String -> String, potem sprejme niz in vrne niz. Toda če je String -> IO String, potem naredi tudi nekaj V/I. To je lahko dostop do diska, dostop do omrežja, branje s terminala itd.


Če ima funkcija vrsto št IO, potem vemo, da ne izvaja nobenih V/I operacij. V spletni aplikaciji lahko na primer ugotovite, ali funkcija spreminja zbirko podatkov preprosto tako, da pogledate njeno vrsto. Tega ne zmorejo nobeni dinamični in skoraj nobeni statični jeziki. To je značilnost jezikov z najmočnejšimi sistemi tipkanja.


V večini jezikov bi se morali prebijati skozi funkcijo in vse funkcije, ki se kličejo od tam, in tako naprej, da bi poskušali najti nekaj, kar spremeni bazo podatkov. To je dolgočasen proces in zlahka dela napake. In sistem tipa Haskell lahko na to vprašanje odgovori preprosto in zanesljivo.


Primerjajte to moč z Go, ki ne more izraziti preproste ideje MyList, kaj šele "funkcije, ki sprejme dva argumenta, oba numerična in istega tipa, in ki opravlja V/I."


Pristop Go olajša pisanje orodij za programiranje Go (zlasti implementacija prevajalnika je lahko preprosta). Poleg tega se je treba naučiti manj konceptov. Kakšne so te prednosti v primerjavi s pomembnimi omejitvami, je subjektivno vprašanje. Vendar pa ni mogoče trditi, da se je Haskell težje naučiti kot Go in da je Haskellov sistem tipov veliko močnejši in da lahko Haskell prepreči veliko več vrst napak pri prevajanju.


Go in Haskell sta tako različna jezika, da je lahko združevanje v isti razred "statičnih jezikov" zavajajoče, čeprav je izraz uporabljen pravilno. Ko primerjamo praktične varnostne prednosti, je Go bližje dinamičnim jezikom kot Haskell.


Po drugi strani pa so nekateri dinamični jeziki varnejši od nekaterih statičnih jezikov. (Python na splošno velja za veliko bolj varnega kot C). Ko želite posplošiti statične ali dinamične jezike kot skupine, ne pozabite na ogromno število razlik med jeziki.

Konkretni primeri razlik v zmožnostih sistemov za tipkanje

Zmogljivejši sistemi za tipkanje lahko določijo omejitve na manjših ravneh. Tukaj je nekaj primerov, vendar se ne obremenjujte z njimi, če sintaksa ni jasna.


V Go lahko rečete "funkcija dodajanja vzame dve celi števili in vrne celo število":


func add(x int, y int) int ( return x + y )

V Haskellu lahko rečete "funkcija vzame kajštevilski tip in vrne število istega tipa":


f:: Num a => a -> a -> a seštej x y = x + y

V Idrisu lahko rečete "funkcija vzame dve celi števili in vrne celo število, vendar mora biti prvi argument manjši od drugega argumenta":


dodaj: (x: Nat) -> (y: Nat) -> (samodejno manjše: LT x y) -> Nat dodaj x y = x + y

Če poskusite poklicati funkcijo add 2 1, kjer je prvi argument večji od drugega, bo prevajalnik zavrnil program v času prevajanja. Nemogoče je napisati program, kjer je prvi argument večji od drugega. Redko kateri jezik ima to zmožnost. V večini jezikov se to preverjanje zgodi med izvajanjem: napisali bi nekaj takega, kot če je x >= y: dvigni SomeError() .


Ni Haskella, ki bi bil enakovreden tipu v zgornjem primeru Idris, in ni Go, ki bi bil enakovrednega primeru Haskell ali Idris. Posledično lahko Idris prepreči številne napake, ki jih Haskell ne more preprečiti, Haskell pa lahko prepreči številne napake, ki jih Go ne bo opazil. V obeh primerih so potrebne dodatne zmožnosti sistema za tipkanje, da postane jezik bolj zapleten.

Sistemi tipkanja nekaterih statičnih jezikov

Tukaj je približen seznam sistemov tipkanja nekaterih jezikov po naraščajoči moči. Ta seznam vam bo dal splošno predstavo o moči sistemov, ne obravnavajte ga kot absolutno resnico. Jeziki, zbrani v eni skupini, se lahko med seboj zelo razlikujejo. Vsak sistem tipkanja ima svoje posebnosti in večina jih je zelo zapletenih.

  • C (1972), Pojdi (2009): Ti sistemi sploh niso zmogljivi brez podpore za generične vrste. Tipa MyList, ki bi pomenil "seznam celih števil", "seznam nizov" itd., ni mogoče definirati. Namesto tega boste morali narediti "seznam nedoločenih vrednosti". Programer mora ročno sporočiti "to je seznam nizov" vsakič, ko je niz pridobljen s seznama, kar lahko povzroči napako pri izvajanju.
  • Java (1995), C# (2000): Oba jezika podpirata generične vrste, tako da bi lahko rekli MyList in dobite seznam nizov, ki jih prevajalnik pozna in lahko uveljavi pravila tipa. Elementi na seznamu bodo tipa String in prevajalnik bo vsilil pravila prevajanja kot običajno, zato so napake med izvajanjem manj verjetne.
  • Haskell (1990), Rust (2010), Swift (2014): Vsi ti jeziki imajo več naprednih funkcij, vključno z generičnimi tipi, algebraičnimi podatkovnimi tipi (ADT) in tipskimi razredi ali nečim podobnim (vrste razredov, lastnosti in protokoli). Rust in Swift sta bolj priljubljena kot Haskell in ju spodbujajo velike organizacije (Mozilla oziroma Apple).
  • Agda (2007), Idris (2011): Ti jeziki podpirajo odvisne tipe, kar vam omogoča ustvarjanje tipov, kot je "funkcija, ki sprejme dve celi števili x in y, kjer je y večji od x." Celo omejitev "y je večji od x" je vsiljena med prevajanjem. Ko se izvede, y nikoli ne bo manjši ali enak x, ne glede na to, kaj se zgodi. V teh jezikih je mogoče statično preveriti zelo subtilne, a pomembne lastnosti sistema. Zelo malo programerjev jih preučuje, vendar ti jeziki med njimi vzbujajo veliko navdušenje.

Obstaja jasen premik k zmogljivejšim tipkarskim sistemom, zlasti kar se meri s priljubljenostjo jezikov in ne zgolj dejstvom, da jeziki obstajajo. Pomembna izjema je Go, kar pojasnjuje, zakaj mnogi zagovorniki statičnih jezikov menijo, da je to korak nazaj.


Druga skupina (Java in C#) sta običajna jezika, zrela in široko uporabljena.


Tretja skupina je na pragu vstopa v mainstream z veliko podporo Mozille (Rust) in Apple (Swift).


Skupina štiri (Idris in Agda) je daleč od mainstreama, vendar se to lahko sčasoma spremeni. Jeziki tretje skupine so bili pred desetimi leti daleč od mainstreama.

Da bi čim bolj preprosto razložili dve popolnoma različni tehnologiji, začnimo od začetka. Prva stvar, s katero se programer sreča pri pisanju kode, je deklariranje spremenljivk. Morda boste opazili, da morate na primer v programskem jeziku C++ določiti vrsto spremenljivke. To pomeni, da če deklarirate spremenljivko x, potem morate dodati int - za shranjevanje celoštevilskih podatkov, float - za shranjevanje podatkov s plavajočo vejico, char - za znakovne podatke in druge razpoložljive vrste. Posledično C++ uporablja statično tipkanje, tako kot njegov predhodnik C.

Kako deluje statično tipkanje?

V trenutku deklariranja spremenljivke mora prevajalnik vedeti, katere funkcije in parametre lahko uporablja v zvezi z njo in katerih ne. Zato mora programer takoj jasno navesti vrsto spremenljivke. Upoštevajte tudi, da vrste spremenljivke ni mogoče spremeniti, medtem ko se koda izvaja. Lahko pa ustvarite svoj tip podatkov in ga uporabite v prihodnosti.

Poglejmo majhen primer. Ko inicializiramo spremenljivko x (int x;), podamo identifikator int - to je okrajšava za shranjevanje samo celih števil v območju od - 2 147 483 648 do 2 147 483 647. Tako prevajalnik ve, da lahko izvaja matematične vrednosti na tem spremenljivka - vsota, razlika, množenje in deljenje. Toda na primer funkcije strcat(), ki povezuje dve vrednosti char, ni mogoče uporabiti za x. Konec koncev, če odstranite omejitve in poskusite povezati dve int vrednosti s simbolno metodo, bo prišlo do napake.

Zakaj so bili potrebni dinamično tipkani jeziki?

Kljub nekaterim omejitvam ima statično tipkanje številne prednosti in ne povzroča veliko nelagodja pri pisanju algoritmov. Vendar pa lahko različni nameni zahtevajo bolj "ohlapna pravila" glede tipov podatkov.

Dober primer, ki ga lahko navedemo, je JavaScript. Ta programski jezik se običajno uporablja za vdelavo v ogrodje za pridobitev funkcionalnega dostopa do objektov. Zaradi te funkcije je pridobil veliko popularnost v spletnih tehnologijah, kjer je dinamično tipkanje idealno. Pisanje majhnih skriptov in makrov je zelo poenostavljeno. Obstaja tudi prednost ponovne uporabe spremenljivk. Vendar se ta možnost uporablja zelo redko zaradi možnih zmede in napak.

Katera vrsta tipkanja je boljša?

Razprava o tem, ali je dinamično tipkanje boljše od strogega tipkanja, se nadaljuje še danes. Običajno se pojavijo med visoko specializiranimi programerji. Seveda spletni razvijalci vsak dan v celoti izkoriščajo prednosti dinamičnega tipkanja za ustvarjanje visokokakovostne kode in končnega programskega izdelka. Hkrati sistemski programerji, ki razvijajo zapletene algoritme v programskih jezikih nizke ravni, običajno ne potrebujejo takšnih zmožnosti, zato jim je statično tipkanje povsem dovolj. Seveda obstajajo izjeme od pravil. Na primer, dinamično tipkanje je v celoti implementirano v Python.

Zato je treba samo na podlagi vhodnih parametrov določiti vodstvo določene tehnologije. Za razvoj lahkih in prilagodljivih ogrodij je boljše dinamično tipkanje, medtem ko je za ustvarjanje masivnih in kompleksnih arhitektur bolje uporabiti močno tipkanje.

Delitev na "močno" in "šibko" tipkanje

Med gradivi o programiranju v ruskem in angleškem jeziku lahko najdete izraz "močno" tipkanje. To ni ločen pojem, oziroma tak pojem v strokovnem leksikonu sploh ne obstaja. Čeprav si mnogi to poskušajo razlagati drugače. Pravzaprav je treba "močno" tipkanje razumeti kot tisto, ki vam ustreza in s katerim je najbolj udobno delati. In "šibek" sistem je za vas nepriročen in neučinkovit.

Funkcija dinamike

Verjetno ste opazili, da na stopnji pisanja kode prevajalnik analizira zapisane konstrukte in bo ustvaril napako, če se tipi podatkov ne ujemajo. Ampak ne JavaScript. Njegova edinstvenost je, da bo operacijo opravil v vsakem primeru. Tu je enostaven primer – dodati želimo simbol in številko, kar nima smisla: "x" + 1.

V statičnih jezikih ima ta operacija lahko različne posledice, odvisno od jezika samega. Toda v večini primerov ne bo dovoljeno niti prevesti, saj bo prevajalnik vrgel napako takoj po pisanju takšne konstrukcije. Enostavno se bo zdel napačno in imel bo popolnoma prav.

V dinamičnih jezikih je to operacijo mogoče izvesti, vendar bo v večini primerov do napake prišlo že v fazi izvajanja kode, saj prevajalnik ne analizira tipov podatkov v realnem času in ne more sprejemati odločitev o napakah na tem področju. JavaScript je edinstven v tem, da izvede to operacijo in na koncu dobi nabor neberljivih znakov. Za razliko od drugih jezikov, ki bodo preprosto prekinili program.

Ali so možne sosednje arhitekture?

Trenutno ne obstaja sorodna tehnologija, ki bi lahko hkrati podpirala statično in dinamično tipkanje v programskih jezikih. In z gotovostjo lahko trdimo, da se ne bo pojavil. Ker se arhitekture med seboj razlikujejo v temeljnih konceptih in jih ni mogoče uporabljati hkrati.

Toda kljub temu lahko v nekaterih jezikih spremenite tipkanje z dodatnimi okviri.

  • V programskem jeziku Delphi - podsistem Variant.
  • V programskem jeziku AliceML obstajajo dodatni paketi.
  • V programskem jeziku Haskell - knjižnica Data.Dynamic.

Kdaj je močno tipkanje res boljše od dinamičnega tipkanja?

Prednost strogega tipkanja pred dinamičnim lahko zagotovo navedete le, če ste programer začetnik. S tem se strinjajo absolutno vsi IT strokovnjaki. Ko se učite temeljnih in osnovnih veščin programiranja, je bolje uporabiti močno tipkanje, da pridobite nekaj discipline pri delu s spremenljivkami. Nato lahko po potrebi preklopite na dinamiko, vendar bodo delovne sposobnosti, pridobljene s strogim tipkanjem, igrale pomembno vlogo. Naučili se boste skrbno preverjati spremenljivke in upoštevati njihove vrste pri načrtovanju in pisanju kode.

Prednosti dinamičnega tipkanja

  • Zmanjša število znakov in vrstic kode zaradi neuporabnosti predhodne deklaracije spremenljivk in navedbe njihove vrste. Vrsta bo določena samodejno po dodelitvi vrednosti.
  • V majhnih blokih kode je vizualno in logično zaznavanje struktur poenostavljeno zaradi odsotnosti "dodatnih" deklaracijskih vrstic.
  • Dinamika pozitivno vpliva na hitrost prevajalnika, saj ne upošteva vrst in jih ne preverja za skladnost.
  • Poveča fleksibilnost in omogoča vsestransko oblikovanje. Na primer, ko ustvarjate metodo, ki mora komunicirati s podatkovno matriko, vam ni treba ustvariti ločenih funkcij za delo s številskimi, besedilnimi in drugimi vrstami matrik. Dovolj je, da napišete eno metodo in delovala bo s poljubnimi vrstami.
  • Poenostavlja izpis podatkov iz sistemov za upravljanje baz podatkov, zato se dinamično tipkanje aktivno uporablja pri razvoju spletnih aplikacij.

Izvedite več o statično tipkanih programskih jezikih

  • C++ je najbolj razširjen splošni programski jezik. Danes ima več velikih izdaj in veliko vojsko uporabnikov. Priljubljena je postala zaradi svoje prilagodljivosti, možnosti neomejene širitve in podpore različnim programskim paradigmam.

  • Java je programski jezik, ki uporablja objektno usmerjen pristop. Postala je zelo razširjena zaradi svoje večplatformske narave. Ko je prevedena, se koda interpretira v bajtno kodo, ki jo je mogoče izvesti v katerem koli operacijskem sistemu. Java in dinamično tipkanje nista združljiva, ker je jezik strogo tipiziran.

  • Haskell je tudi eden izmed priljubljenih jezikov, katerega kodo je mogoče integrirati v druge jezike in z njimi komunicirati. Toda kljub tej prilagodljivosti ima strogo tipkanje. Opremljen z velikim vgrajenim naborom vrst in možnostjo ustvarjanja lastnih.

Več o programskih jezikih z dinamičnim tipkanjem

  • Python je programski jezik, ki je bil ustvarjen predvsem zato, da programerju olajša delo. Ima številne funkcionalne izboljšave, zaradi katerih povečuje berljivost kode in njeno pisanje. To je bilo v veliki meri doseženo zahvaljujoč dinamičnemu tipkanju.

  • PHP je jezik za ustvarjanje skriptov. Široko se uporablja v spletnem razvoju, saj omogoča interakcijo z bazami podatkov za ustvarjanje interaktivnih dinamičnih spletnih strani. Dinamično tipkanje močno olajša delo z bazami podatkov.

  • JavaScript je zgoraj omenjeni programski jezik, ki je našel uporabo v spletnih tehnologijah za ustvarjanje spletnih skriptov, ki se izvajajo na strani odjemalca. Dinamično tipkanje se uporablja za lažje pisanje kode, ker je običajno razdeljena na majhne bloke.

Dinamični tip tipkanja – slabosti

  • Če je pri uporabi ali deklaraciji spremenljivk prišlo do tipkarske ali hude napake, je prevajalnik ne bo prikazal. Težave pa se bodo pojavile pri izvajanju programa.
  • Pri uporabi statičnega tipkanja so vse deklaracije spremenljivk in funkcij običajno postavljene v ločeno datoteko, kar vam omogoča enostavno ustvarjanje dokumentacije v prihodnosti ali celo uporabo same datoteke kot dokumentacije. Skladno s tem dinamično tipkanje ne dovoljuje uporabe takšne funkcije.

Povzemite

Statično in dinamično tipkanje se uporabljata za povsem različne namene. V nekaterih primerih razvijalci zasledujejo funkcionalne koristi, v drugih pa čisto osebne razloge. V vsakem primeru, da se sami odločite za vrsto tipkanja, jih morate natančno preučiti v praksi. V prihodnosti, ko ustvarjate nov projekt in izbirate tipkanje zanj, bo to igralo veliko vlogo in zagotovilo razumevanje učinkovite izbire.

Predpogoji

Stroga tipizacija pomeni izpolnjevanje naslednjih obveznih pogojev:

  1. Vsak podatkovni objekt (spremenljivka, konstanta, izraz) v jeziku ima vedno strogo definiran tip, ki je fiksen v času prevajanja programa (statično tipkanje) ali določen med izvajanjem (dinamično tipkanje).
  2. Spremenljivki je dovoljeno dodeliti samo vrednost, ki ima popolnoma enak podatkovni tip kot spremenljivka; enake omejitve veljajo za podajanje parametrov in vračanje rezultatov funkcije.
  3. Vsaka operacija zahteva parametre strogo definiranih vrst.
  4. Implicitna pretvorba tipa ni dovoljena (to pomeni, da prevajalec vsak poskus uporabe vrednosti tipa, ki ni deklariran za spremenljivko, parameter, funkcijo ali operacijo, obravnava kot sintaktično napako).

Če se strogo upoštevajo stroge zahteve glede tipkanja, so celo tipi podatkov, ki so enaki v sestavi vrednosti in dovoljenih operacijah, nezdružljivi. Če mora program dodeliti vrednost enega podatkovnega tipa spremenljivki drugega tipa, je to mogoče storiti, vendar le z izrecno uporabo posebne operacije pretvorbe tipa, ki je v takih primerih običajno del programskega jezika (čeprav lahko formalno ni ena, ampak jo zagotavljajo standardne knjižnice).

Tipkanje v programskih jezikih

Povezave

Poglej tudi


Fundacija Wikimedia. 2010.

Oglejte si, kaj je »Strong typing« v drugih slovarjih:

    Tip podatkov je temeljni koncept v teoriji programiranja. Podatkovni tip definira nabor vrednosti, nabor operacij, ki jih je mogoče uporabiti za te vrednosti, in po možnosti način izvajanja shranjevanja vrednosti in izvajanja operacij. Katera koli ... ... Wikipedia

    Tipkanje podatkov Varnost tipa Sklepanje o tipu Dinamično tipkanje Statično tipkanje Močno tipkanje Mehko tipkanje Odvisni tipi Duck tipkanje Glavni članek: Močno tipkanje Dinamično tipkanje je tehnika, ki je široko... ... Wikipedia

    Tipkanje podatkov Varnost tipa Sklepanje tipa Dinamično tipkanje Statično tipkanje Močno tipkanje Mehko tipkanje Odvisni tipi Duck tipkanje Glavni članek: Močno tipkanje Statično tipkanje je tehnika, ki je razširjena... ... Wikipedia

    Dinamično tipkanje je tehnika, ki se pogosto uporablja v programskih jezikih in specifikacijskih jezikih, pri kateri je spremenljivka povezana s tipom v trenutku dodeljevanja vrednosti in ne v trenutku deklaracije spremenljivke. Tako na različnih področjih ... Wikipedia

    Tipkanje podatkov Varnost tipa Sklepanje tipa Dinamično tipkanje Statično tipkanje Močno tipkanje Mehko tipkanje Odvisni tipi Duck tipkanje Sklepanje tipa v programiranju je funkcija prevajalnika... ... Wikipedia

    Tipkanje podatkov Varnost tipa Sklepanje o tipu Dinamično tipkanje Statično tipkanje Močno tipkanje Mehko tipkanje Odvisni tipi Duck tipkanje Odvisen tip, v računalništvu in logiki, tip, ki je odvisen od vrednosti. Vzdrževanci... ... Wikipedia

    - (najdemo tudi izraz podatkovni tip) je temeljni koncept teorije programiranja. Podatkovni tip definira nabor vrednosti, nabor operacij, ki jih je mogoče uporabiti za take vrednosti, in morebiti način za izvajanje shranjevanja vrednosti in... ... Wikipedia

    Tip podatkov Vsebina 1 Zgodovina 2 Definicija 3 Potreba po uporabi tipov podatkov ... Wikipedia

    Ta izraz ima druge pomene, glejte ML (pomeni). Semantika ML: multi-paradigma: funkcionalna, imperativna, modularna Nastalo leta: 1973 Avtor(ji): Robin Milner et al. Univerza v Edinburgu ... Wikipedia

Ta članek vsebuje potrebni minimum tistih stvari, ki jih preprosto morate vedeti o tipkanju, da dinamičnega tipkanja ne bi označili za zlo, Lispa za breztipski jezik in C-ja za strogo tipkani jezik.

Polna različica vsebuje podroben opis vseh vrst tipkanja, začinjeno s primeri kode, povezavami do priljubljenih programskih jezikov in ilustrativnimi slikami.

Priporočam, da najprej preberete kratko različico članka, nato pa po želji še celotno različico.

Kratka različica

Glede na tipkanje se programski jeziki običajno delijo na dva velika tabora - tipizirani in netipizirani (breztipski). V prvo sodijo na primer C, Python, Scala, PHP in Lua, v drugo pa zbirni jezik, Forth in Brainfuck.

Ker je »breztipsko tipkanje« v svojem bistvu tako preprosto kot čep, se ne deli naprej na nobene druge vrste. Toda tipkani jeziki so razdeljeni v več prekrivajočih se kategorij:

  • Statično/dinamično tipkanje. Statičnost je opredeljena z dejstvom, da so končni tipi spremenljivk in funkcij nastavljeni v času prevajanja. Tisti. prevajalnik je že 100% prepričan, kateri tip je kje. Pri dinamičnem tipkanju se vse vrste odkrijejo med izvajanjem programa.

    Primeri:
    Statični: C, Java, C#;
    Dinamično: Python, JavaScript, Ruby.

  • Močno/šibko tipkanje (včasih imenovano tudi močno/ohlapno). Močno tipkanje odlikuje dejstvo, da jezik ne dovoljuje mešanja različnih vrst v izrazih in ne izvaja samodejnih implicitnih pretvorb, na primer, od niza ne morete odšteti niza. Šibko tipizirani jeziki samodejno izvajajo številne implicitne pretvorbe, čeprav lahko pride do izgube natančnosti ali pa je pretvorba dvoumna.

    Primeri:
    Močna: Java, Python, Haskell, Lisp;
    Šibko: C, JavaScript, Visual Basic, PHP.

  • Eksplicitno/implicitno tipkanje. Eksplicitno tipizirani jeziki se razlikujejo po tem, da mora biti tip novih spremenljivk/funkcij/njihovih argumentov eksplicitno določen. V skladu s tem jeziki z implicitnim tipkanjem to nalogo prenesejo na prevajalnik/tolmač.

    Primeri:
    Eksplicitno: C++, D, C#
    Implicitno: PHP, Lua, JavaScript

Upoštevati je treba tudi, da se vse te kategorije prekrivajo, na primer jezik C ima statično šibko eksplicitno tipkanje, jezik Python pa dinamično močno implicitno tipkanje.

Vendar pa ni jezikov s statičnim in dinamičnim tipkanjem hkrati. Čeprav bom, če pogledam naprej, rekel, da ležim tukaj - res obstajajo, a o tem kasneje.

Podrobna različica

Če vam kratka različica ni bila dovolj, je prav. Nisem zaman napisal podrobnega? Glavna stvar je, da je bilo preprosto nemogoče vse uporabne in zanimive informacije umestiti v kratko različico, podrobna pa bi bila verjetno predolga, da bi jo vsi prebrali brez naprezanja.

Breztipsko tipkanje

V breztipskih programskih jezikih se vse entitete obravnavajo preprosto kot zaporedja bitov različnih dolžin.

Breztipsko tipkanje je običajno značilno za nizkonivojske (sestavljalni jezik, Forth) in ezoterične (Brainfuck, HQ9, Piet) jezike. Vendar pa ima poleg slabosti tudi nekaj prednosti.

Prednosti
  • Omogoča vam pisanje na izjemno nizki ravni, prevajalnik/tolmač pa ne bo motil nobenih tipskih preverjanj. Izvajate lahko kakršne koli operacije na kateri koli vrsti podatkov.
  • Dobljena koda je običajno bolj učinkovita.
  • Preglednost navodil. Če poznate jezik, običajno ni dvoma, kakšna je ta ali ona koda.
Napake
  • Kompleksnost. Pogosto je treba predstaviti kompleksne vrednosti, kot so seznami, nizi ali strukture. To lahko povzroči nevšečnosti.
  • Pomanjkanje pregledov. Vsa nesmiselna dejanja, na primer odštevanje kazalca na matriko od simbola, se bodo štela za povsem običajna, kar je polno subtilnih napak.
  • Nizka stopnja abstrakcije. Delo s katero koli kompleksno vrsto podatkov se ne razlikuje od dela s številkami, kar bo seveda povzročilo veliko težav.
Močno breztipsko tipkanje?

Da, to obstaja. Na primer, v zbirnem jeziku (za arhitekturo x86/x86-64, drugih ne poznam) ne morete sestaviti programa, če poskušate naložiti podatke iz registra rax (64 bitov) v register cx (16 bitov) .

mov cx, eax; napaka v času sestavljanja

Torej se izkaže, da ima asembler še vedno tipkanje? Menim, da ti pregledi niso dovolj. In vaše mnenje je seveda odvisno samo od vas.

Statično in dinamično tipkanje

Glavna stvar, ki razlikuje statično tipkanje od dinamičnega tipkanja, je, da se vsa preverjanja tipov izvajajo v času prevajanja, ne med izvajanjem.

Nekateri ljudje morda mislijo, da je statično tipkanje preveč omejujoče (v resnici je, vendar je to s pomočjo nekaterih tehnik že dolgo odpravljeno). Nekateri pravijo, da se dinamično tipkani jeziki igrajo z ognjem, toda po katerih lastnostih izstopajo? Imata obe vrsti res možnost obstoja? Če ne, zakaj potem obstaja toliko jezikov, ki so statično in dinamično tipkani?

Ugotovimo.

Prednosti statičnega tipkanja
  • Preverjanje tipa se izvede samo enkrat - v fazi prevajanja. To pomeni, da nam ne bo treba nenehno ugotavljati, ali poskušamo število deliti z nizom (in bodisi sprožiti napako ali izvesti pretvorbo).
  • Hitrost izvajanja. Iz prejšnje točke je jasno, da so statično tipkani jeziki skoraj vedno hitrejši od dinamično tipkanih.
  • Pod nekaterimi dodatnimi pogoji vam omogoča odkrivanje morebitnih napak že v fazi prevajanja.
Prednosti dinamičnega tipkanja
  • Enostavnost ustvarjanja univerzalnih zbirk - na kupe vsega in vsakogar (redko se pojavi takšna potreba, ko pa se pojavi dinamično tipkanje, bo pomagalo).
  • Priročnost opisovanja posplošenih algoritmov (na primer razvrščanje nizov, ki ne bo delovalo le na seznamu celih števil, temveč tudi na seznamu realnih števil in celo na seznamu nizov).
  • Enostaven za učenje - dinamično tipkani jeziki so običajno zelo dobri za začetek programiranja.

Generalizirano programiranje

V redu, najpomembnejši argument za dinamično tipkanje je priročnost opisovanja generičnih algoritmov. Predstavljajmo si problem - potrebujemo funkcijo za iskanje po več nizih (ali seznamih) - nizu celih števil, nizu realnih in nizu znakov.

Kako ga bomo rešili? Rešimo ga v treh različnih jezikih: enem z dinamičnim tipkanjem in dveh s statičnim tipkanjem.

Uporabil bom enega najpreprostejših iskalnih algoritmov - brute force. Funkcija bo prejela iskani element, samo matriko (ali seznam) in vrnila indeks elementa ali, če elementa ni mogoče najti - (-1).

Dinamična rešitev (Python):

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

Kot lahko vidite, je vse preprosto in ni težav s tem, da lahko seznam vsebuje številke, sezname ali druge nize. Zelo dobro. Gremo še dlje - rešimo isti problem v C!

Statična rešitev (C):

Unsigned int find_int(int required_element, int array, unsigned int size) ( for (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); }

No, vsaka funkcija posebej je podobna različici Python, ampak zakaj so tri? Je statično programiranje res izgubilo?

Da in ne. Obstaja več tehnik programiranja, eno od njih bomo zdaj obravnavali. Imenuje se generično programiranje in jezik C++ ga zelo dobro podpira. Oglejmo si novo različico:

Statična rešitev (generično programiranje, C++):

Predloga unsigned int find(T zahtevan_element, std::vector array) ( for (unsigned int i = 0; i< array.size(); ++i) if (required_element == array[i]) return i; return (-1); }

Globa! Ne izgleda veliko bolj zapleteno kot različica Python in ne zahteva veliko pisanja. Poleg tega smo dobili izvedbo za vsa polja, ne le za 3, ki so potrebna za rešitev problema!

Zdi se, da je ta različica točno to, kar potrebujemo - dobimo tako prednosti statičnega tipkanja kot nekatere prednosti dinamičnega tipkanja.

Super je, da je to sploh mogoče, lahko pa bi bilo še bolje. Prvič, posplošeno programiranje je lahko bolj priročno in lepše (na primer v jeziku Haskell). Drugič, poleg posplošenega programiranja lahko uporabite tudi polimorfizem (rezultat bo slabši), preobremenitev funkcij (podobno) ali makre.

Statika v dinamiki

Omeniti je treba tudi, da številni statični jeziki omogočajo dinamično tipkanje, na primer:

  • C# podpira dinamični psevdotip.
  • F# podpira sintaktični sladkor v obliki operatorja ?, na podlagi katerega je mogoče implementirati posnemanje dinamičnega tipkanja.
  • Haskell - dinamično tipkanje omogoča modul Data.Dynamic.
  • Delphi - prek posebnega tipa Variant.

Tudi nekateri dinamično tipkani jeziki vam omogočajo, da izkoristite prednosti statičnega tipkanja:

  • Common Lisp - deklaracije tipa.
  • Perl - od različice 5.6 dokaj omejen.

Močno in šibko tipkanje

Strogo tipizirani jeziki ne dovoljujejo mešanja entitet različnih tipov v izrazih in ne izvajajo samodejnih pretvorb. Imenujejo se tudi "močno tipizirani jeziki". Angleški izraz za to je močno tipkanje.

Šibko tipizirani jeziki, nasprotno, spodbujajo programerja, da meša različne tipe v enem izrazu, prevajalnik pa bo sam vse zmanjšal na en sam tip. Imenujejo se tudi "ohlapno tipkani jeziki". Angleški izraz za to je šibko tipkanje.

Šibko tipkanje se pogosto zamenjuje z dinamičnim tipkanjem, kar je popolnoma napačno. Dinamično tipiziran jezik je lahko šibko ali močno tipiziran.

Vendar le redki pripisujejo pomen strogosti tipkanja. Pogosto se trdi, da če je jezik statično tipkan, potem lahko med prevajanjem ujamete veliko potencialnih napak. Lažejo vam!

Jezik mora imeti tudi močno tipkanje. Dejansko, če prevajalnik, namesto da bi javil napako, preprosto doda niz številu ali, kar je še huje, od enega polja odšteje drugega, kaj nam pomaga, da bodo vsa "preverjanja" tipov pri prevajanju stopnja? Tako je – šibko statično tipkanje je še slabše od močnega dinamičnega tipkanja! (No, to je moje mnenje)

Torej šibko tipkanje nima nobenih prednosti? Morda je videti tako, a kljub temu, da sem vnet zagovornik močnega tipkanja, se moram strinjati, da ima šibko tipkanje tudi prednosti.

Želite vedeti, katere?

Prednosti močnega tipkanja
  • Zanesljivost - namesto nepravilnega vedenja boste prejeli izjemo ali napako prevajanja.
  • Hitrost - Namesto skritih pretvorb, ki so lahko precej drage, jih morate pri močnem tipkanju napisati eksplicitno, zaradi česar programer vsaj ve, da je ta del kode morda počasen.
  • Razumevanje, kako program deluje - znova, namesto implicitnega uvajanja tipa, programer vse napiše sam, kar pomeni, da približno razume, da se primerjava niza in števila ne zgodi sama od sebe in ne po čarovniji.
  • Gotovost - ko ročno pišete transformacije, točno veste, kaj pretvarjate in v kaj. Prav tako se boste vedno zavedali, da lahko takšne pretvorbe povzročijo izgubo natančnosti in nepravilne rezultate.
Prednosti šibkega tipkanja
  • Priročnost uporabe mešanih izrazov (na primer iz celih in realnih števil).
  • Abstrahiranje od tipkanja in osredotočanje na nalogo.
  • Kratkost vnosa.

V redu, ugotovili smo, izkazalo se je, da ima šibko tipkanje tudi prednosti! Ali obstajajo načini za prenos prednosti šibkega tipkanja na močno tipkanje?

Izkazalo se je, da sta celo dva.

Implicitno ulivanje tipa, v nedvoumnih situacijah in brez izgube podatkov

Vau... Kar dolgo. Naj še skrajšam na "omejeno implicitno pretvorbo". Kaj torej pomenita nedvoumna situacija in izguba podatkov?

Nedvoumna situacija je transformacija ali operacija, v kateri je bistvo takoj jasno. Na primer, seštevanje dveh številk je nedvoumna situacija. Toda pretvorba števila v matriko ni (morda bo ustvarjena matrika enega elementa, morda matrika s takšno dolžino, privzeto napolnjena z elementi, in morda bo številka pretvorjena v niz in nato v matriko znakov).

Izguba podatkov je še lažja. Če realno število 3,5 pretvorimo v celo število, bomo izgubili del podatkov (pravzaprav je tudi ta operacija dvoumna – kako bo izvedeno zaokroževanje? Gor? Dol? Zavrženje ulomka?).

Pretvorbe v dvoumnih situacijah in pretvorbe z izgubo podatkov so zelo, zelo slabe. V programiranju ni nič hujšega od tega.

Če mi ne verjamete, preučite jezik PL/I ali celo poiščite njegove specifikacije. Ima pravila za pretvorbo med VSEMI vrstami podatkov! To je samo pekel!

V redu, spomnimo se na omejeno implicitno pretvorbo. Ali obstajajo taki jeziki? Da, na primer v Pascalu lahko pretvorite celo število v realno število, ne pa tudi obratno. Podobni mehanizmi obstajajo tudi v C#, Groovy in Common Lisp.

V redu, rekel sem, da še vedno obstaja način, da dobite nekaj prednosti šibkega tipkanja v močnem jeziku. In ja, obstaja in se imenuje konstruktorski polimorfizem.

Razložil bom na primeru čudovitega jezika Haskell.

Polimorfni konstruktorji so nastali na podlagi opažanja, da so pri uporabi številskih literalov najpogosteje potrebne varne implicitne pretvorbe.

Na primer, v izrazu pi + 1 ne želite napisati pi + 1,0 ali pi + float(1). Želim samo napisati pi + 1!

In to je narejeno v Haskellu, zahvaljujoč dejstvu, da literal 1 nima konkretnega tipa. Ni niti cela, niti resnična niti kompleksna. To je samo številka!

Kot rezultat, pri pisanju preproste funkcije vsota x y , množenje vseh števil od x do y (s prirastkom 1), dobimo več različic hkrati - vsota za cela števila, vsota za realna števila, vsota za racionalna števila, vsota za kompleksna števila in celo vsoto za vse tiste številske vrste, ki ste jih sami definirali.

Seveda ta tehnika prihrani le pri uporabi mešanih izrazov s številskimi literali in to je le vrh ledene gore.

Tako lahko rečemo, da je najboljša rešitev ravnovesje na meji med močnim in šibkim tipkanjem. Toda noben jezik še ne dosega popolnega ravnovesja, zato se bolj nagibam k močno tipkanim jezikom (kot so Haskell, Java, C#, Python) namesto k slabo tipkanim (kot so C, JavaScript, Lua, PHP).

Eksplicitno in implicitno tipkanje

Eksplicitno tipiziran jezik zahteva, da programer določi tipe vseh spremenljivk in funkcij, ki jih deklarira. Angleški izraz za to je eksplicitno tipkanje.

Po drugi strani vas implicitno tipiziran jezik spodbuja, da pozabite na tipe in prepustite nalogo sklepanja o tipih prevajalniku ali tolmaču. Angleški izraz za to je implicitno tipkanje.

Sprva boste morda mislili, da je implicitno tipkanje enakovredno dinamičnemu, eksplicitno tipkanje pa statičnemu, vendar bomo kasneje videli, da temu ni tako.

Ali ima vsaka vrsta prednosti in spet, ali obstajajo njihove kombinacije in ali obstajajo jeziki, ki podpirajo obe metodi?

Prednosti eksplicitnega tipkanja
  • Če ima vsaka funkcija podpis (na primer int add(int, int)), je lažje ugotoviti, kaj funkcija počne.
  • Programer takoj zapiše, katere vrste vrednosti je mogoče shraniti v določeno spremenljivko, s čimer odpravi potrebo po tem, da bi si jo zapomnili.
Prednosti implicitnega tipkanja
  • Skrajšan zapis – def add(x, y) je očitno krajši od int add(int x, int y).
  • Odpor do sprememb. Na primer, če je bila v funkciji začasna spremenljivka istega tipa kot vhodni argument, boste morali v eksplicitno tipiziranem jeziku pri spreminjanju tipa vhodnega argumenta spremeniti tudi tip začasne spremenljivke.

V redu, jasno je, da imata oba pristopa prednosti in slabosti (kdo je pričakoval kaj drugega?), zato poiščimo načine za kombinacijo teh dveh pristopov!

Eksplicitno tipkanje po izbiri

Obstajajo jeziki s privzetim implicitnim tipkanjem in možnostjo določanja vrste vrednosti, če je potrebno. Prevajalec bo samodejno izpisal pravo vrsto izraza. Eden od teh jezikov je Haskell, naj navedem preprost primer za jasnost:

Brez izrecne specifikacije tipa add (x, y) = x + y -- Eksplicitna specifikacija tipa add:: (Integer, Integer) -> Integer add (x, y) = x + y

Opomba: namenoma sem uporabil funkcijo uncurried in namenoma napisal zasebni podpis namesto bolj splošnega add:: (Num a) -> a -> a -> a , ker Želel sem pokazati idejo, ne da bi razložil Haskell sintakso.

Hm. Kot vidimo, je zelo lepo in kratko. Pisanje funkcije traja samo 18 znakov v eni vrstici, vključno s presledki!

Vendar je avtomatsko sklepanje tipov precej zapletena stvar in celo v tako kul jeziku, kot je Haskell, včasih ne uspe. (primer je omejitev monomorfizma)

Ali obstajajo jeziki z eksplicitnim tipkanjem privzeto in implicitnim tipkanjem, če je potrebno? Con
seveda.

Implicitno tipkanje po izbiri

Novi jezikovni standard C++, imenovan C++11 (prej imenovan C++0x), je uvedel ključno besedo auto, ki omogoča prevajalniku sklepanje o vrsti na podlagi konteksta:

Primerjajmo: // Ročno določanje tipa unsigned int a = 5; unsigned int b = a + 3; // Samodejni izhod tipa unsigned int a = 5; avto b = a + 3;

Ni slabo. Toda posnetek se ni veliko zmanjšal. Oglejmo si primer z iteratorji (če ne razumete, ne bojte se, glavna stvar, ki jo morate upoštevati, je, da je snemanje močno zmanjšano zaradi samodejnega izpisa):

// Ročno določanje tipa std::vector vec = randomVector(30); for (std::vector::const_iterator it = vec.cbegin(); ...) ( ... ) // Samodejno sklepanje tipa auto vec = randomVector (trideset); for (auto it = vec.cbegin(); ...) ( ... )

Vau! To je okrajšava. V redu, toda ali je mogoče narediti nekaj takega, kot je Haskell, kjer je vrsta vrnitve odvisna od vrste argumentov?

In spet je odgovor pritrdilen, zahvaljujoč ključni besedi decltype v kombinaciji z auto:

// Ročni tip int divide(int x, int y) ( ... ) // Samodejni tip inference auto divide(int x, int y) -> decltype(x / y) ( ... )

Ta oblika zapisa se morda ne zdi zelo dobra, vendar v kombinaciji z generičnim programiranjem (predloge/generiki) implicitno tipkanje ali samodejno sklepanje tipa dela čudeže.

Nekateri programski jeziki glede na to klasifikacijo

Podal bom majhen seznam priljubljenih jezikov in napisal, kako so razdeljeni v vsako kategorijo "tipkanja".

JavaScript - dinamično / šibko / implicitno Ruby - dinamično / močno / implicitno Python - dinamično / močno / implicitno Java - statično / močno / eksplicitno PHP - dinamično / šibko / implicitno C - statično / šibko / eksplicitno C++ - statično / polmočno / Eksplicitni Perl - dinamični / šibki / implicitni Objective-C - statični / šibki / eksplicitni C# - statični / močni / eksplicitni Haskell - statični / močni / implicitni Common Lisp - dinamični / močni / implicitni

Mogoče sem se kje zmotil, predvsem pri CL, PHP in Obj-C, če imate drugačno mnenje o kakšnem jeziku, napišite v komentar.

Zaključek

V REDU. Kmalu bo svetlo in mislim, da o tipkanju ni več kaj reči. Oh, kako? Je tema brez dna? Je ostalo veliko neizrečenega? Delite koristne informacije v komentarjih.