Erősen és gyengén típusos programozási nyelvek
Erősen vagy szigorúan típusos programozási nyelveknek nevezzük azokat a nyelveket, melyekben minden kifejezés és részkifejezés típusa fordítási időben ismert. Á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
[szerkeszté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 String 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
[szerkesztés]// 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
[szerkesztés]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
[szerkesztés]- 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
[szerkesztés]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ában olyan 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”
[szerkesztés]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 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
[szerkesztés]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
[szerkesztés]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
[szerkeszté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
[szerkeszté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
[szerkesztés]- 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 típusmentes. Minden műveletet a programozónak ellenőriznie kell, hogy a megfelelő módon értelmezve fussanak le.
Jegyzetek
[szerkesztés]Források
[szerkesztés]- ↑ 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. december 18.). „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.