Array ( [0] => 15485882 [id] => 15485882 [1] => cswiki [site] => cswiki [2] => Scheme [uri] => Scheme [3] => [img] => [4] => [day_avg] => [5] => [day_diff] => [6] => [day_last] => [7] => [day_prev_last] => [8] => [oai] => [9] => [is_good] => [10] => [object_type] => [11] => 1 [has_content] => 1 [12] => **Scheme** Scheme je minimalistický a elegantní programovací jazyk, který patří do rodiny jazyků LISP. Byl navržen na konci 70. let 20. století s cílem poskytnout silný a flexibilní nástroj pro výuku a praxi v oblasti informatiky. Je známý svým jasným a srozumitelným syntaxem, který usnadňuje porozumění programovacím konceptům a podporuje kreativní myšlení. Jedním z hlavních rysů Schemu je jeho podpora funkcionality, což znamená, že funkce jsou prvotními obyvateli jazyka. To umožňuje programátorům strukturovat kód elegantně a efektivně a zaměřit se na vývoj komplexních systémů bez zbytečného zmatku. Otevřenost jazyka a jeho minimalistická povaha podporují inovaci a experimentování. Scheme také poskytuje bohaté nástroje pro abstrakci a modulární programování, což usnadňuje spolupráci a opakované použití kódu. Tato vlastnost činí jazyk oblíbeným v akademickém prostředí, kde se často používá k výuce základů algoritmizace a konstrukce programů. I když může být pro nové uživatele ze začátku náročnější se s ním seznámit, jakmile se do jazyka ponoří, objeví jeho krásu a možnosti. Schopnost řešit složité problémy pomocí jednoduchých a elegantních řešení je pro mnohé programátory inspirující. Dnes je Scheme součástí širší komunity jazyků, která zahrnuje různé dialekty a implementace. Projekty jako Racket rozšiřují možnosti jazyka a umožňují jeho použití v různých oblastech, od webového vývoje po vzdělávací nástroje. Celkově je Scheme mocným a pozitivním prostředkem, který v rukou kreativních jedinců podporuje inovace a progres. [oai_cs_optimisticky] => **Scheme** Scheme je minimalistický a elegantní programovací jazyk, který patří do rodiny jazyků LISP. Byl navržen na konci 70. let 20. století s cílem poskytnout silný a flexibilní nástroj pro výuku a praxi v oblasti informatiky. Je známý svým jasným a srozumitelným syntaxem, který usnadňuje porozumění programovacím konceptům a podporuje kreativní myšlení. Jedním z hlavních rysů Schemu je jeho podpora funkcionality, což znamená, že funkce jsou prvotními obyvateli jazyka. To umožňuje programátorům strukturovat kód elegantně a efektivně a zaměřit se na vývoj komplexních systémů bez zbytečného zmatku. Otevřenost jazyka a jeho minimalistická povaha podporují inovaci a experimentování. Scheme také poskytuje bohaté nástroje pro abstrakci a modulární programování, což usnadňuje spolupráci a opakované použití kódu. Tato vlastnost činí jazyk oblíbeným v akademickém prostředí, kde se často používá k výuce základů algoritmizace a konstrukce programů. I když může být pro nové uživatele ze začátku náročnější se s ním seznámit, jakmile se do jazyka ponoří, objeví jeho krásu a možnosti. Schopnost řešit složité problémy pomocí jednoduchých a elegantních řešení je pro mnohé programátory inspirující. Dnes je Scheme součástí širší komunity jazyků, která zahrnuje různé dialekty a implementace. Projekty jako Racket rozšiřují možnosti jazyka a umožňují jeho použití v různých oblastech, od webového vývoje po vzdělávací nástroje. Celkově je Scheme mocným a pozitivním prostředkem, který v rukou kreativních jedinců podporuje inovace a progres. ) Array ( [0] => {{Infobox - programovací jazyk [1] => | název = Scheme [2] => | logo = Lambda lc 2.svg [3] => | popisek loga = [4] => | paradigma = [[funkcionální programování]] [5] => | vznik = 1975 [6] => | autor = [[Guy L. Steele]] a [[Gerald Jay Sussman]] [7] => | typování = silné, dynamické [8] => | dialekty = [[T (programovací jazyk)|T]] [9] => | implementace = [[PLT Scheme]], [[MIT/GNU Scheme]], [[Scheme 48]], [[Chicken (implementace Scheme)|Chicken]], [[Gambit (implementace Scheme)|Gambit]], [[Fluent, Inc.|FLUENT]], [[GNU Guile|Guile]], [[Bigloo]], [[Chez Scheme]], [[STk]], [[STklos]], [[Larceny (implementace Scheme)|Larceny]], [[SCM (implementace Scheme)|SCM]] [10] => | ovlivněno = [[Lisp programovací jazyk|Lisp]], [[ALGOL]] [11] => | ovlivnil = [[Common Lisp]], [[JavaScript]], [[Ruby]] [12] => }} [13] => '''Scheme''' je [[multiparadigmatický programovací jazyk|multiparadigmatický]] [[programovací jazyk]]. Funkcionální programovací paradigma patří mezi tzv. '''funkcionální paradigmata'''. Scheme je jeden ze dvou hlavních dialektů [[funkcionální programování|funkcionálního]] [[programovací jazyk|programovacího jazyka]] [[Lisp]]. Jazyk navrhli Guy Lewis Steele a Gerald Jay Sussman a jeho první popis byl sepsán v roce [[1975]]. [14] => Scheme byl představen akademickému světu skrze sérii článků, nyní známých jako Sussmanovy a Steelovy ''Lambda Papers''.{{Citace elektronické monografie [15] => | titul = The Original 'Lambda Papers' [16] => | url = http://library.readscheme.org/page1.html [17] => | datum přístupu = 2007-06-25 [18] => | url archivu = https://web.archive.org/web/20160510140804/http://library.readscheme.org/page1.html [19] => | datum archivace = 2016-05-10 [20] => | nedostupné = ano [21] => }} Jazyk Scheme definují dva standardy: oficiální [[IEEE]] standard a standard nazývaný ''Revisedn Report on the Algorithmic Language Scheme'', ve zkratce R''n''RS, kde ''n'' je číslo revize. Současný standard je '''R5RS''''''R5RS''' [22] => {{Citace elektronické monografie [23] => | spoluautoři = Richard Kelsey, William Clinger, Jonathan Rees et al. [24] => | datum = 2007-6-25 [25] => | url = http://www.schemers.org/Documents/Standards/R5RS/ [26] => | titul = Revised5 Report on the Algorithmic Language Scheme [27] => | jazyk = anglicky [28] => }}, a '''R6RS''''''R6RS''' {{Citace elektronické monografie [29] => | titul = R6RS.org [30] => | url = http://www.r6rs.org/ [31] => | datum přístupu = 2007-06-25 [32] => | url archivu = https://web.archive.org/web/20130812014945/http://www.r6rs.org/ [33] => | datum archivace = 2013-08-12 [34] => | nedostupné = ano [35] => }} je ve vývoji. [36] => [37] => Oproti Lispu se Scheme snaží o minimalismus – poskytovat co nejmenší počet základních funkcí, na nichž jsou pak v knihovnách postaveny složitější konstrukce. Díky tomu má dosud poslední reference jazyka jen 50 stran. [38] => [39] => Scheme byl prvním dialektem Lispu, který nabízel volbu mezi lexikálním nebo dynamickým rozsahem platnosti proměnné. Také byl jedním z programovacích jazyků, který podporoval „first-class [[continuation]]“. [40] => [41] => Tento jazyk je v praxi používaný jen zřídka, používá se především ve školách pro výuku programování algoritmů. [42] => Nejznámější implementací je grafický editor [[GIMP]], jehož dodatečné zásuvné moduly a skripty jsou psány v dialektu jazyka Scheme. [43] => [44] => == Původ == [45] => Na počátku zrodu jazyka Scheme stála potřeba Guye Steela a Geralda Sussmana z MIT (Massachusettský technický institut), vyzkoušet si některé aspekty modelu [[aktor]]ů, který v roce 1973 veřejnosti představil [[Carl Hewitt]]. Protože LISP se k tomuto příliš nehodil, bylo potřeba navrhnout nový jazyk. Ten byl nakonec implementován v LISPu. A dokonce i syntaxí LISP hodně připomínal. Byl však o dost jednodušší, a odstraňoval některé z nepříjemných vlastností LISPu. [46] => [47] => ''"Chceme lépe porozumět Hewittovu [[Aktor]] modelu, ale máme problémy vztáhnout aktor model a jeho neobvyklou terminologii známých programových notací. Plánovali jsme zkonstruovat ukázkovou implementaci [[aktor]] jazyka tak, abychom si s ní mohli hrát. Použitím MacLisp, jakožto pracovního prostředí, jsme napsali tenký [[interpret (software)|interpret]] [[Lisp]]u a poté přidali mechanismus k vytváření aktorů a posílání zpráv.„'' [48] => [49] => Poprvé byl jazyk Scheme veřejně popsán v roce 1975 v práci Sussmana a Steela “ Scheme: an interpreter for extended lambda calculus". V roce 1976 pak Sussman a Steele napsali dvě publikace "LAMBDA: The Ultimate Imperative" a "LAMBDA: The Ultimate Declarative", v nichž popsali, jak řešit běžné programové konstrukce. [50] => [51] => V roce 1978 byl jazyk Scheme standardizován. Základem se stala "Revidovaná zpráva o Scheme" – dialektu LISPu. Tato zpráva popisovala vývoj jazyka, poté co byla MIT implementace rozšířena o podporu inovativního kompilátoru. Další zpráva, která byla nazvána "Revize revize reportu Scheme, neboli neobvyklý LISP" byla publikována v roce 1985. Tradice revizí revize revize se zachovala a dnes je již na světě poslední pátá revize z února roku 1998. [52] => [53] => Původní název jazyka byl Schemer. Po vzoru dobových jazyků pro umělou inteligenci [[Planner]] a [[Conniver]]. Protože však autoři používali operační systém [[Incompatible Timesharing System|ITS]], který limitoval délku souborů a adresářů šesti znaky, byly vždy soubory pro Schemer uloženy v adresáři Scheme. Z toho vzešel název Scheme, který tak nahradil Schemer. [54] => [55] => == Budoucnost == [56] => {{aktualizovat}} [57] => Nový standardizační proces začal na 2003 Scheme workshopu, s cílem vytvoření R6RS standardu v roce 2006. [58] => R6RS přinese standardní modulární systém; povolí dělit mezi jádrem jazyka a knihovnami. [59] => Koncept R6RS specifikace (žertovně pojmenovaný "R5.91RS") byl uvolněn k testování v říjnu 2006. [60] => Aktualizovaný koncept, R5.92RS, byl uvolněn 19. ledna 2007, a další, R5.93RS, 22. března 2007. Poslední koncept je R5.95RS a byl uvolněn 25. června 2007. [61] => [62] => == Ukázka kódu == [63] => [64] => Tradiční program [[hello world]] vypadá v jazyce Scheme třeba takto: [65] => [66] => (define (hello) [67] => (display "Ahoj svete!") [68] => (newline)) [69] => (hello) [70] => [71] => [72] => Na prvním řádku začíná definice procedury ''hello'', která vypíše text „Ahoj svete!“ a odřádkuje. Na čtvrtém řádku je pak tato procedura zavolána. [73] => [74] => Příkaz define slouží také k definici proměnných: [75] => [76] => (define pi 3.14) [77] => [78] => [79] => Následující příklad ukazuje definici funkce, která vypočítá [[faktoriál]] zadaného čísla: [80] => [81] => (define fact [82] => (lambda (n) [83] => (if (= n 0) [84] => 1 [85] => (* n (fact (- n 1)))))) [86] => [87] => [88] => Psaní konstrukce ''lambda'' může být zdlouhavé, a tak Scheme nabízí zkratku: [89] => [90] => (define (fact n) [91] => (if (= n 0) [92] => 1 [93] => (* n (fact (- n 1))))) [94] => [95] => [96] => Funkci pak lze zavolat: [97] => [98] => (fact 4) [99] => [100] => [101] => Na výstupu bychom dostali číslo 24. Výše uvedený příklad ukazuje několik zajímavých konstrukcí. Jednak je zřejmé, že v jazyce Scheme se používá prefixového zápisu: [102] => [103] => (+ 1 2) ; součet [104] => (- 5 3) ; rozdíl [105] => (* 4 5) ; součin [106] => (/ 9 3) ; podíl [107] => [108] => (+ 1 3 7) ; není třeba se omezovat na dvě čísla [109] => [110] => [111] => Druhou zajímavou věcí je podmínka ''if''. Ta má tvar ''(if (výraz) true false)'', kde větev ''true'' se provede, je-li výraz pravdivý (není-li vyhodnocen jako ''#f''), větev ''false'' v případě, že je výraz nepravdivý (''#f''; ekvivalentní části ''else'' v jiných jazycích). [112] => [113] => Třetí zajímavou věcí je [[rekurze|rekurzivní]] volání sebe sama na pátém řádku definice funkce. Funkci pro výpočet faktoriálu lze přepsat: [114] => [115] => (define (fact n) [116] => (let fact-iter ((n n) [117] => (result 1)) [118] => (if (= n 0) [119] => result [120] => (fact-iter (- n 1) (* n result))))) [121] => [122] => [123] => V takovém to případě budou všechna rekurzivní volání [[koncová rekurze|koncově rekurzivní]]. Průběžné hodnoty nejsou ukládány na zásobník, ale jsou předávány jako argumenty rekurzivní funkce a interpret, může zahodit obsah zásobníku a znovu zavolat funkci. Tzn. že výpočet funkce probíhá v konstantním paměťovém prostoru. Standard jazyka Scheme [http://www.schemers.org/Documents/Standards/R5RS/ R5RS], přesně definuje, kdy dojde ke koncovému volání. V ukázce kódu je také použitá konstrukce „pojmenovaný let“, která se používá na vytvoření rekurze v těle funkce, aniž bychom explicitně definovali funkci v globálním prostředí. To lze také za pomoci lambda výrazů: [124] => [125] => (define fact [126] => ((lambda (f) (f f)) [127] => (lambda (self) [128] => (lambda (n) [129] => (if (= n 0) [130] => 1 [131] => (* n ((self self) (- n 1)))))))) [132] => [133] => [134] => == Elementy jazyka == [135] => === Komentáře === [136] => [137] => Každý komentář je uvozen středníkem (;) a je platný po celý zbytek řádku. Některé implementace dovolují zakomentovat více řádků, obalí-li se do #|…|#. [138] => [139] => === Identifikátory === [140] => * extrémně volná pravidla; [141] => * mohou obsahovat: [142] => ** písmena a–z, A–Z ; [143] => ** číslice; [144] => ** znaky ? ! . + – / < = > : $ % ^ & _ ~ [145] => * nesmí obsahovat závorky; [146] => [147] => [148] => příklady: [149] => x3, prumerny-plat, Maximum, ?$* [150] => [151] => === Konvence pro identifikátory === [152] => * jména predikátů (vracejí pravdivostní hodnotu) končí otazníkem, např. number?; [153] => * jména procedur s vedlejšími efekty (např. změna hodnoty nějaké proměnné) končí vykřičníkem, např. pridej-prvek!; [154] => * procedury konvertující jeden typ na druhý bývají pojmenovány typ1->typ2. [155] => [156] => === Čísla === [157] => * celá: 160, +24, –78; [158] => * racionální (zlomky): 1/2, –29/30; [159] => * s plovoucí řádovou čárkou: 3.14, .33, –7.689e4; [160] => * komplexní: 3+2i; [161] => * nemá přísnou [[Typová kontrola|typovou kontrolu]] ani typované proměnné, výpočet může kombinovat několik typů. [162] => [163] => === Řetězce === [164] => Řetězce jsou uzavřeny do dvojitých uvozovek: "ahoj světe". [165] => [166] => === Pravdivostní hodnoty === [167] => * true a false zapisovány jako #t a #f [168] => * revidovaná specifikace umožňuje místo #f používat ve stejném významu i prázdný seznam () [169] => [170] => === Dvojice === [171] => [172] => Základem jazyka Scheme jsou tečkové páry. Je to (jediná) složená datová struktura s konstruktorem cons a selektory car a cdr [kudr]. Tečkový pár může například reprezentovat 2D souřadnice, imaginární číslo, nebo české a cizí slovo ve slovníku. [173] => [174] => [175] => > (define a (cons 1 2)) [176] => > a [177] => (1 . 2) [178] => [179] => > (car a) [180] => 1 [181] => [182] => > (cdr a ) [183] => 2 [184] => [185] => [186] => === Seznamy === [187] => Seznamy jsou definovány rekurzivně '''pomocí dvojic'''. Každý seznam je definován jako posloupnost tečkových párů, přičemž poslední tečkový pár má na své druhé pozici prázdný seznam. [188] => [189] => [190] => > (cons 1 (cons 2 (cons 3 ()))) [191] => [192] => (1 2 3) [193] => [194] => [195] => Mohou obsahovat atomické hodnoty i další seznamy. Lze je vnořovat : ((1) (2 (3 4) 5 6) 7 ((8))). Všechny seznamy mají konečnou délku a jsou ukončeny prázdným seznamem. [196] => [197] => * '''prázdný seznam''' je reprezentován konstantami nil, () [198] => ** ''seznam s jedním prvkem:'' (cons 1 () ) [199] => * '''neprázdný seznam''' je dvojice hlava (první prvek) a ocas (seznam zbylých prvků), anglicky head a tail [200] => ** ''uzavřen do závorek, prvky oddělovány mezerami:'' (a b c), (12 "šroubek" .8) [201] => [202] => * '''procedura list''': konstrukce seznamu, s proměnným počtem argumentů. [203] => [204] => > (list 1 2 3) [205] => (1 2 3) [206] => [207] => [208] => K přistupování k hodnotám v seznamu slouží funkce car a cdr. [209] => * '''car''' – vrací první prvek v seznamu (hlavičku), seznam musí být nenulový; [210] => * '''cdr''' – vrací zbytek seznamu (ocásek), pokud seznam obsahuje jediný prvek, vrací prázdný seznam; [211] => * příklad: zisk třetího prvku seznamu: (car (cdr (cdr x))). [212] => [213] => ==== Procedury pro seznamy ==== [214] => * (list? x) je x seznam? [215] => * (pair? x) je x pár? [216] => * (null? x) je x prázdný seznam? [217] => * (list operandy) vyhodnotí operandy a vytvoří seznam obsahující výsledky vyhodnocení [218] => ** (list 6 (* 3 5) 'a) ''vytvoří seznam'' (6 15 a) [219] => * (length seznam) počet prvků seznamu [220] => * (append seznam1 seznam2 seznam3 …) spojí seznamy do jednoho [221] => * (reverse seznam) obrátí pořadí prvků v seznamu [222] => [223] => ==== Další ukázky práce se seznamy ==== [224] => [225] => ;odstraneni prvniho vyskytu prvku ze seznamu [226] => (define (odstran-prvni p s) [227] => (cond ((null? s) '()) [228] => ((equal? p (car s)) (cdr s)) [229] => (else (cons (car s) (odstran-prvni p (cdr s)))))) [230] => [231] => ;odstrani vsechny vyskyty prvku ze seznamu [232] => (define (odstran-vsechny p s) [233] => (cond ((null? s) '()) [234] => ((equal? p (car s)) (odstran-vsechny p (cdr s))) [235] => (else (cons (car s) (odstran-vsechny p (cdr s)))))) [236] => [237] => ;; vrátí n-tý prvek ze seznamu [238] => ;; nehlídáme přitom, zda je index mimo seznam [239] => (define (nprvek index seznam) [240] => (if (= index 0) (car seznam) [241] => (nprvek (- index 1) (cdr seznam)))) [242] => (nprvek 4 '(jan ales marketa petr josef)) [243] => [244] => ;; N-tý prvek pole včetně kontroly, zda nejsme mimo index [245] => ;; Reagovat můžeme jakkoliv -- vrátit specifickou chybu nebo třeba prázdný seznam. [246] => (define (nprvek index seznam) [247] => (if (>= index (length seznam)) [248] => (error "Index je mimo seznam") [249] => (let nprvek ((index index) [250] => (seznam seznam)) [251] => (if (= index 0) [252] => (car seznam) [253] => (nprvek (- index 1) (cdr seznam)))))) [254] => [255] => ;spojeni seznamu - vzdy prvni prvek s prvnim [256] => (define (spoj-prvni s1 s2) [257] => (if (or (null? s1) (null? s2)) '() [258] => (cons (cons (car s1) (car s2)) [259] => (spoj-prvni (cdr s1) (cdr s2))))) [260] => [261] => (odstran-prvni 'ivan '(jan ales libor tomas radek petr ivan ivan)) [262] => (odstran-vsechny 'ivan '(jan ales libor tomas radek petr ivan ivan ivan ivan)) [263] => (spoj-prvni '(milos ales petr jan alan) '(janicek novak kral novotny klaus havel)) [264] => [265] => ;; Možná implementace funkce map beroucí pouze jeden seznam [266] => (define (my-easy-map funkce seznam) [267] => (if (null? seznam) [268] => '() [269] => (cons (funkce (car seznam)) [270] => (my-easy-map funkce (cdr seznam))))) [271] => (my-easy-map - '(1 2 3 4 5 6)) [272] => ; Vrátí: (-1 -2 -3 -4 -5 -6) [273] => [274] => [275] => [276] => [277] => [278] => === Proměnné === [279] => * dynamicky typované [280] => * uvozeny výrazem '''define'''. [281] => [282] => [283] => (define var1 value) [284] => [285] => [286] => Výraz define modifikuje vazbu symbolu v aktuálním prostředí. Oproti tomu speciální forma let vytváří nové prostředí (scope) a v tomto prostředí navazuje na symboly nové vazby. let jako takový nedokáže přepsat již existující vazbu, vždy pouze vytváří nová prostředí. To je hlavní rozdíl oproti speciální formě define, který dokáže přepsat existující vazby. [287] => [288] => [289] => (let ((var1 value)) [290] => ... [291] => ; scope of var1 [292] => ...) [293] => [294] => [295] => Rozdíl mezi let a define můžeme zčásti ilustrovat na následujícím příkladu: [296] => [297] => [298] => (let ((a 10)) [299] => (cons [300] => (let ((a 20)) [301] => (define a 30) [302] => a) [303] => a)) [304] => [305] => [306] => První let vytvoří své prostředí, ve kterém naváže na a hodnotu 10. Druhý let také vytvoří prostředí a naváže na a hodnotu 20. Pokud bychom nepoužili define, byl by výsledkem operace tečkový pár 20 . 10, protože sice existují dva symboly a, ale v jiných prostředí, kde mají vlastní vazbu. define ale modifikuje vazbu v aktuálním prostředí, takže ve vnořeném vnitřním letu změní vazbu symbolu a na třicet. Výsledkem operace tak bude tečkový pár 30 . 10. [307] => [308] => let je pouze konvenční syntaxe, která není nezbytná a může být přímo nahrazena použitím procedury. Například kód výše je přímým ekvivalentem zápisu: [309] => [310] => [311] => ((lambda (var1) [312] => ... [313] => ; scope of var1 [314] => ...) value) [315] => [316] => [317] => === Procedury === [318] => [319] => 1 (define fun [320] => (lambda (arg1 arg2) [321] => ...)) [322] => 2 (define (fun arg1 arg2) [323] => ...) [324] => 3 (fun value1 value2) [325] => [326] => [327] => Procedury jsou ve Scheme [[First-Class Objekt (FCO)|first-class objekty]]. Mohou být argumenty jiných procedur a mohou být jinými procedurami vraceny. Mohou být přiřazeny do proměnné. Procedury jsou tvořeny lambda formami. Například procedury se dvěma argumenty arg1 jsou definovány na řádku 1, řádek 2 je kratší, ekvivalentní výraz. Řádek 3 ukazuje jak jsou procedury spouštěny. Na prvním místě je název procedury a zbytkem jsou její argumenty. [328] => [329] => V Scheme jsou procedury rozděleny do dvou základních kategorií: uživatelské procedury a primitiva (primitivní procedury). Všechna primitiva jsou procedury, ale ne všechny procedury jsou primitiva. Primitiva jsou předdefinované funkce jazyka Scheme. To zahrnuje např. +, -, *, /, set!, car, cdr, a další. V různých variacích Scheme může uživatel redefinovat primitivum. Příklad: [330] => [331] => [332] => (define (+ x y) [333] => (- x y)) [334] => [335] => [336] => nebo jednoduše [337] => [338] => [339] => (define + -) [340] => [341] => [342] => což způsobí, že + primitivum provede rozdíl namísto součtu. [343] => [344] => === Cykly === [345] => Cykly ve standardu Scheme neexistují, ale v různých implementacích se můžeme setkat například s cyklem do. Ačkoliv programujeme-li funkcionálně, cykly nevyužijeme, protože jsou založené na vedlejším efektu. Častěji se používá rekurze. Syntaxe cyklu do je následující: [346] => [347] => [348] => (do (( ) [349] => ( ) [350] => ... ) [351] => ( ) [352] => [353] => [354] => ... ) [355] => [356] => [357] => Nejdříve následuje seznam proměnných, které budou iterovat, včetně výchozí hodnoty a indikátoru změny po každé iteraci. Jako druhý argument je uvedena ukončující podmínka cyklu. Ve chvíli, kdy je splněna, je cyklus ukončen. Následuje seznam příkazů, které se mají v cyklu provést. Příklad jednoduchého cyklu, který vytiskne čísla od jedné do devíti: [358] => [359] => [360] => (do ((x 1 (+ x 1))) [361] => ((= x 10)) [362] => (print x) [363] => (newline)) [364] => [365] => [366] => Příklad cyklu procházející seznam: [367] => [368] => [369] => (do ((x '(1 2 3 4 5 6) (cdr x))) [370] => ((null? x)) [371] => (print (car x)) [372] => (newline)) [373] => [374] => [375] => === Rovnost === [376] => Scheme rozlišuje tři druhy rovnosti: "eq?" vrací #t jestliže jeho parametry reprezentují stejné datové objekty v paměti; "eqv?" je to samé jako eq?, ale zachází s některými objekty (např. znaky a čísly) speciálně tak, že čísla, která jsou si = jsou také eqv? pouze když nejsou eq?; equal? porovnává datové struktury jako seznamy, vektory, řetězce k zjištění, že mají stejnou strukturu a eqv? obsah. [377] => [378] => V Scheme dále existují: string=?; porovnání řetězců; char=? porovnání znaků; = porovnání čísel [379] => [380] => === Řídící struktury === [381] => ==== Vyhodnocování podmínek ==== [382] => Pro vyhodnocování podmínek nabízí Scheme tři speciální formy. If, case a cond. If se až na formu zápisu nijak neliší od if, které používá většina ostatních jazyků. Forma cond dovoluje použít libovolné množství podmínek a návratovou hodnotu pro každou z nich. Forma case je podobná formě cond postupně vyhodnocuje seznamy a pokud nalezne odpovídající prvek, vrátí jeho příslušnou hodnotu. [383] => [384] => [385] => ''Použití if:'' [386] => [387] => [388] => (if test then-expr else-expr) [389] => [390] => [391] => Výraz test je vyhodnocen takto: jestliže výsledek vyhodnocení je „true“ (což je něco jiného nežli #f), pak je vyhodnocen výraz then-expr, jinak else-expr. [392] => [393] => ''Použití cond:'' [394] => [395] => [396] => (cond (test1 expr1 ...) [397] => (test2 expr2 ...) [398] => ... [399] => (else exprn)) [400] => [401] => [402] => První výraz, který bude true, bude vyhodnocen, jestliže všechny výsledky jsou #f, pak je vyhodnocena else klauzule. [403] => [404] => === Vstup/Výstup === [405] => [406] => Scheme užívá konceptu ''portů'' pro čtení a zápis. R5RS definuje dva výchozí porty, přístupné pomocí funkcí current-input-port a current-output-port, což koresponduje s Unixovými pojmy stdin and stdout. Mnoho implementací poskytuje též current-error-port. [407] => [408] => === Makra === [409] => [410] => Scheme zná makra, což je velice mocná zbraň v rukou programátora. Makra transformují zdrojový kód, makroexpanzi provádí preprocesor a samotný interpret už žádná makra nevidí, vidí pouze hotový zdrojový kód, který je určen ke zpracování. Pomocí maker si programátor může dovolit různé věci, které by jinak nebyl schopný provést. První příklad bude anaforický if, který se chová podobně jako klasický if, pouze si výsledek podmínky uchovává do symbolu it, takže v těle anaforického ifu se můžeme lehce odkázat na výsledek podmínky: [411] => [412] => [413] => (define-macro aif [414] => (lambda (cond true false) [415] => `(let ((it ,cond)) [416] => (if it [417] => ,true [418] => ,false)))) [419] => [420] => ;; Příklady použití [421] => (aif (+ 5 5) it #f) [422] => ; 10 [423] => (aif (member 3 '(1 2 3 4 5 6)) it #f) [424] => ; (3 4 5 6) [425] => [426] => [427] => Další příklad je makro dolist, které provádí iteraci přímo nad seznamem. Bere jako argument iterační symbol, do kterého se bude vždy ukládat hodnota aktuálně procházeného prvku seznamu, seznam samotný a pak tělo. [428] => [429] => [430] => (define-macro (dolist instrukce . telo) [431] => (let ((symbol (car instrukce)) [432] => (seznam (cadr instrukce)) [433] => (iter (gensym))) [434] => `(do ((,iter ',seznam (cdr ,iter)) [435] => (,symbol (car ',seznam))) [436] => ((null? ,iter)) [437] => (set! ,symbol (car ,iter)) [438] => ,@telo))) [439] => [440] => ;; Příklady použití [441] => (dolist (x (1 2 3 4 5 6)) (print x) (newline)) [442] => [443] => [444] => V příkladu také vidíme funkci gensym, která slouží ke generování náhodných proměnných, ke kterým nemá uživatel přístup. Slouží to k ochraně před tzv. '''„symbol capture“''', což nastává v případě, kdy makro potřebuje nějakou vnitřní pomocnou proměnnou. Pokud bychom nepoužili náhodný symbol, mohl by uživatel k tomuto symbolu přistupovat. Špatně definované makro dolist by mohlo vypadat takto: [445] => [446] => [447] => (define-macro (dolist-ugly instrukce . telo) [448] => (let ((symbol (car instrukce)) [449] => (seznam (cadr instrukce))) [450] => `(do ((iter ',seznam (cdr iter)) [451] => (,symbol (car ',seznam))) [452] => ((null? iter)) [453] => (set! ,symbol (car iter)) [454] => ,@telo))) [455] => [456] => ;; Příklad volání, kdy pocítíme symbol capture [457] => (dolist-ugly (x (1 2 3 4)) (print iter)) [458] => ; Vrátí: (1 2 3 4)(2 3 4)(3 4)(4) Přičemž by to mělo zobrazit chybu na neexistující symbol. [459] => [460] => [461] => Příklady dalších užitečných maker: [462] => [463] => [464] => ;; Makro when se chová podobně jako if, pouze nemá žádnou else větev. [465] => ;; V případě, že podmínka není splněna, automaticky vrátí false. [466] => ;; True větev ale může obsahovat více výrazů. [467] => (define-macro (when cond . true) [468] => `(if ,cond [469] => (begin [470] => ,@true) [471] => #f)) [472] => [473] => ; Příklady použití: [474] => (when 1 2) [475] => ; 2 [476] => (when 1 (print 1) 2) [477] => ; 12 [478] => (when #f (print 1) 2) [479] => ; #f [480] => [481] => [482] => ;; Makro unless se chová opačně než makro when — neguje podmínku. [483] => ;; True větev se tudíž provede, není-li splněna předaná podmínka. [484] => ;; Prakticky to lze přepsat jako (when (not ) ...). [485] => (define-macro (unless cond . true) [486] => `(if (not ,cond) [487] => (begin [488] => ,@true) [489] => #f)) [490] => [491] => ; Příklady použití: [492] => (unless 1 2) [493] => ; #f [494] => (unless 1 (print 5) 10) [495] => ; #f [496] => (unless (= 1 2) (print 5) 10) [497] => ; 510 [498] => [499] => [500] => Hezkým příkladem jsou také podmíněné výrazy pracující s pravděpodobností. Například klasický if upravený tak, že namísto podmínky přebírá pouze procentuální vyjádření pravděpodobnosti, zda se provede true větev. [501] => [502] => [503] => (define-macro (prob-if probability true false) [504] => `(if (<= (+ 1 (random 100)) ,probability) [505] => ,true [506] => ,false)) [507] => [508] => ; Příklady použití: [509] => ; (V 80 % případů se vrátí jednička, ve 20 % dvojka.) [510] => > (prob-if 80 1 2) [511] => 1 [512] => > (prob-if 80 1 2) [513] => 1 [514] => > (prob-if 80 1 2) [515] => 1 [516] => > (prob-if 80 1 2) [517] => 2 [518] => > (prob-if 80 1 2) [519] => 1 [520] => > (prob-if 80 1 2) [521] => 1 [522] => [523] => [524] => === Streamy === [525] => [526] => Pomocí maker můžeme také realizovat líné vyhodnocování, kdy se veškeré argumenty funkcí budou vyhodnocovat líně, tj. až když budou třeba. Díky tomuto můžeme naprogramovat if jako funkci. Líného vyhodnocení využijeme i při implementaci Streamů. Stream bude tvořen tečkovými páry, ale s tím rozdílem, že bude mít vyhodnocen pouze car část, nikoli cdr. To realizujeme tím způsobem, že cdr část uložíme jako proceduru, kterou vyhodnotíme až při volání cdr streamu: [527] => [528] => [529] => (define-macro (delay . expr) [530] => `(lambda() ,@expr)) [531] => [532] => ; Příklady použití [533] => > (delay (print 100) (newline) (* 50 50)) [534] => # [535] => > (define d (delay (print 100) (newline) (* 50 50))) [536] => > d [537] => # [538] => > (d) [539] => 100 [540] => 2500 [541] => [542] => [543] => Pomocí makra delay jsme odložili vyhodnocení výrazů (print 100) (newline) (* 50 50) až do chvíle, kdy jsme to opravdu potřebovali — když jsme zavolali (d). Zbytek už nadefinujeme snadno: [544] => [545] => [546] => (define-macro (cons-stream car-str cdr-str) [547] => `(cons ,car-str [548] => (delay ,cdr-str))) [549] => [550] => (define stream-car car) [551] => [552] => (define (stream-cdr stream) [553] => ((cdr stream))) [554] => [555] => [556] => A nyní už jen aplikace streamů: [557] => [558] => [559] => ;; Vrací nekonečný proud jedniček [560] => (define (ones) [561] => (cons-stream 1 (ones))) [562] => [563] => > (ones) [564] => (1 . #) [565] => > (stream-cdr (ones)) [566] => (1 . #) [567] => > (stream-cdr (stream-cdr (stream-cdr (stream-cdr (ones))))) [568] => (1 . #) [569] => [570] => [571] => ;; Vrací nekonečný proud přirozených čísel [572] => (define (naturals n) [573] => (cons-stream n (naturals (+ n 1)))) [574] => [575] => > (naturals 1) [576] => (1 . #) [577] => [578] => > (stream-cdr (naturals 1)) [579] => (2 . #) [580] => [581] => > (stream-cdr (stream-cdr (stream-cdr (stream-cdr (naturals 1))))) [582] => (5 . #) [583] => [584] => [585] => == Související články == [586] => * [[Rekurze]] [587] => * [[Prolog (programovací jazyk)]] [588] => * [[Logické programování]] [589] => * [[Deklarativní programování]] [590] => * [[GIMP]] [591] => [592] => == Externí odkazy == [593] => * {{Commonscat}} [594] => * [http://www.swiss.ai.mit.edu/projects/scheme/ oficiální stránky jazyka Scheme] [595] => * [http://www.plt-scheme.org/ Interpret jazyka Scheme — DrScheme] [596] => * [http://www.schemers.org/ www.schemers.org] – informace, reference jazyka, [597] => * [https://web.archive.org/web/20121115102611/http://upcase.inf.upol.cz/courses/cs1pp/misc.html Skripta k Paradigmata programování — Scheme] [598] => * [http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html Teach yourself Scheme in fixnum days] – velmi dobrá online učebnice Scheme [599] => * [https://web.archive.org/web/20070701173552/http://www.kai.tul.cz/~satrapa/vyuka/altprog/ Přednášky a cvičení pro podporu předmětu „Alternativní metody programování“] – na TUL Liberec [600] => * [http://www.r6rs.org/ r6rs.org] {{Wayback|url=http://www.r6rs.org/ |date=20130812014945 }} [601] => * [https://web.archive.org/web/20160510140804/http://library.readscheme.org/page1.html Online verze Lambda Papers] (PDF format) [602] => [603] => == Reference == [604] => [605] => [606] => {{Programovací jazyky}} [607] => {{Autoritní data}} [608] => [609] => [[Kategorie:Programovací jazyky]] [610] => [[Kategorie:Funkcionální jazyky]] [] => )
good wiki

Scheme

Scheme je multiparadigmatický programovací jazyk. Funkcionální programovací paradigma patří mezi tzv.

More about us

About

Byl navržen na konci 70. let 20. století s cílem poskytnout silný a flexibilní nástroj pro výuku a praxi v oblasti informatiky. Je známý svým jasným a srozumitelným syntaxem, který usnadňuje porozumění programovacím konceptům a podporuje kreativní myšlení. Jedním z hlavních rysů Schemu je jeho podpora funkcionality, což znamená, že funkce jsou prvotními obyvateli jazyka. To umožňuje programátorům strukturovat kód elegantně a efektivně a zaměřit se na vývoj komplexních systémů bez zbytečného zmatku. Otevřenost jazyka a jeho minimalistická povaha podporují inovaci a experimentování. Scheme také poskytuje bohaté nástroje pro abstrakci a modulární programování, což usnadňuje spolupráci a opakované použití kódu. Tato vlastnost činí jazyk oblíbeným v akademickém prostředí, kde se často používá k výuce základů algoritmizace a konstrukce programů. I když může být pro nové uživatele ze začátku náročnější se s ním seznámit, jakmile se do jazyka ponoří, objeví jeho krásu a možnosti. Schopnost řešit složité problémy pomocí jednoduchých a elegantních řešení je pro mnohé programátory inspirující. Dnes je Scheme součástí širší komunity jazyků, která zahrnuje různé dialekty a implementace. Projekty jako Racket rozšiřují možnosti jazyka a umožňují jeho použití v různých oblastech, od webového vývoje po vzdělávací nástroje. Celkově je Scheme mocným a pozitivním prostředkem, který v rukou kreativních jedinců podporuje inovace a progres.

Expert Team

Vivamus eget neque lacus. Pellentesque egauris ex.

Award winning agency

Lorem ipsum, dolor sit amet consectetur elitorceat .

10 Year Exp.

Pellen tesque eget, mauris lorem iupsum neque lacus.

You might be interested in

,'aktor','GIMP','funkcionální programování','Lisp','programovací jazyk','faktoriál','koncová rekurze','First-Class Objekt (FCO)','Prolog (programovací jazyk)','Kategorie:Programovací jazyky','continuation','MIT/GNU Scheme'