Programmeringssprog - Programming language

Den kildekoden til et simpelt computerprogram skrevet i sproget C programmering . De grå linjer er kommentarer, der hjælper med at forklare programmet for mennesker på et naturligt sprog . Når det kompileres og køres , vil det give output " Hej, verden! ".

Et programmeringssprog er et formelt sprog, der omfatter et sæt strenge, der producerer forskellige former for maskinkodeoutput . Programmeringssprog er en slags computersprog og bruges i computerprogrammering til at implementere algoritmer .

De fleste programmeringssprog består af instruktioner til computere . Der er programmerbare maskiner, der bruger et sæt specifikke instruktioner frem for generelle programmeringssprog . Siden begyndelsen af 1800'erne har programmerne været brugt til at lede adfærd maskiner såsom Jacquard væve , spilledåser og spiller klaverer . Programmerne til disse maskiner (f.eks. Et pianos klaverruller) producerede ikke forskellig adfærd som reaktion på forskellige input eller betingelser.

Tusindvis af forskellige programmeringssprog er blevet oprettet, og flere bliver oprettet hvert år. Mange programmeringssprog er skrevet i en tvingende form (dvs. som en sekvens af operationer, der skal udføres), mens andre sprog bruger den deklarative form (dvs. det ønskede resultat er angivet, ikke hvordan man opnår det).

Beskrivelsen af ​​et programmeringssprog er normalt opdelt i de to komponenter i syntaks (form) og semantik (betydning). Nogle sprog er defineret af et specifikationsdokument (f.eks. Er C -programmeringssproget specificeret af en ISO -standard), mens andre sprog (f.eks. Perl ) har en dominerende implementering , der behandles som en reference . Nogle sprog har begge dele, idet det grundlæggende sprog er defineret af en standard, og udvidelser taget fra den dominerende implementering er fælles.

Programmeringssprogsteori er et underfelt inden for datalogi, der beskæftiger sig med design, implementering, analyse, karakterisering og klassificering af programmeringssprog.

Definitioner

Et programmeringssprog er en notation for at skrive programmer , som er specifikationer for en beregning eller algoritme . Nogle forfattere begrænser udtrykket "programmeringssprog" til de sprog, der kan udtrykke alle mulige algoritmer. Egenskaber, der ofte betragtes som vigtige for, hvad der udgør et programmeringssprog, omfatter:

Funktion og mål
Et computerprogrammeringssprog er et sprog, der bruges til at skrive computerprogrammer , hvilket indebærer, at en computer udfører en form for beregning eller algoritme og muligvis styrer eksterne enheder såsom printere , diskdrev , robotter og så videre. For eksempel oprettes PostScript -programmer ofte af et andet program for at styre en computerprinter eller -skærm. Mere generelt kan et programmeringssprog beskrive beregning på en, muligvis abstrakt, maskine. Det er generelt accepteret, at en komplet specifikation for et programmeringssprog indeholder en beskrivelse, muligvis idealiseret, af en maskine eller processor til dette sprog. I de fleste praktiske sammenhænge involverer et programmeringssprog en computer; følgelig defineres og studeres programmeringssprog normalt på denne måde. Programmeringssprog adskiller sig fra naturlige sprog , idet naturlige sprog kun bruges til interaktion mellem mennesker, mens programmeringssprog også giver mennesker mulighed for at kommunikere instruktioner til maskiner.
Abstraktioner
Programmeringssprog indeholder normalt abstraktioner til at definere og manipulere datastrukturer eller kontrollere udførelsesstrømmen . Den praktiske nødvendighed, at et programmeringssprog understøtter tilstrækkelige abstraktioner, udtrykkes ved abstraktionsprincippet . Dette princip er undertiden formuleret som en anbefaling til programmøren om at gøre korrekt brug af sådanne abstraktioner.
Udtryksfuld kraft
Den teori om beregning klassificerer sprog ved beregningerne, de er i stand til at udtrykke. Alle Turing-komplette sprog kan implementere det samme sæt algoritmer . ANSI/ISO SQL-92 og Velgørenhed er eksempler på sprog, der ikke er Turing-færdige, men alligevel ofte kaldes programmeringssprog.

Markup -sprog som XML , HTML eller troff , der definerer strukturerede data , betragtes normalt ikke som programmeringssprog. Programmeringssprog kan dog dele syntaksen med markeringssprog, hvis der er defineret en beregningsmæssig semantik. XSLT er for eksempel et Turing -komplet sprog, der udelukkende bruger XML -syntaks. Desuden indeholder LaTeX , der mest bruges til strukturering af dokumenter, også en komplet Turing -delmængde.

Udtrykket computersprog bruges undertiden i flæng med programmeringssprog. Brugen af ​​begge udtryk varierer imidlertid mellem forfattere, herunder det nøjagtige omfang af hver. Én anvendelse beskriver programmeringssprog som en delmængde af computersprog. På samme måde er sprog, der bruges i computing, der har et andet mål end at udtrykke computerprogrammer, generelt betegnet computersprog. For eksempel omtales markupsprog undertiden som computersprog for at understrege, at de ikke er beregnet til at blive brugt til programmering.

En anden anvendelse betragter programmeringssprog som teoretiske konstruktioner til programmering af abstrakte maskiner og computersprog som delsættet deraf, der kører på fysiske computere, som har begrænsede hardwareresurser. John C. Reynolds understreger, at formelle specifikationssprog er lige så mange programmeringssprog som sprog, der er beregnet til udførelse. Han argumenterer også for, at tekst- og endda grafiske inputformater, der påvirker en computers adfærd, er programmeringssprog, på trods af at de normalt ikke er Turing-komplette, og bemærker, at uvidenhed om programmeringssprogskoncepter er årsagen til mange fejl i inputformater.

Historie

Tidlige udviklinger

Meget tidlige computere, såsom Colossus , blev programmeret uden hjælp af et lagret program ved at ændre deres kredsløb eller indstille banker til fysiske kontroller.

Lidt senere kunne programmer skrives på maskinsprog , hvor programmøren skriver hver instruktion i en numerisk form, som hardwaren kan udføre direkte. For eksempel kan instruktionen om at tilføje værdien i to hukommelsessteder bestå af 3 tal: en "opcode", der vælger "tilføj" -operationen og to hukommelsesplaceringer. Programmerne i decimal eller binær form blev læst ind fra hullede kort , papirbånd, magnetbånd eller slået til kontakter på computerens frontpanel . Maskinsprog blev senere betegnet første generations programmeringssprog (1GL).

Det næste trin var udviklingen af ​​de såkaldte anden generations programmeringssprog (2GL) eller samlingssprog , som stadig var tæt knyttet til instruktionssætets arkitektur for den specifikke computer. Disse tjente til at gøre programmet meget mere læseligt og lettede programmøren for kedelige og fejludsatte adresseberegninger.

De første programmeringssprog på højt niveau , eller tredje generations programmeringssprog (3GL), blev skrevet i 1950'erne. Et tidligt programmeringssprog på højt niveau, der skulle designes til en computer, var Plankalkül , udviklet til den tyske Z3 af Konrad Zuse mellem 1943 og 1945. Det blev dog først implementeret i 1998 og 2000.

John Mauchly 's Short Code , foreslog i 1949, var en af de første på højt niveau sprog nogensinde er udviklet til en elektronisk computer . I modsætning til maskinkode repræsenterede Short Code -sætninger matematiske udtryk i forståelig form. Programmet skulle imidlertid oversættes til maskinkode hver gang det kørte, hvilket gjorde processen meget langsommere end at køre den tilsvarende maskinkode.

University of Manchester , Alick Glennie udviklet Autocode i begyndelsen af 1950'erne. Som et programmeringssprog brugte det en compiler til automatisk at konvertere sproget til maskinkode. Den første kode og kompilator blev udviklet i 1952 til Mark 1- computeren ved University of Manchester og anses for at være det første sammensatte programmeringssprog på højt niveau.

Den anden autokode blev udviklet til Mark 1 af RA Brooker i 1954 og blev kaldt "Mark 1 Autocode". Brooker udviklede også en autokode til Ferranti Mercury i 1950'erne i forbindelse med University of Manchester. Versionen til EDSAC 2 blev udtænkt af DF Hartley fra University of Cambridge Mathematical Laboratory i 1961. Kendt som EDSAC 2 Autocode, det var en direkte udvikling fra Mercury Autocode tilpasset lokale forhold og blev kendt for sin objektkodeoptimering og kildesprog diagnostik, der blev avanceret til den tid. Atlas Autocode, der er en moderne, men separat udviklingstråd, blev udviklet til University of Manchester Atlas 1 -maskine.

I 1954 blev FORTRAN opfundet hos IBM af John Backus . Det var det første meget udbredte programmeringssprog på generelt højt plan til at have en funktionel implementering, i modsætning til kun et design på papir. Det er stadig et populært sprog til højtydende computere og bruges til programmer, der benchmarker og rangerer verdens hurtigste supercomputere .

Et andet tidligt programmeringssprog blev udtænkt af Grace Hopper i USA, kaldet FLOW-MATIC . Det blev udviklet til UNIVAC I ved Remington Rand i perioden fra 1955 til 1959. Hopper fandt ud af, at forretningsdatabehandlingskunder var utilpas med matematisk notation, og i begyndelsen af ​​1955 skrev hun og hendes team en specifikation for et engelsk programmeringssprog og implementerede en prototype. FLOW-MATIC-kompilatoren blev offentligt tilgængelig i begyndelsen af ​​1958 og var i det væsentlige færdig i 1959. FLOW-MATIC var en stor indflydelse på designet af COBOL , da kun den og dens direkte efterkommer AIMACO var i faktisk brug på det tidspunkt.

Forfining

Den øgede brug af sprog på højt niveau indførte et krav om programmeringssproglavt niveau eller systemprogrammeringssprog . Disse sprog giver i varierende grad faciliteter mellem samlingssprog og sprog på højt niveau. De kan bruges til at udføre opgaver, der kræver direkte adgang til hardwarefaciliteter, men stadig giver kontrolstrukturer på højere niveau og fejlkontrol.

Perioden fra 1960'erne til slutningen af ​​1970'erne bragte udviklingen af ​​de store sprogparadigmer, der nu er i brug:

Hvert af disse sprog affødte efterkommere, og de fleste moderne programmeringssprog tæller mindst et af dem i deres aner.

1960'erne og 1970'erne oplevede også betydelig debat om fordelene ved struktureret programmering , og om programmeringssprog skulle være designet til at understøtte det. Edsger Dijkstra , i et berømt brev fra 1968, der blev offentliggjort i ACM 's meddelelser , argumenterede for, at Goto -udsagn skulle fjernes fra alle programmer på "højere niveau".

Konsolidering og vækst

Et udvalg af lærebøger, der lærer programmering, på både populære og uklare sprog. Disse er kun få af de tusinder af programmeringssprog og dialekter, der er designet i historien.

1980'erne var år med relativ konsolidering. C ++ kombineret objektorienteret og systemprogrammering. Den amerikanske regering standardiserede Ada , et systemprogrammeringssprog afledt af Pascal og beregnet til brug af forsvarsentreprenører. I Japan og andre steder blev enorme summer brugt på at undersøge de såkaldte "femte generations" sprog, der inkorporerede logiske programmeringskonstruktioner. Det funktionelle sprogfællesskab flyttede til standardisering af ML og Lisp. I stedet for at opfinde nye paradigmer uddybede alle disse bevægelser de ideer, der blev opfundet i de foregående årtier.

En vigtig tendens i sprogdesign til programmering af store systemer i løbet af 1980'erne var et øget fokus på brugen af moduler eller store organisatoriske kodeenheder. Modula-2 , Ada og ML udviklede alle bemærkelsesværdige modulsystemer i 1980'erne, som ofte var knyttet til generiske programmeringskonstruktioner .

Den hurtige vækst i internettet i midten af 1990'erne skabt muligheder for nye sprog. Perl , oprindeligt et Unix -scriptværktøj, der først blev udgivet i 1987, blev almindeligt på dynamiske websteder . Java kom til at blive brugt til programmering på serversiden, og virtuelle bytecode-maskiner blev igen populære i kommercielle omgivelser med deres løfte om " Skriv en gang, kør hvor som helst " ( UCSD Pascal havde været populær i en tid i begyndelsen af ​​1980'erne). Disse udviklinger var ikke grundlæggende nye; de var snarere forbedringer af mange eksisterende sprog og paradigmer (selvom deres syntaks ofte var baseret på C -familien af ​​programmeringssprog).

Programmeringssprogsudviklingen fortsætter i både industri og forskning. Nuværende anvisninger omfatter verifikation af sikkerhed og pålidelighed , nye former for modularitet ( mixins , delegerede , aspekter ) og databaseintegration såsom Microsofts LINQ .

Fjerde generations programmeringssprog (4GL) er computerprogrammeringssprog, der har til formål at give et højere abstraktionsniveau af de interne computerhardwaredetaljer end 3GL'er. Femte generations programmeringssprog (5GL) er programmeringssprog baseret på at løse problemer ved hjælp af begrænsninger givet til programmet, frem for at bruge en algoritme skrevet af en programmør.

Elementer

Alle programmeringssprog har nogle primitive byggesten til beskrivelse af data og de processer eller transformationer, der anvendes på dem (f.eks. Tilføjelse af to tal eller valg af et element fra en samling). Disse primitiver er defineret af syntaktiske og semantiske regler, der beskriver henholdsvis deres struktur og betydning.

Syntaks

Parsetræ af Python -kode med indsat tokenisering
Syntaksfremhævelse bruges ofte til at hjælpe programmører med at genkende elementer i kildekoden. Sproget ovenfor er Python .

Et programmeringssprogs overfladeform er kendt som dets syntaks . De fleste programmeringssprog er rent tekstlige; de bruger tekstsekvenser, herunder ord, tal og tegnsætning, ligesom skriftlige naturlige sprog. På den anden side er der nogle programmeringssprog, der er mere grafiske i naturen, ved hjælp af visuelle forhold mellem symboler til at specificere et program.

Syntaksen for et sprog beskriver de mulige kombinationer af symboler, der danner et syntaktisk korrekt program. Betydningen givet til en kombination af symboler håndteres af semantik (enten formel eller hårdkodet i en referenceimplementering ). Da de fleste sprog er tekstlige, diskuterer denne artikel tekstsyntaks.

Programmeringssprogssyntaks defineres normalt ved hjælp af en kombination af regulære udtryk (for leksikalsk struktur) og Backus – Naur -form (for grammatisk struktur). Nedenfor er en simpel grammatik, baseret på Lisp :

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

Denne grammatik specificerer følgende:

  • et udtryk er enten et atom eller en liste ;
  • et atom er enten et tal eller et symbol ;
  • et tal er en ubrudt sekvens af et eller flere decimalcifre, eventuelt forud for et plus- eller minustegn;
  • et symbol er et bogstav efterfulgt af nul eller flere af alle tegn (undtagen mellemrum); og
  • en liste er et par parenteser, der har nul eller flere udtryk indeni.

Følgende er eksempler på velformede token sekvenser i denne grammatik: 12345, ()og (a b c232 (1)).

Ikke alle syntaktisk korrekte programmer er semantisk korrekte. Mange syntaktisk korrekte programmer er ikke desto mindre dårligt formede i henhold til sprogets regler; og kan (afhængigt af sprogspecifikationen og implementeringens sundhed) resultere i en fejl ved oversættelse eller udførelse. I nogle tilfælde kan sådanne programmer udvise en udefineret adfærd . Selv når et program er veldefineret inden for et sprog, kan det stadig have en betydning, som ikke er tiltænkt af den person, der skrev det.

Ved at bruge naturligt sprog som eksempel er det muligvis ikke muligt at tildele en mening til en grammatisk korrekt sætning, eller sætningen kan være falsk:

Det følgende C -sprogfragment er syntaktisk korrekt, men udfører operationer, der ikke er semantisk definerede (operationen *p >> 4har ingen betydning for en værdi, der har en kompleks type og p->imer ikke defineret, fordi værdien af per nullmarkøren ):

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

Hvis typedeklarationen på den første linje blev udeladt, ville programmet udløse en fejl på en udefineret variabel punder kompilering. Programmet vil dog stadig være syntaktisk korrekt, da typedeklarationer kun giver semantisk information.

Den grammatik, der er nødvendig for at angive et programmeringssprog, kan klassificeres efter dens position i Chomsky -hierarkiet . Syntaksen for de fleste programmeringssprog kan specificeres ved hjælp af en Type-2-grammatik, dvs. de er kontekstfrie grammatikker . Nogle sprog, herunder Perl og Lisp, indeholder konstruktioner, der tillader udførelse under analysefasen. Sprog, der har konstruktioner, der gør det muligt for programmøren at ændre parserens adfærd, gør syntaksanalyse til et uafklareligt problem og slører generelt sondringen mellem parsing og eksekvering. I modsætning til Lisp's makrosystem og Perls BEGINblokke, som kan indeholde generelle beregninger, er C -makroer blot strengudskiftninger og kræver ikke kodeudførelse.

Semantik

Udtrykket semantik refererer til sprogets betydning i modsætning til deres form ( syntaks ).

Statisk semantik

Den statiske semantik definerer begrænsninger for strukturen af ​​gyldige tekster, der er svære eller umulige at udtrykke i standard syntaktiske formalismer. For kompilerede sprog inkluderer statisk semantik i det væsentlige de semantiske regler, der kan kontrolleres ved kompileringstidspunktet. Eksempler omfatter kontrol af, at hver identifikator er erklæret, før den bruges (på sprog, der kræver sådanne erklæringer), eller at etiketterne på armen på en sagserklæring er forskellige. Mange vigtige begrænsninger af denne type, som f.eks. At kontrollere, at identifikatorer bruges i den relevante kontekst (f.eks. Ikke at tilføje et helt tal til et funktionsnavn), eller at subrutineopkald har det passende antal og typen argumenter, kan håndhæves ved at definere dem som regler i en logik kaldet et typesystem . Andre former for statiske analyser som dataflowanalyse kan også være en del af statisk semantik. Nyere programmeringssprog som Java og C# har decideret tildelingsanalyse , en form for dataflowanalyse, som en del af deres statiske semantik.

Dynamisk semantik

Når data er angivet, skal maskinen instrueres i at udføre operationer på dataene. For eksempel kan semantikken definere den strategi, hvormed udtryk evalueres til værdier, eller den måde, hvorpå kontrolstrukturer betinget udfører udsagn . Den dynamiske semantik (også kendt som eksekveringssemantik ) i et sprog definerer, hvordan og hvornår de forskellige konstruktioner af et sprog skal frembringe en programadfærd. Der er mange måder at definere eksekveringssemantik på. Naturligt sprog bruges ofte til at specificere eksekveringssemantikken for sprog, der normalt bruges i praksis. En betydelig mængde akademisk forskning gik ind på formel semantik i programmeringssprog , som gør det muligt at specificere eksekveringssemantik på en formel måde. Resultater fra dette forskningsfelt har set begrænset anvendelse på programmeringssprogs design og implementering uden for den akademiske verden.

Typesystem

Et typesystem definerer, hvordan et programmeringssprog klassificerer værdier og udtryk i typer , hvordan det kan manipulere disse typer og hvordan de interagerer. Målet med et typesystem er at verificere og normalt håndhæve et vist niveau af korrekthed i programmer, der er skrevet på det sprog, ved at registrere visse forkerte handlinger. Ethvert system, der kan vælges , indebærer en afvejning: Selvom det afviser mange forkerte programmer, kan det også forbyde nogle korrekte, omend usædvanlige programmer. For at omgå denne ulempe har et antal sprog type smuthuller , normalt ukontrollerede kast, der kan bruges af programmereren til eksplicit at tillade en normalt ikke tilladt operation mellem forskellige typer. I de fleste typesprog bruges typesystemet kun til at skrive tjekprogrammer, men et antal sprog, normalt funktionelle, udleder typer , hvilket befri programmereren fra behovet for at skrive typeanmærkninger. Det formelle design og undersøgelse af typesystemer er kendt som typeteori .

Skrevet versus ikke -indtastede sprog

Der skrives et sprog, hvis specifikationen for hver operation definerer datatyper, som operationen er relevant for. For eksempel er dataene repræsenteret ved "this text between the quotes"en streng , og i mange programmeringssprog har et tal med en streng ingen betydning og vil ikke blive eksekveret. Den ugyldige handling kan blive opdaget, når programmet kompileres ("statisk" typekontrol) og vil blive afvist af kompilatoren med en kompilationsfejlmeddelelse, eller det kan blive opdaget, mens programmet kører ("dynamisk" typekontrol), hvilket resulterer i en undtagelse i løbetid . Mange sprog tillader en funktion kaldet en undtagelseshåndterer at håndtere denne undtagelse og f.eks. Altid returnere "-1" som resultatet.

Et specielt tilfælde af indtastede sprog er de enkelttypede sprog. Disse er ofte script- eller markeringssprog, f.eks. REXX eller SGML , og har kun én datatype - mest almindelige tegnstrenge, der bruges til både symbolske og numeriske data.

I modsætning hertil tillader et ubeskrevet sprog , såsom de fleste samlingssprog , enhver handling at udføre på alle data, generelt sekvenser af bits af forskellig længde. Højt niveau ikke-indtastede sprog inkluderer BCPL , Tcl og nogle sorter af Forth .

I praksis, mens få sprog anses for at være skrevet fra typeteorien (verificering eller afvisning af alle operationer), tilbyder de fleste moderne sprog en grad af typning. Mange produktionssprog tilvejebringer midler til at omgå eller undergrave typesystemet, bytte type-sikkerhed for finere kontrol over programmets udførelse (se casting ).

Statisk versus dynamisk skrivning

Ved statisk typning har alle udtryk deres typer bestemt, før programmet udføres, typisk ved kompileringstidspunkt. For eksempel er 1 og (2+2) heltalsudtryk; de kan ikke sendes til en funktion, der forventer en streng eller gemmes i en variabel, der er defineret til at indeholde datoer.

Statisk indtastede sprog kan enten være tydeligt indtastet eller afledt . I det første tilfælde skal programmøren eksplicit skrive typer på bestemte tekstpositioner (f.eks. Ved variable deklarationer ). I det andet tilfælde, compileren udleder de typer af udtryk og erklæringer baseret på kontekst. De fleste almindelige statisk typede sprog, såsom C ++ , C# og Java , er tydeligvis skrevet. Komplet type slutning har traditionelt været forbundet med mindre almindelige sprog, såsom Haskell og ML . Imidlertid understøtter mange tydelig typede sprog delvis type slutning; for eksempel C ++ , Java og C# alle udlede typer i visse begrænsede tilfælde. Derudover tillader nogle programmeringssprog, at nogle typer automatisk konverteres til andre typer; for eksempel kan en int bruges, hvor programmet forventer en float.

Dynamisk typning , også kaldet latent typing , bestemmer typesikkerheden ved operationer i løbetid; med andre ord er typer forbundet med værdier i løbetid frem for tekstudtryk . Som med sprog, der udledes af typen, kræver dynamisk indtastede sprog ikke, at programmereren skriver eksplicitte typeanmærkninger på udtryk. Dette kan blandt andet muliggøre, at en enkelt variabel refererer til værdier af forskellige typer på forskellige punkter i programmets udførelse. Men typen fejl ikke kan registreres automatisk, indtil et stykke kode er faktisk henrettet, potentielt gør debugging vanskeligere. Lisp , Smalltalk , Perl , Python , JavaScript og Ruby er alle eksempler på dynamisk indtastede sprog.

Svag og stærk skrivemåde

Svag skrivning gør det muligt at behandle en værdi af en type som en anden, for eksempel at behandle en streng som et tal. Dette kan lejlighedsvis være nyttigt, men det kan også tillade, at nogle former for programfejl ikke opdages på kompileringstidspunktet og endda i løbetid .

Stærk indtastning forhindrer disse programfejl. Et forsøg på at udføre en handling på den forkerte værditype giver anledning til en fejl. Stærkt indtastede sprog betegnes ofte som typesikre eller sikre .

En alternativ definition for "svagt indtastet" refererer til sprog, f.eks. Perl og JavaScript , som tillader et stort antal implicitte konverteringer. I JavaScript for eksempel udtrykket 2 * ximplicit konverterer xtil et nummer, og denne konvertering lykkes, selv om xer null, undefinedet Array, eller en streng af bogstaver. Sådanne implicitte konverteringer er ofte nyttige, men de kan maskere programmeringsfejl. Stærk og statisk betragtes nu generelt som ortogonale begreber, men brugen i litteraturen er forskellig. Nogle bruger udtrykket stærkt skrevet til at betyde stærkt, statisk indtastet eller endnu mere forvirrende at betyde simpelthen statisk maskinskrevet . Således er C blevet kaldt både stærkt maskinskrevet og svagt, statisk skrevet.

Det kan virke mærkeligt for nogle professionelle programmører, at C kunne være "svagt, statisk skrevet". Bemærk dog, at brugen af ​​den generiske markør, void* pointer, muliggør casting af pointers til andre pointers uden at skulle foretage en eksplicit cast. Dette ligner ekstremt meget som på en eller anden måde at kaste en række bytes til enhver form for datatype i C uden at bruge en eksplicit cast, såsom (int)eller (char).

Standard bibliotek og driftstidssystem

De fleste programmeringssprog har et tilhørende kernebibliotek (undertiden kendt som 'standardbiblioteket', især hvis det er inkluderet som en del af den publicerede sprogstandard), som konventionelt stilles til rådighed af alle implementeringer af sproget. Kernebiblioteker indeholder typisk definitioner for almindeligt anvendte algoritmer, datastrukturer og mekanismer til input og output.

Grænsen mellem et sprog og dets kernebibliotek er forskellig fra sprog til sprog. I nogle tilfælde behandler sprogdesignerne biblioteket som en separat enhed fra sproget. Imidlertid behandles et sprogs kernebibliotek ofte som en del af sproget af dets brugere, og nogle sprogspecifikationer kræver endda, at dette bibliotek gøres tilgængeligt i alle implementeringer. Nogle sprog er faktisk designet, så betydningen af ​​visse syntaktiske konstruktioner ikke engang kan beskrives uden at henvise til kernebiblioteket. For eksempel i Java er en streng bogstavelig defineret som en forekomst af java.lang.Stringklassen; ligeledes i Smalltalk , en anonym funktion ekspression (en "blok") konstruerer en instans af bibliotekets BlockContextklasse. Omvendt indeholder Scheme flere sammenhængende undersæt, der er tilstrækkelige til at konstruere resten af ​​sproget som biblioteksmakroer, og derfor gider sprogdesignerne ikke engang at sige, hvilke dele af sproget der skal implementeres som sprogkonstruktioner, og hvilke der skal implementeres som dele af et bibliotek.

Design og implementering

Programmeringssprog deler egenskaber med naturlige sprog, der er relateret til deres formål som kommunikationsmidler, med en syntaktisk form adskilt fra dens semantik og viser sprogfamilier på beslægtede sprog, der forgrener sig fra hinanden. Men som kunstige konstruktioner adskiller de sig også på grundlæggende måder fra sprog, der har udviklet sig gennem brug. En væsentlig forskel er, at et programmeringssprog kan beskrives og studeres fuldt ud i sin helhed, da det har en præcis og endelig definition. Derimod har naturlige sprog skiftende betydninger givet af deres brugere i forskellige samfund. Mens konstruerede sprog også er kunstige sprog designet fra bunden med et specifikt formål, mangler de den præcise og komplette semantiske definition, som et programmeringssprog har.

Mange programmeringssprog er designet fra bunden, ændret for at imødekomme nye behov og kombineret med andre sprog. Mange er i sidste ende faldet i brug. Selvom der har været forsøg på at designe ét "universelt" programmeringssprog, der tjener alle formål, er det ikke lykkedes dem alle generelt at udfylde denne rolle. Behovet for forskellige programmeringssprog stammer fra mangfoldigheden af ​​kontekster, hvor sprog bruges:

  • Programmer spænder fra bittesmå scripts skrevet af individuelle hobbyfolk til enorme systemer skrevet af hundredvis af programmører .
  • Programmerere spænder fra ekspertise fra nybegyndere, der har brug for enkelhed frem for alt til eksperter, der kan have det godt med en betydelig kompleksitet.
  • Programmer skal afbalancere hastighed, størrelse og enkelhed på systemer lige fra mikrocontrollere til supercomputere .
  • Programmer kan skrives en gang og ikke ændres i generationer, eller de kan løbende ændres.
  • Programmerere kan ganske enkelt variere i deres smag: de er måske vant til at diskutere problemer og udtrykke dem på et bestemt sprog.

En fælles tendens i udviklingen af ​​programmeringssprog har været at tilføje flere evner til at løse problemer ved hjælp af et højere abstraktionsniveau . De tidligste programmeringssprog var knyttet meget tæt til computerens underliggende hardware. Efterhånden som nye programmeringssprog er udviklet, er der tilføjet funktioner, der lader programmører udtrykke ideer, der er mere fjernt fra simpel oversættelse til underliggende hardwareinstruktioner. Fordi programmører er mindre knyttet til computerens kompleksitet, kan deres programmer lave mere computing med mindre indsats fra programmøren. Dette lader dem skrive mere funktionalitet pr. Tidsenhed.

Natursproget programmering er blevet foreslået som en måde at eliminere behovet for et specialiseret sprog til programmering. Dette mål er imidlertid stadig fjernt, og dets fordele er åbne for debat. Edsger W. Dijkstra indtog den holdning, at brugen af ​​et formelt sprog er afgørende for at forhindre indførelse af meningsløse konstruktioner og afviste programmering af naturligt sprog som "tåbeligt". Alan Perlis afviste på samme måde ideen. Hybride tilgange er blevet taget i struktureret engelsk og SQL .

Et sprogs designere og brugere skal konstruere en række artefakter, der styrer og muliggør programmering. De vigtigste af disse artefakter er sproget specifikationen og implementering .

Specifikation

Specifikationen af et programmeringssprog er en artefakt, at de sproglige brugere og implementors kan bruge til at blive enige om, hvorvidt et stykke kildekode er en gyldig program på dette sprog, og hvis ja, hvad dens adfærd skal være.

En programmeringssprogsspecifikation kan antage flere former, herunder følgende:

Implementering

En implementering af et programmeringssprog giver en måde at skrive programmer på det sprog og udføre dem på en eller flere konfigurationer af hardware og software. Der er stort set to metoder til implementering af programmeringssprog: kompilering og fortolkning . Det er generelt muligt at implementere et sprog ved hjælp af begge teknikker.

Output fra en compiler kan udføres af hardware eller et program kaldet en tolk. I nogle implementeringer, der gør brug af tolketilgangen, er der ingen tydelig grænse mellem kompilering og fortolkning. For eksempel kompilerer nogle implementeringer af BASIC og udfører derefter kilden en linje ad gangen.

Programmer, der udføres direkte på hardwaren, kører normalt meget hurtigere end dem, der tolkes i software.

En teknik til forbedring af udførelsen af ​​fortolkede programmer er kompilering lige i tide . Her oversætter den virtuelle maskine , lige før eksekvering, de byte -kodeblokke, der skal bruges til at maskinkode, til direkte udførelse på hardwaren.

Proprietære sprog

Selvom de fleste af de mest anvendte programmeringssprog har helt åbne specifikationer og implementeringer, eksisterer mange programmeringssprog kun som proprietære programmeringssprog, med implementeringen kun tilgængelig fra en enkelt leverandør, hvilket kan hævde, at et sådant proprietært sprog er deres intellektuelle ejendomsret. Proprietære programmeringssprog er almindeligvis domænespecifikke sprog eller interne scriptsprog for et enkelt produkt; nogle proprietære sprog bruges kun internt hos en leverandør, mens andre er tilgængelige for eksterne brugere.

Nogle programmeringssprog findes på grænsen mellem proprietær og åben; for eksempel, Oracle Corporation hævder ejendomsrettigheder til nogle aspekter af programmeringssproget Java , og Microsoft 's C # programmeringssprog, der har åbne implementeringer af de fleste dele af systemet, har også Common Language Runtime (CLR) som et lukket miljø.

Mange proprietære sprog er meget udbredt på trods af deres ejendomsretlige karakter; eksempler inkluderer MATLAB , VBScript og Wolfram Language . Nogle sprog kan gøre overgangen fra lukket til åben; for eksempel var Erlang oprindeligt et Ericssons interne programmeringssprog.

Brug

Tusindvis af forskellige programmeringssprog er blevet oprettet, hovedsageligt inden for databehandlingsområdet. Individuelle softwareprojekter bruger normalt fem programmeringssprog eller mere.

Programmeringssprog adskiller sig fra de fleste andre former for menneskeligt udtryk, idet de kræver en større grad af præcision og fuldstændighed. Når man bruger et naturligt sprog til at kommunikere med andre mennesker, kan menneskelige forfattere og talere være tvetydige og lave små fejl og stadig forvente, at deres hensigt bliver forstået. Men billedligt talt gør computere "præcis det, de får besked på at gøre", og kan ikke "forstå", hvilken kode programmøren havde til hensigt at skrive. Kombinationen af ​​sprogdefinitionen, et program og programmets input skal fuldt ud specificere den eksterne adfærd, der opstår, når programmet udføres inden for kontrolområdet for det pågældende program. På den anden side kan ideer om en algoritme kommunikeres til mennesker uden den præcision, der kræves til udførelse ved hjælp af pseudokode , som blander naturligt sprog med kode skrevet i et programmeringssprog.

Et programmeringssprog tilvejebringer en struktureret mekanisme til at definere stykker data og de operationer eller transformationer, der kan udføres automatisk på disse data. En programmør bruger abstraktionerne i sproget til at repræsentere de begreber, der er involveret i en beregning. Disse begreber er repræsenteret som en samling af de enkleste tilgængelige elementer (kaldet primitiver ). Programmering er den proces, hvorved programmører kombinerer disse primitiver til at sammensætte nye programmer eller tilpasse eksisterende programmer til nye anvendelser eller et miljø i forandring.

Programmerne for en computer kan udføres i en batchproces uden menneskelig interaktion, eller en bruger kan skrive kommandoer i en interaktiv session af en tolk . I dette tilfælde er "kommandoer" simpelthen programmer, hvis udførelse kædes sammen. Når et sprog kan køre sine kommandoer gennem en tolk (f.eks. En Unix-shell eller anden kommandolinjegrænseflade ) uden at kompilere, kaldes det et scriptsprog .

Måling af sprogbrug

Det er vanskeligt at bestemme, hvilket er det mest anvendte programmeringssprog, da definitionen af ​​brug varierer efter kontekst. Et sprog kan optage det større antal programmerertimer, et andet har flere kodelinjer, og et tredje kan bruge mest CPU -tid. Nogle sprog er meget populære til bestemte former for applikationer. F.eks. Står COBOL stadig stærkt i virksomhedens datacenter, ofte på store mainframes ; Fortran inden for videnskabelige og tekniske applikationer; Ada inden for rumfart, transport, militær, realtid og integrerede applikationer; og C i integrerede applikationer og operativsystemer. Andre sprog bruges regelmæssigt til at skrive mange forskellige slags applikationer.

Der er blevet foreslået forskellige metoder til måling af sprogets popularitet, der hver har en forskellig bias over det, der måles:

  • tælle antallet af stillingsannoncer, der nævner sproget
  • antallet af solgte bøger, der underviser eller beskriver sproget
  • skøn over antallet af eksisterende kodelinjer skrevet på sproget - hvilket kan undervurdere sprog, der ikke ofte findes i offentlige søgninger
  • optællinger af sprogreferencer (dvs. til sprogets navn) fundet ved hjælp af en websøgemaskine.

Ved at kombinere og beregne oplysninger fra forskellige internetsider rapporterede stackify.com de ti mest populære programmeringssprog som (i faldende rækkefølge efter samlet popularitet): Java , C , C ++ , Python , C# , JavaScript , VB .NET , R , PHP og MATLAB .

Dialekter, smag og implementeringer

En dialekt af et programmeringssprog eller et dataudvekslingssprog er en (relativt lille) variation eller udvidelse af sproget, der ikke ændrer dets iboende karakter. Med sprog som Scheme og Forth kan standarder anses for utilstrækkelige, utilstrækkelige eller ulovlige af implementatorer, så ofte vil de afvige fra standarden og lave en ny dialekt . I andre tilfælde oprettes en dialekt til brug på et domænespecifikt sprog , ofte et delsæt. I Lisp- verden betragtes de fleste sprog, der bruger grundlæggende S-udtrykssyntaks og Lisp-lignende semantik, som Lisp-dialekter, selvom de varierer voldsomt, som f.eks. Racket og Clojure . Da det er almindeligt, at et sprog har flere dialekter, kan det blive ret svært for en uerfaren programmør at finde den rigtige dokumentation. Den BASIC programmeringssprog har mange dialekter .

Eksplosionen af ​​Forth -dialekter førte til ordsproget "Hvis du har set en Forth ... har du set en Forth."

Taksonomier

Der er ingen overordnet klassificeringsordning for programmeringssprog. Et givet programmeringssprog har normalt ikke et enkelt forfædresprog. Sprog opstår sædvanligvis ved at kombinere elementerne i flere forgængersprog med nye ideer i omløb dengang. Ideer, der stammer fra ét sprog, vil sprede sig i en familie af beslægtede sprog og derefter pludselig springe over familiære huller for at blive vist i en helt anden familie.

Opgaven kompliceres yderligere af, at sprog kan klassificeres langs flere akser. For eksempel er Java både et objektorienteret sprog (fordi det tilskynder til objektorienteret organisation) og et samtidigt sprog (fordi det indeholder indbyggede konstruktioner til at køre flere tråde parallelt). Python er et objektorienteret scriptsprog .

I store streger opdeles programmeringssprog i programmeringsparadigmer og en klassificering efter tiltænkt brugsdomæne, med generelle programmeringssprog adskilt fra domænespecifikke programmeringssprog . Traditionelt har programmeringssprog været betragtet som at beskrive beregning i form af tvingende sætninger, dvs. udsendelse af kommandoer. Disse kaldes generelt imperative programmeringssprog . En stor forskning i programmeringssprog har været rettet mod at sløre sondringen mellem et program som et sæt instruktioner og et program som en påstand om det ønskede svar, som er hovedtræk ved deklarativ programmering . Mere forfinede paradigmer omfatter procedureprogrammering , objektorienteret programmering , funktionel programmering og logisk programmering ; nogle sprog er hybrider af paradigmer eller multi-paradigmatiske. Et forsamlingssprog er ikke så meget et paradigme som en direkte model af en underliggende maskinarkitektur. Med det formål kan programmeringssprog betragtes som generelle formål, systemprogrammeringssprog , scriptsprog, domænespecifikke sprog eller samtidige/distribuerede sprog (eller en kombination af disse). Nogle sprog til generelle formål blev stort set designet med uddannelsesmål.

Et programmeringssprog kan også klassificeres efter faktorer, der ikke er relateret til programmeringsparadigme. For eksempel, de fleste programmeringssprog bruger engelsksprogede søgeord, mens et mindretal ikke gøre . Andre sprog kan klassificeres som bevidst esoteriske eller ej.

Se også

Referencer

Yderligere læsning

eksterne links