Erősen típusos programozási nyelv
A programozási nyelvek csoportosíthatók a bennük létrehozott változókra, típusokra vonatkozó műveletek szigorúsága alapján: ezen szempontból beszélhetünk erősen vagy gyengén típusos nyelvekről. Azon nyelveket, melyekben minden kifejezés és részkifejezés típusa fordítási időben ismert, erősen vagy szigorúan típusos nyelveknek nevezzük.
Általában az erősen tipizált nyelv szigorúbb gépelési szabályokkal rendelkezik a fordítás idején, ami azt jelenti, hogy a hibák és a kivételek nagyobb valószínűséggel történnek a fordítás során. Ezen szabályok többsége befolyásolja a változó hozzárendelését, a függvény visszatérési értékeit, az eljárás argumentumait és a függvényhívásokat. A dinamikus nyelveket (ahol a típusellenőrzés futási időben történik) erősen lehet beírni. Vegyük figyelembe, hogy a dinamikusan beírt nyelvekben az értékeknek típusai vannak, nem változóik!
A gyengén tipizált nyelv lazább gépelési szabályokkal rendelkezik, és kiszámíthatatlan vagy akár hibás eredményeket hozhat, vagy futás közben implicit típusú konverziót hajthat végre[1]. A dinamikusan tipizált (általában "gyengén tipizált") nyelvek szószólói az aggodalmakat túlzottnak találják, és úgy vélik, hogy a statikus tipizálás valójában egy exponenciálisan nagyobb problémakört és hatékonyságot eredményez.[2] Más, de ehhez kapcsolódó fogalom a látens tipizálás.
Értelmezés
Általánosságban az erősen típusos nyelvek szigorú korlátozásokat tartalmaznak a bennük használható változók között végzett műveletek áttetszőségével kapcsolatban. Amely program ezen korlátozásokat megszegi, az már a fordítás idején megakad, tipikusan a fordító hibát generál, és az algoritmus nem is éri el a futási időt. Ilyen korlátozásokra példa, hogy az összeadás nem értelmezhető ezen nyelvekben szám és szöveg (sztring) típusú változók között, vagy listákon végezhető művelet nem hívható meg számokra.
Ilyen nyelv például a Java, C#, C++, Python, Object Pascal. (Ellenben gyengén típusos pl. a JavaScript, vagy a BASIC.)
Példa
// gyengén típusos nyelvnél ez működik:
int a = 2;
String b = "2";
return a + b; // 4-et ad vissza
b.concat(a); // "22"-t ad vissza
// erősen típusos nyelvnél a fenti típushibát generál (Type mismatch), mivel számot nem tud szöveggel összeadni
// ilyen nyelveknél tipikusan a következők szerint lehet eljárni
return Integer.toString(a)+b; // "22"-t ad vissza (szövegként)
return a+Integer.parseInt(b); // 4-et ad vissza
Története
1974-ben Barbara Liskov és Stephen Zilles egy erősen tipizált nyelvet határozott meg, amelyben "amikor egy objektumot egy hívó függvényről átadnak egy hívott függvényre, annak típusának kompatibilisnek kell lennie a meghívott függvényben deklarált típussal"[3]. 1977-ben K. Jackson azt írta: "egy erősen tipizált nyelven minden adatterületnek külön típusa lesz, és minden folyamat meg fogja határozni a kommunikációs követelményeit e típusok tekintetében".[4]
Tulajdonságok
- Típusbiztosság (type-safety): futási vagy fordítási időben meg van akadályozva, hogy illegális művelet hajtódjon végre adatokon.
- A változók típusa a program futása során nem változhat meg.
- A típus-rendszer megkerülhetetlen: nincs olyan mód, kiskapu, amit a programozók kihasználva típusfüggetlenné tehetnének egy változót.
- Nincs implicit típuskonverzió: csak a programozó, explicit módon határozhatja meg, mikor van szükség típusegyeztetésre.
- Fordítási időben történik az ellenőrzés.
Az "erős" vagy a "gyenge" meghatározása
Számos különböző nyelvtervezési döntések szolgálnak bizonyítékul az "erős" vagy "gyenge" tipizálásra. Ezek közül sokat pontosabban úgy értünk, mint a típusbiztonság, a memória biztonsága, a statikus típusellenőrzés vagy a dinamikus típusellenőrzés jelenléte vagy hiánya.
Az "erős tipizálás" általábanolyan programozási nyelvtípus használtára utal, ami rögzíti a kód mindkét invertálását, és biztosítja annak helyességét, határozottan kizárja a programozási hibák bizonyos osztályait. Így sok "erős típusozással" kapcsolatos szakterületet használnak e célok eléréséhez.
Implicit típusú konverziók és "tipizálások"
Néhány programozási nyelv megkönnyíti egyes típusok értékeinek használatát, mintha egy másfajta típushoz tartozó érték lenne. Ezt néha "gyenge típusozásnak" nevezik.
Mint például Aahz Maruch megállapította: "A korlátozás akkor következik be, mikor statikusan típusos nyelv van, és a nyelv szintaktikai jellemzőit használja arra, hogy egy típus használatára kényszerítse, mintha más típus lenne (vegyük figyelembe a void * általános használatát a C-ben). Ez a kényszer általában a gyenge típusozás jele. A konverzió viszont egy teljesen új, megfelelő típusú objektumot hoz létre."[5]
Egy másik példa, ahogy a GCC leírja ezt a tipizálást és figyelmeztet, hogy megtöri a szigorú átnevezést. Thiago Macieira több olyan problémát is tárgyal, amelyek felmerülhetnek, amikor a tipizálás miatt a fordító nem megfelelő optimalizálást végez[6].
Számos példa van a nyelvek, amelyek lehetővé teszik az implicit típusátalakítások, de egy típus-biztonságos módon. Például mind a C ++, mind a C # lehetővé teszi a programok számára, hogy meghatározzák az operátorokat, amivel egy értéket szemantikailag értelmesen átalakítsanak egyik típusról a másikra. Amikor egy C ++ fordító ilyen konverzióval találkozik, a műveletet ugyanúgy kezeli, mint egy függvényhívást. Ezzel szemben az érték konvertálása C type void *-gá nem biztonságos művelet, amely a fordító számára láthatatlan.
Mutatók
Egyes programozási nyelvek úgy mutatják ki a mutatókat, mintha numerikus értékek lennének, és levehőté teszik a felhasználók számára, hogy számtani műveletek végezzenek rajtuk. Ezeket a nyelveket néha "gyengén tipizált" néven emlegetik, mivel a mutató aritmetikája használható a nyelv típusrenderének megkerülésére.
Cimkézetlen egyesítések
Néhány programozási nyelv támogatja a cimkézetlen egyesítéseket, amelyek lehetővé teszik egyfajta típusú érték megtekintését, mintha egy másik típusú érték lenne.
Statikus típusellenőrzés
Luca Cardelli Typeful Programming[7] című cikkében, az "erős tipizálási rendszert" olyan rendszerként írja le, amelyben nincs lehetőség ellenőrizhetetlen futásidejű hibára. Más forrásokban az ellenprizetlen futásidejű hibák hiányát biztonságnak vagy típusbiztonságnak nevezik; Tony Hoare korai lapjai nevezték ezt a tulajdonságot biztonságnak[8].
Dinamikus típusellenőrzés
Egyes programnyelvekben nincsen statikus típusellenőrzés. Számos ilyen nyelvben könnyű olyan programokat írni, amelyeket a legtöbb statikus típusellenőrző elutasítana. Például egy változó eltárolhat egy számot, vagy "hamis" logikai értéket
Változatok
- Java, C#, Pascal, Ada, C nyelvek mindegyikében szükséges, hogy a változóknak legyen egy definiált típusuk, és a köztük való műveleteket explicit konverziókkal érhetjük el.
- Objektumorientált nyelveknél, mint például a Ruby, Python, Smalltalk, az objektumok között létezhet egyfajta implicit konverzió, mert a fordító nem ellenőrzi a típusokat szigorúan.
- ML, F#, OCaml, és több más (elsősorban funkcionális) nyelvek esetén a fordító következtet az adattagok típusára, az azokon végzett műveletek alapján, amit statikusan kezel. Tehát ha egy változót egész számként értelmez a program futása elején, valamilyen aritmetikai művelet hatására, akkor a futás közben beszúrt sztring művelet a változón hibát fog generálni.
- Visual Basic-ben létezik egy Variant nevű adattípus, mely egyfajta hibrid, bármilyen adattagot tartalmazhat, tárolhat, és végezhetőek rajta az alapvető műveletek - mint egy gyengén típusos nyelv esetén.
- Az assembly nyelv típusmentes. Minden műveletet a programozónak ellenőriznie kell, hogy a megfelelő módon értelmezve fussanak le.
Jegyzetek
Források
- ↑ Strong versus weak typing. www.cs.cornell.edu. (Hozzáférés: 2021. április 29.)
- ↑ JavaZone (2013. szeptember 12.). „The Unreasonable Effectiveness of Dynamic Typing for Practical Programs”.
- ↑ Liskov, Barbara (1974. március 28.). „Programming with abstract data types”. ACM SIGPLAN Notices 9 (4), 50–59. o. DOI:10.1145/942572.807045. ISSN 0362-1340.
- ↑ Jackson, K. (1977. augusztus 25.). „Parallel processing and modular software construction” (angol nyelven). Design and Implementation of Programming Languages, Berlin, Heidelberg, 436–443. o, Kiadó: Springer. DOI:10.1007/BFb0021435.
- ↑ a b Typing: Strong vs. Weak, Static vs. Dynamic. www.artima.com. (Hozzáférés: 2021. április 29.)
- ↑ Type-punning and strict-aliasing (angol nyelven). www.qt.io. (Hozzáférés: 2021. április 29.)
- ↑ Cardelli, Luca. Typeful Programming (PDF) (angol nyelven) [1993]. Hozzáférés ideje: 2021. április 29.
- ↑ Hoare, Charles Antony Richard. Hints on Programming Language Design, Computer Systems Reliability (PDF). OCLC 2513961. Hozzáférés ideje: 2021. április 29.
- ↑ Umann Kristóf. Programozási Nyelvek: C++Gyakorlat és előadásjegyzet (PDF). Hozzáférés ideje: 2021. április 29.