Last active
January 24, 2018 17:40
-
-
Save Yoxem/e9255fef767270d2df86dfaee29a6cd6 to your computer and use it in GitHub Desktop.
scheme 系 (define-syntax) (syntax-rule) 的用法舉隅
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; #lang r5rs -> scheme R5Rs | |
;; scheme 系 (define-syntax) (syntax-rule) 的用法舉隅(有關巨集 macro) | |
;;; 求算平方和,sqrt-num 是巨集名稱 | |
;; 期望輸出結果 | |
; (sqrt-sum 2) => 4 (回傳值,= 2^2) | |
; (sqrt-sum 1 3) => 10 (=1^2+3^2) | |
; (sqrt-sum 1 3 5) => 35 (=1^2+3^2+5^2) | |
(define-syntax sqrt-sum | |
(syntax-rules () | |
((_ x) ; 一元引數時。底線_代表 sqrt-num 這個函數,當然也可以直接寫成 sqrt-num。下同 | |
(* x x)) ; 處理方法 | |
((_ x y ...) ; 二元以上引數 | |
(+ (_ x)(_ y ...))) ; 處理方法,可遞迴表示 | |
) | |
) | |
;; 另一種寫法,利用尾遞迴來避免堆棧耗用過度 | |
(define-syntax sqrt-sum | |
(syntax-rules () | |
((_ x) ; 一元引數時。底線_代表 sqrt-num 這個函數,當然也可以直接寫成 sqrt-num。下同 | |
(* x x)) ; 處理方法 | |
((_ x y ...) ; 二元以上引數 | |
(begin ; 執行多個指令 | |
; 定義尾遞迴表示 | |
(define (sqrt-sum-iter a arg-list) | |
(if (eq? arg-list '()) a ; 若 arg-list 為空,傳回值 | |
;; else 去 arg-list 頭,將頭的平方和加到 a | |
(sqrt-sum-iter | |
(+ a (* (car arg-list) (car arg-list))) | |
(cdr arg-list)) | |
) | |
) | |
(sqrt-sum-iter 0 (list x y ...))) ; 處理方法,可用尾遞迴表示,避免堆棧使用過多 | |
) | |
) | |
) | |
;; syntax-case 的使用,在 racket 可以用,但 Drracket 附隨的 scheme r5rs不行 | |
;(define-syntax sqrt-sum | |
; (lambda (stx) ;; 要加 | |
; (syntax-case stx () | |
; ((_ x) | |
; (syntax (* x x))) ;; 執行的動作,要包 syntax | |
; ((_ x y ...) | |
; (syntax (+ (sqrt-sum x) (sqrt-sum y ...)))) ;; syntax 內不能使用 _ 表示原本函數 | |
; ))) | |
; syntax-case 的使用,在 racket 可以用,但 Drracket 附隨的 scheme r5rs不行 | |
; 另一種寫法,stx 表示 sqrt-num 的參數 | |
;(define-syntax (sqrt-sum stx) | |
; (syntax-case stx () ( | |
; ((_ x) ; lambda (stx) 等不要加 | |
; (syntax (* x x))) ;; 執行的動作,要包 syntax | |
; ((_ x y ...) | |
; (syntax (+ (sqrt-sum x) (sqrt-sum y ...)))) ;; syntax 內不能使用 _ 表示原本函數 | |
; )) | |
;; 其他關於 macro 可以參考:https://artyom.me/learning-racket-2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment