Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Zero


Redakcija dne 11:22, 27. oktober 2009 od Ales (Pogovor | prispevki)
(prim) ←Starejša revizija | poglejte trenutno redakcijo (prim) | Novejša revizija→ (prim)

O jeziku

Zero je eksperimentalen, objektno usmerjen, statično tipiziran programski jezik, ki ga je razvil dr. Sašo Greiner. Osnovne značilnosti so čista objektna abstrakcija, predstavitev stanja z metodami in metaprogramiranje. Glavna ideja jezika Zero, ki je sicer zgrajen na temeljih jezika Z0, je možnost dinamičnega spreminjanja obnašanja in strukture programov. Jezikovni koncepti jezika so večidel 'klasični' na področju objektno sumerjenih jezikov, saj vključujejo razredno hierarhijo, večkratno dedovanje, statično (hibridno) tipiziranje in preveden programski kod. Jezik omogoča metaprogramiranje s pomočjo strukturalne refleksije, ki ohranja pravilnost tipov v času izvajanja. Zero se po splošni metodi pojmovanja uvršča med statično tipizirane jezike, podobno kot Java, C++ ter C#, čeprav je preverjanje tipov v času izvajanja na določenih mestih neizogibno. Če izhajamo iz tega gledišča, je Zero hibridno tipiziran jezik.

Stanje objekta ni, kot je to v navadi pri večini objektno usmerjenih jezikov, predstavljeno z instančnimi spremenljivkami, temveč z metodami. Ta pristop je bolj kot pri razrednih jezikih v uporabi pri prototipnih jezikih. Stanje objekta se spreminja s spreminjanjem metod, pri čemer gre za metaprogramiranje. Metaprogramiranje zahteva, da smo jeziku dodali metarazrede Class, Method ter Closure.

Metaprogramiranje je realizirano z refleksijo. Refleksijski mehanizmi v jeziku Zero ne omogočajo zgolj poizvedovanja po informacijah, kot so imena razredov, metod, tipi parametrov itn. temveč tudi njihovo spreminjanje. Zraven behavioralne refleksije, ki omogoča manipulacijo obnašanja posameznih jezikovnih konstruktov, jezik omogoča tudi strukturalne spremembe v posameznih konstruktih. Strukturalne spremembe morajo ohranjati obstoječe signature metod in razredov. To je cena statično tipiziranega jezika. Prednost je v tem, da pri takšnem metaprogramiranju ne more (ne sme) priti do napak povezanih s tipi. Metode in razrede je mogoče spreminjati, ko so že naloženi v pomnilniški prostor virtualnega stroja. V času izvajanja je mogoče metode povsem nadomestiti ali jih spremeniti le delno.

Zero velja za 'čisti' objektno usmerjen jezik. To pomeni, da so vsi konstrukti, tudi bloki in iterativni stavki (zanke) predstavljeni uniformno - kot objekt. Metarazred Closure, na keterem temeljijo vse krmilne strukture jezika, omogoča vpogled v te strukture in spremembo obnašanja. Na ta način je npr. mogoče spremeniti obnašanja zanke For. Telo krmilnih struktur je samo sestavljena iz vgnezdenih struktur. Funkcionalnost razreda Closure omogoča vpogled v te vgnezdene strukture in njihovo spreminjanje. Tako je v času izvajanja možno skoraj poljubno sestavljanje programov.

V jeziku Zero so metode predstavljene kot prvorazredne vrednosti, kar pomeni, da jih lahko tretiramo enako kot spremenljivke. Lahko jih vrnemo iz druge metode ali jih podamo kot argument. Signatura metode se preveri v času prevajanja, tako da je večino napak mogoče odkriti v tej fazi. V času izvajanja se signature metod preverjajo samo pri pretvarjanju metodnih tipov iz osnovnega v bolj izpeljanega. Narava jezika Zero je imperativna, kljub temu pa je uporaba metod višjega reda praktična in razumljiva. Metode oz. funkcije višjega reda so sicer značilnejša lastnost funkcijskih programskih jezikov.

Izvorni kod jezika Zero se prevede v zložni kod virtualnega stroja Z.

Primeri

Števec implementiramo na sledeč način:

class Counter {

   public Counter { /* prazen konstruktor */ }
   public getValue : Integer
   {
       return 0;
   }
   public increment
   {
       Integer v = getValue();
       getValue <- method : Integer { return v + 1; };
   }
   public main
   {
       Counter counter = new Counter;
               
       while{ counter.getValue() < 10; } {                          
           ("vrednost je " + counter.getValue()).toString().print();
           counter.increment();
       };       
   }

}


Bloki in krmilne strukture jezika so prvorazredne vrednosti - objekti, ki jih lahko shranjujemo v spremenljivke, vračamo iz metod in jih podamo kot argumente. Oboji temeljijo na zaprtjih (closures), kar pomeni, da jih lahko v času izvajanja s pomočjo refleksije spreminjamo:

Integer n = 60;
// shrani while zanko v spremenljivko
Executable loop = while { n <= 80; } {

      ("n je " + n).print();
       n++; 
  }

// izvedi while zanko. izpiše števila od 60 do 80.
loop.exec();

// spremeni pogojni blok zanke
loop.setChild( loop.getChildren().at(0), { n < 90; } );

// in telo, ki izpisuje samo soda števila
Closure newBody = { if{ n%2==0;} then { ("n je " + n).print(); }; n++; };
loop.setChild( loop.getChildren().at(1), newBody );

// izvedi spremenjeno zanko while
n = 70;
loop.exec(); // izpiše soda števila od 70 do 90


Razredna hierarhija krmilnih strutkur je sledeča:

Closures.jpg


Metode višjega reda

Metode (funkcije) višjega reda so navadno podprte v funkcijskih programksih jezikih kot so Lisp, ML in Haskell. Jezik Zero kljub imperativni naravi omogoča metode višjega reda. Takšne metode so predstavljene kot objekti prvorazredne vrednosti. Metode višjega reda v jeziku Zero so statično tipizirane, preverjanje tipov v času izvajanja se opravlja samo na mestih, kjer gre za razširjanje tipov. Čista metodna usmerjenost je vzrok, da se prvorazredne metode uporabljajo zelo pogosto. Takšen primer so anonimne metode, ki se nahajajo skoraj na vsakem mestu, kjer gre za spremembo instančne metode. Anonimno metodo ustvarimo z rezervirano besedo method:

// argument metodnega tipa
executeMyMethod(Method(String s) m){

  m( "executing " + m.getName() );

}
...
// anonimno metodo podamo kot argument
executeMyMethod( method(String s) { s.print(); } );


Metodo lahko shranimo tudi v spremenljivko:

Method(Integer) m = method(Integer a) { ("anonimna metoda, a=" + a).print(); }

// jo pokličemo
m( 66 );

// ali tudi tako
Vector args = new Vector;
args.add( 55 );

m.invoke( args );


Metodne tipe pretvarjamo kot navadne. Gornjo metodo 'm' lahko pretvorimo:

Method g = m; // brez preverjanja
// klic zahteva eksplicitno pretvorbo v originalen tip
(g as Method(Integer))(66);