[racket] struct-copy with parent type

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Mon May 27 13:34:15 EDT 2013

On Fri, May 24, 2013 at 1:37 PM, Nick Shelley <nickmshelley at gmail.com> wrote:
> Thanks Jay.
>
> So with the generics approach I would just create a gen-struct-copy with the
> same signature as struct-copy, then the implementation of gen-struct-copy in
> each of my structs would just call struct-copy with the correct struct-id.
> Is that the right approach?

A generic can't be a macro, so really you'd have some explicit like a
"posn-update-x" function in the generic.

> Also, is there a way to introspect the struct-id if the struct is
> transparent? Something like:
>
> (define p (3posn 1 2 3))
> (struct-copy (struct-id p) p [x #:parent posn 5])
>
> This obviously wouldn't work if p was a posn, but in my use case, the parent
> class is abstract so I know I'm getting child classes. I scanned through
> some of the struct docs, but couldn't find a way to introspect a struct
> type.

It's possible to do something like what you want, but I wouldn't
recommend it because there's no way to recover the names of the fields
at runtime. You can just know how many there are. For example:


>
> On Fri, May 24, 2013 at 1:16 PM, Jay McCarthy <jay.mccarthy at gmail.com>
> wrote:
>>
>> On Fri, May 24, 2013 at 11:18 AM, Nick Shelley <nickmshelley at gmail.com>
>> wrote:
>> > The struct-copy docs say "The result of struct-expr can be an instance
>> > of a
>> > sub-type of id, but the resulting copy is an immediate instance of id
>> > (not
>> > the sub-type)." Why is this?
>>
>> The technical reason this is the case is that in (struct-copy <struct>
>> ... ...) the <struct> binding describes the fields of the structure
>> and gives access to the constructor. Thus, in your example code, you
>> are saying "copy this posn" and not "copy this thing and modify the
>> posn pieces". You could imagine that we could create a link between
>> parent and sub-structures, but it would be messy and imperative, in my
>> mind.
>>
>> Alternatively, you could make a version that lists the possible
>> children directly:
>>
>>
>> https://github.com/jeapostrophe/exp/blob/cf6822f41c7637d9074638d0e9b4d4d2d7d27d7b/struct-copy-ish.rkt
>>
>> Alternatively, you could use generics
>>
>> > For instance, I would hope this would work:
>> >
>> > (struct posn (x y))
>> > (struct 3d-posn posn (z))
>> > (3d-posn-z (struct-copy posn (3d-posn 1 2 3) [x 5]))
>> >
>> > My actual use case is that I'm representing some data with structs. I
>> > have
>> > the common data in a parent struct and the specific data in the child
>> > structs. One of the common fields is a unique id (a number I just
>> > increment). I'd like to be able to copy a piece of data and just change
>> > the
>> > unique id in the struct-copy. Instead I have to have a cond or a match
>> > that
>> > does the same struct-copy but with different struct ids for each sub
>> > type.
>> >
>> > Is there an easier way to do what I'm trying to do?
>> >
>> > ____________________
>> >   Racket Users list:
>> >   http://lists.racket-lang.org/users
>> >
>>
>>
>>
>> --
>> Jay McCarthy <jay at cs.byu.edu>
>> Assistant Professor / Brigham Young University
>> http://faculty.cs.byu.edu/~jay
>>
>> "The glory of God is Intelligence" - D&C 93
>
>



--
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93

Posted on the users mailing list.