Data typ

En datatyp ( typ ) är en uppsättning värden och operationer på dessa värden (IEEE Std 1320.2-1998) [1] .

Andra definitioner:

En typ definierar möjliga värden och deras betydelse, operationer och hur värdena för typen lagras. Studeras med typteori . En integrerad del av de flesta programmeringsspråk är typsystem , som använder typer för att ge en viss grad av typsäkerhet .

Definition

Datatypen kännetecknar samtidigt:

Den första egenskapen kan ses som en mängdteoretisk definition av begreppet typ; den andra är som en processuell (eller beteendemässig) definition.

Vid programmering används dessutom en lågnivådefinition av en typ - som givna dimensionella och strukturella egenskaper hos en minnescell, i vilken ett visst värde som motsvarar dessa egenskaper kan placeras. En sådan definition är ett specialfall av den mängdteoretiska. I praktiken är ett antal viktiga egenskaper associerade med det (på grund av särdragen i organisationen av datorminne ), som kräver separat övervägande .

Den uppsättningsteoretiska definitionen, särskilt i sin lågnivåvariant, används oftast i imperativ programmering . Procedurdefinition är mer förknippad med parametrisk polymorfism . Objektorienterad programmering använder procedurdefinition när man beskriver interaktionen mellan programkomponenter, och set-teoretisk definition när man beskriver implementeringen av dessa komponenter på en dator, respektive, med hänsyn till " klass-som-beteende " och " klass-som-objekt i minnet " " .

Operationen att tilldela en typ till informationsenheter kallas typning . Tilldelning och kontroll av typkonsistens kan göras i förväg ( statisk typning ), direkt vid användning ( dynamisk typning ), eller en kombination av båda metoderna. Typer kan tilldelas "en gång för alla" ( stark skrivning ) eller tillåtas ändras ( svag skrivning ).

Typer undviker Russells paradox , i synnerhet introducerade Church typer i lambdakalkylen för just detta syfte [6] .

I naturligt språk är frågepronomen ansvariga för att skriva .

Den enhetliga behandlingen av data av olika typer kallas polymorfism [7] [8] .

Begreppet typsäkerhet bygger i första hand på procedurtypdefinition. Till exempel kommer ett försök att dela ett tal med en sträng att avvisas av de flesta språk, eftersom inget motsvarande beteende är definierat för dessa typer. Svagt skrivna språk tenderar att vara lågnivådefinitioner. Till exempel, " nummer " och " post " har olika beteende, men värdet på adressen för " post " i datorns minne kan ha samma lågnivårepresentation som "nummer". Svagt skrivna språk ger möjligheten att bryta typsystemet genom att tilldela " nummer " beteende till ett värde genom en cast- operation . Sådana knep kan användas för att öka effektiviteten hos program, men medför risk för krascher och är därför inte tillåtna på säkra språk, eller är strikt isolerade.

Klassificering

Det finns olika klassificeringar av typer och regler för deras tilldelning.

I analogi med matematik delas datatyper in i skalär ( primitiv ) och icke- skalär ( aggregerad ). Ett värde av en icke-skalär typ (ett icke-skalär värde) har många användarsynliga komponenter, medan ett värde av en skalär typ (ett skalärt värde) inte har det. [9] Exempel på en icke-skalär typ är arrayer , listor och så vidare; exempel på en skalär typ är " heltal ", " boolean " osv.

Strukturella (aggregerade) typer bör inte identifieras med datastrukturer : vissa datastrukturer är direkt förkroppsligade av vissa strukturella typer, men andra är byggda genom sin sammansättning, oftast rekursiva. I det senare fallet talar man om rekursiva datatyper . Ett exempel på datastrukturer som nästan alltid byggs upp genom objektsammansättning av rekursiv typ är binära träd .

Enligt en annan klassificering delas typer in i oberoende och beroende . Viktiga sorter av de senare är referenstyper , som i sin tur är pekare . Referenser (inklusive pekare) är en icke-kompositberoende typ, vars värden är adressen i datorminnet för ett annat värde. Till exempel, i C -typsystemet skrivs typen " pekare till ett osignerat heltal " som " unsigned *" , i ML -språket skrivs typen " referens till ett osignerat heltal " som " word ref" .

Typer delas också in i monomorfa och polymorfa (se typvariabel ).

Några vanliga datatyper

Boolesk typ

Logiska, eller booleska värden (efter namnet på deras uppfinnare - Boole), kan bara ha ett av två tillstånd - "sant" eller "falskt". På olika språk betecknas de boolmed , BOOLeller boolean. "Sanning" kan betecknas som true, TRUEeller #T. "False", respektive false, FALSEeller #F. I C och C++ behandlas alla icke-nolltal som sant och noll behandlas som falskt. I Python tilldelas vissa enstaka typer också ett "booleskt" värde. I princip räcker en bit för att implementera typen, men på grund av mikroprocessorernas natur är storleken på booleska värden vanligtvis lika med storleken på ett maskinord i praktiken .

Heltalstyper

Heltalstyper innehåller värden tolkade som tal (signerade och osignerade).

Flyttal

Används för att representera reella (inte nödvändigtvis heltal) tal. I det här fallet skrivs talet som x=a*10^b. Där 0<=a<1 och b är något heltal från ett visst område. a kallas mantissan, b är ordningen. Mantissan lagrar flera siffror efter decimalkomma, och b lagras i sin helhet.

Strängtyper

En sekvens av tecken som behandlas som en helhet i en variabels kontext. Olika programmeringsspråk lägger olika begränsningar på strängvariabler. Strängar kan innehålla escape-sekvenser .

Pekare

En pekare är en variabel vars värdeintervall består av adresser till minnesplatser eller ett speciellt värde för att indikera att ingenting för närvarande är lagrat i variabeln.

Identifieringstyper

Identitetstyper tolkas inte som ett nummer, utan som en unik objektidentifierare. Till exempel FourCC .

Abstrakta datatyper

Datatyper som beaktas oavsett sammanhang och implementering i ett visst programmeringsspråk. Abstraktion i matematisk mening innebär att dataalgebra behandlas upp till isomorfism . Abstrakta typer används ofta i programmeringsmetodik baserad på steg-för-steg programutveckling. Vid konstruktionen av specifikationen för det designade programmet modellerar dataalgebra objekten i ämnesområdet, i termer av det problem som ska lösas. I processen med inkrementell förfining konkretiseras data genom att överföras till mellanliggande representationer tills dess implementering hittas med användning av den underliggande dataalgebra för det använda programmeringsspråket. Det finns flera sätt att definiera abstrakta typer: algebraiska, modell och axiomatiska. I modellansatsen definieras dataelement explicit. Den algebraiska metoden använder metoder för algebraiska relationer, medan den axiomatiska metoden använder logisk formalisering.

Exempel

Självansöker

En typ kan parametriseras av en annan typ, i enlighet med principerna för abstraktion och parametrisitet . Till exempel, för att implementera en funktion för att sortera sekvenser, är det inte nödvändigt att känna till alla egenskaper hos dess beståndsdelar - det är bara nödvändigt att de tillåter en jämförelseoperation - och då kan den sammansatta typen " sekvens " definieras som parametriskt polymorf . Det betyder att dess komponenter inte definieras med hjälp av konkreta typer (som " heltal " eller " matris av heltal "), utan typparametrar. Sådana parametrar kallas typvariabler ( engelsk  typvariabel ) - de används i definitionen av en polymorf typ på samma sätt som värdeparametrar i en funktionsdefinition. Att ersätta betongtyper som faktiska parametrar för en polymorf typ ger en monomorf typ. Således är en parametriskt polymorf typ en typkonstruktor , det vill säga en operator på typer i typaritmetik.

Att definiera en sorteringsfunktion som parametriskt polymorf innebär att den sorterar en abstrakt sekvens, det vill säga en sekvens av element av någon (okänd) typ. I det här fallet behöver funktionen bara känna till två egenskaper om sin parameter - att det är en sekvens och att jämförelseoperationen är definierad för dess element . Att överväga parametrar på ett procedurmässigt snarare än deklarativt sätt (det vill säga att använda dem baserat på beteende snarare än värde) gör att du kan använda en enda sorteringsfunktion för alla sekvenser - för sekvenser av heltal, för sekvenser av strängar, för sekvenser av sekvenser av booleska värden och så vidare— och ökar avsevärt kodåteranvändningsfaktorn . Dynamisk typning ger samma flexibilitet , men till skillnad från parametrisk polymorfism kommer den förra med overhead. Parametrisk polymorfism är mest utvecklad i Hindley-Milner-typade språk , det vill säga ättlingar till ML-språket . I objektorienterad programmering kallas parametrisk polymorfism för generisk programmering .

Trots de uppenbara fördelarna med parametrisk polymorfism, ibland blir det nödvändigt att tillhandahålla olika beteende för olika subtyper av samma allmänna typ, eller liknande beteende för inkompatibla typer - det vill säga i någon form av ad-hoc polymorfism . Det finns dock ingen matematisk grund för det, så typsäkerhetskravet gjorde det svårt att använda under lång tid. Ad-hoc polymorfism implementerades inom ett parametriskt polymorft system genom olika knep. För detta ändamål användes antingen varianttyper eller parametriska moduler ( funktioner eller de så kallade " typindexerade värdena "), som i sin tur också har ett antal implementeringar [ 10] .  Typklasser , introducerade i Haskell-språket gav en mer elegant lösning på detta problem.

Om informationsenheten i fråga är en typ, kommer att tilldela en typ till den leda till konceptet av en " typ av typ " (" metatyp "). I typteorin kallas detta begrepp " typ av typer " ( eng.  typ av typ eller typslag ). Till exempel *inkluderar släktet " " alla typer och släktet " * -> *" inkluderar alla unära typkonstruktörer . Kön används uttryckligen i typfull programmering  , till exempel som typkonstruktörer i språk i ML -familjen .

Utvidgningen av det säkra polymorfa typsystemet till klasser och typsläkten gjorde Haskell till det första helt maskinskrivna språket. Det resulterande typsystemet har påverkat andra språk (t.ex. Scala , Agda ).

En begränsad form av metatyper finns också i ett antal objektorienterade språk i form av metaklasser . I ättlingarna till Smalltalk-språket (som Python ) är varje entitet i ett program ett objekt som har en typ som i sig är ett objekt – alltså är metatyper en naturlig del av språket. I C++- språket implementeras RTTI- delsystemet separat från språkets huvudtypsystem , vilket också tillhandahåller typinformation i form av en speciell struktur.

Den dynamiska belysningen av metatyper kallas reflektion (och även reflexivitet eller introspektion).

Datorrepresentation

Den mest märkbara skillnaden mellan verklig programmering och formell informationsteori är övervägandet av effektivitetsfrågor, inte bara när det gäller O-notation , utan också utifrån den ekonomiska genomförbarheten av att implementera vissa krav i en fysiskt tillverkad dator . Och först och främst påverkar detta den tillåtna noggrannheten i beräkningar: begreppet "tal" i en dator är i praktiken inte identiskt med begreppet ett tal i aritmetik . Numret i datorn representeras av en minnescell , vars storlek bestäms av datorarkitekturen , och intervallet av värden för numret begränsas av storleken på denna cell. Till exempel tillhandahåller processorer med Intel x86- arkitekturen celler vars storlek i byte är satt till en potens av två: 1, 2, 4, 8, 16 , etc. Processorer i Setun- arkitekturen tillhandahåller celler vars storlek i egenskaper är inställd på en multipel av tre: 1, 3, 6, 9 osv.

Ett försök att skriva till en cell ett värde som överskrider den maximalt tillåtna gränsen för den (vilket är känt ) resulterar i ett spillfel . Om det är nödvändigt att beräkna på större siffror används en speciell teknik, som kallas lång aritmetik , som på grund av den betydande resursintensiteten inte kan utföras i realtid. För de vanligaste datorarkitekturerna för närvarande är "native" cellstorleken 32 och 64 bitar (det vill säga 4 och 8 byte ).

Dessutom har heltal och reella tal olika representationer i dessa celler: icke-negativa heltal representeras direkt , negativa heltal representeras i tvås komplement , och reella tal kodas på ett speciellt sätt . På grund av dessa skillnader är tillägg av siffror " 1" och " 0.1", som i teorin ger värdet " 1.1", direkt omöjligt på en dator. För att implementera det måste du först utföra en typkonvertering , generera ett 1nytt värde av den verkliga typen " " baserat på värdet av heltalstypen " 1.0", och först sedan lägga till " 1.0" och " 0.1". På grund av detaljerna i implementeringen av reella tal på en dator, utförs en sådan transformation inte helt exakt, men med en viss grad av approximation. Av samma anledning behandlar starkt typade språk (som Standard ML ) den verkliga typen som likhetstyper (eller identitetstyper) ( Equality type ).

För lågnivårepresentationen av sammansatta typer är konceptet datajustering viktigt . Språk på hög nivå isolerar (abstrakt) vanligtvis programmeraren från den här egenskapen, men det måste tas i beaktande när man länkar oberoende kompilerade moduler till varandra. Vissa språk ( C -, C ++ ) ger dock möjligheten att kontrollera lågnivårepresentationen av typer, inklusive justering. Sådana språk kallas ibland mellannivåspråk.

Anteckningar

  1. IEEE Std 1320.2-1998 (R2004) IEEE Standard for Conceptual Modeling Language Syntax and Semantics för IDEF1X97:
    en uppsättning värden och operationer på dessa värden
  2. ISO/IEC/IEEE 24765-2010 Systems and software engineering - Ordförråd Arkiverad 17 juni 2016 på Wayback Machine :
    en klass av data, kännetecknad av medlemmarna i klassen och de operationer som kan tillämpas på dem
  3. IEEE Std 1320.2-1998 (R2004) IEEE Standard for Conceptual Modeling Language Syntax and Semantics för IDEF1X97:
    en kategorisering av en abstrakt uppsättning möjliga värden, egenskaper och uppsättning operationer för ett attribut
  4. ISO/IEC 19500-2:2003, Informationsteknik - Öppen distribuerad bearbetning - Del 2: General Inter-ORB Protocol (GIOP)/Internet Inter-ORB Protocol (IIOP):
    en kategorisering av värdeoperationsargument, som vanligtvis täcker både beteende och representation
  5. C. J. Datum . Om de logiska skillnaderna mellan typer, värden och variabler // Datum på databasen: Writings 2000-2006, Apress, 2006, ISBN 978-1-59059-746-0
  6. Harrison J. Introduktion till funktionell programmering  = http://www.cl.cam.ac.uk/Teaching/Lectures/funprog-jrh-1996/ . - 1997. Arkiverad 11 januari 2015.
  7. Strachey, 1967 , 3.6.4. Polymorphism, sid. 36-37.
  8. Cardelli, 1991 , 2. Typfulla språk, sid. 5.
  9. Datum K.J., 2005 .
  10. Typindexerade värden . Hämtad 15 juli 2014. Arkiverad från originalet 21 april 2016.

Litteratur