Kifejezések, változók
Elnevezési konvenciók
A Dylan megengedi különleges karakterek használatát az azonosítókban. Ezek használatával adott egy elnevezési konvenció:
<string> |
egy osztály |
insert! |
módosító függvény (módosít bizonyos argumentumokat) |
empty? |
igaz/hamis függvény (egy vagy több argumentumot tesztel, és igaz/hamis
értékkel tér vissza) |
write-line |
két szóból álló azonosító |
$name |
konstans |
*name* |
modul szintű változó |
Igaz, hamis
A Dylan az igaz értéket a #t, míg a hamis értéket a #f azonosítokkal jelöli. Amikor egy logikai kifejezést kiértékel, akkor minden érték igaznak számít, kiveve a #f-et. Tehát a 0 - és minden más, ami más nyelvekben szokásosan "hamis"-nak értékelődik ki - Dylanben igaz értékű lesz.
A változók
Dylan-ben a változók különböznek a C-ben vagy Pascal-ban megszokottaktól. Ahelyyet, hogy az értéküket tárolnák, hivatkoznak rájuk. Hasonlítanak a C++ referenciáira, vagy a Java objektum típusú változóira. Mint a referenciák, a Dylan változókat is indirekció nélkül értékelhetjük ki. Mint a mutatóknál, bármikor át lehet egy másik objektumra állitani, ha a programozó úgy kívánja.
Továbbá, minden szám, ami egy Dylan programban előfordul, mindössze egyetlen egyszer létezik valójában. Minden változó, ami a 2-re hivatkozik - vagy ahogyan Dylan-ban hívják, a 2-höz kötött - , pontosan ugyanaz a dolog.
let x = 2; // x létrehozása, és kötése a 2-höz
x := 3; // x átkötése a 3-as értékhez
let y = x; // y létrehozása, és kötése ahhoz, amihez az x is kötve van
Ha két változó egy objektumhoz van kötve, aminek van belső struktúrája, az igencsak meglepheti a C programozókat.
let car1 = make(); // car1 létrehozása, és kötése egy új car objektumhoz
car1.odometer := 10000; // odometer módosítása
let car2 = car1; // új név kötése car1-hez
car2.odometer := 0; // odometer törlése
car1.odometer; // kiértékelése 0!
Attól kezdve, hogy egy vagy több változó hivatkozik egy objektumra, az folyamoatosan létezik. Amikor az utolsó hivatkozás is kikerül a láthatósági mezőből, vagy átkötik máshotvá, az objektumot a szemétgyűjtő begyűjti. Ha a program már nem hivatkozik többé az objektumra, a szemétgyűjtő mehanizmus felszabítja a lekötött memóriát, és szükség esetén újrahasznosítja azt.
Megjegyzés: a Dylan változókat deklarásiónál köthetjük nem egyértelmű értékekhez is. A típushelyesség, és a hatékonyság érdekében, minden változót jól definált objektumokhoz kössünk.
Értékadás, egyenlőság, azonosság
A Dylan 3 különböző "egyenlőség" operátort használ. A Pascal := értékadó operátorát, ami átköti a változót az új értékhez. A Pascal = egyenlőség operátorát, ami az egyenlőséget vizsgálja Dylan-ben. Két objektum általánosságban akkor egyenlő Dylan-ban, ha azonos osztályba tartoznak, és a struktúrájuk is egyenlő (rekurzívan). Valamint a C == operátorát, ami az azonosság operátor Dylan-ban. Két változó akkor azonos, ha ugyanahoz az objektumhoz kötöttek.
A következő példa nagyából ugyanazt jelenti:
(a == b) // Dylan
(&a == &b) // C or C++
(@a = @b) // Pascal
A következő kódrészlet a 3 operátort mutatja be:
let car1 = make();
let car2 = make();
let car3 = car2;
car2 = car3; // #t
car1 = car2; // ??? (lásd lent)
car2 == car3; // #t
car1 == car2; // #f
car2 := car1; // átkötés
car1 == car2; // #t
let x = 2;
let y = 2;
x = y; // #t
x == y; // #t (csak egy 2 van!)
Két példát érdemes megemlíteni. Az első, amit nem tudunk, hogy vajon car1 = car2? Mert nem tudjuk, hogy a make mindkét autót azonos sorozatszámmal, sofőrrel, és egyéb információkkal hozta-e létre? Csak ha egyetlen értékben sem térnek el, akkor lesznek egyenlőek. A második, hogy x == y, mert minden változó egy számhoz van kötve, ami ugyanaz a szám a programozó szemszögéből. (A fordítóprogram természetesen csinálhat valami más, sokkal hatékonyabb dolgot is, amikor a gépi kódot generálja.) A string-ek máshogyan viselkednek, mint a számok. A string-ek külön tárolódnak, és két string ha egyenlő, akkor nem feltétlenül kell ugyanannak a string-nek lenniük.
Párhuzamos értékadás
Lehetséges egyidőben több változó átkötése is. Pédául:
let x = 2; // egyesével
let y = 3;
let z = 4;
let (x, y, z) = (2, 3, 4); // párhozamosan
Perl-ben a megfelelő utasítás az értékek vektorát rendeli hozzá a változók vektorához. Dylan-ben nem kell vektorokat használni. Minden érték közvetlenül rendelődik a változóhoz. (Implementáció függő megoldásokkal.)
Típusos deklarációk
A Dylan változóinak lehet egyértelmű (explicit) típusa. Ez lehetővé teszi a fordítóprogram számára, hogy a típushibákat fordítási időben felfedje, és hogy hatékonyabb kódot generáljon. Ezen lehetőség előnyeinek kihasználásához a :: opertátort kell használni:
let x :: = 2;
let vehicle :: = make();
let y :: = 3; // bármilyen szám
let z :: = vehicle; // HIBA!
Ahogy az a példából is látszik, egy változó köthető egy értékhez, aminek a típusa a deklarációban szereplő típusú, vagy annak egy alosztálya. Így a típushibákra fordítási ídőben fény derül. Általában a fordító következtet a változók típusára, amikor a kódot generálja. Ha például egy lokális változó soha nem kötődik át máshoz, csak ineger-hez, akkor a fordító ezt felismeri, és optimalizálja a kódot.
Modul szintű változók és konstansok
A Dylan támogatja a module szintű változókat, ami leginkább a C globális változóihoz hasonlítanak. Jólehet a let függvény csak a metóduson belül használható, a belül definiált változókat és konstansokat kívül is lehet használni.
define variable *x* :: = 3;
define variable *y* = 4;
define constant $hi = "Hi!";