Erősen típusos programozási nyelv

A Wikipédiából, a szabad enciklopédiából


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 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[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]

  1. Strong versus weak typing. www.cs.cornell.edu. (Hozzáférés: 2021. április 29.)
  2. JavaZone (2013. szeptember 12.). „The Unreasonable Effectiveness of Dynamic Typing for Practical Programs”.  
  3. 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.  
  4. Jackson, K. (1977. április 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.  
  5. a b Typing: Strong vs. Weak, Static vs. Dynamic. www.artima.com. (Hozzáférés: 2021. április 29.)
  6. Type-punning and strict-aliasing (angol nyelven). www.qt.io. (Hozzáférés: 2021. április 29.)
  7. Cardelli, Luca. Typeful Programming (PDF) (angol nyelven) [1993]. Hozzáférés ideje: 2021. április 29. 
  8. Hoare, Charles Antony Richard. Hints on Programming Language Design, Computer Systems Reliability (PDF). OCLC 2513961. Hozzáférés ideje: 2021. április 29. 
  9. Umann Kristóf. Programozási Nyelvek: C++Gyakorlat és előadásjegyzet (PDF). Hozzáférés ideje: 2021. április 29. 

Kapcsolódó szócikkek[szerkesztés]