On Mon, Jan 20, 2014 at 6:49 PM, Scott Klarenbach <sc...@pointyhat.ca> wrote: >> Using a binding that carries everything with it, or using a syntax-time >> hash table that carries out of band data that can be looked up based on the >> original binding, is reliable. > > > Good point, Sam made it at the same time. :) > > Wouldn't a syntax-time hash-table introduce problems as well since there's > no guarantee it gets copied over either?
There are techniques for managing syntax-time state such as hash tables to make this work better [1], but as you say, this is trickier. That's why when it's possible, it's basically always better to go with binding information. That's why `struct` works the way it does. [1] See the papers "You want it when" by Matthew, or "Languages as Libraries" by a bunch of us for more on these techniques. Sam > > > > On Mon, Jan 20, 2014 at 3:35 PM, Carl Eastlund <carl.eastl...@gmail.com> > wrote: >> >> But there's no guarantee that if someone imports the original name >> somewhere, renames it somehow, etc., that they'll copy over a <name>-META >> binding as well. Using a binding that carries everything with it, or using >> a syntax-time hash table that carries out of band data that can be looked up >> based on the original binding, is reliable. Using an extra binding that >> _should_ be there in most namespaces, can be broken by contexts you have no >> control over. >> >> Carl Eastlund >> >> >> On Mon, Jan 20, 2014 at 6:31 PM, Scott Klarenbach <sc...@pointyhat.ca> >> wrote: >>>> >>>> If/when it does matter, instead you could use a hashtable on the side, >>>> mapping from the procedure to the info. Of course that way, you need >>>> to use `(lookup thing)` to get the info. >>> >>> >>> Not to mention that it's vastly simpler to do it this way. You get a >>> straightforward transformer proc and a hashtable bound as syntax. >>> >>> This is partly a learning exercise for me - so it's valuable to go >>> through - but the more I look at it the more I think it's a lot of >>> complexity just to be able to overload the struct name, when it would >>> suffice for match and other macros that wanted compile-time meta info to >>> follow a convention like struct-name-META or something. Afterall, structs >>> already come with a lot of magical bindings that you have to learn by >>> convention, what's one more? >>> >>> Just my two cents. >>> >>> sk >>> >>> >>> On Mon, Jan 20, 2014 at 1:41 PM, <users-requ...@racket-lang.org> wrote: >>>> >>>> Send users mailing list submissions to >>>> users@racket-lang.org >>>> >>>> To subscribe or unsubscribe via the World Wide Web, visit >>>> http://lists.racket-lang.org/users/listinfo >>>> or, via email, send a message with subject or body 'help' to >>>> users-requ...@racket-lang.org >>>> >>>> You can reach the person managing the list at >>>> users-ow...@racket-lang.org >>>> >>>> When replying, please edit your Subject line so it is more specific >>>> than "Re: Contents of users digest..." >>>> >>>> >>>> [Racket Users list: >>>> http://lists.racket-lang.org/users ] >>>> >>>> >>>> Today's Topics: >>>> >>>> 1. Re: Structs and syntax-local-value ... how is the struct name >>>> overloaded? (Carl Eastlund) >>>> 2. Re: Structs and syntax-local-value ... how is the struct name >>>> overloaded? (Greg Hendershott) >>>> >>>> >>>> ---------------------------------------------------------------------- >>>> >>>> Message: 1 >>>> Date: Mon, 20 Jan 2014 13:00:35 -0500 >>>> From: Carl Eastlund <carl.eastl...@gmail.com> >>>> To: "Alexander D. Knauth" <alexan...@knauth.org> >>>> Cc: Scott Klarenbach <sc...@pointyhat.ca>, Racket mailing list >>>> <users@racket-lang.org> >>>> Subject: Re: [racket] Structs and syntax-local-value ... how is the >>>> struct name overloaded? >>>> Message-ID: >>>> >>>> <CAEOPtY09_5EUFpOn6uYBcJAB+TXTdDk=EK-DUHbLU2wu=xz...@mail.gmail.com> >>>> Content-Type: text/plain; charset="utf-8" >>>> >>>> Yes, that's exactly it. >>>> >>>> Carl Eastlund >>>> >>>> >>>> On Mon, Jan 20, 2014 at 10:13 AM, Alexander D. Knauth >>>> <alexan...@knauth.org>wrote: >>>> >>>> > 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 >>>> > >>>> > >>>> > >>>> -------------- next part -------------- >>>> An HTML attachment was scrubbed... >>>> URL: >>>> <http://lists.racket-lang.org/users/archive/attachments/20140120/1cbff376/attachment-0001.html> >>>> >>>> ------------------------------ >>>> >>>> Message: 2 >>>> Date: Mon, 20 Jan 2014 16:40:56 -0500 >>>> From: Greg Hendershott <greghendersh...@gmail.com> >>>> To: users@racket-lang.org >>>> Subject: Re: [racket] Structs and syntax-local-value ... how is the >>>> struct name overloaded? >>>> Message-ID: >>>> >>>> <CAGspUn3DeoWR7Qfw=uPamDuV+6ig9asRt=-dcajh+uvibbt...@mail.gmail.com> >>>> Content-Type: text/plain; charset=ISO-8859-1 >>>> >>>> >> and prop:procedure is how you make a procedure that can also be >>>> >> something >>>> >> else. >>>> >>>> One thing to keep in mind is that there is _some_ overhead. In my >>>> recent experience, applying via prop:procedure took roughly 1.6X the >>>> time as applying a plain procedure. (This with the variant of >>>> prop:procedure where its value is an index to the field in the struct >>>> holding the procedure.) >>>> >>>> I don't know how much of the extra time is due to memory reference, >>>> missing the optimizer, and/or other? >>>> >>>> For many applications that doesn't matter, and it's worth it to have >>>> `thing` self-evaluate to the info. >>>> >>>> If/when it does matter, instead you could use a hashtable on the side, >>>> mapping from the procedure to the info. Of course that way, you need >>>> to use `(lookup thing)` to get the info. >>>> >>>> >>>> End of users Digest, Vol 101, Issue 60 >>>> ************************************** >>> >>> >>> >>> >>> -- >>> 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 > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > ____________________ Racket Users list: http://lists.racket-lang.org/users