心衰竭是什么病| 脚趾头麻木是什么原因| 顺理成章是什么意思| 什么什么生机| 心悸是什么症状| nb是什么牌子| 鱼为什么睁着眼睛睡觉| 歧路亡羊告诉我们什么道理| 肾在五行中属什么| 放量十字星是什么意思| 吃什么可以变白| 遗尿是什么症状| 祝福是什么意思| 女生爱出汗是什么原因| 肚子疼吃什么药管用| 食欲亢进是什么意思| 儿童腮腺炎挂什么科| 载体是什么| nec医学上是什么意思| 口角炎涂什么药膏| 手麻抽筋是什么原因引起的| 吃什么食物补钾| 一箭双雕是指什么生肖| 夏天有什么植物| 今天什么日| 学富五车是什么意思| yk是什么意思| 太阳五行属什么| 药玉是什么| 懦弱的反义词是什么| prg是什么意思| smile是什么牌子| 什么是abo| 右派是什么意思| 勇气是什么| 手抽筋吃什么药| 一个人自言自语的说话是什么病| 回光返照是什么意思| cr医学上是什么意思| 什么都值得买| 子子念什么| mb是什么意思| 病毒性结膜炎用什么眼药水| 彩霞是什么意思| 真空什么意思| 又双叒叕念什么啥意思| 梦到被狗咬是什么意思| 蚂蚁最怕什么| 异型增生是什么意思啊| 排骨炖什么汤好喝| 由是什么意思| 傻狍子为什么叫傻狍子| 什么东西燃烧脂肪最快| 部分是什么意思| 白蛋白偏低是什么原因| 肠炎有什么症状表现| 吃饭掉筷子有什么预兆| 毕是什么意思| 老人过生日送什么礼物好| 莺是什么鸟| 跳楼是什么感觉| 1月13是什么星座| 阴虚火旺吃什么调理| 子宫脱落是什么原因引起的| bcr是什么意思| 孕早期生气对胎儿有什么影响| 皮炎是什么原因引起的| 支抗钉是什么| ads是什么| 怕老婆的男人说明什么| 4月15日什么星座| 奔豚是什么意思| 手指僵硬暗示什么疾病| 胃糜烂可以吃什么水果| 司空见惯的惯是什么意思| 正军级是什么级别| 止血敏又叫什么| 人活着意义是什么| 肺癌有什么症状| 一见钟情是什么感觉| 杨梅是什么季节的水果| 吃什么东西补脑| 生牛乳是什么意思| 鸡是什么动物| 帕金森是什么引起的| 类风湿因子高吃什么药| 疼痛科主要看什么病| 尿痛什么原因引起的| 用眼过度用什么眼药水| 药物过敏用什么药| 孕晚期感冒可以吃什么药| 猫薄荷是什么东西| 抗风疹病毒抗体igg高是什么意思| 什么水果汁减肥效果好| 两个方一个土读什么| 车船税是什么意思每年都交吗| 沉香手串有什么好处| 脚底拔罐对女人有什么好处| 为什么短信验证码收不到| ins是什么| 马达是什么| 辛巳五行属什么| 58年属狗是什么命| 体外射精是什么| 9.25是什么星座| 进字五行属什么| 无住生心是什么意思| 什么叫肌酸激酶| 谷草谷丙偏高代表什么| 中焦湿热吃什么中成药| 手电筒的金属外壳相当于电路中的什么| 什么是低钠盐| 闻鸡起舞是什么意思| 印度为什么叫三哥| 右肾盂分离是什么意思| 手足口病喝什么汤| 怀孕初期怕冷是什么原因| 什么是金融行业| 权衡是什么意思| 品保是做什么的| 沵是什么意思| h是什么意思| 补气血吃什么药效果好| 浪琴名匠系列什么档次| 血糖高会出现什么症状| 肌酐高了是什么原因| 马华读什么| 什么是琉璃| 氯偏低是什么原因| 过期牛奶可以做什么| 脖子上长痘痘是什么原因| 主导是什么意思| 降低转氨酶吃什么药| 什么应外合| 艺不压身是什么意思| 额头长痘什么原因| bata鞋属于什么档次| 隐形眼镜护理液可以用什么代替| 方脸适合什么耳环| 骨质疏松有什么症状表现| 孕妇吃葡萄对胎儿有什么好处| 转氨酶高吃什么药好| 尿蛋白高是什么意思| 晚上蝴蝶来家什么预兆| 造影是什么检查| 足金什么意思| 眼睛老是流眼泪是什么原因| 猫发烧吃什么药| 总蛋白是什么| 归宁是什么意思| gg是什么品牌| oem贴牌是什么意思| 朱元璋长什么样| 什么山什么水| 魔芋是什么植物| 27属相是什么生肖| 收尾是什么意思| 2.25是什么星座| 白带发黄吃什么药| 宫颈囊肿多发是什么意思| 中国是什么时区| 莅临什么意思| 甘甜是什么意思| 什么是玄关在哪个位置| 勾绞煞是什么意思| 祖字五行属什么| 多吃什么可以长高| 头寸是什么意思| 减肥期间吃什么好| 科学的尽头是什么| 巨细胞病毒阳性什么意思| 肚脐眼红是什么原因| 喉炎吃什么药| 83年猪是什么命| 悲观是什么意思| 长脸男生适合什么发型| 吃什么雌激素会增多| 什么叫抑郁症| 我好想你是什么歌| 血管瘤是什么样子的图| 宫颈常大是什么意思| 大水冲了龙王庙什么意思| 防晒霜什么牌子好| 月经来前有什么征兆| 白居易号什么居士| 猪与什么属相相冲| 红脸关公代表什么意思| 但愿人长久的下一句是什么| 男人长阴虱是什么原因| 厚积薄发是什么意思啊| 肚兜是什么| 为什么一动就满头大汗| 福星贵人是什么意思| 储备是什么意思| 火把节在每年农历的什么时间举行| 棉花糖是什么做的| 什么叫尊重| 穿旗袍配什么发型好看| 后羿是一个什么样的人| 脑梗吃什么水果好| 夏天喝什么茶减肥| pth是什么| 脑干出血是什么原因造成的| 什么是二型糖尿病| 自然堂适合什么年龄| 许莫氏结节是什么| fw是什么意思| 什么是一二三级医院| 塔丝隆是什么面料| ad医学上是什么意思| 肩周炎看什么科| 丝光棉是什么面料| 步步生花是什么意思| sama是什么药| 为什么叫六小龄童| nova是什么牌子| 低密度脂蛋白偏高是什么意思| 苍蝇馆子什么意思| gaba是什么| 检查尿酸挂什么科| 蒲瓜是什么瓜| 孕妇吃什么鱼| 腰果是什么树的果实| 房间里放什么阳气旺| 房颤什么意思| 以什么当什么| 十点多是什么时辰| 得艾滋病的人有什么症状| 耳朵后面疼是什么原因| 左肺上叶肺大泡是什么意思| 情感什么意思| 绿五行属什么| 为什么会得骨癌| mri是什么| 观音婢是什么意思| theme什么意思| 曼妥思是什么糖| 白内障的症状是什么| 知柏地黄丸适合什么人吃| 人体缺钠会出现什么症状| 摩拳擦掌是什么意思| 大小脸挂什么科| 什么是牛黄| 10月26日什么星座| 脱发用什么药最好| 什么叫咳嗽变异性哮喘| 紫水晶属于五行属什么| 掉筷子有什么预兆| 吃什么治疗阳痿| 氨咖黄敏胶囊主治什么| 御是什么意思| 什么叫造口| 刘晓庆什么星座| 水乳是什么| clarks是什么牌子| 机能鞋是什么意思| 什么是百分数| 咽喉疼吃什么药| 背疼什么原因| 什么食物是碱性的| 伤口发炎化脓用什么药| 为什么北京是首都| 佝偻病什么症状| 百鸟归巢什么意思| 百度P?esko?it na obsah

英国私人补习班报名火爆 学者:恐影响教育公平

Z Wikipedie, otev?ené encyklopedie
Scheme
Paradigmafunkcionální programování
Vznik1975
AutorGuy L. Steele a Gerald Jay Sussman
Typová kontrolasilné, dynamické
Hlavní implementacePLT Scheme, MIT/GNU Scheme, Scheme 48, Chicken, Gambit, FLUENT, Guile, Bigloo, Chez Scheme, STk, STklos, Larceny, SCM
DialektyT
Ovlivněn jazykyLisp, ALGOL
Ovlivnil jazykyCommon Lisp, JavaScript, Ruby
百度 ”而停水的时间为当天的上午9点30分至晚上8点30分,共计11个小时。

Scheme je multiparadigmaticky programovací jazyk. Funkcionální programovací paradigma pat?í mezi tzv. funkcionální paradigmata. Scheme je jeden ze dvou hlavních dialekt? funkcionálního programovacího jazyka Lisp. Jazyk navrhli Guy Lewis Steele a Gerald Jay Sussman a jeho první popis byl sepsán v roce 1975. Scheme byl p?edstaven akademickému světu skrze sérii ?lánk?, nyní známych jako Sussmanovy a Steelovy Lambda Papers.[1] Jazyk Scheme definují dva standardy: oficiální IEEE standard a standard nazyvany Revisedn Report on the Algorithmic Language Scheme, ve zkratce RnRS, kde n je ?íslo revize. Sou?asny standard je R5RS[2], a R6RS[3] je ve vyvoji.

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.

Scheme byl prvním dialektem Lispu, ktery nabízel volbu mezi lexikálním nebo dynamickym rozsahem platnosti proměnné. Také byl jedním z programovacích jazyk?, ktery podporoval ?first-class continuation“.

Tento jazyk je v praxi pou?ívany jen z?ídka, pou?ívá se p?edev?ím ve ?kolách pro vyuku programování algoritm?. Nejznáměj?í implementací je graficky editor GIMP, jeho? dodate?né zásuvné moduly a skripty jsou psány v dialektu jazyka Scheme.

Na po?átku zrodu jazyka Scheme stála pot?eba Guye Steela a Geralda Sussmana z MIT (Massachusettsky technicky institut), vyzkou?et si některé aspekty modelu aktor?, ktery v roce 1973 ve?ejnosti p?edstavil Carl Hewitt. Proto?e LISP se k tomuto p?íli? nehodil, bylo pot?eba navrhnout novy 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?íjemnych vlastností LISPu.

"Chceme lépe porozumět Hewittovu Aktor modelu, ale máme problémy vztáhnout aktor model a jeho neobvyklou terminologii známych programovych 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 tenky interpret Lispu a poté p?idali mechanismus k vytvá?ení aktor? a posílání zpráv.?

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.

V roce 1978 byl jazyk Scheme standardizován. Základem se stala "Revidovaná zpráva o Scheme" – dialektu LISPu. Tato zpráva popisovala vyvoj 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 neobvykly 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.

P?vodní název jazyka byl Schemer. Po vzoru dobovych jazyk? pro umělou inteligenci Planner a Conniver. Proto?e v?ak auto?i pou?ívali opera?ní systém ITS, ktery 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, ktery tak nahradil Schemer.

Budoucnost

[editovat | editovat zdroj]

Novy standardiza?ní proces za?al na 2003 Scheme workshopu, s cílem vytvo?ení R6RS standardu v roce 2006. R6RS p?inese standardní modulární systém; povolí dělit mezi jádrem jazyka a knihovnami. Koncept R6RS specifikace (?ertovně pojmenovany "R5.91RS") byl uvolněn k testování v ?íjnu 2006. Aktualizovany 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.

Ukázka kódu

[editovat | editovat zdroj]

Tradi?ní program hello world vypadá v jazyce Scheme t?eba takto:

(define (hello)
  (display "Ahoj svete!")
  (newline))
(hello)

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.

P?íkaz define slou?í také k definici proměnnych:

(define pi 3.14)

Následující p?íklad ukazuje definici funkce, která vypo?ítá faktoriál zadaného ?ísla:

(define fact
  (lambda (n)
    (if (= n 0)
      1
      (* n (fact (- n 1))))))

Psaní konstrukce lambda m??e byt zdlouhavé, a tak Scheme nabízí zkratku:

(define (fact n)
  (if (= n 0)
    1
    (* n (fact (- n 1)))))

Funkci pak lze zavolat:

(fact 4)

Na vystupu bychom dostali ?íslo 24. Vy?e uvedeny p?íklad ukazuje několik zajímavych konstrukcí. Jednak je z?ejmé, ?e v jazyce Scheme se pou?ívá prefixového zápisu:

(+ 1 2) ; sou?et
(- 5 3) ; rozdíl
(* 4 5) ; sou?in
(/ 9 3) ; podíl

(+ 1 3 7) ; není t?eba se omezovat na dvě ?ísla

Druhou zajímavou věcí je podmínka if. Ta má tvar (if (vyraz) true false), kde větev true se provede, je-li vyraz pravdivy (není-li vyhodnocen jako #f), větev false v p?ípadě, ?e je vyraz nepravdivy (#f; ekvivalentní ?ásti else v jinych jazycích).

T?etí zajímavou věcí je rekurzivní volání sebe sama na pátém ?ádku definice funkce. Funkci pro vypo?et faktoriálu lze p?epsat:

(define (fact n)
  (let fact-iter ((n n) 
                  (result 1))
    (if (= n 0)
        result
        (fact-iter (- n 1) (* n result)))))

V takovém to p?ípadě budou v?echna rekurzivní volání 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 vypo?et funkce probíhá v konstantním pamě?ovém prostoru. Standard jazyka Scheme R5RS, p?esně definuje, kdy dojde ke koncovému volání. V ukázce kódu je také pou?itá konstrukce ?pojmenovany 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 vyraz?:

(define fact
  ((lambda (f) (f f))
    (lambda (self)
      (lambda (n)
        (if (= n 0)
            1
            (* n ((self self) (- n 1))))))))

Elementy jazyka

[editovat | editovat zdroj]

Komentá?e

[editovat | editovat zdroj]

Ka?dy komentá? je uvozen st?edníkem (;) a je platny po cely zbytek ?ádku. Některé implementace dovolují zakomentovat více ?ádk?, obalí-li se do #|…|#.

Identifikátory

[editovat | editovat zdroj]
  • extrémně volná pravidla;
  • mohou obsahovat:
    • písmena a–z, A–Z ;
    • ?íslice;
    • znaky ? ! . + – / < = > : $ % ^ & _ ~
  • nesmí obsahovat závorky;


p?íklady:

 x3, prumerny-plat, Maximum, ?$*

Konvence pro identifikátory

[editovat | editovat zdroj]
  • jména predikát? (vracejí pravdivostní hodnotu) kon?í otazníkem, nap?. number?;
  • jména procedur s vedlej?ími efekty (nap?. změna hodnoty nějaké proměnné) kon?í vyk?i?níkem, nap?. pridej-prvek!;
  • procedury konvertující jeden typ na druhy byvají pojmenovány typ1->typ2.
  • celá: 160, +24, –78;
  • racionální (zlomky): 1/2, –29/30;
  • s plovoucí ?ádovou ?árkou: 3.14, .33, –7.689e4;
  • komplexní: 3+2i;
  • nemá p?ísnou typovou kontrolu ani typované proměnné, vypo?et m??e kombinovat několik typ?.

?etězce jsou uzav?eny do dvojitych uvozovek: "ahoj světe".

Pravdivostní hodnoty

[editovat | editovat zdroj]
  • true a false zapisovány jako #t a #f
  • revidovaná specifikace umo?ňuje místo #f pou?ívat ve stejném vyznamu i prázdny seznam ()

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?kovy pár m??e nap?íklad reprezentovat 2D sou?adnice, imaginární ?íslo, nebo ?eské a cizí slovo ve slovníku.

> (define a (cons 1 2))
> a
(1 . 2)

> (car a)
1

> (cdr a )
2

Seznamy jsou definovány rekurzivně pomocí dvojic. Ka?dy seznam je definován jako posloupnost te?kovych pár?, p?i?em? poslední te?kovy pár má na své druhé pozici prázdny seznam.

> (cons 1 (cons 2 (cons 3 ())))

(1 2 3)

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ázdnym seznamem.

  • prázdny seznam je reprezentován konstantami nil, ()
    • seznam s jedním prvkem: (cons 1 () )
  • neprázdny seznam je dvojice hlava (první prvek) a ocas (seznam zbylych prvk?), anglicky head a tail
    • uzav?en do závorek, prvky oddělovány mezerami: (a b c), (12 "?roubek" .8)
  • procedura list: konstrukce seznamu, s proměnnym po?tem argument?.
> (list 1 2 3)
(1 2 3)

K p?istupování k hodnotám v seznamu slou?í funkce car a cdr.

  • car – vrací první prvek v seznamu (hlavi?ku), seznam musí byt nenulovy;
  • cdr – vrací zbytek seznamu (ocásek), pokud seznam obsahuje jediny prvek, vrací prázdny seznam;
  • p?íklad: zisk t?etího prvku seznamu: (car (cdr (cdr x))).

Procedury pro seznamy

[editovat | editovat zdroj]
  • (list? x) je x seznam?
  • (pair? x) je x pár?
  • (null? x) je x prázdny seznam?
  • (list operandy) vyhodnotí operandy a vytvo?í seznam obsahující vysledky vyhodnocení
    • (list 6 (* 3 5) 'a) vytvo?í seznam (6 15 a)
  • (length seznam) po?et prvk? seznamu
  • (append seznam1 seznam2 seznam3 …) spojí seznamy do jednoho
  • (reverse seznam) obrátí po?adí prvk? v seznamu

Dal?í ukázky práce se seznamy

[editovat | editovat zdroj]
;odstraneni prvniho vyskytu prvku ze seznamu
(define (odstran-prvni p s)
  (cond ((null? s) '())
        ((equal? p (car s)) (cdr s))
        (else (cons (car s) (odstran-prvni p (cdr s))))))

;odstrani vsechny vyskyty prvku ze seznamu
(define (odstran-vsechny p s)
  (cond ((null? s) '())
        ((equal? p (car s)) (odstran-vsechny p (cdr s)))
        (else (cons (car s) (odstran-vsechny p (cdr s))))))

;; vrátí n-ty prvek ze seznamu
;; nehlídáme p?itom, zda je index mimo seznam
(define (nprvek index seznam)
  (if (= index 0) (car seznam)
      (nprvek (- index 1) (cdr seznam))))
(nprvek 4 '(jan ales marketa petr josef))

;; N-ty prvek pole v?etně kontroly, zda nejsme mimo index
;; Reagovat m??eme jakkoliv -- vrátit specifickou chybu nebo t?eba prázdny seznam.
(define (nprvek index seznam)
  (if (>= index (length seznam))
      (error "Index je mimo seznam")
      (let nprvek ((index index)
                   (seznam seznam))
        (if (= index 0)
            (car seznam)
            (nprvek (- index 1) (cdr seznam))))))

;spojeni seznamu - vzdy prvni prvek s prvnim
(define (spoj-prvni s1 s2)
  (if (or (null? s1) (null? s2)) '()
      (cons (cons (car s1) (car s2)) 
            (spoj-prvni (cdr s1) (cdr s2)))))

(odstran-prvni 'ivan '(jan ales libor tomas radek petr ivan ivan))
(odstran-vsechny 'ivan '(jan ales libor tomas radek petr ivan ivan ivan ivan))
(spoj-prvni '(milos ales petr jan alan) '(janicek novak kral novotny klaus havel))

;; Mo?ná implementace funkce map beroucí pouze jeden seznam
(define (my-easy-map funkce seznam)
  (if (null? seznam)
      '()
      (cons (funkce (car seznam))
            (my-easy-map funkce (cdr seznam)))))
(my-easy-map - '(1 2 3 4 5 6))
; Vrátí: (-1 -2 -3 -4 -5 -6)

Proměnné

[editovat | editovat zdroj]
  • dynamicky typované
  • uvozeny vyrazem define.
  (define var1 value)

Vyraz 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 takovy 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, ktery doká?e p?epsat existující vazby.

  (let ((var1 value))
    ...
    ; scope of var1
    ...)

Rozdíl mezi let a define m??eme z?ásti ilustrovat na následujícím p?íkladu:

(let ((a 10))
  (cons
   (let ((a 20))
     (define a 30)
     a)
   a))

První let vytvo?í své prost?edí, ve kterém navá?e na a hodnotu 10. Druhy let také vytvo?í prost?edí a navá?e na a hodnotu 20. Pokud bychom nepou?ili define, byl by vysledkem operace te?kovy pár 20 . 10, proto?e sice existují dva symboly a, ale v jinych 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. Vysledkem operace tak bude te?kovy pár 30 . 10.

let je pouze konven?ní syntaxe, která není nezbytná a m??e byt p?ímo nahrazena pou?itím procedury. Nap?íklad kód vy?e je p?ímym ekvivalentem zápisu:

  ((lambda (var1)
    ...
    ; scope of var1
    ...) value)
1 (define fun
   (lambda (arg1 arg2)
     ...))
2 (define (fun arg1 arg2)
   ...)
3 (fun value1 value2)

Procedury jsou ve Scheme first-class objekty. Mohou byt argumenty jinych procedur a mohou byt jinymi procedurami vraceny. Mohou byt 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í vyraz. ?ádek 3 ukazuje jak jsou procedury spou?těny. Na prvním místě je název procedury a zbytkem jsou její argumenty.

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?znych variacích Scheme m??e u?ivatel redefinovat primitivum. P?íklad:

(define (+ x y)
  (- x y))

nebo jednodu?e

(define + -)

co? zp?sobí, ?e + primitivum provede rozdíl namísto sou?tu.

Cykly ve standardu Scheme neexistují, ale v r?znych 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í:

(do ((<proměnná1> <vychozí hodnota 1> <změna1>)
     (<proměnná2> <vychozí hodnota 2> <změna2>) 
      ... )
  (<test1> <test2>)
  <p?íkaz1>
  <p?íkaz2> 
  ... )

Nejd?íve následuje seznam proměnnych, které budou iterovat, v?etně vychozí hodnoty a indikátoru změny po ka?dé iteraci. Jako druhy 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, ktery vytiskne ?ísla od jedné do devíti:

(do ((x 1 (+ x 1)))
  ((= x 10))
  (print x)
  (newline))

P?íklad cyklu procházející seznam:

(do ((x '(1 2 3 4 5 6) (cdr x)))
  ((null? x))
  (print (car x))
  (newline))

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ěkterymi 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.

V Scheme dále existují: string=?; porovnání ?etězc?; char=? porovnání znak?; = porovnání ?ísel

?ídící struktury

[editovat | editovat zdroj]

Vyhodnocování podmínek

[editovat | editovat zdroj]

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.


Pou?ití if:

(if test then-expr else-expr)

Vyraz test je vyhodnocen takto: jestli?e vysledek vyhodnocení je ?true“ (co? je něco jiného ne?li #f), pak je vyhodnocen vyraz then-expr, jinak else-expr.

Pou?ití cond:

(cond (test1 expr1 ...)
      (test2 expr2 ...)
      ...
      (else exprn))

První vyraz, ktery bude true, bude vyhodnocen, jestli?e v?echny vysledky jsou #f, pak je vyhodnocena else klauzule.

Vstup/Vystup

[editovat | editovat zdroj]

Scheme u?ívá konceptu port? pro ?tení a zápis. R5RS definuje dva vychozí porty, p?ístupné pomocí funkcí current-input-port a current-output-port, co? koresponduje s Unixovymi pojmy stdin and stdout. Mnoho implementací poskytuje té? current-error-port.

Scheme zná makra, co? je velice mocná zbraň v rukou programátora. Makra transformují zdrojovy kód, makroexpanzi provádí preprocesor a samotny interpret u? ?ádná makra nevidí, vidí pouze hotovy zdrojovy kód, ktery je ur?en ke zpracování. Pomocí maker si programátor m??e dovolit r?zné věci, které by jinak nebyl schopny provést. První p?íklad bude anaforicky if, ktery se chová podobně jako klasicky if, pouze si vysledek podmínky uchovává do symbolu it, tak?e v těle anaforického ifu se m??eme lehce odkázat na vysledek podmínky:

(define-macro aif
  (lambda (cond true false)
    `(let ((it ,cond))
       (if it
           ,true
           ,false))))

;; P?íklady pou?ití
(aif (+ 5 5) it #f)
; 10
(aif (member 3 '(1 2 3 4 5 6)) it #f)
; (3 4 5 6)

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 samotny a pak tělo.

(define-macro (dolist instrukce . telo)
  (let ((symbol (car instrukce))
        (seznam (cadr instrukce))
        (iter (gensym)))
    `(do ((,iter ',seznam (cdr ,iter))
          (,symbol (car ',seznam)))
       ((null? ,iter))
       (set! ,symbol (car ,iter))
       ,@telo)))

;; P?íklady pou?ití
(dolist (x (1 2 3 4 5 6)) (print x) (newline))

V p?íkladu také vidíme funkci gensym, která slou?í ke generování náhodnych proměnnych, ke kterym 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áhodny symbol, mohl by u?ivatel k tomuto symbolu p?istupovat. ?patně definované makro dolist by mohlo vypadat takto:

(define-macro (dolist-ugly instrukce . telo)
  (let ((symbol (car instrukce))
        (seznam (cadr instrukce)))
    `(do ((iter ',seznam (cdr iter))
          (,symbol (car ',seznam)))
       ((null? iter))
       (set! ,symbol (car iter))
       ,@telo)))

;; P?íklad volání, kdy pocítíme symbol capture
(dolist-ugly (x (1 2 3 4)) (print iter))
; 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.

P?íklady dal?ích u?ite?nych maker:

;; Makro when se chová podobně jako if, pouze nemá ?ádnou else větev.
;; V p?ípadě, ?e podmínka není splněna, automaticky vrátí false.
;; True větev ale m??e obsahovat více vyraz?.
(define-macro (when cond . true)
  `(if ,cond 
       (begin
         ,@true)
       #f))

; P?íklady pou?ití:
(when 1 2)
; 2
(when 1 (print 1) 2)
; 12
(when #f (print 1) 2)
; #f


;; Makro unless se chová opa?ně ne? makro when — neguje podmínku.
;; True větev se tudí? provede, není-li splněna p?edaná podmínka.
;; Prakticky to lze p?epsat jako (when (not <podmínka>) ...).
(define-macro (unless cond . true)
  `(if (not ,cond)
       (begin
         ,@true)
       #f))

; P?íklady pou?ití:
(unless 1 2)
; #f
(unless 1 (print 5) 10)
; #f
(unless (= 1 2) (print 5) 10)
; 510

Hezkym p?íkladem jsou také podmíněné vyrazy pracující s pravděpodobností. Nap?íklad klasicky if upraveny tak, ?e namísto podmínky p?ebírá pouze procentuální vyjád?ení pravděpodobnosti, zda se provede true větev.

(define-macro (prob-if probability true false)
  `(if (<= (+ 1 (random 100)) ,probability)
       ,true
       ,false))

; P?íklady pou?ití:
; (V 80 % p?ípad? se vrátí jedni?ka, ve 20 % dvojka.)
> (prob-if 80 1 2)
1
> (prob-if 80 1 2)
1
> (prob-if 80 1 2)
1
> (prob-if 80 1 2)
2
> (prob-if 80 1 2)
1
> (prob-if 80 1 2)
1

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?kovymi 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:

(define-macro (delay . expr)
  `(lambda() ,@expr))

; P?íklady pou?ití
> (delay (print 100) (newline) (* 50 50))
#<procedure>
> (define d (delay (print 100) (newline) (* 50 50)))
> d
#<procedure:d>
> (d)
100
2500

Pomocí makra delay jsme odlo?ili vyhodnocení vyraz? (print 100) (newline) (* 50 50) a? do chvíle, kdy jsme to opravdu pot?ebovali — kdy? jsme zavolali (d). Zbytek u? nadefinujeme snadno:

(define-macro (cons-stream car-str cdr-str)
  `(cons ,car-str
         (delay ,cdr-str)))

(define stream-car car)

(define (stream-cdr stream)
  ((cdr stream)))

A nyní u? jen aplikace stream?:

;; Vrací nekone?ny proud jedni?ek
(define (ones)
  (cons-stream 1 (ones)))

> (ones)
(1 . #<procedure>)
> (stream-cdr (ones))
(1 . #<procedure>)
> (stream-cdr (stream-cdr (stream-cdr (stream-cdr (ones)))))
(1 . #<procedure>)


;; Vrací nekone?ny proud p?irozenych ?ísel
(define (naturals n)
  (cons-stream n (naturals (+ n 1))))

> (naturals 1)
(1 . #<procedure>)

> (stream-cdr (naturals 1))
(2 . #<procedure>)

> (stream-cdr (stream-cdr (stream-cdr (stream-cdr (naturals 1)))))
(5 . #<procedure>)

Související ?lánky

[editovat | editovat zdroj]

Externí odkazy

[editovat | editovat zdroj]
  1. The Original 'Lambda Papers' [online]. [cit. 2025-08-14]. Dostupné v archivu po?ízeném dne 2025-08-14. 
  2. R5RS Revised5 Report on the Algorithmic Language Scheme [online]. 2007-6-25. Dostupné online. (anglicky) 
  3. R6RS R6RS.org [online]. [cit. 2025-08-14]. Dostupné v archivu po?ízeném dne 2025-08-14. 
麦冬的功效与作用是什么 肾阴虚吃什么食物补 什么水果能马上通便 五十路是什么意思 5月22日是什么星座
结肠是什么病 2月23号是什么星座 狮子座的幸运色是什么 辟邪剑谱和葵花宝典有什么关系 结膜炎是什么原因引起的
冷面是什么面 有胆结石的人不能吃什么东西 爸爸的弟弟叫什么 身份证什么时候可以办 hr是什么品牌
脾胃有火是什么症状 去香港买什么划算 过誉是什么意思 血脂高看什么科 诺欣妥是什么药
胎监是检查什么的hcv9jop0ns7r.cn 心烦意乱是什么意思xianpinbao.com 后知后觉什么意思hcv9jop8ns2r.cn 鲱鱼是什么鱼hcv8jop7ns1r.cn 看见双彩虹有什么征兆hcv8jop1ns9r.cn
小孩睡觉磨牙是什么原因引起的hcv9jop3ns4r.cn 气溶胶是什么hkuteam.com 手指头麻是什么原因引起的hcv7jop7ns0r.cn 心管是什么部位hcv8jop6ns6r.cn d3什么时候吃效果最好520myf.com
白头发吃什么药helloaicloud.com 春天都开什么花aiwuzhiyu.com 什么人没有国籍hcv9jop3ns2r.cn 高危型hpv66阳性是什么意思520myf.com 突然血糖高是什么原因引起的hcv8jop3ns3r.cn
鼻血流不停是什么原因hcv9jop7ns3r.cn 日加立念什么字aiwuzhiyu.com 喉咙痒吃什么药好hcv7jop6ns1r.cn hbc是什么意思hcv7jop6ns2r.cn 过房是什么意思hcv9jop2ns3r.cn
百度