Re: [racket-dev] struct + match not interacting via a macro
And if it isn't clear, since it is looking at foo's static binding, your macro is only binding the values from define-struct, not the syntaxes. Jay On Sun, Oct 9, 2011 at 6:39 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Sun, Oct 9, 2011 at 8:31 PM, Shriram Krishnamurthi s...@cs.brown.edu wrote: What exactly does the struct form of match (in the ASL language) use to identify the structure? The following works fine: I'm not sure if ASL's match is the same as the one in `racket/match', but almost certainly it's using the static struct info bound by to `foo' by `define-struct'. You can see the documentation about that here: http://docs.racket-lang.org/reference/structinfo.html -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev -- Jay McCarthy j...@cs.byu.edu Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay The glory of God is Intelligence - DC 93 _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] struct + match not interacting via a macro
On Mon, Oct 10, 2011 at 8:13 AM, Jay McCarthy jay.mccar...@gmail.com wrote: And if it isn't clear, since it is looking at foo's static binding, your macro is only binding the values from define-struct, not the syntaxes. Jay, can you elaborate? What is doing the looking -- the match struct clause? What does it mean to look at foo's static binding? I understand that my macro is binding only the values, not the original syntaxes (other than foo itself, which is carried through from the user's source). The name struct:foo here is completely synthetic because it's being introduced by build-struct-names. Is that what you're referring to? In that case, does writing such a macro require an explicit breaking of hygiene? Shriram _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] struct + match not interacting via a macro
One of the bindings that (define-struct foo (a b) #:transparent #:mutable) binds is 'foo', and it is bound the static information about the structure, basically: (define-syntax foo (list #'make-foo #'foo? (list #'foo-a #'foo-b) (list #'set-foo-a! #'set-foo-b!))) (But not exactly right because there's some other information. See around 'struct-info' in the docs.) When you write (match ... [(struct foo (... ...)) ...]) the static binding for 'foo' is inspected (using syntax-local-value) to get that static information so it knows to use foo? and foo-a and foo-b for the pieces. In the case of your macro, (begin (define-values (foo struct:foo make-foo foo? foo-a set-foo-a! foo-b set-foo-b!) (let () (begin (define-struct foo (a b) #:transparent #:mutable) (let ([make-foo (lambda (a b) ...)] [set-foo-a! (lambda (struct-inst new-val) ...)] [set-foo-b! (lambda (struct-inst new-val) ...)]) (values foo struct:foo make-foo foo? foo-a set-foo-a! foo-b set-foo-b!)) You are binding foo, but you are only binding it as a *value* rather than as *syntax*. So when match see the (struct foo ...) clause, it sees that foo has no static binding and thus says that no such struct exists. You would have to expand to something that includes both the static and runtime pieces: (begin (define-values ( ... ) ... ) (define-syntaxes ( ... ) ... )) But that's going to be difficult because ideally you'd just use the static binding that define-struct sets up. One approach would be to put the define-struct at the top-level but with altered names that you control: (begin (define-struct foo* (a b) ...) (define-syntax foo foo*) (define (make-foo ...) (make-foo* ... )) etc) So that you could still add whatever you're adding. The define-type macro in PLAI does this (although it doesn't make the structs compatible with match.) Jay On Mon, Oct 10, 2011 at 6:24 AM, Shriram Krishnamurthi s...@cs.brown.edu wrote: On Mon, Oct 10, 2011 at 8:13 AM, Jay McCarthy jay.mccar...@gmail.com wrote: And if it isn't clear, since it is looking at foo's static binding, your macro is only binding the values from define-struct, not the syntaxes. Jay, can you elaborate? What is doing the looking -- the match struct clause? What does it mean to look at foo's static binding? I understand that my macro is binding only the values, not the original syntaxes (other than foo itself, which is carried through from the user's source). The name struct:foo here is completely synthetic because it's being introduced by build-struct-names. Is that what you're referring to? In that case, does writing such a macro require an explicit breaking of hygiene? Shriram -- Jay McCarthy j...@cs.byu.edu Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay The glory of God is Intelligence - DC 93 _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] struct + match not interacting via a macro
I'm afraid omit-defined-values didn't work. I'm not entirely sure how to carry through Jay's proposal, and I also need something that will work inside the local context of ASL (which imposes some restrictions). Joe Politz suggested I just go with SET! instead -- roughly, -- (begin (define-struct ...) (set! ...)) which can be made to work in a local context -- -- (begin (define-struct ...) (set! dummy ...)) and so on, but now local is trying to parse the define-struct, and doesn't like #:mutable, and removing that means that the name of the mutator appears to Racket to be unbound because of hygiene. Let's see what else I can do! Shriram _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] struct + match not interacting via a macro
Ya, that sounds much better On Mon, Oct 10, 2011 at 7:19 AM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Mon, Oct 10, 2011 at 8:38 AM, Jay McCarthy jay.mccar...@gmail.com wrote: You would have to expand to something that includes both the static and runtime pieces: (begin (define-values ( ... ) ... ) (define-syntaxes ( ... ) ... )) But that's going to be difficult because ideally you'd just use the static binding that define-struct sets up. One approach would be to put the define-struct at the top-level but with altered names that you control: Another approach that might work is to use the `#:omit-define-values' keyword with regular `racket/base' `define-struct': #lang racket (define (make-foo . args) args) (define foo? list?) (define (foo-x v) (car v)) (define (foo-y v) (cadr v)) (define-struct foo (x y) #:omit-define-values) (match (make-foo 1 2) [(struct foo (x y)) (+ x y)]) -- sam th sa...@ccs.neu.edu -- Jay McCarthy j...@cs.byu.edu Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay The glory of God is Intelligence - DC 93 _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] struct + match not interacting via a macro
Wait, now I realize I misunderstood Sam's proposal. Doesn't this just make all structs into lists? Like back to the bad old days of 1995? _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] struct + match not interacting via a macro
On Mon, Oct 10, 2011 at 9:42 AM, Shriram Krishnamurthi s...@cs.brown.edu wrote: Wait, now I realize I misunderstood Sam's proposal. Doesn't this just make all structs into lists? Like back to the bad old days of 1995? No, that was just an example of how to define the `make-foo', `foo-x', etc functions. More sensible definitions should work too. The runtime meaning of the functions should be irrelevant. -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
[racket-dev] struct + match not interacting via a macro
What exactly does the struct form of match (in the ASL language) use to identify the structure? The following works fine: (define-struct foo (a b)) (match (make-foo 1 2) [(struct foo (x y)) (+ x y)]) But I have a macro over define-struct for which I get the error match: foo does not refer to a structure definition in: foo (pointing at the foo in struct foo (x y)). My macro uses build-struct-names to synthesize the names of the constructor, selectors, etc. It binds all these names (including the struct:foo name); for good measure I'm also binding foo. The coloring in the Macro Stepper isn't instructive (to me, anyway -- there is only one step of reduction before the error). Here is the sample output (... elides irrelevant detail): (define-struct: foo ([a : Number$] [b : Number$])) -- (begin (define-values (foo struct:foo make-foo foo? foo-a set-foo-a! foo-b set-foo-b!) (let () (begin (define-struct foo (a b) #:transparent #:mutable) (let ([make-foo (lambda (a b) ...)] [set-foo-a! (lambda (struct-inst new-val) ...)] [set-foo-b! (lambda (struct-inst new-val) ...)]) (values foo struct:foo make-foo foo? foo-a set-foo-a! foo-b set-foo-b!)) Any ideas? Shriram _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] struct + match not interacting via a macro
On Sun, Oct 9, 2011 at 8:31 PM, Shriram Krishnamurthi s...@cs.brown.edu wrote: What exactly does the struct form of match (in the ASL language) use to identify the structure? The following works fine: I'm not sure if ASL's match is the same as the one in `racket/match', but almost certainly it's using the static struct info bound by to `foo' by `define-struct'. You can see the documentation about that here: http://docs.racket-lang.org/reference/structinfo.html -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev