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