ebooksgratis.com

See also ebooksgratis.com: no banners, no cookies, totally FREE.

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
Privacy Policy Cookie Policy Terms and Conditions
Scheme - Wikipédia

Scheme

A Wikipédiából, a szabad enciklopédiából.

A Scheme programozási nyelv a Lisp nyelvcsalád egyik tagja, illetve a Lisp egyik nyelvjárása (dialektusa). A Scheme tervezői arra törekedtek, hogy a Lispből minden fölösleges tulajdonságot kigyomláljanak, és egy egyszerű, kevés szabállyal leírható, de erőteljes nyelvet hozzanak létre. Például a Scheme-ben egyetlen egységes névtérben találhatók a függvények és a változók. A nyelv precíz leírása és egyszerűsége miatt az oktatásban jól használható; alkalmazását valós problémák megoldására viszont némileg akadályozza, hogy kevés a szabványos eljárás, nincsenek kiterjedt szabványos könyvtárak. Ezt a hiányosságot azonban az utóbbi években igyekeznek pótolni (SFRI = Scheme Request for Implementation) – ma már a legtöbb Scheme implementáció tartalmaz több-kevesebb SRFI-megvalósítást.

[szerkesztés] A nyelv nagyon rövid története

A Scheme nyelv első leírását Gerald Jay Sussman és Guy Lewis Steele Jr. alkotta meg 1975-ben. A nyelvet azóta a javított jelentések (Revised Reports) írják le, melyekből az első 1978, a legutóbbi, az R5RS 1998-ban jelent meg. Az IEEE is szabványosította a nyelvet (IEEE Std 1178-1990). A legújabb szabvány, azaz az R6RS létrehozása éppen folyamatban van. A nyelvet 1981-ben kezdték oktatásra használni az MIT-n, a Yale-en és az Indiana University-n. 1984-ben jelent meg a SICP (Structure and Interpretation of Computer Programs) első kiadása. Ez egy meghatározó jelentőségű számítástechnikai tankönyv amely a Scheme nyelvet használja.

[szerkesztés] A Scheme nyelv jellemzői

(Egyelőre nem teljes a leírás, főleg az egyedi jelleget, illetve más Lisp nyelvjárásoktól való eltérést hangsúlyozzuk. Javasoljuk, hogy a tisztelt olvasó tanulmányozza a Lisp bejegyzést is.)

A Scheme-ben is a Lispben megszokott teljesen zárójelezett prefix kifejezésforma használatos, pl. az

 1 + (2 * 3)

(matematikai, vagy más nyelvekben szokásos) kifejezést az

 (+ 1 (* 2 3))

formában írhatjuk le.

Az adatok között megjelenik a #t és #f logikai érték, amely az igaz és hamis értéket jelöli. Fontos, hogy az üres lista (nil) nem számít hamis értéknek, mint más Lispeknél.

Változó létrehozása:

 (define d 5)
 (define z '(1 2))

Értékadás:

 (set! z #t)

Általában a mellékhatással rendelkező eljárások neve felkiáltójellel végződik.

Eljárások létrehozása:

 (define (f x)
   (+ x d))

A Scheme-ben a Lisp más nyelvjárásaiban szokásos függvény elnevezés helyett az eljárás szót használják.

A Scheme-ben a Lisp történetében szokatlan módon a lexikális hatókör szabálya érvényesül (mint az Algolban vagy A Pascalban. Ez azt jelenti, hogy az eljárások hívásakor a definíciójukkor érvényes környezetben keresik a változó értékét, nem pedig a hívási környezetben. (A környezet nem más, mint változó-érték kötések halmaza.) A lexikális hatókörre mintapélda (az előző példákat is figyelembe véve):

 (let ((d 1))
   (f d))

Ez a kifejezés a 6 értéket adja vissza, mivel az f eljárás definíciós környezetében a d változó értéke 5. Ha a dinamikus hatókör lenne érvényben (mint például a Common Lispben a globális változók esetén) akkor a let kifejezés értéke 2 lenne.

A Scheme-ben az adatok típusa nem a változókhoz, hanem az értékekhez van kötve, azaz a Scheme dinamikus típusokat használó nyelv (mint a többi Lisp):

 (define v 1)

Itt az v változó értéke 1, amely egész típusú, de a

 (set! v '(1 2))

értékadással már az (1 2) lista lesz az értéke.

A Scheme-ben létrehozott objektumok (értékek) élettartama nem korlátozott, tehát ha egy eljárás lokális változóját valahogy el tudjuk érni, akkor annak értéke megmarad a hívás után is:

 (define (osszeado z)
   (lambda (x) (+ z x)))
 (define plusz2 (osszeado 2))

Az osszeado eljárással egy tetszőleges számmal növelő eljárást tudunk létrehozni. Annak ellenére, hogy a program futása – a kifejezések kiértékelése – közben újabb és újabb tárterületeket használ el ez általában nem jelenti azt, hogy gyorsan elfogy a rendszerünk összes tárkapacitása: ha egy érték többé már nem elérhető a rendszer az általa elfoglalt helyet újrahasznosítja. Ez a folyamat a szemétgyűjtés (ilyet más nyelvek is használnak, mint pl. a Perl, Python vagy a Java).

Az eljárások hívásánál a paraméterek átadása mindig érték szerint történik (call-by-value) (mint általában a Lispben, a C-ben, Pascalban, de például nem úgy, mint a Haskellben, ahol ún. szükség szerinti átadásról beszélünk (call-by-need)). Ezt a paraméterátadási stratégiát mohó kiértékelésnek is nevezzük, ahol a paraméterként megadott kifejezések az eljárás hívása előtt kiértékelődnek – ellentétben a lusta kiértékeléssel, ahol a paraméterként átadott kifejezés csak akkor értékelődik ki, amikor szükség van erre az értékre. Példa:

 (define (moho x y) x)
 (moho 1 (/ 1 0))

A moho függvény hívásakor hibajelzést kapunk, holott az y paraméter értékét nem használjuk a kifejezésünkben – de az érték szerinti paraméterátadás szabálya szerint a ki kell értékelni a (/ 1 0) kifejezés értékét a moho hívása előtt, és ez hibajelzéshez vezet.

A Scheme nyelvben az eljárások is első osztályú polgárai a nyelvnek, azaz eljárást át lehet adni paraméterként, használható visszatérési értékként (mint azt az osszeado eljárásnál láttuk), adatstruktúra része lehet. Névtelen függvényeket a lambda szimbólummal definiálhatunk:

 (lambda (x y) (+ x y 1))

Ez az eljárás összeadja a két paraméterét és még egyet ad hozzá, pl. a

 ((lambda (x y) (+ x y 1)) 2 3)

kifejezés a 6 értéket adja vissza.

Más Lisp dialektusokkal ellentétben az eljárás- (vagy függvény)hívás első tagja egy tetszőleges kifejezés, amely értéke eljárás kell, hogy legyen:

 (define (buta-pelda x y)
   ((if (> x 0) + *) x y))

Ez az eljárás összeadja két paraméterét ha x nagyobb mint 0, egyébként összeszorozza őket. (A Common Lisppel ellentétben itt nincs szükség a function speciális formára, vagy a funcall függvényre, mivel egy névtérben laknak az eljárás-értékek az egyéb adatértékekkel.)

A Scheme nyelv talán egyik legérdekesebb fogalma a folytatás (continuation). A folytatás egy adott számítás menetének jövőjét jelenti, azaz egy program kifejezése kiértékelésének egy adott pillanatától számított további működését. A folytatás a más nyelvekben megtalálható goto, exit, return, catch névvel illetett utasítások, illetve mechanizmusok általánosítása. A folytatás megvalósítására a call-with-current-continuation (szokásos rövid neve: call/cc) eljárás szolgál.

A call-with-current-continuation eljárást egy egyparaméteres eljárásparaméterrel (általában lambda-kifejezéssel) kell meghívni. Az átadott eljárásnak a paramétere egy szökési eljárás, amellyel az átadott eljárásból kiléphetünk.

Ebben a példában a call-with-current-continuation eljárás egy egyszerű használatát mutatjuk be:

 (call-with-current-continuation
   (lambda (exit)
     (for-each (lambda (x)
                 (if (negative? x)
                   (exit x)))
               '(54 0 37 -3 245 19))
     #t))

Ezen kifejezés értéke a lista első negatív eleme lesz, azaz -3. (A for-each eljárás az első paraméterként adott eljárást hívja meg sorban a második paraméterében adott lista minden elemére.) Itt egyszerűen egy strukturált kilépésként használtuk a szökési eljárást. Mivel ez a folytatás egyenrangú adatnak számít a Scheme-ben, ezért visszatérési értékként használhatjuk, eltárolhatjuk, esetleg később többször is meghívhatjuk mint bármelyik más függvényt: ezzel többféle, a szokástól eltérő vezérlési struktúrát hozhatunk létre.


aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -