KATEDR� INFORMATIKY� PÍRODOV DECK� FAKULT� UNIVERZIT� PALACKÉHO� OLOMOU�
PARADIGMAT� PROGRAMOVÁN� 2� MAKR� II�
Slajd� vytvo°il� Vilé� Vychodi� � Ja� Kone£n�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� � � 2�
Implementace maker realizujících cykly ;; cyklus typu while (define-macro while (lambda (condition . body) (let 1)) `(let ,loop-name () (if ,condition (begin ,@body (,loop-name))))))) P°íklad pouºití: (let ((i 0) (j 0)) (while (< i 10) (set! j (+ j i)) (set! i (+ i 1))) (list i j)) Z=) (10 45) (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 2 / 29 Úprava: vrací hodnotu vyhodnocení posledního výrazu v t¥le (define-macro while (lambda (condition . body) (let ((loop-name (gensym)) (last-value (gensym))) `(let ,loop-name 2)) (if ,condition (,loop-name (begin ,@body)) ,last-value))))) P°íklad pouºití: (let 3) (while (< i 10) (set! j (+ j i)) (set! i (+ i 1)) (list i j))) Z=) (10 45) (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 3 / 29 Makr� pr� cyklu� typ� fo� (C� PER� � dal²í�
C� chcem� napodobit�
�
in� � � 0�
in� resul� � 0�
fo� (� � 5� � � 0� i–�
�
printf(“Stav� %� %i\n”� i� result)�
result++�
�
printf(“Koncovy� %� %i\n”� i� result)� �
Pozn.� zatí� nebudem� °e²i� brea� � continue�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� � � 2�
Makr� pr� cyklu� typ� fo�
P°íkla� zamý²lenéh� cykl�
(le� 4)�
(displa� (lis� “Koncovy� � � result)� (newline)�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� � � 2�
e²en�
;� cyklu� typ� fo� (C� PER� � dal²í�
(define-macr� fo� (lambd� (ini� conditio� inc� � body� (le� 5)�
`(begi� ,ini� (le� ,loop-nam� (� (i� ,conditio� (begi� ,@bod� ,inc� (,loop-name)))))))� (KI� U� Olomouc� P� 2A� Lekc� � Makr� II� � � 2� Cyklus do: Nativní cyklus jazyka Scheme P°íklad pouºití: (do ((x '(1 3 5 7 9) (cdr x)) ; navázaný symbol (sum 0 (+ sum (car x)))) ; navázaný symbol ((null? x) sum) ; limitní podmínka (display (list x sum)) ; t¥lo cyklu (newline)) Z=) 25 B¥hem iterace se postupn¥ zobrazí: ((1 3 5 7 9) 0) ((3 5 7 9) 1) ((5 7 9) 4) ((7 9) 9) ((9) 16) (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 7 / 29 ;� cyklu� d� pomoc� letre� (define-macr� d� (lambd� (bindin� conditio� � body� (le� ((loop-nam� (gensym))� `(letre� 6)))))�
(,loop-nam� ,@(ma� cad� binding)))))�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� � � 2�
;� cyklu� d� pomoc� pojmenovanéh� let� (úprav� p°edchozího�
(define-macr� d�
(lambd� (bindin� conditio� � body�
(le� 7)�
`(le� ,loop-nam� ,(ma� (lambd� (x� (lis� (ca� x� (cad� x))� binding� (i� ,(ca� condition� (begi� ,@(cd� condition)� (begi� ,@bod� (,loop-nam� ,@(ma� cadd� binding)))))))� (KI� U� Olomouc� P� 2A� Lekc� � Makr� II� � � 2� Cyklus typu repeat until P°íklad zamý²leného pouºití (let ((x 20) (y 15)) (repeat (set! y (+ y 4)) (set! x (- x 1)) (until ((<= x 10) (list 'foo x y)) ((>= y 30) (list 'bar y (+ x 20)))))) Z=) (bar 31 36) p°íkazy v t¥le vºdy prob¥hnou alespo¬ jednou cyklus se opakuje, dokud není spln¥na (n¥která) limitní podmínka test limitních podmínek probíhá vºdy po dokon£ení t¥la (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 10 / 29 (define but-last (lambda (l) (cond ((null? l) #f) ((null? (cdr l)) (cons '() (car l))) (else (let ((result (but-last (cdr l)))) (cons (cons (car l) (car result)) (cdr result))))))) (but-last '(a b c d)) Z=) ((a b c) . d) (define but-last (lambda (l) (foldr (lambda (x y) (if y (cons (cons x (car y)) (cdr y)) (cons '() x))) #f l))) (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 11 / 29 ;� makr� realizujíc� cyklu� typ� repeatunti� (define-macr� repea� (lambd� arg� (defin� but-las� � � � intern� denovan� but-las� (let� ((split-arg� (but-las� args)� (bod� (ca� split-args)� (limit� (cd� split-args)� (loop-nam� (gensym))� `(le� ,loop-nam� (� ,@bod� (con� ,@(ma� (lambd� (conds�
`(,(ca� conds� (begi� ,@(cd� conds)))� (cd� limits)� (els� (,loop-name))))))�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 1� � 2�
Poznámka o makrech v Dr. Scheme transforma£ní procedura makra se neaplikuje v prost°edí svého vzniku, ale v prost°edí po£áte£ních vazeb, prost°edí po£áte£ních vazeb 6= globální prost°edí, prost°edí po£áte£ních vazeb: nelze v n¥m denovat vazby, omezení Dr. Scheme kv·li odd¥lení makroexpanze a vyhodnocování. ;; pomocná procedura (define proc (lambda (x) (list '- x))) ;; makro (define-macro m (lambda (elem) (proc elem))) (m 10) Z=) Error: Symbol proc je nenavázaný (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 13 / 29 KVAZIKVOTOVÁNÍ úkolem je vyrobit makro realizující kvazikvotování (kvaziquote blah) + (quote blah) Z=) blah (kvaziquote (a b)) + (apply append (list (quote a)) (list (quote b)) (quote ())) Z=) (a b) (kvaziquote (a (unquote (+ 1 2)))) + (apply append (list (quote a)) (list (+ 1 2)) (quote ())) (kvaziquote (a (unquote-splicing l))) + (apply append (list (quote a)) l (quote ())) Z=) (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 14 / 29 ;; pomocná transforma£ní procedura (define trans-expr (lambda (expr) (cond 8) (null? expr)) (list 'list (list 'quote expr))) 9)) 10) 11)) (else (list 'list (list 'kvaziquote expr)))))) (te 1) Z=) (list (quote 1)) (te '()) Z=) (list (quote ())) (te '(1 2 3)) Z=) (list (kvaziquote (1 2 3))) (te '(unquote (1 2 3))) Z=) (list (1 2 3)) (te '(unquote-splicing (1 2 3))) Z=) (1 2 3) (te '(kvaziquote (1 2))) Z=) (list (quote (kvaz. (1 2)))) (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 15 / 29 ;� makr� pr� kvazikvotován� be� pouºit� kvazikvotován�
(define-macr� kvaziquot� (lambd� (expr�
;� pomocn� transforma£n� procedur� (p°edchoz� slide�
(defin� trans-exp� (lambd� (expr� � )�
;� vlastn� transformac�
(i� (no� (list� expr)�
(lis� 'quot� expr�
(appl� lis� 'appl� 'appen�
(appen� (ma� trans-exp� expr�
'12))))))�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 1� � 2�
HYGIENICK� MAKR�
Pro� hygienická�
Protoº� umoº¬uj� vytvá°e� bezpe£n� makra�
Základn� rys�
denován� � R5R� (krom� Scheme� poku� vím� nikd� nemá� kompletn� jin� p°ístu� � makr·� ne� define-macr� makr� jso� denován� pomoc� (n¥kolika� p°episovacíc� pravide� Výhod�
praktick� odpadaj� sloºit� kvazikvotovan� výraz� nem·º� nasta� symbo� captur� makr� jso� � soulad� � lexikální� rozsahe� platnost� makr� lz� denova� lokáln� Nevýhod�
n¥kter� makr� s� tímt� zp·sobe� ned¥laj� pohodln�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 1� � 2�
Soula� � lexikální� rozsahe� platnost� spo£ív� ve�
1 Jestliº� j� � t¥l� makr� denován� vazb� n� dosu� nepouºit� symbol� tent� symbo� j� � t¥l� makr� automatick� p°ejmenová� tak� ab� nemohl� dojí� k� koliz� s� jméne� ji� existujícíh� symbolu� � p°ejmenován� symbol� s� programáto� nestará� p°ejmenován� probíh� zcel� transparentn� 2 P°� vyhodnocován� t¥l� makr� s� vazb� v²ec� volnýc� výskyt� symbol� (t� jes� vazb� symbol·� kter� nebyl� vytvo°en� lokáln� � rámc� makra� hledaj� � prost°ed� denic� makr� prost°ed� denic� makr� � lexikáln� p°ede� p°� pouºit� makr� nezáleº� n� vazbác� � prost°ed� pouºit� makr� (KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 1� � 2�
Vytvo°en� hygienickéh� makr�
(define-synta� /naze� ./transformacni-procedur� .� /transformacni-procedur� � vznik� pomoc� spec� form� syntax-rule� Vytvo°en� transforma£n� procedur� hygienickéh� makr�
(syntax-rule� /klicova-slov� ./pravidlo� ./pravidlo� � ..� � /klicova-slov� � � � � sezna� symbol·� kter� jso� dál� chápán� jak� klí£ov� slov� (sezna� m·º� bý� prázdný� /pravidlo� � � � � p°episovac� pravidla� vi� dál� P°episovac� pravidl� jso� pravidl� tvar� (/vzo� ./nahrazn� .)� kd� /vzo� � j� výra� specikujíc� konkrétn� p°ípa� pouºit� makra� vi� dál�
/nahrazn� � j� libovoln� výraz� který� bud� volán� makra� nahrazen� � p°ípad� shod� � daný� vzore� (KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 1� � 2�
Vzor� (pr� detail� vi� R5RS� s� skládaj� ze�
symbol� � � � ozna£uj� klí£ov� slov� neb� vstupn� element� seznam� skládajíc� s� z� vzor� speciáln� vzo� výpustk� ..� � (t°� te£ky� význam� vzo� p°e� který� j� výpustk� s� m·º� n¥kolikrá� opakova� neb� nemus� bý� p°ítome� Vzor� s� porovnávaj� (n� úplno� shodu� s� vstupe� jede� p� druhém�
Symbol� vyskytujíc� s� v� vzor� (krom� prvního� moho� být�
1 symbol� vyskytujíc� s� mez� klí£ovým� slov� shod� s� vzore� nastáv� pouz� � p°ípad¥� kd� m� vstupn� výra� n� dan� pozic� stejn� symbo� 2 symbol� nevyskytujíc� s� mez� klí£ovým� slov� b¥he� porovnáván� vstupníh� výraz� s� vzore� jso� takov� symbol� navázán� n� vstupn� výra� Prvn� symbo� v� vzor� s� shoduj� � názve� makra�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 2� � 2�
Makr� an� realizovan� jak� hygienick� makr� (define-synta� an�
(syntax-rule� (� � ºádn� klí£ov� slov� 13))�
Makr� setf� (� tomt� p°ípad� slouº� car� cd� � re� jak� klí£ov� slov� (define-synta� setf�
(syntax-rule� (ca� cd� ref� 14))�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 2� � 2�
Nefunk£ní verze setf! (car, cdr a ref nejsou uvedena jako klí£ová slova (define-syntax setf! (syntax-rules () 15) 16) 17) 18))) P°íklad, pro£ vý²e uvedené nefunguje: (define p (cons 10 20)) (setf! (cdr p) 'svete) ; pouºito bude první pravidlo p Z=) (svete . 20) D·vod nefunk£nosti: symbol cdr ve vstupním výrazu se naváºe na symbol car vstupní výraz tím pádem odpovídá prvnímu pravidlu (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 22 / 29 Makr� o� realizovan� jak� hygienick� makr�
(define-synta� o�
(syntax-rule� (�
19))))�
Makr� de� jak� hygienick� makr� (zd� záleº� n� po°ad� pravidel�
(define-synta� de� (syntax-rule� (� 20)� 21))�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 2� � 2�
Sloºit¥j²� p°íkla� pouºit� hygienickýc� maker� for� � l� Pasca�
fo� � :� star� to/downt� en� [ste� k� d� stmt� stmt�
.. �
stmt�
endfo�
Cyklu� bycho� cht¥l� pouºíva� takto�
(fo� � :� � t� 1� d� (displa� i� (newline)� (fo� � :� 1� downt� � d� (displa� i� (newline)� (fo� � :� � t� 1� ste� � d� (displa� i� (newline)� (fo� � :� 1� downt� � ste� � d� (displa� i� (newline)�
Pomoc� r·znýc� vzor� rozli²ím� jednotliv� p°ípad� pouºití�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 2� � 2�
P°íka� fo� v� styl� jazyk� Pasca�
(define-synta� fo� (syntax-rule� (:� t� downt� d� step� 22))))� 23))))�
.
.
� pokra£ujem� n� dal²í� slajd�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 2� � 2�
.
.
� pokra£ován� � p°edchozíh� slajd�
(KI� U� Olomouc� P� 2A� Lekc� � Makr� II� 2� � 2�
Hygienická makra je moºné denovat lokáln¥ pomocí speciálních forem: let-syntax . . . jednotlivá pravidla se vzájemn¥ nevidí letrec-syntax . . . pravidla se v²echna vzájemn¥ vidí , pravidla mohou pouºívat ostatní pravidla (hrozí zacyklení) P°íklad lokální denice makra when v procedu°e (define f (lambda (n) (let-syntax 26))))) (when (> n 3) (display “BLAH”) (newline) (+ n 1))))) (f 1) Z=) nedenovaná hodnota (f 4) Z=) 5 rovn¥º vytiskne BLAH (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 27 / 29 V následujícím p°íkladu nedojde u symbolu test k jeho zachycení (define f (lambda (n) (let-syntax 27))))) (let 28) (when (> n 3) (display (list test “BLAH”)) (newline) (+ n 1)))))) (f 1) Z=) nedenovaná hodnota (f 4) Z=) 5 rovn¥º se vytiskne (#f BLAH) (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 28 / 29 Následující nebude fungovat: & je denované pomocí & (let-syntax 29)))) (& 1 2 3)) Z=) Error: & not bound Následující uº bude fungovat (díky letrec-syntax) (letrec-syntax 30)))) (& 1 2 3)) Z=) 3 (KI, UP Olomouc) PP 2A, Lekce 5 Makra III 29 / 29