[racket] Struct fields in struct-info + match enhancements
Here's my suggestion:
- We add an `extract-extended-struct-info` procedure which always
produces a struct that implements `prop:struct-info` (it's easy to use
a simply struct to wrap the list when needed)
- We change `struct` & `define-struct` to use a structure implementing
`prop:struct-info`, but with an additional field holding the list you
want (or perhaps this should be a new structure property)
- When `match` encounters a struct reference, it uses
`extract-extended-struct-info`, checks if it's an instance of this
extended struct, and if it is, uses that info.
- When `match` encounters a struct reference that doesn't support the
new behavior, the sort of keyword syntax you describe is a syntax
error.
I think this (a) preserves backwards compatibility (b) supports future
extension (c) accomplishes what you need.
Sam
On Wed, May 14, 2014 at 1:08 PM, J. Ian Johnson <ianj at ccs.neu.edu> wrote:
> I'm talking about the transformer binding. Specifically the result of extract-struct-info that both struct-copy and match use in their expansion, which produces a six-element list that satisfies struct-info?.
> This six-element list has
> optional identifier bound to type descriptor
> optional identifier bound to type constructor
> optional identifier bound to type predicate
> list of field accessor identifiers (optional last value of #f)
> list of optional field mutator identifiers
> optional super type identifier
>
> I want a 7th element that is the list of field identifiers themselves as given to the struct form or the define-signature form (which I believe produces the expected struct-info transformer binding, so I don't have to actually change define-signature). The expectation is that the field names and the field accessor names correspond 1-to-1.
>
> 7 is not 6, thus backwards-incompatible.
> I know many programs use positional accessors rather than match on the whole structure of the list, so I imagine adding a 7th element is not very intrusive.
> -Ian
> ----- Original Message -----
> From: "Sam Tobin-Hochstadt" <samth at cs.indiana.edu>
> To: "J. Ian Johnson" <ianj at ccs.neu.edu>
> Cc: "users" <users at racket-lang.org>
> Sent: Wednesday, May 14, 2014 12:42:56 PM GMT -05:00 US/Canada Eastern
> Subject: Re: [racket] Struct fields in struct-info + match enhancements
>
> On Wed, May 14, 2014 at 12:35 PM, J. Ian Johnson <ianj at ccs.neu.edu> wrote:
>> tl;dr if you use struct-info in your programs, I might break them. Please continue reading.
>>
>> I had a PR a while ago suggesting a change to struct-copy due to its unhygienic nature with fields. It did not go through since there wasn't enough information in the struct-info to separate the struct-name and the field-name. Because struct-info does not have a procedural-only interface, changing it to instead or also hold the individual field identifiers would be backwards incompatible. However, I also expect that struct-info manipulation outside of core Racket is rare.
>>
>> Is there anyone out there that would be affected by a this change that would be unwilling to make slight modifications to support the new struct-info?
>> I ask not because of struct-copy itself, but for an additional enhancement to racket/match: named field selection from structs instead of positional only.
>> I'm getting bitten by pervasive refactoring woes whenever I add fields to structs. All of my match patterns must change to have an extra _ somewhere.
>
> I don't understand why this would require a backwards-incompatible
> change to struct-info.
>
> Also, this discussion is confusing because it's not clear whether you
> mean the dynamic value produced by the `struct-info` procedure, or the
> structure type transformer binding. I think you mean the latter, in
> which case I expect you could do what you want by implementing
> `prop:struct-info` appropriately with an extended structure, and
> handling existing values (such as six-element lists) appropriately
> with defaults.
>
> Sam