Ugrás a tartalomhoz

Erősen és gyengén típusos programozási nyelvek

Ellenőrzött
A Wikipédiából, a szabad enciklopédiából
(Erősen típusos programozási nyelv szócikkből átirányítva)

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