A multinyelv

Egy régi cikket olvasgatva eszembe jutott egy gondolatom, amit már meg akartam írni egy ideje, de sose jutottam hozzá. Az ősi programozómondás szerint a programozó erénye a lustaság. (Ha az olvasó nem érti, hogy miért, akkor nyilván nem programozó, és nem biztos, hogy a cikk további részében örömét leli.) De nekem sokszor úgy tűnik, hogy ezt az erényt nem hasznosítjuk eléggé, vagy nem szolgáljuk ki eléggé, vagy tudomisén mit.
  Itt vannak például a különböző nyelvek. Gyakorta megesik, hogy ráakad az ember egy klassz algoritmusra valahol már lekódolva, föl is használná, de – másik nyelven van. A programozó ilyenkor mit tehet, lefordítja. Csak hát ez ellentmond az ősi alapelvnek, hiszen a fordításnál elkövethetünk olyan hibákat, amiket a copy-paste technikával biztosan nem.
  De voltaképpen mi a különbség a programnyelvek között? Ha lecsupaszítjuk a dolgot, akkor annyi, hogy minden nyelvet és nyelvjárást egy-egy szoftver valósít meg, és mindegyiknek megvannak a saját szintaktikai és szemantikai szabályai. Egyik sem tűnik olyasminek, ami visszavonhatatlanul megakadályozza a nyelvek egyesítését. Ha egy nyelv, mondjuk a PHP 6 értelmezésére már megírtak egy programot (a PHP programot, ami letölthető a PHP.netről), akkor ugyanígy meg lehet írni még egy programot. És ha egy nyelv, mondjuk a Spectrum BASIC szintaxisa és szemantikája különbözik a PHP-étől, akkor lehet írni olyan programot, ami összehozza a kettőt.
  Ez nyilvánvaló. Tessék egy forrásszöveg példa gyanánt.

10 PRINT "Hello, world!"

#include <iostream>
int main()
{
  std::cout << "Hello, world!n";
}

: HELLO  ( -- )  ." Hello, world!" CR ;
  HELLO

print [Hello, world!]

program hello;
begin
  writeln('Hello, world!');
end.

echo "Hello, world!";

A programozó olvasó ránézésre fel fogja ismerni, hogy a forrásszöveg valójában hat forrásszöveg, éspedig ugyanazt a Hello, world! programot másoltam ide öt nyelven. Sőt azt is ránézésre fel fogja ismerni, hogy a nyelvek sorban: sorszámozott BASIC, C++, Forth, Logo, Pascal és PHP. A programozó olvasó olyan forrásszöveget is kitűnően meg fog érteni, aminek nyelvét nem vagy hibásan azonosítja, például ezt:

function main()
{
  message("Hello, world!")
}

Az olvasó tudja ebből, hogy Baan Tools nyelven van, 3GL formátumban? Én nem tudnám, mégis minden betűjét hibátlanul megértem. (A példák természetesen a Wikibooks listájából valók.)
  Én még azt se gondolom, hogy a gépet meg kellene tanítani felismerni a programnyelvet, ámbár ha ezt tennénk, az se lenne csoda. A számítástechnika történetének egyik folyamata arról szól, hogy a gépeket megtanítjuk olyan dolgokra, amiket mi mindig is tudtunk. Tudnak papírra írni, olvasni (OCR), sakkozni, zenélni – de volt idő, amikor ezeket még nem tudták. De programnyelvet felismerni nem feltétlenül kellene megtanítani őket.

Én a következőt képzeltem el. Lehetne írni egy olyan fejlesztőkörnyezetet, ami Minden Nyelven Tud. Hiszen a nyelvek végeredményben csak a szintaxisban és a mögötte levő szemantikában különböznek. (Ez így nem igaz, de momentán megteszi.) A mai programnyelvek már mind parsert használnak, egy külön programot, ami elolvassa a forráskódot és lefordítja egy köztes kódra, amit aztán a fordító vagy az értelmező feldolgoz. Akkor mi lenne, ha több parser lenne a fejlesztőkörnyezetben?
  Egy olyan parsert képzeltem el, ami egy központi részből és sok-sok pluginból áll. Minden nyelvhez, nyelvjáráshoz egy plugin jár, és a központi rész választja ki, hogy mikor melyiket válassza. Például így:

#BASIC
10 PRINT "Hello, world!"

#C
#include <iostream>
int main()
{
  std::cout << "Hello, world!n";
}

#FORTH
: HELLO  ( -- )  ." Hello, world!" CR ;
  HELLO

#LOGO
print [Hello, world!]

#PASCAL
program hello;
begin
  writeln('Hello, world!');
end.

#PHP
echo "Hello, world!";

Például így. A parser központi része látja a nyelveket jelölő direktívákat és meghívogatja a pluginokat. Azok lefordítják a nyelvükön írt részeket, és egyetlen köztes kódot (Pascal-terminológiával P-kódot) kapunk, amit aztán egyetlen fordítónak vagy értelmezőnek lehet föltálalni.
  Miért jó ez? Több okból. Ha találunk a neten egy alkalmas algoritmust, azt fordítgatás nélkül beilleszthetjük a programunkba. Ugyanazon a projekten úgy dolgozhat több programozó, hogy mindenki a neki legjobban megfelelő nyelven írhatja a neki jutó részeket. És a különböző nyelvek profitálhatnak egymás képességeiből.
  Azt mondtam, hogy a nyelvek csak a szintaxisban és a szemantikában különböznek, és hozzátettem, hogy ez így nem igaz. Persze hogy nem igaz, hiszen a nyelvek mögött egy szoftver van, ami különféle rutinokat tartalmaz. Például a Logo minden interpretációja tartalmazza a teknőcgrafikát, amit a többi nyelvben úgy kell külön létrehozni, ha szükség van rá.
  Ha több parserünk van, amik ugyanazt a pszeudokódot állítják elő, az csak úgy ér valamit, ha a fordítóban benne vannak a szükséges rutinok is. Vagyis ha tudunk Logót interpretálni, akkor a teknőcgrafikához szükséges rutinoknak is benne kell lenniük a fordítóban. De ha benne vannak a fordítóban, akkor a többi nyelvből is elérhetjük őket. Hogyan? Ki kell dolgozni rá a módszereket. Ilyesféléket:

#TRANSLATE
  FROM PHP
    forward(#VAR#);
  END FROM
  TO LOGO
    forward #VAR#
  END TO
END TRANSLATE

Innentől PHP-ben a forward() függvény a Logo-beli forward utasítást fogja jelenteni.
  Szerintem nyereség lenne egy ilyet összehozni.

»»»»»»