4
A
回答
3
使用#'
(即syntax
)時,你是不是構建一個新的語法對象,因爲當你只是引用與syntax-case
或with-syntax
結合的模式變量。
使用#'
作爲臨時語法對象,如(syntax->list #'(id ...))
。
使用#'
表示語法對象,這些語法對象表示您知道其中沒有語法錯誤的語法對象,或者其中的語法錯誤是宏實現的錯誤,而不是宏的使用。
使用syntax/loc
當您構造表達式時,由於錯誤地使用了宏,可能會包含語法錯誤。
讓我們考慮一個具體的例子:
形式display-let
應該工作完全像正常let
,除了它是評估主體之前顯示綁定的值。
這是第一個實現:
(define-syntax (display-let-1 stx)
(syntax-case stx()
[(_ ([id expr] ...) body ...)
#'((lambda (id ...)
(displayln (format "~a is bound to ~a" 'id id)) ...
body ...)
expr ...)]))
這是一個正確的使用宏的例子:
> (display-let-1 ([x 1] [y 2]) (+ x y))
x is bound to 1
y is bound to 2
3
現在讓我們看看會發生什麼當宏使用不當:
> (display-let-1())
lambda: bad syntax in: (lambda())
此用法不正確,因爲使用let
必須始終有一個空的身體。除了打印錯誤消息,DrRacket顏色此代碼紅色:
(lambda (id ...)
(displayln (format "~a is bound to ~a" 'id id)) ...
body ...)
雖然是正確的,由宏構建的lambda
表達不正確,(lambda())
是不合法的,它不是由於錯誤的宏,但由於宏的使用不正確。
要將指定的lambda
表達式與syntax/loc
重新定向,請使用syntax/loc
的第一個參數作爲紅色的位置。
(define-syntax (display-let-2 stx)
(syntax-case stx()
[(display-let ([id expr] ...) body ...)
#`(#,(syntax/loc stx (lambda (id ...) body ...)) expr ...)]))
> (display-let-2())
display-let-2: bad syntax in: (display-let-2())
這次在REPL進入(display-let-2())
周圍是紅色,並且錯誤消息中提到display-let-2
而不是lambda
。
相關問題
- 1. Python:什麼時候應該使用子類而不是方法?
- 2. 什麼是phtml,什麼時候應該使用.phtml擴展名而不是.php?
- 3. 什麼時候應該使用AWS,什麼時候不使用
- 4. 什麼時候應該使用async/await,什麼時候不用?
- 5. 什麼時候應該使用INNER-LOOP-JOIN而不是INNER JOIN
- 6. 什麼時候應該使用susy-media而不是susy-breakpoint
- 7. 什麼時候應該使用double而不是小數?
- 8. 什麼時候應該使用UIImagePickerControllerSourceTypePhotoLibrary而不是UIImagePickerControllerSourceTypeSavedPhotosAlbum?
- 9. Python:什麼時候應該使用subprocess.Popen而不是os.popen?
- 10. 什麼時候應該使用ThreadLocal而不是Thread.SetData/Thread.GetData?
- 11. 什麼時候應該使用fputs而不是fprintf?
- 12. 什麼時候應該使用字符串而不是stringstream?
- 13. 什麼時候應該使用宏而不是內聯函數?
- 14. 什麼時候應該使用的NSKeyedArchiver,而不是SQLite的?
- 15. 什麼時候應該使用angular.component而不是angular.directive?
- 16. Swift:我應該什麼時候使用「var」而不是「let」?
- 17. 什麼時候應該使用Task.Run()而不是等待?
- 18. 什麼時候應該使用Map而不是For循環?
- 19. 什麼時候應該使用UserControl而不是Page?
- 20. 什麼時候應該使用組件而不是指令?
- 21. 什麼時候應該使用ReBuild而不是Build?
- 22. 什麼時候應該使用reg而不是電線?
- 23. 什麼時候應該使用#ifdef而不是if()?
- 24. 什麼時候應該使用IBOutlet而不是IBAction?
- 25. 什麼時候應該使用OpenStruct而不是哈希?
- 26. 什麼時候應該使用Regex而不是String.IndexOf()?或String.Contains()?
- 27. 什麼時候應該使用HStoreField而不是JSONField?
- 28. 什麼時候應該使用會話變量而不是cookie?
- 29. 什麼時候應該使用Class方法而不是init實例方法?
- 30. 什麼時候應該使用sed,什麼時候應該使用awk