2013-07-02 35 views
7

Trong ngữ cảnh viết macro Vợt, cú pháp 3D có nghĩa là gì?"Cú pháp 3D" là gì?

Tôi đã nghe cụm từ một vài lần. Bao gồm một lần liên quan đến macro Tôi đã được viết. Nhưng đó là một lúc trước; Tôi đã sửa nó, và bây giờ tôi không thể nhớ chính xác những gì tôi đã làm sai ban đầu.

Ngoài ra: Cú pháp 3D có phải là luôn luôn không? Hoặc là nó giống như eval (nếu bạn nghĩ rằng bạn cần phải sử dụng nó, có lẽ bạn đang sai, nhưng có một số sử dụng hợp lệ hợp lệ trong tay chuyên gia)?

+0

Trong tương lai, có thể mọi thứ sẽ được ghi lại đầy đủ! 1 cho khó khăn. Trông giống như một câu hỏi tiền thưởng tốt cho tôi. Điều duy nhất tôi có thể xác định có liên quan là cuộc thảo luận này: http://lists.racket-lang.org/dev/archive/2013-January/011637.html – jdero

Trả lời

6

Đối tượng cú pháp thường được cho là chỉ serializable data. Cú pháp 3D làm suy yếu điều kiện này: nó cho phép chúng ta lẻn vào các giá trị tùy ý, và không chỉ dữ liệu đơn giản. Đó là những gì làm cho chúng "3d": chúng là những giá trị vượt lên trên những thứ phẳng bình thường mà bạn mong đợi từ các đối tượng cú pháp.

Ví dụ: chúng tôi có thể lẻn vào các giá trị lambda!

#lang racket 

(define ns (make-base-namespace)) 
(define (set-next! n) 
    (parameterize ([current-namespace ns]) 
    (eval #`(define next #,n)))) ;; <-- 3d-syntax here 

(define (compute s) 
    (parameterize ([current-namespace ns]) 
    (eval s))) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
(define counter 0) 
(set-next! (lambda() 
      (set! counter (add1 counter)) 
      counter)) 

(compute '(+ (next) 
      (next) 
      (next) 
      (next))) 

Thực hiện điều này thường là một điều xấu, vì sự hiện diện của các giá trị này có thể là nỗ lực không thành công để tiết lộ thông tin trong các giai đoạn biên dịch. Kết quả là cái gì đó có khả năng không thể phân tách riêng. Nếu bạn thấy lỗi có âm như sau:

write: cannot marshal value that is embedded in compiled code value 

thì rất có thể là do macro đã tạo ra một đoạn cú pháp 3d không thể được tuần tự hóa thành bytecode.

Đôi khi, trong những trường hợp hiếm hoi, chúng tôi thực sự muốn có cú pháp 3d, thường trong ngữ cảnh đánh giá động. Như một ví dụ cụ thể, một trình gỡ lỗi trong DrRacket có thể muốn chú thích cú pháp của một chương trình để các ứng dụng hàm gọi trực tiếp trở lại các chức năng của trình gỡ rối, để chúng ta có thể thực hiện những việc như tô màu mã tương tác trong trình chỉnh sửa chương trình. Theo nghĩa đó, cú pháp 3d có thể hoạt động như một kênh giao tiếp giữa mã được đánh giá động và môi trường xung quanh của nó.

+0

ngay cả trong bối cảnh như vậy, mặc dù, có vẻ như sạch hơn để tiêm hàm như một phụ thuộc cấp mô-đun, bằng cách nào đó. Mặc dù, um, các stepper là rife với cú pháp 3d. –

+0

Đồng ý. Nhưng tôi gặp phải một số vấn đề lạ khi cố gắng làm như vậy: http://lists.racket-lang.org/dev/archive/2013-April/012126.html, và tiếc là tôi không có thời gian trong những ngày này để tìm ra chính xác tôi đang mất tích. – dyoo

+1

Đầu tiên, cảm ơn bạn đã trả lời! Tôi đã đọc lại, suy nghĩ và cố gắng xử lý câu trả lời của bạn. Đối với một điều, tôi figured câu trả lời sẽ đòi hỏi phải nói về máy biến áp cú pháp, nhưng bạn đang sử dụng eval và không gian tên, và tôi đang cố gắng để suy nghĩ thông qua những gì có nghĩa là. Ngoài ra, tôi đang bối rối và/hoặc bị phân tâm bởi việc sử dụng các không gian tên trong ví dụ của bạn, và cố gắng hiểu nếu đó là điều cần thiết và nếu như vậy làm thế nào/tại sao. [This] (https://gist.github.com/greghendershott/5923364) đơn giản hơn. Nó cho cùng một câu trả lời: 10. Nó có tương đương hay không? –

Các vấn đề liên quan