What is the purpose of syntax objects in a schema?

I am trying to write a small language similar to a circuit in python in order to try to better understand the circuit.

The problem is that I am stuck on syntax objects. I can’t realize them because I don’t understand what they work for and how they work.

To try to understand them, I played a little with syntax objects in DrRacket.

From what I could find, the rating is #'(+ 2 3)no different from the rating '(+ 2 3), except when there is a lexical variable +that obscures the one that is in the top-level namespace, in this case (eval '(+ 2 3))it still returns 5, but (eval #'(+ 2 3))just throws an error.

For instance:

(define (top-sym)
  '(+ 2 3))
(define (top-stx)
  #'(+ 2 3))
(define (shadow-sym)
  (define + *)
  '(+ 2 3))
(define (shadow-stx)
  (define + *)
  #'(+ 2 3))

(eval (top-sym)), (eval (top-stx)) (eval (shadow-sym)) 5, (eval (shadow-stx)) . 6.

, , , ( , ), , , .

, .

, : , ?

+5
1

- Racket. , , :

#lang racket/base
(* 3 4)

, . , , :

#lang racket/base

(define example-program 
  (open-input-string
   "
    #lang racket/base
    (* 3 4)
   "))

(read-accept-reader #t)
(define thingy (read-syntax 'the-test-program example-program))
(print thingy) (newline)
(syntax? thingy)

, * thingy. * in thingy , : . * * of #lang racket/base.

, . (. eval, , .)

, , :

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

;; This macro is only meant to let us see what the compiler is dealing with
;; at compile time.

(define-syntax (at-compile-time stx)
  (syntax-case stx ()
    [(_ expr)
     (let ()
       (define the-expr #'expr)
       (printf "I see the expression is: ~s\n" the-expr)

       ;; Ultimately, as a macro, we must return back a rewrite of
       ;; the input.  Let just return the expr:
       the-expr)]))


(at-compile-time (* 3 4))

at-compile-time, . DrRacket, , DrRacket , . , at-compile-time, .

, - :

I see the expression is: #<syntax:20:17 (* 3 4)>

, identifier-binding:

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

(define-syntax (at-compile-time stx)
  (syntax-case stx ()
    [(_ expr)
     (let ()
       (define the-expr #'expr)
       (printf "I see the expression is: ~s\n" the-expr)
       (when (identifier? the-expr)
         (printf "The identifier binding is: ~s\n" (identifier-binding the-expr)))

       the-expr)]))


((at-compile-time *) 3 4)

(let ([* +])
  ((at-compile-time *) 3 4))

DrRacket, :

I see the expression is: #<syntax:21:18 *>
The identifier binding is: (#<module-path-index> * #<module-path-index> * 0 0 0)
I see the expression is: #<syntax:24:20 *>
The identifier binding is: lexical
12
7

(: at-compile-time ? ! -, raco make, , .)

, at-compile-time, , . identifier-binding , , ( #lang racket/base, module-path-index). , : (let ([* +]) ...), , * , let.

Racket , , .


eval : , , ! , .

, , s- :

#lang racket/base

(module mod1 racket/base
  (provide x)
  (define x #'(* 3 4)))

(module mod2 racket/base
  (define * +) ;; Override!
  (provide x)
  (define x  #'(* 3 4)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require (prefix-in m1: (submod "." mod1))
         (prefix-in m2: (submod "." mod2)))

(displayln m1:x)
(displayln (syntax->datum m1:x))
(eval m1:x)

(displayln m2:x)
(displayln (syntax->datum m2:x))
(eval m2:x)

, , , eval. ,

(module broken-mod2 racket/base
  (provide x)
  (define x  
    (let ([* +])
      #'(* 3 4))))

, eval x, broken-mod2, , eval. eval - .

+11

All Articles