Linking self-reference via macros

The project I'm working on defines some complex structures that receive messages and start their own stream. Structures are user-defined and are converted using macros to threads and the runtime. Roughly speaking, we can say that a complex structure consists of some behavior that implements logic and a procedure for spawning an instance of behavior. In the code below, I have greatly simplified the situation where the behavior defined by a macro create-thread-behaviouris a simple piece that can be created using a macro spawn. I would like to realize the ability (instance) of behavior to send messages to myself using a parameter selfthat will be bound to (current-thread)(~ the thread executing the behavior).

I tried to fine-tune something with help syntax-parameterize, but for some reason cannot make it work. The code below implements a simple application that should clarify what I want to achieve - a special point of interest is the link (not implemented) <self>to the bottom.

#lang racket
(require (for-syntax syntax/parse))

(define-syntax (create-thread-behaviour stx)
  (syntax-parse stx
    [(_ body:expr ...+)
     #'(λ () body ...)]))

(define-syntax (spawn stx)
  (syntax-parse stx
    [(_ behaviour:id)
     #'(thread behaviour)]))


(define behaviour
  (create-thread-behaviour
   (let loop ()
     (define message (thread-receive))
     (printf "message: ~a~n" message)
     (thread-send <self> "And this is crazy.")
     (loop))))

(define instance (spawn behaviour))
(thread-send instance "Hey I just met you")

So, the thing with the syntax options that I tried is the following, which raises the self-determined error "can only be used in behavior." I know that I used the syntax parameters correctly before, but maybe I looked at the problem for too long.

(require racket/stxparam)

(define-syntax-parameter self
  (lambda (stx) (raise-syntax-error (syntax-e stx) "can only be used in a behaviour")))

(define-syntax (spawn stx)
  (syntax-parse stx
    [(_ behaviour:id)
     #'(thread
        (lambda ()
          (syntax-parameterize ([self #'(current-thread)])
            (behaviour))))]))
+4
source share
1 answer

, . , , , . .

, - , define-syntax-parameter, . syntax-parameterize, , , . .

, , make-variable-like-transformer syntax/transformer, , , , . , , , (current-thread) . syntax-parameterize :

(require (for-syntax syntax/transformer))

(syntax-parameterize ([self (make-variable-like-transformer #'(current-thread))])
  (behaviour))

" " self .

, , , , , , . , syntax-parameterize (behavior) self behavior.

, , . , : Racket , : , . , . , let, , , .

, , syntax-parameterize spawn , behavior spawn. syntax-parameterize create-thread-behavior, , , :

(define (behavior-impl)
  (define message (thread-receive))
  (printf "message: ~a~n" message)
  (thread-send self "And this is crazy.")
  (behavior-impl))

(define behaviour
  (create-thread-behavior
   (behavior-impl)))

self syntax-parameterize, .

, , , , , . , , self create-thread-behavior. self , : (current-thread). self:

(define-syntax self (make-variable-like-transformer #'(current-thread)))

self , current-thread. , , self - ( , ), .

+4

Source: https://habr.com/ru/post/1665539/


All Articles