2012-04-10 26 views
8

Tôi muốn tạo một dạng cú pháp trong Racket có thể chấp nhận một đối số từ khóa, cách mà một số hàm có thể.Macro Racket có thể lấy đối số từ khóa không?

Sau khi giảm nó đến một ví dụ đơn giản, tôi đã cố gắng viết:

(define-syntax sum-of-products 
    (syntax-rules (#:extra) 
    [(sum-of-products ([a b] ...)) 
    (+ (* a b) ...)] 
    [(sum-of-products ([a b] ...) #:extra extra) 
    (+ extra (* a b) ...)])) 

như vậy mà dữ liệu sau rồi sẽ làm việc:

(sum-of-products ([2 2] [3 3])) → 13 
(sum-of-products ([2 2] [3 3]) #:extra 5) → 18 

Thật không may, Racket gọi đây là "cú pháp xấu", do đó rõ ràng nỗ lực đó không chính xác.

Việc này có thể thực hiện được không?

Trả lời

12

Từ khóa trong các mẫu cú pháp được xử lý giống như các chữ như số vv, vì vậy bạn không cần phải chỉ định chúng làm từ khóa. (Đó là cần thiết chỉ cho định danh.) Vì vậy, các công trình sau đây (lưu ý rằng tôi sửa lỗi đánh máy bạn đã có trong ví dụ thứ hai):

#lang racket 
(define-syntax sum-of-products 
    (syntax-rules() 
    [(sum-of-products ([a b] ...)) 
    (+ (* a b) ...)] 
    [(sum-of-products ([a b] ...) #:extra extra) 
    (+ extra (* a b) ...)])) 
(sum-of-products ([2 2] [3 3])) 
(sum-of-products ([2 2] [3 3]) #:extra 5) 

Xem thêm syntax-parse cho một tiện ích mà có thể làm cho parsing keywords dễ dàng hơn.

+3

Cụ thể, tài liệu 'cú pháp-phân tích cú pháp 'có toàn bộ [phần] (http://docs.racket-lang.org/syntax/Optional_Keyword_Arguments.html) về cách viết macro với đối số từ khóa. –

+0

(Ugh, tôi quên thêm liên kết đó ...) –