Programmeringsspråk - Programming language

Den källkoden för ett enkelt datorprogram skrivet i språket C-programmering . De grå linjerna är kommentarer som hjälper till att förklara programmet för människor på ett naturligt språk . När den sammanställs och körs kommer den att ge utgången " Hej, värld! ".

Ett programmeringsspråk är ett formellt språk som består av en uppsättning strängar som producerar olika typer av maskinkodutmatningar . Programmeringsspråk är ett slags datorspråk och används i datorprogrammering för att implementera algoritmer .

De flesta programmeringsspråk består av instruktioner för datorer . Det finns programmerbara maskiner som använder en uppsättning specifika instruktioner , snarare än allmänna programmeringsspråk . Sedan början av 1800 -talet har program använts för att styra beteendet hos maskiner som Jacquard vävstolar , musiklådor och pianon . Programmen för dessa maskiner (som ett pianos rullar) gav inte olika beteenden som svar på olika ingångar eller förhållanden.

Tusentals olika programmeringsspråk har skapats och fler skapas varje år. Många programmeringsspråk skrivs i en tvingande form (dvs. som en sekvens av operationer att utföra) medan andra språk använder deklarationsformen (dvs. det önskade resultatet anges, inte hur man uppnår det).

Beskrivningen av ett programmeringsspråk är vanligtvis uppdelad i de två komponenterna i syntax (form) och semantik (mening). Vissa språk definieras av ett specifikationsdokument (till exempel C -programmeringsspråket anges av en ISO -standard) medan andra språk (t.ex. Perl ) har en dominerande implementering som behandlas som en referens . Vissa språk har båda, med det grundläggande språket definierat av en standard och tillägg som tagits från den dominerande implementeringen är vanliga.

Programmeringsspråkteori är ett delområde inom datavetenskap som behandlar design, implementering, analys, karakterisering och klassificering av programmeringsspråk.

Definitioner

Ett programmeringsspråk är en notation för att skriva program , som är specifikationer för en beräkning eller algoritm . Vissa författare begränsar termen "programmeringsspråk" till de språk som kan uttrycka alla möjliga algoritmer. Egenskaper som ofta anses vara viktiga för vad som utgör ett programmeringsspråk inkluderar:

Funktion och mål
Ett datorprogrammeringsspråk är ett språk som används för att skriva datorprogram , vilket innebär att en dator utför någon form av beräkning eller algoritm och eventuellt styr externa enheter som skrivare , hårddiskar , robotar och så vidare. Till exempel skapas PostScript -program ofta av ett annat program för att styra en dators skrivare eller bildskärm. Mer generellt kan ett programmeringsspråk beskriva beräkning på någon, möjligen abstrakt, maskin. Det är allmänt accepterat att en komplett specifikation för ett programmeringsspråk innehåller en beskrivning, möjligen idealiserad, av en maskin eller processor för det språket. I de flesta praktiska sammanhang involverar ett programmeringsspråk en dator; följaktligen definieras och studeras programmeringsspråk på detta sätt. Programmeringsspråk skiljer sig från naturliga språk genom att naturliga språk endast används för interaktion mellan människor, medan programmeringsspråk också tillåter människor att kommunicera instruktioner till maskiner.
Abstraktioner
Programmeringsspråk innehåller vanligtvis abstraktioner för att definiera och manipulera datastrukturer eller kontrollera flödet av körning . Den praktiska nödvändigheten att ett programmeringsspråk stöder adekvata abstraktioner uttrycks av abstraktionsprincipen . Denna princip formuleras ibland som en rekommendation till programmeraren att göra korrekt användning av sådana abstraktioner.
Uttrycksfull kraft
Den teorin om beräknings klassificerar språk genom beräkningarna de kan uttrycka. Alla Turing-kompletta språk kan implementera samma uppsättning algoritmer . ANSI/ISO SQL-92 och välgörenhet är exempel på språk som inte är Turing fullständiga, men som ofta kallas programmeringsspråk.

Markeringsspråk som XML , HTML eller troff , som definierar strukturerad data , betraktas vanligtvis inte som programmeringsspråk. Programmeringsspråk kan dock dela syntaxen med markeringsspråk om en beräkningssemantik definieras. XSLT , till exempel, är ett komplett Turing -språk helt och hållet med XML -syntax. Dessutom innehåller LaTeX , som mest används för att strukturera dokument, också en komplett Turing -delmängd.

Begreppet datorspråk används ibland omväxlande med programmeringsspråk. Användningen av båda termerna varierar emellertid mellan författarna, inklusive det exakta omfånget för varje. En användning beskriver programmeringsspråk som en delmängd av datorspråk. På samma sätt är språk som används i datorer som har ett annat mål än att uttrycka datorprogram generellt betecknade datorspråk. Till exempel kallas uppmärkningsspråk ibland som datorspråk för att betona att de inte är avsedda att användas för programmering.

En annan användning betraktar programmeringsspråk som teoretiska konstruktioner för programmering av abstrakta maskiner och datorspråk som delmängden därav som körs på fysiska datorer som har begränsade hårdvaruresurser. John C. Reynolds betonar att formella specifikationsspråk är lika mycket programmeringsspråk som språk som är avsedda för körning. Han hävdar också att text- och till och med grafiska inmatningsformat som påverkar datorns beteende är programmeringsspråk, trots att de vanligtvis inte är Turing-kompletta, och påpekar att okunskap om programmeringsspråkbegrepp är orsaken till många brister i inmatningsformat.

Historia

Tidiga utvecklingar

Mycket tidiga datorer, till exempel Colossus , programmerades utan hjälp av ett lagrat program , genom att ändra deras kretsar eller ställa in banker för fysiska kontroller.

Lite senare kan program skrivas på maskinspråk , där programmeraren skriver varje instruktion i numerisk form som hårdvaran kan köra direkt. Till exempel kan instruktionen att lägga till värdet i två minnesplatser bestå av tre nummer: en "opcode" som väljer "lägg till" -operationen och två minnesplatser. Programmen, i decimal eller binär form, lästes in från hålkort , papperstejp, magnetband eller växlas in växlar på frontpanelen på datorn. Maskinspråk kallades senare första generationens programmeringsspråk (1GL).

Nästa steg var utvecklingen av de så kallade andra generationens programmeringsspråk (2GL) eller samlingsspråk , som fortfarande var nära knutna till instruktionsuppsättningsarkitekturen för den specifika datorn. Dessa tjänade till att göra programmet mycket mer läsbart för människor och avlastade programmeraren från tråkiga och felbenägna adressberäkningar.

De första programmeringsspråken på hög nivå , eller tredje generationens programmeringsspråk (3GL), skrevs på 1950-talet. Ett tidigt programmeringsspråk på hög nivå som skulle utformas för en dator var Plankalkül , utvecklat för tyska Z3 av Konrad Zuse mellan 1943 och 1945. Det implementerades dock inte förrän 1998 och 2000.

John Mauchly 's Short Code föreslog 1949, var en av de första högnivåspråk någonsin utvecklats för en elektronisk dator . Till skillnad från maskinkod representerade Short Code -påståenden matematiska uttryck i förståelig form. Programmet måste dock översättas till maskinkod varje gång det körs, vilket gör processen mycket långsammare än att köra motsvarande maskinkod.

Vid University of Manchester , Alick Glennie utvecklade Autocode i början av 1950-talet. Som programmeringsspråk använde den en kompilator för att automatiskt konvertera språket till maskinkod. Den första koden och kompilatorn utvecklades 1952 för Mark 1- datorn vid University of Manchester och anses vara det första sammanställda programmeringsspråket på hög nivå.

Den andra autokoden utvecklades för Mark 1 av RA Brooker 1954 och kallades "Mark 1 Autocode". Brooker utvecklade också en autokod för Ferranti Mercury på 1950 -talet tillsammans med University of Manchester. Versionen för EDSAC 2 utformades av DF Hartley från University of Cambridge Mathematical Laboratory 1961. Känd som EDSAC 2 Autocode, det var en rak utveckling från Mercury Autocode anpassad för lokala förhållanden och känd för sin objektkodoptimering och källspråk diagnostik som var avancerad för tiden. En modern men separat utvecklingstråd, Atlas Autocode utvecklades för University of Manchester Atlas 1 -maskin.

1954 uppfanns FORTRAN på IBM av John Backus . Det var det första allmänt använda programmeringsspråket på hög nivå som hade en funktionell implementering, i motsats till bara en design på papper. Det är fortfarande ett populärt språk för högpresterande datorer och används för program som jämför och rankar världens snabbaste superdatorer .

Ett annat tidigt programmeringsspråk utvecklades av Grace Hopper i USA, kallat FLOW-MATIC . Det utvecklades för UNIVAC I vid Remington Rand under perioden 1955 till 1959. Hopper fann att affärsdatabearbetningskunder var obekväma med matematisk notering, och i början av 1955 skrev hon och hennes team en specifikation för ett engelskt programmeringsspråk och implementerade en prototyp. FLOW-MATIC-kompilatorn blev allmänt tillgänglig i början av 1958 och var väsentligen färdig 1959. FLOW-MATIC var ett stort inflytande i utformningen av COBOL , eftersom endast den och dess direkta ättling AIMACO var i faktisk användning vid den tiden.

Förfining

Den ökade användningen av språk på hög nivå införde ett krav på programmeringsspråklåg nivå eller systemprogrammeringsspråk . Dessa språk ger i varierande grad möjligheter mellan sammansättningsspråk och språk på hög nivå. De kan användas för att utföra uppgifter som kräver direkt åtkomst till hårdvaruanläggningar men ändå ger kontrollstrukturer på högre nivå och felkontroll.

Perioden från 1960 -talet till slutet av 1970 -talet förde utvecklingen av de stora språkparadigmen som nu används:

Var och en av dessa språk skapade ättlingar, och de flesta moderna programmeringsspråk räknar minst ett av dem i deras anor.

På 1960- och 1970 -talen kom det också stor debatt om fördelarna med strukturerad programmering och om programmeringsspråk borde utformas för att stödja den. Edsger Dijkstra , i ett berömt brev från 1968 som publicerades i Communications of the ACM , hävdade att Goto -uttalanden borde elimineras från alla "högre nivå" programmeringsspråk.

Konsolidering och tillväxt

Ett urval av läroböcker som lär ut programmering, på både populära och oklara språk. Det här är bara några av de tusentals programmeringsspråk och dialekter som har utformats i historien.

1980 -talet var år av relativ konsolidering. C ++ kombinerad objektorienterad och systemprogrammering. USA: s regering standardiserade Ada , ett systemprogrammeringsspråk som härrör från Pascal och som är avsett att användas av försvarsentreprenörer. I Japan och på andra håll spenderades stora summor på att undersöka de så kallade "femte generationens" språk som införlivade logiska programmeringskonstruktioner. Den funktionella språkgemenskapen flyttade till standardisering av ML och Lisp. I stället för att uppfinna nya paradigm utarbetade alla dessa rörelser idéerna som uppfanns under de föregående decennierna.

En viktig trend inom språkutformning för programmering av storskaliga system under 1980-talet var ett ökat fokus på användning av moduler eller storskaliga organisatoriska kodenheter. Modula-2 , Ada och ML utvecklade alla anmärkningsvärda modulsystem på 1980-talet, som ofta kombinerades med generiska programmeringskonstruktioner .

Internetets snabba tillväxt i mitten av 1990-talet skapade möjligheter för nya språk. Perl , ursprungligen ett Unix -skriptverktyg som först släpptes 1987, blev vanligt på dynamiska webbplatser . Java kom att användas för programmering på serversidan, och virtuella datakodmaskiner blev populära igen i kommersiella miljöer med sitt löfte om " Skriv en gång, kör var som helst " ( UCSD Pascal hade varit populär en tid i början av 1980-talet). Denna utveckling var inte i grunden ny; de var snarare förfiningar av många befintliga språk och paradigm (även om deras syntax ofta var baserad på C -familjen programmeringsspråk).

Utvecklingen av programmeringsspråk fortsätter, både inom industri och forskning. Nuvarande riktningar inkluderar säkerhet och tillförlitlighetsverifiering , nya typer av modularitet ( mixins , delegater , aspekter ) och databasintegration som Microsofts LINQ .

Fjärde generationens programmeringsspråk (4GL) är datorprogrammeringsspråk som syftar till att ge en högre grad av abstraktion av de interna datormaskinvaruuppgifterna än 3GL. Femte generationens programmeringsspråk (5GL) är programmeringsspråk baserade på att lösa problem med hjälp av begränsningar som ges till programmet, snarare än att använda en algoritm skriven av en programmerare.

Element

Alla programmeringsspråk har några primitiva byggstenar för beskrivning av data och de processer eller transformationer som tillämpas på dem (som tillägg av två nummer eller val av ett objekt från en samling). Dessa primitiv definieras av syntaktiska och semantiska regler som beskriver deras struktur respektive betydelse.

Syntax

Analysera trädet av Python -kod med infogad tokenisering
Syntaxmarkering används ofta för att hjälpa programmerare att känna igen element i källkoden. Språket ovan är Python .

Ett programmeringsspråks ytform är känd som dess syntax . De flesta programmeringsspråk är rent textuella; de använder sekvenser av text inklusive ord, siffror och skiljetecken, ungefär som skrivna naturliga språk. Å andra sidan finns det några programmeringsspråk som är mer grafiska till sin natur, med visuella relationer mellan symboler för att specificera ett program.

Syntaxen för ett språk beskriver möjliga kombinationer av symboler som bildar ett syntaktiskt korrekt program. Betydelsen som ges till en kombination av symboler hanteras av semantik (antingen formell eller hårdkodad i en referensimplementering ). Eftersom de flesta språk är textuella, diskuterar denna artikel textsyntax.

Programmeringsspråksyntax definieras vanligtvis med en kombination av reguljära uttryck (för lexikal struktur) och Backus – Naur -form (för grammatisk struktur). Nedan följer en enkel grammatik, baserad på Lisp :

expression ::= atom | list
atom       ::= number | symbol
number     ::= [+-]?['0'-'9']+
symbol     ::= ['A'-'Z''a'-'z'].*
list       ::= '(' expression* ')'

Denna grammatik anger följande:

  • ett uttryck är antingen en atom eller en lista ;
  • en atom är antingen ett tal eller en symbol ;
  • ett tal är en obruten sekvens med en eller flera decimaler, eventuellt föregående av ett plus- eller minustecken;
  • en symbol är en bokstav följt av noll eller fler av alla tecken (exklusive blanksteg); och
  • en lista är ett matchat par parenteser, med noll eller fler uttryck inuti.

Följande är exempel på välformade symboliska sekvenser i denna grammatik: 12345, ()och (a b c232 (1)).

Alla syntaktiskt korrekta program är inte semantiskt korrekta. Många syntaktiskt korrekta program är ändå dåligt utformade enligt språkets regler; och kan (beroende på språkspecifikationen och implementeringens sundhet) resultera i ett fel vid översättning eller körning. I vissa fall kan sådana program uppvisa odefinierat beteende . Även om ett program är väldefinierat inom ett språk kan det fortfarande ha en betydelse som inte är avsedd av den som skrev det.

Med naturligt språk som exempel är det kanske inte möjligt att tilldela en mening till en grammatiskt korrekt mening eller så kan meningen vara falsk:

Följande C -språkfragment är syntaktiskt korrekt, men utför operationer som inte är semantiskt definierade (operationen *p >> 4har ingen betydelse för ett värde som har en komplex typ och p->imär inte definierat eftersom värdet på pär nollpekaren ):

complex *p = NULL;
complex abs_p = sqrt(*p >> 4 + p->im);

Om typdeklarationen på den första raden utelämnades skulle programmet utlösa ett fel på odefinierad variabel punder sammanställningen. Programmet skulle dock fortfarande vara syntaktiskt korrekt eftersom typdeklarationer endast tillhandahåller semantisk information.

Grammatiken som behövs för att ange ett programmeringsspråk kan klassificeras efter dess position i Chomsky -hierarkin . Syntaxen för de flesta programmeringsspråk kan specificeras med en typ-2-grammatik, dvs de är sammanhangsfria grammatiker . Vissa språk, inklusive Perl och Lisp, innehåller konstruktioner som tillåter körning under analysfasen. Språk som har konstruktioner som gör att programmeraren kan ändra beteendet hos parsern gör syntaxanalys till ett obestämbart problem och i allmänhet suddar skillnaden mellan analys och körning. I motsats till Lisps makrosystem och Perls BEGINblock, som kan innehålla allmänna beräkningar, är C -makron bara strängbyten och kräver inte kodkörning.

Semantik

Termen semantik refererar till betydelsen av språk, i motsats till deras form ( syntax ).

Statisk semantik

Den statiska semantiken definierar begränsningar för strukturen av giltiga texter som är svåra eller omöjliga att uttrycka i vanliga syntaktiska formalismer. För sammanställda språk inkluderar statisk semantik i huvudsak de semantiska reglerna som kan kontrolleras vid kompileringstidpunkten. Exempel inkluderar att kontrollera att varje identifierare deklareras innan den används (på språk som kräver sådana deklarationer) eller att etiketterna på armarna i ett ärendebesked är olika. Många viktiga begränsningar av denna typ, som att kontrollera att identifierare används i rätt sammanhang (t.ex. att inte lägga till ett heltal i ett funktionsnamn), eller att subrutinsamtal har rätt antal och typ av argument, kan verkställas genom att definiera dem som regler i en logik som kallas ett typsystem . Andra former av statiska analyser som dataflödesanalys kan också vara en del av statisk semantik. Nyare programmeringsspråk som Java och C# har bestämd tilldelningsanalys , en form av dataflödesanalys, som en del av deras statiska semantik.

Dynamisk semantik

När data har specificerats måste maskinen instrueras att utföra operationer på data. Semantiken kan till exempel definiera den strategi genom vilken uttryck utvärderas till värden, eller hur kontrollstrukturer villkorligt utför uttalanden . Den dynamiska semantiken (även känd som exekutionssemantik ) för ett språk definierar hur och när de olika konstruktionerna av ett språk ska producera ett programbeteende. Det finns många sätt att definiera exekveringssemantik. Naturligt språk används ofta för att specificera exekveringssemantiken för språk som vanligtvis används i praktiken. En betydande mängd akademisk forskning gick in på formell semantik för programmeringsspråk , vilket gör att exekveringssemantik kan specificeras på ett formellt sätt. Resultat från detta forskningsområde har sett begränsad tillämpning på programmeringsspråksdesign och implementering utanför akademin.

Typsystem

Ett typsystem definierar hur ett programmeringsspråk klassificerar värden och uttryck i typer , hur det kan manipulera dessa typer och hur de interagerar. Målet med ett typsystem är att verifiera och vanligtvis genomdriva en viss nivå av korrekthet i program skrivna på det språket genom att upptäcka vissa felaktiga operationer. Alla system för avgörbar typ innebär en avvägning: även om det avvisar många felaktiga program kan det också förbjuda vissa korrekta, om än ovanliga program. För att kringgå denna baksida har ett antal språk typ kryphål , vanligtvis okontrollerade kast som kan användas av programmeraren för att uttryckligen tillåta en normalt otillåten operation mellan olika typer. På de flesta skrivspråk används typsystemet endast för att skriva kontrollprogram , men ett antal språk, vanligtvis funktionella, slutsatser , vilket befriar programmeraren från behovet av att skriva typkommentarer. Den formella utformningen och studien av typsystem kallas typteori .

Typat mot oskrivet språk

Ett språk skrivs in om specifikationen för varje operation definierar typer av data som operationen är tillämplig på. Till exempel är data som representeras av "this text between the quotes"en sträng , och i många programmeringsspråk har delning av ett tal med en sträng ingen betydelse och kommer inte att köras. Den ogiltiga åtgärden kan upptäckas när programmet kompileras ("statisk" typkontroll) och kommer att avvisas av kompilatorn med ett kompileringsfelmeddelande, eller så kan det upptäckas medan programmet körs ("dynamisk" typkontroll), vilket resulterar i undantag för körning . Många språk tillåter en funktion som kallas en undantagshanterare att hantera detta undantag och till exempel alltid returnera "-1" som resultatet.

Ett specialfall av maskinskrivna språk är de enkelskrivna språken. Dessa är ofta skript- eller markeringsspråk, till exempel REXX eller SGML , och har bara en datatyp - de vanligaste teckensträngarna som används för både symboliska och numeriska data.

Däremot tillåter ett oskrivet språk , som de flesta sammansättningsspråk , vilken operation som helst på alla data, vanligtvis sekvenser av bitar av olika längd. Högt skrivna språk inkluderar BCPL , Tcl och några sorter av Forth .

I praktiken, medan få språk anses vara typade från typteorin (verifiera eller avvisa alla operationer), erbjuder de flesta moderna språk en viss typ av skrivning. Många produktionsspråk ger medel för att kringgå eller undergräva typsystemet, byta typ-säkerhet för finare kontroll över programmets körning (se casting ).

Statisk kontra dynamisk skrivning

Vid statisk typning har alla uttryck sina typer bestämda före när programmet körs, vanligtvis vid kompileringstid. Till exempel är 1 och (2+2) heltalsuttryck; de kan inte skickas till en funktion som förväntar sig en sträng eller lagras i en variabel som är definierad för att hålla datum.

Statiskt skrivna språk kan antingen skrivas uppenbart eller antas . I det första fallet måste programmeraren uttryckligen skriva typer på vissa textpositioner (till exempel vid variabla deklarationer ). I det andra fallet, kompilatorn härleder de typer av uttryck och deklarationer baserade på sammanhanget. De flesta vanligt statiskt skrivna språk, som C ++ , C# och Java , skrivs uppenbarligen. Fullständig slutsats har traditionellt förknippats med mindre vanliga språk, till exempel Haskell och ML . Många uppenbarligen skrivna språk stöder emellertid partiell slutsats; till exempel C ++ , Java och C# alla slutsatser i vissa begränsade fall. Dessutom tillåter vissa programmeringsspråk att vissa typer automatiskt konverteras till andra typer; till exempel kan en int användas där programmet förväntar sig en float.

Dynamisk typning , även kallad latent typning , bestämmer typsäkerheten för operationer vid körning; med andra ord, typer är associerade med körtidsvärden snarare än textuttryck . Precis som med typinledda språk kräver dynamiskt skrivna språk inte programmeraren att skriva tydliga typkommentarer på uttryck. Detta kan bland annat tillåta att en enda variabel refererar till värden av olika typer på olika punkter i programkörningen. Men typ fel kan inte automatiskt upptäcks förrän en bit kod som faktiskt utförs, potentiellt göra felsökning svårare. Lisp , Smalltalk , Perl , Python , JavaScript och Ruby är alla exempel på dynamiskt skrivna språk.

Svag och stark skrivning

Svag skrivning gör att ett värde av en typ kan behandlas som en annan, till exempel att behandla en sträng som ett tal. Detta kan ibland vara användbart, men det kan också tillåta att vissa typer av programfel blir oupptäckta vid kompileringstid och till och med vid körning .

Stark skrivning förhindrar dessa programfel. Ett försök att utföra en operation på fel typ av värde ger ett fel. Starkt typade språk ofta kallas typ säker eller säker .

En alternativ definition för "svagt skrivna" avser språk, som Perl och JavaScript , som tillåter ett stort antal implicita typkonverteringar. I JavaScript, till exempel uttrycket 2 * xkonverteras implicit xtill ett nummer, och denna omvandling lyckas även om xär null, undefineden Array, eller en sträng av bokstäver. Sådana implicita konverteringar är ofta användbara, men de kan dölja programmeringsfel. Starka och statiska betraktas nu allmänt som ortogonala begrepp, men användningen i litteraturen skiljer sig åt. Vissa använder termen starkt maskinskriven för att betyda starkt, statiskt maskinskriven eller, ännu mer förvirrande, att helt enkelt beteckna statiskt . Således har C kallats både starkt maskinskrivet och svagt, statiskt typat.

Det kan tyckas konstigt för vissa professionella programmerare att C kan vara "svagt, statiskt typat". Observera dock att användningen av den generiska pekaren, void* -pekaren, gör det möjligt att kasta pekare till andra pekare utan att behöva göra en tydlig gjutning. Detta liknar extremt att på något sätt kasta en uppsättning byte till någon typ av datatyp i C utan att använda en explicit kast, till exempel (int)eller (char).

Standardbibliotek och körtidssystem

De flesta programmeringsspråk har en associerad kärn bibliotek (ibland kallas 'standardbiblioteket', särskilt om det ingår som en del av den publicerade språket standard), som konventionellt görs tillgänglig för alla implementeringar av språket. Kärnbibliotek innehåller vanligtvis definitioner för vanliga algoritmer, datastrukturer och mekanismer för in- och utdata.

Gränsen mellan ett språk och dess kärnbibliotek skiljer sig från språk till språk. I vissa fall kan språkdesignerna behandla biblioteket som en separat enhet från språket. Ett språks kärnbibliotek behandlas dock ofta som en del av språket av dess användare, och vissa språkspecifikationer kräver till och med att detta bibliotek görs tillgängligt i alla implementationer. Vissa språk är faktiskt utformade så att betydelsen av vissa syntaktiska konstruktioner inte ens kan beskrivas utan att referera till kärnbiblioteket. Till exempel i Java definieras en strängbokstav som en instans av java.lang.Stringklassen; på samma sätt, i Smalltalk , konstruerar ett anonymt funktionsuttryck (ett "block") en instans av bibliotekets BlockContextklass. Omvänt innehåller Scheme flera sammanhängande delmängder som räcker för att konstruera resten av språket som biblioteksmakron, och så bryr sig språkdesignerna inte ens om vilka delar av språket som måste implementeras som språkkonstruktioner, och vilka som måste implementeras som delar av ett bibliotek.

Design och implementering

Programmeringsspråk delar fastigheter med naturliga språk som är relaterade till deras syfte som kommunikationsmedel, med en syntaktisk form åtskild från dess semantik och visar språkfamiljer till besläktade språk som förgrenar sig från varandra. Men som konstgjorda konstruktioner skiljer de sig också på grundläggande sätt från språk som har utvecklats genom användning. En signifikant skillnad är att ett programmeringsspråk fullt ut kan beskrivas och studeras i sin helhet eftersom det har en exakt och ändlig definition. Däremot har naturliga språk förändrade betydelser som användarna ger i olika samhällen. Även om konstruerade språk också är konstgjorda språk utformade från grunden med ett specifikt syfte saknar de den exakta och fullständiga semantiska definitionen som ett programmeringsspråk har.

Många programmeringsspråk har utformats från grunden, ändrats för att möta nya behov och kombinerats med andra språk. Många har så småningom blivit oanvända. Även om det har gjorts försök att designa ett "universellt" programmeringsspråk som tjänar alla syften, har alla misslyckats med att allmänt accepteras som fyller denna roll. Behovet av olika programmeringsspråk härrör från mångfalden av sammanhang där språk används:

  • Programmen sträcker sig från små manus som skrivits av enskilda hobbyister till enorma system skrivna av hundratals programmerare .
  • Programmerare varierar i expertis från nybörjare som behöver enkelhet framför allt till experter som kan vara bekväma med stor komplexitet.
  • Program måste balansera hastighet, storlek och enkelhet på system som sträcker sig från mikrokontroller till superdatorer .
  • Program kan skrivas en gång och inte ändras på generationer, eller så kan de genomgå kontinuerliga ändringar.
  • Programmerare kan helt enkelt skilja sig åt i sin smak: de kan vara vana vid att diskutera problem och uttrycka dem på ett visst språk.

En vanlig trend i utvecklingen av programmeringsspråk har varit att lägga till mer förmåga att lösa problem med en högre abstraktionsnivå . De tidigaste programmeringsspråken var mycket nära knutna till datorns underliggande hårdvara. När nya programmeringsspråk har utvecklats har funktioner lagts till som låter programmerare uttrycka idéer som är mer avlägsna från enkel översättning till underliggande maskinvaruinstruktioner. Eftersom programmerare är mindre knutna till datorns komplexitet kan deras program göra mer beräkning med mindre ansträngning från programmeraren. Detta låter dem skriva mer funktionalitet per tidsenhet.

Naturligt språkprogrammering har föreslagits som ett sätt att eliminera behovet av ett specialiserat språk för programmering. Detta mål är dock fortfarande avlägset och dess fördelar är öppna för debatt. Edsger W. Dijkstra intog ståndpunkten att användningen av ett formellt språk är avgörande för att förhindra introduktion av meningslösa konstruktioner och avfärdade naturligt språkprogrammering som "dåraktigt". Alan Perlis avfärdade på samma sätt idén. Hybridmetoder har använts i strukturerad engelska och SQL .

Ett språks designers och användare måste konstruera ett antal artefakter som styr och möjliggör programmering. Den viktigaste av dessa artefakter är språkspecifikationen och genomförande .

Specifikation

Specifikationen av ett programmeringsspråk är en artefakt som språkanvändare och implementatörer kan använda för att komma överens om huruvida en bit källkod är ett giltigt program på det språket, och i så fall vad dess beteende skall vara.

En specifikation för programmeringsspråk kan ha flera former, inklusive följande:

Genomförande

En implementering av ett programmeringsspråk ger ett sätt att skriva program på det språket och köra dem på en eller flera konfigurationer av hårdvara och programvara. Det finns i stort två sätt att implementera programmeringsspråk: sammanställning och tolkning . Det är i allmänhet möjligt att implementera ett språk med endera tekniken.

Utmatningen från en kompilator kan köras av hårdvara eller ett program som kallas en tolk. I vissa implementeringar som använder tolkmetoden finns det ingen tydlig gräns mellan kompilering och tolkning. Till exempel kompilerar vissa implementeringar av BASIC och kör källan sedan en rad åt gången.

Program som körs direkt på hårdvaran körs vanligtvis mycket snabbare än de som tolkas i programvara.

En teknik för att förbättra prestanda för tolkade program är just-in-time compilation . Här översätter den virtuella maskinen , precis före körning, blocken av bytekod som kommer att användas för att bearbeta kod för direkt körning på hårdvaran.

Proprietära språk

Även om de flesta av de mest använda programmeringsspråken har helt öppna specifikationer och implementeringar, finns många programmeringsspråk bara som egna programmeringsspråk med implementeringen endast tillgänglig från en enda leverantör, vilket kan hävda att ett sådant språk är deras immateriella egendom. Egna programmeringsspråk är vanligtvis domänspecifika språk eller interna skriptspråk för en enda produkt; vissa språk används endast internt hos en leverantör, medan andra är tillgängliga för externa användare.

Vissa programmeringsspråk finns på gränsen mellan eget och öppet; t ex Oracle Corporation hävdar äganderätt till vissa aspekter av programmeringsspråket Java och Microsofts 's C # programmeringsspråk, som har öppna implementeringar av de flesta delar av systemet har också Common Language Runtime (CLR) som en sluten miljö.

Många proprietära språk används i stor utsträckning, trots sin egenutvecklade natur; exempel inkluderar MATLAB , VBScript och Wolfram Language . Vissa språk kan göra övergången från stängd till öppen; till exempel var Erlang ursprungligen ett Ericssons interna programmeringsspråk.

Använda sig av

Tusentals olika programmeringsspråk har skapats, främst inom databehandlingsområdet. Individuella programvaruprojekt använder vanligtvis fem programmeringsspråk eller fler.

Programmeringsspråk skiljer sig från de flesta andra former av mänskligt uttryck genom att de kräver en högre grad av precision och fullständighet. När man använder ett naturligt språk för att kommunicera med andra människor kan mänskliga författare och talare vara tvetydiga och göra små fel, och ändå förvänta sig att deras avsikt ska förstås. Men bildligt talat gör datorer "exakt vad de uppmanas att göra" och kan inte "förstå" vilken kod programmeraren tänkte skriva. Kombinationen av språkdefinitionen, ett program och programmets ingångar måste fullständigt specificera det externa beteendet som uppstår när programmet körs, inom kontrollområdet för det programmet. Å andra sidan kan idéer om en algoritm kommuniceras till människor utan den precision som krävs för exekvering med hjälp av pseudokod , som sammanfogar naturligt språk med kod skriven på ett programmeringsspråk.

Ett programmeringsspråk tillhandahåller en strukturerad mekanism för att definiera bitar av data och de operationer eller transformationer som kan utföras automatiskt på dessa data. En programmerare använder de abstraktioner som finns på språket för att representera begreppen som ingår i en beräkning. Dessa begrepp representeras som en samling av de enklaste elementen som finns tillgängliga (kallade primitiv ). Programmering är den process genom vilken programmerare kombinerar dessa primitiv för att komponera nya program eller anpassa befintliga till nya användningsområden eller en förändrad miljö.

Program för en dator kan köras i en batchprocess utan mänsklig interaktion, eller så kan en användare skriva kommandon i en interaktiv session hos en tolk . I detta fall är "kommandona" helt enkelt program vars körning är kedjad. När ett språk kan köra sina kommandon via en tolk (t.ex. ett Unix-skal eller ett annat kommandoradsgränssnitt ) utan att kompilera, kallas det ett skriptspråk .

Mätning av språkanvändning

Att avgöra vilket som är det mest använda programmeringsspråket är svårt eftersom definitionen av användning varierar beroende på sammanhang. Ett språk kan ta upp fler programmerartimmar, ett annat har fler kodrader och ett tredje kan ta mest CPU -tid. Vissa språk är mycket populära för vissa typer av applikationer. Till exempel är COBOL fortfarande starkt i företagsdatacenteret, ofta på stora stordatorer ; Fortran i vetenskapliga och tekniska tillämpningar; Ada inom flyg-, transport-, militär-, realtids- och inbäddade applikationer; och C i inbäddade applikationer och operativsystem. Andra språk används regelbundet för att skriva många olika typer av applikationer.

Olika metoder för att mäta språklig popularitet, var och en har olika fördomar över vad som mäts, har föreslagits:

  • räkna antalet jobbannonser som nämner språket
  • antalet böcker som säljs som lär eller beskriver språket
  • uppskattningar av antalet befintliga kodrader skrivna på språket - vilket kan underskatta språk som inte ofta finns i offentliga sökningar
  • antal språkreferenser (dvs. till namnet på språket) som hittats med hjälp av en webbsökmotor.

Genom att kombinera och genomsnittlig information från olika webbplatser rapporterade stackify.com de tio mest populära programmeringsspråken som (i fallande ordning efter total popularitet): Java , C , C ++ , Python , C# , JavaScript , VB .NET , R , PHP och MATLAB .

Dialekter, smaker och implementeringar

En dialekt av ett programmeringsspråk eller ett datautbytesspråk är en (relativt liten) variant eller förlängning av språket som inte förändrar dess inneboende natur. Med språk som Scheme och Forth kan standarder anses vara otillräckliga, otillräckliga eller olagliga av implementatörer, så ofta kommer de att avvika från standarden och göra en ny dialekt . I andra fall skapas en dialekt för användning på ett domenspecifikt språk , ofta en delmängd. I Lisp- världen anses de flesta språk som använder grundläggande S-uttryckssyntax och Lisp-liknande semantik betraktas som Lisp-dialekter, även om de varierar enormt, liksom Racket och Clojure . Eftersom det är vanligt att ett språk har flera dialekter kan det bli ganska svårt för en oerfaren programmerare att hitta rätt dokumentation. Den programmeringsspråket BASIC har många dialekter .

Explosionen av Forth -dialekter ledde till talesättet "Om du har sett en Forth ... har du sett en Forth."

Taxonomier

Det finns inget övergripande klassificeringsschema för programmeringsspråk. Ett givet programmeringsspråk har vanligtvis inte ett enda förfädersspråk. Språk uppstår vanligtvis genom att kombinera elementen i flera föregångarspråk med nya idéer i omlopp vid den tiden. Idéer som har sitt ursprung på ett språk kommer att spridas i en familj av besläktade språk och sedan plötsligt hoppa över familjehål för att visas i en helt annan familj.

Uppgiften kompliceras ytterligare av det faktum att språk kan klassificeras längs flera axlar. Till exempel är Java både ett objektorienterat språk (eftersom det uppmuntrar till objektorienterad organisation) och ett samtidigt språk (eftersom det innehåller inbyggda konstruktioner för att köra flera trådar parallellt). Python är ett objektorienterat skriptspråk .

I stora drag delar programmeringsspråk upp sig i programmeringsparadigm och en klassificering efter avsedd användningsdomän, med generella programmeringsspråk som skiljer sig från domänspecifika programmeringsspråk . Traditionellt har programmeringsspråk betraktats som beskrivande av beräkning i termer av tvingande meningar, dvs utfärdande av kommandon. Dessa kallas i allmänhet imperativa programmeringsspråk . Mycket forskning inom programmeringsspråk har syftat till att göra skillnaden mellan ett program som en uppsättning instruktioner och ett program som ett påstående om önskat svar, vilket är huvuddragen i deklarativ programmering, suddig . Mer förfinade paradigm inkluderar procedurprogrammering , objektorienterad programmering , funktionell programmering och logisk programmering ; vissa språk är paradigmhybrider eller multi-paradigmatiska. Ett monteringsspråk är inte så mycket ett paradigm som en direkt modell av en underliggande maskinarkitektur. Avsiktligt kan programmeringsspråk betraktas som allmänna ändamål, systemprogrammeringsspråk , skriptspråk, domenspecifika språk eller samtidiga/distribuerade språk (eller en kombination av dessa). Vissa språk för allmänna ändamål utformades till stor del med utbildningsmål.

Ett programmeringsspråk kan också klassificeras av faktorer som inte är relaterade till programmeringsparadigm. Till exempel använder de flesta programmeringsspråk engelska sökord, medan en minoritet inte gör det . Andra språk kan klassificeras som avsiktligt esoteriska eller inte.

Se även

Referenser

Vidare läsning

externa länkar