Programozási nyelv - Programming language

A forráskód egy egyszerű számítógépes program írva a C programozási nyelv . A szürke vonalak olyan megjegyzések, amelyek segítenek elmagyarázni a programot az embereknek természetes nyelven . Amikor össze és fut , akkor ad kimeneti „ Helló, világ! ”.

A programozási nyelv egy formális nyelv, amely egy sor karakterláncot tartalmaz , amelyek különféle típusú gépi kimenetet hoznak létre . A programozási nyelvek a számítógépes nyelv egyik fajtája , és a számítógépes programozásban algoritmusok megvalósítására használják .

A legtöbb programozási nyelvek állnak utasításokat a számítógépek . Vannak olyan programozható gépek, amelyek speciális utasításokat használnak , nem pedig általános programozási nyelveket . Az 1800 -as évek eleje óta programokat használnak olyan gépek viselkedésének irányítására, mint Jacquard szövőszékek , zenei dobozok és játékos zongorák . Ezeknek a gépeknek a programjai (például a zongorázó tekercsek) nem viselkedtek másképp a különböző bemenetekre vagy körülményekre reagálva.

Különféle programozási nyelvek ezreit hozták létre, és évente újabbakat hoznak létre. Sok programozási nyelv kényszerítő formában (azaz végrehajtandó műveletsorként) van írva, míg más nyelvek a kijelentő formát használják (azaz a kívánt eredmény van megadva, nem pedig annak elérési módja).

A programozási nyelv leírása általában a szintaxis (forma) és a szemantika (jelentés) két összetevőjére oszlik . Egyes nyelveket egy specifikációs dokumentum határoz meg (például a C programozási nyelvet egy ISO szabvány határozza meg ), míg más nyelvek (például a Perl ) domináns megvalósítással rendelkeznek, amelyet referenciaként kezelnek . Néhány nyelv rendelkezik mindkettővel, az alapnyelvet szabvány határozza meg, és a domináns implementációból vett kiterjesztések gyakoriak.

A programozási nyelvelmélet a számítástechnika egyik részterülete, amely a programozási nyelvek tervezésével, megvalósításával, elemzésével, jellemzésével és osztályozásával foglalkozik.

Definíciók

A programozási nyelv egy jelölés a programok írására , amelyek egy számítás vagy algoritmus specifikációi . Egyes szerzők a "programozási nyelv" kifejezést azokra a nyelvekre korlátozzák, amelyek minden lehetséges algoritmust képesek kifejezni. A programozási nyelv szempontjából gyakran fontosnak tartott tulajdonságok a következők:

Funkció és cél
A számítógépes programozási nyelv olyan számítógépes programok írására használt nyelv , amely magában foglalja a számítógépet, amely valamilyen számítást vagy algoritmust hajt végre, és esetleg külső eszközöket, például nyomtatókat , lemezmeghajtókat , robotokat stb. Például a PostScript programokat gyakran egy másik program hozza létre a számítógép nyomtatójának vagy kijelzőjének vezérlésére. Általánosságban elmondható, hogy egy programozási nyelv leírhatja a számítást néhány, esetleg elvont gépen. Általánosan elfogadott, hogy a programozási nyelv teljes specifikációja magában foglalja az adott nyelvhez tartozó gép vagy processzor leírását, amely esetleg idealizált. A legtöbb gyakorlati környezetben a programozási nyelv magában foglal egy számítógépet; következésképpen a programozási nyelveket általában így határozzák meg és tanulják. A programozási nyelvek abban különböznek a természetes nyelvektől , hogy a természetes nyelveket csak az emberek közötti interakcióra használják, míg a programozási nyelvek lehetővé teszik az emberek számára, hogy utasításokat közöljenek a gépekkel.
Absztrakciók
A programozási nyelvek általában absztrakciókat tartalmaznak az adatstruktúrák meghatározásához és manipulálásához vagy a végrehajtás folyamatának szabályozásához . Az absztrakciós elv kifejezi azt a gyakorlati szükségességet, hogy a programozási nyelv megfelelő absztrakciókat támogasson . Ezt az elvet néha megfogalmazzák ajánlásként a programozó számára, hogy megfelelően használja fel az ilyen absztrakciókat.
Kifejező erő
A számításelmélet a nyelveket azoknak a számításoknak a szerint osztályozza, amelyeket képesek kifejezni. Minden Turing-teljes nyelv ugyanazokat az algoritmusokat valósíthatja meg . Az ANSI/ISO SQL-92 és a Charity példák olyan nyelvekre, amelyek nem teljesek Turingban, de gyakran programozási nyelveknek nevezik őket.

A strukturált adatokat meghatározó jelölési nyelvek, például az XML , a HTML vagy a troff általában nem tekinthetők programozási nyelveknek. A programozási nyelvek azonban megoszthatják a szintaxist a jelölési nyelvekkel, ha számítási szemantika van definiálva. Az XSLT például egy teljes Turing nyelv , amely teljes egészében XML szintaxist használ. Ezenkívül a LaTeX , amelyet többnyire dokumentumok strukturálására használnak, tartalmaz egy Turing teljes részhalmazt is.

A számítógépes nyelv kifejezést néha felcserélve használják a programozási nyelvvel. Mindkét kifejezés használata azonban a szerzők között eltérő, beleértve a pontos alkalmazási kört is. Az egyik használat a programozási nyelveket a számítógépes nyelvek részhalmazaként írja le. Hasonlóképpen, a számítástechnikában használt nyelvek, amelyeknek más célja van, mint a számítógépes programok kifejezése, általánosan meghatározott számítógépes nyelvek. Például a jelölési nyelveket néha számítógépes nyelveknek nevezik, hogy hangsúlyozzák, hogy nem programozásra szolgálnak.

Egy másik használat a programozási nyelveket absztrakt gépek programozására vonatkozó elméleti konstrukciónak tekinti, a számítógépes nyelveket pedig annak részhalmazának, amely véges hardver erőforrásokkal rendelkező fizikai számítógépeken fut. John C. Reynolds hangsúlyozza, hogy a formális specifikációs nyelvek ugyanolyan programozási nyelvek, mint a végrehajtásra szánt nyelvek. Azt is állítja, hogy a számítógép viselkedését befolyásoló szöveges és akár grafikus beviteli formátumok is programozási nyelvek, annak ellenére, hogy általában nem Turing-teljesek, és megjegyzi, hogy a programozási nyelvi fogalmak tudatlansága sok oka a bemeneti formátumoknak.

Történelem

Korai fejlemények

A nagyon korai számítógépeket, például a Colossust , tárolt program segítsége nélkül , az áramkörük módosításával vagy a fizikai vezérlőelemek beállításával programozták .

Kicsit később a programokat gépi nyelven lehetett írni , ahol a programozó minden utasítást numerikus formában ír le, amelyet a hardver közvetlenül végrehajthat. Például az utasítás hozzáadása két memóriahelyhez 3 számból állhat: egy "opcode" -ból, amely az "add" műveletet választja, és két memóriahelyből. A programokat decimális vagy bináris formában lyukasztott kártyákról , papírszalagról, mágnesszalagról olvassák be , vagy bekapcsolják a számítógép előlapján található kapcsolókat . A gépi nyelveket később első generációs programozási nyelveknek (1GL) nevezték.

A következő lépés az úgynevezett második generációs programozási nyelvek (2GL) vagy összeszerelési nyelvek kifejlesztése volt, amelyek még mindig szorosan kötődtek az adott számítógép utasításkészlet-architektúrájához . Ezek azt szolgálták, hogy a program sokkal emberileg olvashatóbb legyen, és mentesítették a programozót az unalmas és hibára hajlamos címszámításoktól.

Az első magas szintű programozási nyelveket vagy harmadik generációs programozási nyelveket (3GL) az 1950-es években írták. A számítógép számára tervezett korai magas szintű programozási nyelv a Plankalkül volt , amelyet Konrad Zuse fejlesztett ki a német Z3 számára 1943 és 1945 között. Ezt azonban csak 1998 és 2000 között hajtották végre.

John Mauchly „s rövid kódot , javasolt 1949-ben egyike volt az első magas szintű nyelv valaha kifejlesztett egy elektronikus számítógép . A gépi kóddal ellentétben a Short Code utasítások érthető formában reprezentálták a matematikai kifejezéseket. A programot azonban minden futtatáskor le kellett fordítani gépi kódra, ami sokkal lassabbá tette a folyamatot, mint az egyenértékű gépi kód futtatása.

A University of Manchester , Alick Glennie kifejlesztett Autocode a korai 1950-es évek. Mint programozási nyelv , akkor használjuk a fordítóprogram automatikusan konvertálja a nyelv gépi kódra. Az első kódot és fordítót 1952-ben fejlesztették ki a Manchesteri Egyetem Mark 1 számítógépéhez, és az első összeállított magas szintű programozási nyelvnek tekintik .

A második autokódot RA Brooker fejlesztette ki a Mark 1 számára 1954 -ben, és a "Mark 1 Autocode" nevet kapta. Brooker az 1950 -es években a Manchesteri Egyetemmel együttműködésben kifejlesztett egy autokódot a Ferranti Mercury számára. Az EDSAC 2 verzióját DF Hartley , a Cambridge-i Egyetem Matematikai Laboratóriumának dolgozta ki 1961-ben. EDSAC 2 Autocode néven ismert, ez a helyi körülményekhez igazított egyenes fejlesztés volt a Mercury Autocode-tól, és az objektumkód-optimalizálásról és a forrásnyelvről volt híres a korszerű diagnosztika. A modern, de különálló fejlesztési szál, az Atlas Autocode -ot a Manchesteri Egyetem Atlas 1 gépéhez fejlesztették ki.

1954 -ben a FORTRAN -t John Backus találta fel az IBM -nél . Ez volt az első, széles körben használt, magas szintű, általános célú programozási nyelv , amely funkcionális megvalósítással rendelkezett, szemben a csak papír alapú tervezéssel. Továbbra is népszerű nyelv a nagy teljesítményű számítástechnikában, és olyan programoknál használják, amelyek összehasonlítják és rangsorolják a világ leggyorsabb szuperszámítógépeit .

Egy másik korai programozási nyelvet Grace Hopper fejlesztett ki az Egyesült Államokban, FLOW-MATIC néven . Úgy alakult, hogy a UNIVAC én a Remington Rand időszakban 1955-ig 1959-Hopper találtuk, hogy az üzleti adatok feldolgozása vevők voltak kellemetlen matematikai jelölés, és a korai 1955-ő és csapata írt leírás egy angol programozási nyelv és végrehajtott egy prototípus. A FLOW-MATIC fordító 1958 elején vált nyilvánosan elérhetővé, és lényegében 1959-ben fejeződött be. A FLOW-MATIC nagy hatással volt a COBOL tervezésére , mivel akkor csak ő és közvetlen leszármazottja, az AIMACO volt ténylegesen használatban.

Finomítás

A magas szintű nyelvek fokozott használata bevezette az alacsony szintű programozási nyelvek vagy a rendszerprogramozási nyelvek követelményét . Ezek a nyelvek különböző mértékben biztosítják az összeszerelési nyelvek és a magas szintű nyelvek közötti kapcsolatot. Használhatók olyan feladatok elvégzésére, amelyek közvetlen hozzáférést igényelnek a hardverberendezésekhez, de még mindig magasabb szintű vezérlési struktúrákat és hibakeresést biztosítanak.

Az 1960 -as évektől az 1970 -es évek végéig tartó időszak hozta létre a jelenleg használatos főbb nyelvi paradigmákat:

Ezen nyelvek mindegyike utódokat szült, és a legtöbb modern programozási nyelv legalább egyet számol fel őseiben.

Az 1960 -as és 1970 -es években is jelentős viták folytak a strukturált programozás előnyeiről , és arról, hogy a programozási nyelveket úgy kell -e kialakítani, hogy támogassák azt. Edsger Dijkstra egy híres 1968 -as levelében, amelyet az ACM kommunikációjában publikált , azzal érvelt, hogy a Goto kijelentéseket ki kell iktatni minden "magasabb szintű" programozási nyelvből.

Konszolidáció és növekedés

Programozást tanító tankönyvek válogatása népszerű és homályos nyelveken. Ez csak néhány a több ezer programozási nyelv és nyelvjárás közül, amelyeket a történelem során terveztek.

Az 1980 -as évek a relatív konszolidáció évei voltak. A C ++ objektum-orientált és rendszerprogramozást kombinált. Az Egyesült Államok kormánya szabványosította az Ada programozási nyelvet, amely a Pascal -ból származik, és amelyet védelmi vállalkozók használnak. Japánban és máshol hatalmas összegeket költöttek az úgynevezett "ötödik generációs" nyelvek vizsgálatára , amelyek logikai programozási konstrukciókat tartalmaztak. A funkcionális nyelvek közössége az ML és a Lisp szabványosítására költözött . Az új paradigmák feltalálása helyett ezek a mozgalmak az előző évtizedekben feltalált ötleteket dolgozták ki.

A nagyszabású rendszerek programozásának nyelvtervezésének egyik fontos irányzata az 1980-as években az volt, hogy fokozott figyelmet fordítottak a modulok vagy nagyszabású szervezeti egységek használatára. A Modula-2 , az Ada és az ML az 1980-as években jelentős modulrendszereket fejlesztett ki, amelyeket gyakran általános programozási konstrukciókba építettek be.

Az internet gyors növekedése a kilencvenes évek közepén lehetőségeket teremtett az új nyelvek számára. A Perl , eredetileg egy Unix szkriptíró eszköz, amelyet 1987 -ben adtak ki, általánossá vált a dinamikus webhelyeken . A Java- t kiszolgálóoldali programozásra használták, és a bájtkódú virtuális gépek ismét népszerűvé váltak a kereskedelmi környezetben, ígéretük szerint " Írj egyszer, fuss bárhol " (az UCSD Pascal egy ideje népszerű volt a nyolcvanas évek elején). Ezek a fejlemények alapvetően nem voltak újszerűek; inkább sok létező nyelv és paradigma finomításai voltak (bár szintaxisuk gyakran a programozási nyelvek C családjára épült).

A programozási nyelv fejlődése folytatódik, mind az iparban, mind a kutatásban. A jelenlegi irányok közé tartozik a biztonság és a megbízhatóság ellenőrzése , az új típusú modularitás ( keverékek , küldöttek , szempontok ) és az adatbázis -integráció, például a Microsoft LINQ -ja .

A negyedik generációs programozási nyelvek (4GL) olyan számítógépes programozási nyelvek, amelyek célja, hogy a 3GL-eknél magasabb szintű absztrakciót biztosítsanak a belső számítógép hardver részleteiben. Az ötödik generációs programozási nyelvek (5GL) olyan programozási nyelvek, amelyek a problémák megoldásán alapulnak, a programhoz adott korlátozások felhasználásával, nem pedigegy programozó által írt algoritmus használatával.

Elemek

Minden programozási nyelv rendelkezik néhány primitív építőelemmel az adatok és a rájuk alkalmazott folyamatok vagy átalakítások leírásához (például két szám hozzáadása vagy egy elem kiválasztása a gyűjteményből). Ezeket a primitíveket szintaktikai és szemantikai szabályok határozzák meg, amelyek leírják szerkezetüket és jelentésüket.

Szintaxis

Elemzési fa a Python kód beszúrt tokenizálás
A szintaxis kiemelését gyakran használják a programozók segítségére a forráskód elemeinek felismerésében. A fenti nyelv a Python .

A programozási nyelv felszínén forma ismert, mint a szintaxis . A legtöbb programozási nyelv tisztán szöveges; szövegsorozatokat használnak, beleértve a szavakat, számokat és írásjeleket, hasonlóan az írott természetes nyelvekhez. Másrészt vannak olyan programozási nyelvek, amelyek grafikusabbak , és a szimbólumok közötti vizuális kapcsolatokat használják a program megadásához.

A nyelv szintaxisa leírja a szimbólumok lehetséges kombinációit, amelyek szintaktikailag helyes programot alkotnak. A szimbólumok kombinációjának adott jelentését szemantika kezeli ( formális vagy keményen kódolt referencia megvalósításban ). Mivel a legtöbb nyelv szöveges, ez a cikk a szöveges szintaxist tárgyalja.

A programozási nyelv szintaxisát általában a reguláris kifejezések (a lexikai szerkezet) és a Backus – Naur forma (a nyelvtani szerkezet) kombinációjával határozzák meg . Az alábbiakban egy egyszerű nyelvtant találunk, amely Lisp alapján készült :

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

Ez a nyelvtan a következőket határozza meg:

  • a kifejezés vagy atom vagy lista ;
  • az atom vagy szám vagy szimbólum ;
  • a szám egy vagy több tizedesjegyből álló töretlen sorozat, amelyet adott esetben egy plusz vagy mínusz jel előz meg;
  • a szimbólum egy betű, amelyet nulla vagy több karakter követ (kivéve a szóközöket); és
  • a lista egy illeszkedő zárójelpár, nulla vagy több kifejezéssel .

A következő példák a jól formált token-szekvenciák e nyelvtani: 12345, ()és (a b c232 (1)).

Nem minden szintaktikailag helyes program szemantikailag helyes. Ennek ellenére sok szintaktikailag helyes program rosszul van kialakítva a nyelv szabályai szerint; és (a nyelv specifikációjától és a megvalósítás megbízhatóságától függően) hibát okozhat a fordításban vagy a végrehajtásban. Bizonyos esetekben az ilyen programok nem meghatározott viselkedést mutathatnak . Még akkor is, ha egy program jól definiált egy nyelven belül, még mindig lehet olyan jelentése, amelyet nem az a személy írt, aki írta.

A természetes nyelvet példaként használva előfordulhat, hogy a nyelvtanilag helyes mondathoz nem lehet jelentést rendelni, vagy a mondat hamis lehet:

A következő C nyelvi töredék szintaktikailag helyes, de szemantikailag nem definiált műveleteket hajt végre (a műveletnek *p >> 4nincs értelme egy komplex típusú értékhez, és p->imnincs definiálva, mert a értéke pa null mutató ):

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

Ha az első sorban lévő típusdeklarációt elhagynánk, a program hibát okozna a nem definiált változón pa fordítás során. A program azonban szintaktikailag helyes lenne, mivel a típusdeklarációk csak szemantikai információkat tartalmaznak.

A programozási nyelv megadásához szükséges nyelvtant a Chomsky -hierarchiában elfoglalt helye alapján lehet osztályozni . A legtöbb programozási nyelv szintaxisa megadható egy 2-es típusú nyelvtan segítségével, azaz környezetfüggetlen nyelvtanok . Egyes nyelvek, köztük a Perl és a Lisp olyan konstrukciókat tartalmaznak, amelyek lehetővé teszik a végrehajtást az elemzési fázisban. Azok a nyelvek, amelyek olyan konstrukciókkal rendelkeznek, amelyek lehetővé teszik a programozó számára, hogy megváltoztassa az elemző viselkedését, a szintaktikai elemzést eldönthetetlen problémává teszik , és általában elmosják a különbséget az elemzés és a végrehajtás között. Ellentétben Lisp makrórendszerével és Perl BEGINblokkjaival, amelyek általános számításokat tartalmazhatnak, a C makrók pusztán karakterlánc -cserék, és nem igényelnek kódfuttatást.

Szemantika

A szemantika kifejezés a nyelvek jelentésére utal, szemben a formájukkal ( szintaxisuk ).

Statikus szemantika

A statikus szemantika korlátozza az érvényes szövegek szerkezetét, amelyeket nehéz vagy lehetetlen szabványos szintaktikai formalizmussal kifejezni. Az összeállított nyelvek esetében a statikus szemantika lényegében azokat a szemantikai szabályokat tartalmazza, amelyek a fordítási időben ellenőrizhetők. Ilyen például annak ellenőrzése, hogy minden azonosítót használat előtt deklarálnak -e (az ilyen nyilatkozatokat igénylő nyelveken), vagy hogy az eseti nyilatkozat karjain lévő címkék megkülönböztethetők -e. Az ilyen típusú számos fontos korlátozást, például annak ellenőrzését, hogy az azonosítókat a megfelelő kontextusban használják -e (pl. Nem egész számot adnak hozzá a függvénynévhez), vagy azt, hogy a szubrutinhívások megfelelő számú és típusú argumentummal rendelkeznek, kikényszeríthetjük szabályként történő meghatározással egy logikai nevezett típusú rendszer . A statikus elemzések más formái, például az adatáramlás -elemzés is része lehet a statikus szemantikának. Újabb programozási nyelvek, mint a Java és C # is határozott megbízás elemzés , egyfajta adatáramlás elemzés részeként a statikus szemantika.

Dinamikus szemantika

Az adatok megadása után a gépet utasítani kell az adatokkal kapcsolatos műveletek végrehajtására. Például a szemantika meghatározhatja azt a stratégiát , amellyel a kifejezéseket értékekre értékeli, vagy azt a módot, ahogyan a vezérlőstruktúrák feltételesen végrehajtják az utasításokat . A nyelv dinamikus szemantikája (más néven végrehajtási szemantika ) határozza meg, hogy a nyelv különböző konstrukciói hogyan és mikor hozzák létre a program viselkedését. A végrehajtási szemantika meghatározásának számos módja van. Gyakran a természetes nyelvet használják a gyakorlatban általánosan használt nyelvek végrehajtási szemantikájának megadására. Jelentős mennyiségű tudományos kutatás bement formális szemantika a programozási nyelvek , amelyek lehetővé teszik a végrehajtás szemantika kell megadni formális módon. E kutatási terület eredményei csak korlátozottan alkalmazhatók a programozási nyelvek tervezésére és megvalósítására az egyetemen kívül.

Típus rendszer

A típusrendszer határozza meg, hogy egy programozási nyelv hogyan osztályozza az értékeket és kifejezéseket típusokba , hogyan tudja ezeket a típusokat manipulálni és hogyan hatnak egymásra. A típusrendszerek célja, hogy bizonyos helytelen műveletek észlelésével ellenőrizzék és általában érvényesítsék a helyesség bizonyos szintjét az adott nyelven írt programokban. Bármilyen eldönthető típusú rendszer kompromisszumot von maga után: bár sok helytelen programot elutasít, néhány helyes, bár szokatlan programot is tilthat. Ennek a hátránynak a kiküszöbölése érdekében számos nyelven vannak típushibák , általában ellenőrizetlen karakterek , amelyeket a programozó használhat arra, hogy kifejezetten lehetővé tegye a különböző típusok között általában nem engedélyezett műveletet. A legtöbb gépelt nyelvben a típusrendszert csak típusellenőrző programokhoz használják, de számos nyelv, általában funkcionális, következtet a típusokra , mentesítve a programozót a típusjegyzetek írásának szükségességétől. A típusrendszerek formális tervezése és tanulmányozása típuselmélet néven ismert .

Gépelt és tipizálatlan nyelvek

A nyelv akkor kerül beírásra, ha minden művelet specifikációja meghatározza azokat az adattípusokat, amelyekre a művelet alkalmazható. Például az adatok által képviselt "this text between the quotes"egy húr , és sok programozási nyelvek elosztjuk a számot egy string nincs értelme, és nem kerül végrehajtásra. Az érvénytelen műveletet a program fordításakor észlelheti ("statikus" típusellenőrzés), és a fordító el fogja utasítani egy fordítási hibaüzenettel, vagy észlelheti a program futása közben ("dinamikus" típusellenőrzés). futási idő kivételével . Sok nyelv lehetővé teszi, hogy a kivételkezelő nevű függvény kezelje ezt a kivételt, és például mindig "-1" értéket adjon vissza eredményként.

A gépelt nyelvek különleges esete az egyszeres nyelv. Ezek gyakran szkript- vagy jelölési nyelvek, például a REXX vagy az SGML , és csak egy adattípussal rendelkeznek - leggyakrabban karakterláncok, amelyeket szimbolikus és numerikus adatokhoz is használnak.

Ezzel szemben egy tipizálatlan nyelv , például a legtöbb összeállítási nyelv , lehetővé teszi bármilyen művelet végrehajtását bármilyen adaton, általában különböző hosszúságú bitek sorozatán. A magas szintű tipizálatlan nyelvek közé tartozik a BCPL , a Tcl és a Forth néhány fajtája .

A gyakorlatban, bár kevés nyelv tekinthető gépeltnek a típuselméletből (minden művelet ellenőrzése vagy elutasítása), a legtöbb modern nyelv kínál bizonyos mértékű gépelést. Sok termelési nyelv eszközöket kínál a típusrendszer megkerülésére vagy felforgatására, a típusbiztonság kereskedelme a program végrehajtásának finomabb szabályozása érdekében (lásd casting ).

Statikus versus dinamikus gépelés

A statikus gépelésnél minden kifejezés típusát a program végrehajtása előtt határozzák meg, általában fordítási időben. Például 1 és (2+2) egész kifejezések; nem adhatók át olyan függvénynek, amely karakterláncot vár, vagy nem tárolható olyan változóban, amely dátumokat tartalmaz.

A statikusan beírt nyelvek nyilvánvalóan gépelhetők, vagy típusból következtethetők . Az első esetben a programozónak kifejezetten írnia kell típusokat bizonyos szöveges pozíciókra (például változó deklarációkhoz ). A második esetben a fordító kontextus alapján következtet a kifejezések és deklarációk típusaira. A legtöbb mainstream statikusan beírt nyelv, például a C ++ , a C# és a Java , nyilvánvalóan gépelt. A teljes típusú következtetést hagyományosan a kevésbé mainstream nyelvekhez társították, mint például a Haskell és az ML . Sok nyilvánvalóan gépelt nyelv azonban támogatja a részleges típusú következtetést; például a C ++ , a Java és a C# bizonyos korlátozott esetekben kikövetkeztet típusokat. Ezenkívül egyes programozási nyelvek lehetővé teszik bizonyos típusok automatikus átalakítását más típusokká; például egy int használható ott, ahol a program lebegést vár.

A dinamikus gépelés , más néven látens gépelés , meghatározza a műveletek típusbiztonságát futás közben; más szavakkal, a típusok futásidejű értékekkel társulnak,nem pedig szöveges kifejezésekkel . A tipikusan kikövetkeztetett nyelvekhez hasonlóan a dinamikusan gépelt nyelvek sem igénylik, hogy a programozó explicit típusú megjegyzéseket írjon a kifejezésekre. Többek között ez lehetővé teheti, hogy egyetlen változó különböző típusú értékekre hivatkozzon a program végrehajtásának különböző pontjain. A típushibákat azonban nem lehet automatikusan észlelni, amíg egy kódrészletet ténylegesen végrehajtanak, ami megnehezítheti a hibakeresést . A Lisp , Smalltalk , Perl , Python , JavaScript és Ruby példák a dinamikusan beírt nyelvekre.

Gyenge és erős gépelés

A gyenge gépelés lehetővé teszi az egyik típus értékének másként való kezelését, például egy karakterlánc számként valókezelését. Ez időnként hasznos lehet, de lehetővé teheti azt is, hogy bizonyos típusú programhibák észrevétlenek maradjanak a fordítás idején , sőt futás közben is .

Az erős gépelés megakadályozza ezeket a programhibákat. Ha egy műveletet rossz típusú értékkel próbál végrehajtani, akkor hiba lép fel. Az erősen gépelt nyelveket gyakran típusbiztonságosnak vagy biztonságosnak nevezik.

A "gyengén gépelt" alternatív meghatározása olyan nyelvekre vonatkozik, mint a Perl és a JavaScript , amelyek nagyszámú implicit típusú konverziót tesznek lehetővé. A JavaScript például a kifejezés 2 * xhallgatólagosan átalakítja xegy számot, és ezt a konverziót sikerül is, ha xvan null, undefinedegy Arrayvagy betűsor. Az ilyen implicit átalakítások gyakran hasznosak, de elfedhetik a programozási hibákat. Az erőset és a statikát ma általában ortogonális fogalmaknak tekintik, de a szakirodalomban eltérő a használat. Vannak, akik az erősen gépelt kifejezést erősen, statikusan gépeltnek , vagy még zavarosabban egyszerűen statikusan gépeltnek használják . Így C -t erősen és gyengén, statikusan gépeltnek is nevezték.

Néhány professzionális programozó számára furcsának tűnhet, hogy a C "gyengén, statikusan beírható". Ne feledje azonban, hogy az általános mutató, a void* mutató használata lehetővé teszi a mutatók más mutatókra való átvitelét anélkül, hogy kifejezetten leadni kellene. Ez rendkívül hasonlít ahhoz, hogy valahogy egy bájt tömböt bármilyen típusú adattípusba öntünk C -ben, kifejezett öntet használata nélkül, például (int)vagy (char).

Szabványos könyvtár és futásidejű rendszer

A legtöbb programozási nyelvhez tartozik egy alapkönyvtár (néha „szabványos könyvtár” néven is ismert, különösen, ha a közzétett nyelvi szabvány részeként szerepel), amelyet hagyományosan a nyelv összes megvalósítása tesz elérhetővé. Az alapvető könyvtárak jellemzően meghatározzák az általánosan használt algoritmusok definícióit, az adatstruktúrákat és a bemeneti és kimeneti mechanizmusokat.

A nyelv és az alapkönyvtár közötti határvonal nyelvenként eltérő. Bizonyos esetekben a nyelvtervezők a könyvtárat a nyelvtől elkülönült entitásként kezelhetik. Azonban egy nyelv alapkönyvtárát a felhasználók gyakran a nyelv részeként kezelik, és egyes nyelvi specifikációk még azt is megkövetelik, hogy ezt a könyvtárat minden megvalósításban elérhetővé tegyék. Valójában egyes nyelveket úgy terveztek, hogy bizonyos szintaktikai konstrukciók jelentései még az alapvető könyvtárra való hivatkozás nélkül sem írhatók le. Például a Java -ban egy karakterlánc -literált az java.lang.Stringosztály példányaként határoznak meg ; hasonlóan a Smalltalkban egy névtelen függvénykifejezés ("blokk") konstruálja a könyvtár BlockContextosztályának egy példányát . Ezzel szemben a séma több koherens részhalmazt tartalmaz, amelyek elegendőek a nyelv többi részének könyvtári makróként való felépítéséhez, így a nyelvtervezők nem is törődnek azzal, hogy megmondják, hogy a nyelv mely részeit kell nyelvkonstrukcióként megvalósítani, és melyeket részeként kell megvalósítani könyvtárról.

Tervezés és kivitelezés

Programozási nyelvek megosztani tulajdonságai a természetes nyelvek kapcsolódó céljuk a járművek kommunikációs, amelynek szintaktikai forma különálló szemantikája, és bemutatja nyelvcsaládok a rokon nyelvek elágazás egymástól. De mesterséges konstrukcióként alapvetően különböznek a használat során kialakult nyelvektől. Lényeges különbség, hogy egy programozási nyelv teljes egészében leírható és tanulmányozható, mivel pontos és véges definíciója van. Ezzel szemben a természetes nyelvek változó jelentéssel bírnak, amelyeket a felhasználók különböző közösségekben használnak. Míg a konstruált nyelvek mesterséges nyelvek, amelyeket az alapoktól kezdve meghatározott céllal terveztek, hiányzik belőlük a programozási nyelv pontos és teljes szemantikai meghatározása.

Sok programozási nyelvet a semmiből terveztek, módosítottak, hogy megfeleljenek az új igényeknek, és más nyelvekkel kombinálják őket. Sokan végül használaton kívül estek. Bár történtek kísérletek egy "univerzális" programozási nyelv megtervezésére, amely minden célt szolgál, mindegyiket nem sikerült általánosan elfogadni ennek a szerepnek a betöltésére. A változatos programozási nyelvek iránti igény abból adódik, hogy a nyelveket különböző környezetekben használják:

  • A programok az egyéni hobbisták által írt apró forgatókönyvektől a hatalmas rendszerekig, amelyeket több száz programozó ír .
  • A programozók széles skálán mozognak a kezdőktől, akiknek mindenekelőtt az egyszerűségre van szükségük, a szakértőkig, akik meglehetősen bonyolultak.
  • A programoknak egyensúlyban kell lenniük a sebességgel, a mérettel és az egyszerűséggel a mikrovezérlőktől a szuperszámítógépekig terjedő rendszereken .
  • A programok egyszer írhatók, és nem változhatnak generációkon keresztül, vagy folyamatosan módosulhatnak.
  • A programozók egyszerűen különbözhetnek ízlésükben: megszokták, hogy megbeszélik a problémákat, és egy adott nyelven fejezik ki azokat.

Egy közös trend a fejlesztés a programozási nyelvek az volt, hogy adjunk több képes megoldani a problémákat egy magasabb szintű absztrakció . A legkorábbi programozási nyelvek nagyon szorosan kapcsolódtak a számítógép alap hardveréhez. Az új programozási nyelvek kifejlesztésével olyan funkciókkal bővültek, amelyek lehetővé teszik a programozók számára, hogy az egyszerű fordítástól távolabbi ötleteket fejezzenek ki a mögöttes hardverutasításokba. Mivel a programozók kevésbé kötődnek a számítógép összetettségéhez, a programjaik több számításra képesek a programozó kevesebb erőfeszítésével. Ez lehetővé teszi számukra, hogy több funkciót írjanak időegységenként.

A természetes nyelvű programozást javasolták annak a módszernek a kiküszöbölésére, hogy szükség van egy speciális nyelvre a programozáshoz. Ez a cél azonban távol áll, és előnyei vitathatók. Edsger W. Dijkstra azt az álláspontot képviselte, hogy a formális nyelv használata elengedhetetlen az értelmetlen konstrukciók bevezetésének megakadályozásához, és elutasította a természetes nyelvi programozást "ostobaságként". Alan Perlis hasonlóan elutasította az ötletet. Hibrid megközelítéseket alkalmaztak strukturált angol és SQL nyelvekben .

Egy nyelv tervezőinek és felhasználóinak számos olyan műterméket kell létrehozniuk, amelyek szabályozzák és lehetővé teszik a programozást. Ezek közül a legfontosabbak a nyelvi specifikáció és a megvalósítás .

Leírás

A specifikáció egy programozási nyelv egy műalkotás, hogy a nyelvi felhasználók és a implementors használhatja megegyezni, hogy egy darab forráskód egy érvényes programot az adott nyelvet, és ha igen, milyen magatartást kell.

A programozási nyelv specifikációja többféle formában is megjelenhet, beleértve a következőket:

Végrehajtás

A programozási nyelv megvalósítása lehetővé teszi a programok írását ezen a nyelven, és a hardver és szoftver egy vagy több konfigurációján történő végrehajtását. A programozási nyelv megvalósításának nagyjából két megközelítése létezik: összeállítás és értelmezés . Általában bármelyik módszerrel megvalósítható egy nyelv.

A fordító kimenetét hardver vagy egy tolmács nevű program hajthatja végre. Bizonyos implementációkban, amelyek az értelmező megközelítést használják, nincs külön határ a fordítás és az értelmezés között. Például a BASIC néhány megvalósítása lefordítja és végrehajtja a forrást egy sorban.

A közvetlenül a hardveren végrehajtott programok általában sokkal gyorsabban futnak, mint a szoftveresen értelmezett programok.

Az értelmezett programok teljesítményének javításának egyik technikája az éppen időben történő fordítás . Itt a virtuális gép , közvetlenül a végrehajtás előtt, lefordítja a bájtkód -blokkokat, amelyeket használni fognak a gépi kódoláshoz, a hardver közvetlen végrehajtásához.

Tulajdonosi nyelvek

Bár a legtöbb leggyakrabban használt programozási nyelv teljesen nyitott specifikációkkal és implementációkkal rendelkezik, sok programozási nyelv csak saját programozási nyelvként létezik, és a megvalósítás csak egyetlen szállítótól érhető el, amely azt állíthatja, hogy egy ilyen saját nyelv az ő szellemi tulajdonuk. A szabadalmazott programozási nyelvek általában domain specifikus nyelvek vagy belső szkriptnyelvek egyetlen termékhez; egyes szabadalmazott nyelveket csak a gyártón belül használnak, míg mások a külső felhasználók számára.

Néhány programozási nyelv létezik a saját és a nyílt határán; például az Oracle Corporation állítja tulajdonosi jogokat bizonyos szempontból a Java programozási nyelv , és a Microsoft „s C # programozási nyelv, amely nyitott implementációk nagy része a rendszernek, szintén Common Language Runtime (CLR), mint egy zárt környezetben.

Számos saját nyelvet használnak széles körben, saját tulajdonuk ellenére; például a MATLAB , a VBScript és a Wolfram Language . Egyes nyelvek átállhatnak a zártról a nyitottra; például az Erlang eredetileg az Ericsson belső programozási nyelve volt.

Használat

Különféle programozási nyelvek ezreit hozták létre, főleg a számítástechnika területén. Az egyes szoftverprojektek általában öt vagy több programozási nyelvet használnak.

A programozási nyelvek abban különböznek a legtöbb emberi kifejezésmódtól, hogy nagyobb pontosságot és teljességet igényelnek. Amikor természetes nyelvet használ a másokkal való kommunikációhoz, az emberi szerzők és beszélők kétértelműek lehetnek, és apró hibákat követhetnek el, és továbbra is elvárják szándékuk megértését. Átvitt értelemben azonban a számítógépek "pontosan azt teszik, amit utasítanak", és nem tudják "megérteni", hogy a programozó milyen kódot akart írni. A nyelvdefiníció, a program és a program bemeneteinek kombinációjának teljes mértékben meg kell határoznia azt a külső viselkedést, amely a program végrehajtásakor jelentkezik, az adott program irányítási tartományában. Másrészről az algoritmusról szóló elképzelések a végrehajtáshoz szükséges pontosság nélkül kommunikálhatók az embereknek, ha pszeudokódot használnak , amely a természetes nyelvet és a programozási nyelven írt kódot összefűzi.

A programozási nyelv strukturált mechanizmust biztosít az adatok darabjainak meghatározásához, valamint azokhoz a műveletekhez vagy átalakításokhoz, amelyek automatikusan végrehajthatók. A programozó a nyelvben található absztrakciókat használja a számításhoz kapcsolódó fogalmak ábrázolására. Ezeket a fogalmakat a rendelkezésre álló legegyszerűbb elemek ( primitívek ) gyűjteményeként ábrázolják . A programozás az a folyamat, amelynek során a programozók egyesítik ezeket a primitíveket, hogy új programokat készítsenek, vagy a meglévőket új felhasználásokhoz vagy változó környezethez igazítsák.

Programok a számítógép lehet végrehajtani egy szakaszos eljárásban emberi beavatkozás nélkül, vagy a felhasználó esetleg írjon parancsokat egy interaktív munkamenet egy tolmács . Ebben az esetben a "parancsok" egyszerűen programok, amelyek végrehajtása össze van láncolva. Ha egy nyelv fordítás nélkül futtathatja a parancsait egy tolmácson keresztül (például Unix shell vagy más parancssori felület ), akkor azt szkriptnyelvnek nevezzük .

A nyelvhasználat mérése

A legszélesebb körben használt programozási nyelv meghatározása nehéz, mivel a használat definíciója kontextusonként változik. Az egyik nyelv több programozói órát foglalhat el, egy másik több kódsorral rendelkezik, a harmadik pedig a legtöbb CPU -időt. Egyes nyelvek nagyon népszerűek bizonyos típusú alkalmazásokhoz. Például a COBOL továbbra is erős a vállalati adatközpontban, gyakran nagy mainframe -eken ; Fortran tudományos és mérnöki alkalmazásokban; Ada az űrhajózásban, a közlekedésben, a katonai, valós idejű és beágyazott alkalmazásokban; és C a beágyazott alkalmazásokban és operációs rendszerekben. Más nyelveket rendszeresen használnak sokféle alkalmazás írásához.

A nyelv népszerűségének mérésére különféle módszereket javasoltak, amelyek mindegyike eltérő elfogultsággal rendelkezik a mért értékekkel szemben:

  • számba véve a nyelvet megemlítő álláshirdetések számát
  • az eladott könyvek száma, amelyek tanítják vagy leírják a nyelvet
  • a nyelven írt kódsorok számának becslése - ami alulbecsülheti a nyilvános keresésekben gyakran nem található nyelveket
  • a webes keresőmotor segítségével talált nyelvi hivatkozások száma (azaz a nyelv nevére).

A különböző internetes oldalakról származó információkat egyesítve és átlagolva a stackify.com a tíz legnépszerűbb programozási nyelvet jelentette (csökkenő sorrendben az általános népszerűség szerint): Java , C , C ++ , Python , C# , JavaScript , VB .NET , R , PHP és MATLAB .

Nyelvjárások, ízek és megvalósítások

A programozási nyelv vagy az adatcsere nyelv dialektusa a nyelv (viszonylag kis) változata vagy kiterjesztése, amely nem változtatja meg belső jellegét. Az olyan nyelveknél, mint a Scheme és a Forth , a szabványokat a végrehajtók elégtelennek, nem megfelelőnek vagy törvénytelennek tarthatják a végrehajtók, ezért gyakran eltérnek a szabványtól, új nyelvjárást hoznak létre . Más esetekben dialektust hoznak létre egy tartomány-specifikus nyelven , gyakran egy részhalmazban való használatra. A Lisp- világban az S-kifejezés alapvető szintaxisát és a Lisp-szerű szemantikát használó nyelvek többsége Lisp-nyelvjárásnak minősül, bár vadul változnak, mint mondjuk Racket és Clojure . Mivel gyakori, hogy egy nyelvnek több nyelvjárása van, egy tapasztalatlan programozó számára meglehetősen nehéz lehet megtalálni a megfelelő dokumentációt. A BASIC programozási nyelv van sok dialektust .

A robbanás a Forth nyelvjárások vezetett a mondás: „Ha láttál egy Forth ... láttál egy Forth”.

Taxonómiák

A programozási nyelvekre nincs átfogó osztályozási séma. Egy adott programozási nyelv általában nem rendelkezik egyetlen ősnyelvvel. A nyelvek általában úgy keletkeznek, hogy több előd nyelv elemeit ötvözik az akkoriban forgalomban lévő új ötletekkel. Az egy nyelven született ötletek elterjednek a rokon nyelvek családjában, majd hirtelen átugranak a családi réseken, hogy egy teljesen más családban jelenjenek meg.

A feladatot tovább bonyolítja, hogy a nyelvek több tengely mentén osztályozhatók. Például a Java egyszerre objektum-orientált nyelv (mert az objektum-orientált szervezést ösztönzi) és párhuzamos nyelv (mivel beépített konstrukciókat tartalmaz több szál párhuzamos futtatásához ). A Python egy objektum-orientált szkriptnyelv .

Nagy vonalakban a programozási nyelvek programozási paradigmákra és osztályozásra oszlanak a tervezett felhasználási terület szerint, az általános célú programozási nyelveket megkülönböztetve a tartományspecifikus programozási nyelvektől . Hagyományosan a programozási nyelveket úgy tekintik, mint amelyek a számításokat az imperatív mondatok, azaz parancsok kiadásával írják le. Ezeket általában imperatív programnyelvnek nevezik . A programozási nyelveken végzett sok kutatás célja az volt, hogy elmossa a különbséget a program, mint utasításkészlet és a program, mint a kívánt válaszra vonatkozó állítás között, ami a deklaratív programozás fő jellemzője . A kifinomultabb paradigmák közé tartozik az eljárási programozás , az objektum-orientált programozás , a funkcionális programozás és a logikai programozás ; egyes nyelvek a paradigmák hibridjei vagy többparadigmatikusak. Az összeszerelési nyelv nem annyira paradigma, mint inkább a mögöttes gépi architektúra közvetlen modellje. Céljuk szerint a programozási nyelvek általános célúaknak, rendszerprogramozási nyelveknek , szkriptnyelveknek, tartományspecifikus nyelveknek vagy párhuzamos/elosztott nyelveknek (vagy ezek kombinációjának) tekinthetők. Néhány általános célú nyelvet nagyrészt oktatási célokra terveztek.

A programozási nyelvet a programozási paradigmához nem kapcsolódó tényezők is besorolhatják. Például a legtöbb programozási nyelv angol nyelvű kulcsszavakat használ , míg a kisebbség nem . Más nyelvek besorolhatók szándékosan ezoterikusnak vagy sem.

Lásd még

Hivatkozások

További irodalom

Külső linkek