I'm just curious, is this what you mean?

#lang racket

(require rackunit
         (for-syntax
          syntax/parse))

(begin-for-syntax
(struct proc-with-info (proc info) #:property prop:procedure (struct-field-index proc)))

(define-syntax thing
  (proc-with-info (lambda (stx)
                    (syntax-parse stx #:literals (thing)
                                  [(thing x ...)
                                   #'(#%app thing x ...)]
                                  [thing
                                   #'(lambda (x) x)]))
                  'info))

(define-syntax get-info
  (lambda (stx)
    (syntax-parse stx
                  [(get-info x)
(datum->syntax stx `(quote ,(proc-with-info-info (syntax-local-value #'x))))])))

(check-equal? (thing 1) 1)
(let ([x (random)])
  (check-equal? (thing x) x))

(check-equal? (get-info thing)
              'info)


On Jan 20, 2014, at 12:37 AM, Carl Eastlund wrote:

It sounds like you've got it. A syntax transformer must be a procedure, and prop:procedure is how you make a procedure that can also be something else. So if you want something to be both a syntax transformer and a struct binding, for instance, you need to use prop:procedure and prop:struct-info. You can't make something both a procedure and a symbol, because symbols don't work via struct properties, but you could make it both a procedure and a struct that contains a symbol.

Carl Eastlund

On Mon, Jan 20, 2014 at 12:21 AM, Scott Klarenbach <sc...@pointyhat.ca> wrote: That doesn't look like a complete program; what does #'done refer to? And where did the "val is: " printout go?

That's just a quick hack for illustration purposes. #''done is just something to return. (note the two quotes) The output is:
val is: #<procedure:self-ctor-checked-struct-info>#<procedure:posn>
'done

But your supposition is correct: posn is always bound as syntax to a self-ctor-checked-struct-info-object. That object works as a syntax transformer; run time references to posn are transformed into references to the actual procedure value you're seeing as #<procedure:posn>.

Thanks Carl, it's starting to make sense. So the prop:procedure of the struct is actually the transformer? And so in expression context it acts as a macro, but in syntax-local-value context it acts as a struct? I was trying to produce something similar, but ran into the following issues:

Say I want (define-syntax (posn) ...) to transform syntax, but I also want (syntax-local-value #'posn) to return 'something. Without the struct trick I can only have one but not the other. I could either have (define-syntax posn 'something), and lose the ability to call it as a macro (illegal syntax), or have (define- syntax (posn) #'something), and then (syntax-local-value #'posn) returns the transformer, rather than 'something.





On Sun, Jan 19, 2014 at 8:57 PM, Scott Klarenbach <sc...@pointyhat.ca> wrote: It's not changing it, I'm just trying to figure out the implementation and understand what I'm seeing.
For example, given this:

(struct posn (x y))

(define-syntax (test stx)
  (syntax-case stx ()
        [(_ x)
         (printf "val is: ~s" (syntax-local-value #'posn))
         #''done]))

> posn
#<procedure:posn>

> (test x)
#<procedure:self-ctor-checked-struct-info>

I'm surprised that the values are different. Is posn actually always a self-ctor-checked-struct-info object, but it's prop:procedure is defined to allow for being used in an expression in the first case?




On Sun, Jan 19, 2014 at 8:40 PM, Carl Eastlund <carl.eastl...@gmail.com > wrote: If syntax-local-value is returning something other than the value you put in, that's a bug. It shouldn't be wrapping it or changing it in any way. Do you have a program where you bind something via define-syntax that satisfies struct-info?, and get something out via syntax-local-value that doesn't?

Carl Eastlund

On Sun, Jan 19, 2014 at 11:27 PM, Scott Klarenbach <sc...@pointyhat.ca> wrote: But I don't see how the same binding can be a transformer and also return something else (like a list, or a checked-struct-info-thing) via syntax-local-value.

If I bind my-fn as a transformer, then any other macros that use it with syntax-local-value will receive the transformer procedure back, not any special meta data. And if I bind it as meta data directly, ie (define-syntax my-fn 'something) then it works with syntax-local- value but any attempts to use it as a transformer result in illegal syntax.

Even if I create a transformer that returns a struct which implements both prop:procedure and prop:struct-info, using that binding with syntax-local-value will return the transformer procedure itself, rather than the final struct.



On Sun, Jan 19, 2014 at 8:04 PM, Carl Eastlund <carl.eastl...@gmail.com > wrote: Yes, I believe that the name of a structure defined by "struct" is bound at syntax-time to a value that implements both prop:procedure, so that it can expand to a use of the constructor when used in an expression, and prop:struct-info so that it can be use to look up static information when passed to relevant macros.

Carl Eastlund


On Sun, Jan 19, 2014 at 11:00 PM, Scott Klarenbach <sc...@pointyhat.ca> wrote: How is it that the definition of (struct my-name (x y)) can bind my- name both as a #<procedure:my-name> at runtime and a transformer- binding my-name that at compile time (via syntax-local-value) produces #<procedure:self-ctor-checked-struct-info>.?

Or, put another way, how can I define a transformer my-fn that produces syntax, but that also exposes hidden meta-data under the same binding to other macros that might wish to know about the binding at compile time?

I'm specifically wondering how the overloading works. Is it some clever use of prop:procedure?

Thanks.

--
Talk to you soon,

Scott Klarenbach

PointyHat Software Corp.
www.pointyhat.ca
p 604-568-4280
e sc...@pointyhat.ca
200-1575 W. Georgia
Vancouver, BC V6G2V3

_______________________________________
To iterate is human; to recur, divine

____________________
  Racket Users list:
  http://lists.racket-lang.org/users





--
Talk to you soon,

Scott Klarenbach

PointyHat Software Corp.
www.pointyhat.ca
p 604-568-4280
e sc...@pointyhat.ca
200-1575 W. Georgia
Vancouver, BC V6G2V3

_______________________________________
To iterate is human; to recur, divine




--
Talk to you soon,

Scott Klarenbach

PointyHat Software Corp.
www.pointyhat.ca
p 604-568-4280
e sc...@pointyhat.ca
200-1575 W. Georgia
Vancouver, BC V6G2V3

_______________________________________
To iterate is human; to recur, divine



--
Talk to you soon,

Scott Klarenbach

PointyHat Software Corp.
www.pointyhat.ca
p 604-568-4280
e sc...@pointyhat.ca
200-1575 W. Georgia
Vancouver, BC V6G2V3

_______________________________________
To iterate is human; to recur, divine

____________________
 Racket Users list:
 http://lists.racket-lang.org/users

____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to