02 - értékek

Hogy is volt ez C-ben

C-ben megszokhattuk, hogy mikor programot írunk, akkor például

  • tudunk változókat deklarálni
  • ezeknek a változókat valamilyen típussal deklaráljuk
  • a változóknak adhatunk alapértéket, mellyel inicializáljuk őket
  • a program futása közben a változók értékét módosíthatjuk
  • a program futása tkp utasítások egymás utáni végrehajtása

Tipikus C programban pl. egy for ciklus:

1
2
3
for( int i = 0; i < 10; i++ ) {
  printf( "%d\n", i );
}

Itt ugye az i egy változó, típusa int, tehát amíg ebben a scope-ban vagyunk, addig az i-nek adhatunk értékül bármit, ami egy int; a for ciklus fejlécében i értékét 0-ra állítjuk, majd az i++ utasítással a ciklusmag minden egyes végrehajtását követően megnöveljük eggyel, a ciklusba való minden egyes belépés előtt pedig kiértékeljük az i < 10 logikai kifejezést, ha igaz, akkor belépünk a ciklusba (újra és újra), ha nem, akkor pedig a for ciklus magjának záró kapcsosa utáni utasítás végrehajtásával folytatjuk a vezérlést.

Progalapon valószínűleg megtanultuk azt is, hogy a ciklus feltételében szereplő logikai kifejezésben valamit meg kell tudnunk változtatni a ciklusmagban, hogy legyen egyáltalán esélyünk kilépni a ciklusból. (Vagy ha nem így, akkor breakelni egy másik feltétel mentén, amit szintén meg kell tudnunk változtatni, ha nem akarunk végtelen ciklust.)

Hogy nincs ez így egy ,,pure'' funkcionális nyelvben

Azt a tulajdonságot, hogy egy változó, egy objektum, egy érték megváltozhat idővel, úgy mondjuk, hogy mutable. Így például a fenti C kódban az i egy mutable int változó.

A kurzus során egyre jobban fogjuk ,,érezni'', hogy mi is a központi szervező elve egy ,,pure funkcionális'' programozási nyelvnek, de rögtön az első, amitől a ,,pure'' jelzőt kapja: nincs benne mutable állapot. Ez pl. azt jelenti, hogy ha a kódban egy E kifejezést (általában majd E mint ,,Expression'' fog kifejezéseket jelölni) két különböző helyre írunk, akkor a két különböző ponton ugyanarra fognak kiértékelődni, függetlenül attól is, hogy a program futása során mikor értékeljük ki, vagy másokkal mi történik közben. A fenti C program futása során pl. amiben szerepel az i változó, az semmi nem ilyen: az i < 10 feltétel is lesz olyan pont, amikor igazra értékelődik ki, és lesz olyan pont is, amikor hamisra.

Egy pure funkcionális nyelvben ilyen nincs: deklarálhatunk ,,változók'' helyett ,,értékeket'' ugyanaszerint a séma szerint, mint C-ben az int i = 0; utasítással: megadhatjuk az érték nevét (i), típusát (int) és inicializálhatjuk (most épp 0-val), a különbségek:

  • kötelesek vagyunk inicializálni egy kifejezéssel az értékünket;
  • nincsenek állapot-megváltoztató, avagy mutátor elemek a programban: így pl. nincs i++ alakú utasítás, ami megváltoztatná az i néven deklarált értéket, és nincs i = 42; alakú értékadás sem -- amit az i jelöl a deklaráció pillanatában, azt fogja jelölni a program futása során végig (vagy legalábbis addig, amíg az érték maga meg nem szűnik úgy, hogy kilépünk az őt deklaráló scope-ból).

Hogy van ez Scalában

1
val i : Int = 0

A val kulcsszóval kezdünk egy új érték deklarálást, aztán jön az érték neve (most i), kettőspont, típusa (ez most Int, típusokról lesz még szó, de ez a szokásos int, ami 32 bites, előjeles és megfelel a Java int primitív típusnak), és egy egyenlőségjel után maga az értéke, ami innentől nem változtatható.

Hogy lesz ebből ciklus akkor???

Rekurzióval! Nemsokára meglátjuk, hogy pure funkcionális nyelvben rekurzióval és szelekcióval (,,iffel'') tudjuk kiváltani az imperatív nyelvek loop konstrukcióit.

Kérdések


Utolsó frissítés: 2020-12-23 19:43:13