ÚVOD:
Jazyk Scheme je funkcionální deklarativní jakyk vycházející z jazyka Lisp. Jeho standart byl stanoven v roce 1978, jeho tvůrci byli pánové G. Sussman a G. Steele.
UPLATNĚNÍ V PRAXI
Každý si jistě řekne, k čemu takový jazyk je. A pro podobné rýpaly mám částečný výčet konkrétních příkladů nasazení Scheme v praxi :
Pro porovnání uvádím odkaz na Prolog Development Center, kde se nacházejí programy psané v Prologu, jiné uplatnění Prologu v praxi jsem nenašel.
ROZDÍLY OPROTI OSTATNÍM JAZYKŮM
Scheme má od každého paradigmata kousek. Přejatou z Imperativního (procedurální – Pascal,C) má možnost vytvářet funkce, a také byl pro zjednodušení přejat IF, který alespoň mě v Prologu velmi chyběl, ovšem už nebyly přejaty infixové operátory tzn. příklad 5+5 se ve Scheme dá napsat jednině (+ 5 5). Ovšem největším překvapením je prvek se kterým jsem se ještě jinde nesetkal, dalo by se to vyjádřit tvrzením Všechno je vším.
%Prolog: funkce jako taková neexistuje, ale je možné ji simulovat
%definici pravidla
vypis() :- write('Ahoj vita te program Example').
secti(X,Y,Result) :- Result is X + Y.
;;;Scheme: funkce existuje a dokonce je sintaxí trochu podobná
;;;funkci definované v nějakém procedurálním jazyce
(define proc ;definujeme funkci s nazvem proc
(lambda(a b) ;urcime ze bude mit 2 parametry a a b
(+ (* a a) (* b b)) ;telo funkce a zaroven return
)
)
%Prolog: if neexistuje, řeší se různě pomocí operatorů porovnání
%v kombinaci s řezy
%příklad: pokud je císlo větší než 50 vrat no, pokud ne
% vrat to cislo na druhou
naDruhou(X,Result) :- X>50,!,fail.
naDruhou(X,Result) :- Result is X * X.
;;;Scheme: if existuje tak jak ho známe, jen podmínka díky
;;;neexistenci infix. opratoru vypada netipicky
(define nadruhou
(lambda(a)
(if(> a 50)
#f
(* a a)
)
)
)
;;;Scheme: operator=funkce=parametr z pohledu sintaxe jsou si
;;;všechny tito věci rovny
(nadruhou 40) ;volani funkce s parametrem 40
(* 1 5 2) ;nasobeni cisel 1*5*2 ... vysledkem bude 10
(* 1 (nadruhou 5) 2) ;50
Predikát ve Scheme má také velmi odlišnou syntaxi od Prologu. Je to vlastně běžná funkce, která má návratové hodnoty #t nebo #f a pri volání se uvádí s ? (otazníkem) – viz. přiklad
;Scheme: porovnání 2 prvků
(define equal
(lambda(a b)
(if(= a b)
#t
#f
)
)
)
(equal? 4 6)
---------------------
%Prolog: pro srovnání
equal(X,X) :- !.
equal(X,Y) :- !,fail.
?- equal(4,5).
Dalším prvkem, kterým se Scheme blíží spíše imperativním jazykům je cyklus. Prolog jej nemá, nahrazuje se rekurzí.
;Scheme:
(do
((x 1 (+ x 1)))
((> x 10) (newline))
(display x)
(display " ")
)
Scheme také nabízí možnost přiřazení.
;Scheme:
(set! p 10)
%Prolog:
(p is 10)
Vrcholem přibližování se Scheme k procedurálním jazykům je blok begin, ten totiž způsobí, že kód do něj uzavřený se bude chovat čistě procedurálne).
V Prologu samozřejmě nemá obdobu.
(begin
(set! x 5)
(* x 5)
)
ZÁVĚREM
Sám sem při tvorbě tohoto článku byl překvapen jak až rozdílné mohou být jazyky partřící do stejné skupiny deklarativních jazyků.
Scheme má mnoho imperativních prvků aď už podmínky (if) tak cykly nebo blok begin, proto je možná považován za dobrý výukový jazyk pro logické programování, a také dobrý na přechod z procedurálního programování. Podle mého názoru pokud začátečník ve Scheme nebude mít dostatečný teoretický základ o deklarativním způsobu a nebude se snažit tak psát, tak bude jen jazyk zneužívat z čehož nebude mít žádný užitek.
Prolog se optori tomu drží striktně deklarativního způsobu a imperativní prvky až na vyjímky nepodporuje, proto začít s ním je mnohem těžší a dokud výborně nepochopíte principy deklarativního programování nenapíšete nic, což možná mnoho lidí odradí, ale ty kteří se nedají budou obohaceni o tuto cennou zkušenost.
Můj závěr tedy je takový, Scheme je dobré pro lidi kteří vědí co chtějí. Ale naučit se deklarativnímu uvažování je jako naučit se plavat, musí Vás hodit do vody, sice se budete chvilku topit, ale pak se z Vás možná stanou dobrí plavci a to splňuje Prolog lépe.
ZDROJE
http://www.htus.org/Book/2001–11–13/howto-Z-H-3.html
http://reboot.cz/howto/programovani/uvod-do-scheme-3-cast/articles.html?id=31
http://atd.havrlant.net/scheme-aneb-programujeme-funkcionalne
http://www.root.cz/clanky/scheme-kostlivec-ve-skrini-nebo-nehasnouci-hvezda/
Proc myslite, ze je Scheme deklarativni, muzete prosim definovat deklarativni?
U deklarace funkce equal ve Scheme vam chybi otaznik,
pokud ji chcete volat jako equal?
U predikatu equal v Prologu tam radek "equal(X,Y) :- !,fail."
nemusi vubec byt.
V Prologu zapis p is 10 je uplny nesmysl, zpusobi jen vypsani
no resp. selhani, pokud by to melo delat neco smysluplneho spise byt tam melo byt P is 10 a navic is v Prologu neni to, co je set! ve Scheme
Dobry den, omlouvam se za chyby jak v cestine tak v Prologu nebo ve Scheme, psal sem to jako referat do skoly a psal sem to pres noc.... Chyby samozrejme opravim, dik za upozorneni...
To xx: (p is 10) .. samozrejme tam melo bejt
vloz(P) :- P is 10.
K tomu jak sem napsal, ze mi v prologu chybelo if, tak to bylo ze zacatku nez jsem alespon trochu pochopil jak funguje... Ze je Scheme deklarativni jsem vycet ze clanku ze kterych sem cerpal...to nemam z vlastni hlavy.
Zdravim, ono k je to s tou deklarativnosti docela tezke,
jelikoz existuje nekolik definic, co to vlastne je.
Podle tech prisnejsich je deklarativni jazyk treba HTML, jelikoz dnes v pripade HTML popisujete strukturu dokumentu, ale uz nepopisujete, jak se to ma zobrazit, to by melo byt v CSS.
Zato zastanci jine definice povazuji kazdy funkcionalni jazyk
za deklarativni.
to roman : pojem funkcionalni vznikl z toho, ze se jedna o matematicky chapanou funkci, kdezto funkce kterou jsem tady popisoval jako prvek syntaxe Scheme je brana jako prvek imperativniho programovani... To si o tom tedy myslim ja... mozna ze se pletu ...
pokud vim tak logicke programovani a funkcionalni programovani jsou jen podvetve spolecne velke vetve zvane deklarativni programovani, tim padem jsou oba deklarativni...(opet muj nazor, pokud mate duvod myslet si neco jineho rad si ho prectu) ;-)
[8]: Pokud je mi známo, sami pánové Sussman a Steele, pokud je mi známo, o funkcích nemluví, ani se ten pojem nevyskytuje nikde v RxRS. Používá se zásadně pojem "procedura". Čestnou výjimku v RxRS tvoří ty procedury, které jsou skutečně funkce (např. "These procedures are part of every implementation that supports general real numbers; they compute the usual transcendental functions."). Taky tu teď leží přede mnou Structure and Interpretation of Computer Programs, a v kapitole 1.1.7 na straně 22 Sussman přiznává, že deklarativní zápis v současnosti dokážeme zpracovat jen ve vymezených třídách úloh, takže ta deklarativnost na úrovni základního jazyka skutečně není. :-) Deklarativní charakter mají syntax-rules, a také mohou mít deklarativní charakter rozhraní konkrétních knihoven, ale základní jazyk opravdu ne. Netuším, jak jste na to přišel.
Zadruhé, takhle prasácky psát závorky! Fuj! ;-) Ukončovací závorka patří hned za poslední prvek, cpát to na samostatný řádek se považuje asi za tak vkusné (a "čitelné"), jako neodsazovat v Cčku nebo míchat taby a mezery v Pythonu. ;-)
Jinak ještě...
"Scheme má mnoho imperativních prvků aď už podmínky (if) tak cykly nebo blok begin, proto je možná považován za dobrý výukový jazyk pro logické programování, a také dobrý na přechod z procedurálního programování. Podle mého názoru pokud začátečník ve Scheme nebude mít dostatečný teoretický základ o deklarativním způsobu a nebude se snažit tak psát, tak bude jen jazyk zneužívat z čehož nebude mít žádný užitek."
Stačí si přečíst zmíněnou knihu (SICP), tam je správný programovací styl ve Scheme rozebrán více než dostatečně. :-) (Kniha má bez rejstříku 610 stran a forma set! se prvně objeví až na straně 220, přičemž vhodnosti a nevhodnosti použití set! v různých případech je věnován poměrně rozsáhlý výklad.)
to Rejpal [9]: Co sa tyka pisania zatvoriek, tiez som uz dávno zvolil cestu ako autor clanku, pretoze mi to napadlo ako jediná moznost "jak prezit v LISPe". Tento sposob je prave inspirovany skusenostou a jazykmi ako C, Python, ... kde spravne odsadzovanie zvysuje citatelnost. Ano v LISPe/Scheme je ina stabna kultura.
Ale ked napriklad napisem
(defun print_sorted_list (lst)
(let
; lokalne premenne: j - counter, lst_cpy - kopia listu
((j 1) (lst_cpy (copy-list lst)))
; vytriedit lokalnu kopiu
(sort lst_cpy #'string-lessp)
; vytlacit cleny vytriedenej kopie
(dolist (mbr lst_cpy)
(format t "~A. člen = '~A' ~%" j mbr)
(setq j (+ j 1))
)
)
)
zda sa mi to citatelnejsie ako napisat do v kuse
(defun print_sorted_list (lst)
(let((j 1) (lst_cpy (copy-list lst)))
(sort lst_cpy #'string-lessp)
(dolist (mbr lst_cpy)(format t "~A. člen = '~A' ~%" j mbr)(setq j (+ j 1)))))
V prvom pripade hned vidim, ako zavtvorky ( a ) koresponduju. V druhom pripade to nevidiet, jedine, ze by si clovek scitoval pocet ( a sucasne od nich odcitoval pocet ). Jedinu vyhodu vidim v tom, ze 2.zapis zaberie menej riadkov.
(:o-))
[11]: V tom případě používáte špatný editor. Neříkám, že každý musí používat Emacs+Paredit+Redshank (přestože tuhle kombinaci považuju za geniální a používám - viz screencast: http://www.foldr.org/~michaelw/emacs/redshank/), ale editace stromové struktury mi přijde tak triviální (v porovnání třeba s tím, co by se pro totéž muselo udělat v Perlu nebo C++ ;-)), že snad každý editor, který si dělá nároky na použitelnost pro Lisp, to musí umět.
Paredit mj. naprosto znemožňuje napsání nevyvážené závorky, takže není třeba vůbec nic počítat, jen se naučit pár klávesových zkratek. Tím pádem není třeba psát závorky na samostatné řádky a stačí se při čtení řídit odsazováním. :-) (Fakt, že se nepoužívá odsazování jako jediný prostředek, plyne z toho, že se to zkoušelo a ukázalo se, že v praxi to není to až tak dobrý nápad - ne vždy chce člověk všechny výrazy sekat na kousky pod sebe).
Pokud někdo nemá rád GNU Emacs, tak třeba pro DrScheme existuje DivaScheme nebo jak se to jmenuje.
Ja pouzivam vim - skoro na vsetko. A ten tiez pri LISPe/Scheme zvyraznuje farebne korespondujuce zatvorky a ked napisete ukoncovaciu zatvorku naviac zvyrazni ju na cerveno. Takze to velmi pomoze.
Problem je len, ked zabudnete jednu ukoncovaciu zatvorku. V tomto pripade pomaha teda ta konvencia pisat ukoncovacie zatvorky pod zacinajuce, pretoze potom na prvy pohlad zbadate ze ukoncenie chyba.
Ale presvedcil ste ma, budem sa snazit zmenit svoje zle navyky.