[racket] using struct-copy with struct subtypes?

From: David Vanderson (david.vanderson at gmail.com)
Date: Tue Nov 18 00:31:08 EST 2014

I like 'copy-prefab-struct' better than my write/read hack.  Thanks!

On 11/17/2014 02:06 PM, Gustavo Massaccesi wrote:
> This version is only works with #:prefab, but don't use the string
> representation so it has less problems with strange values that don't
> have a good string representation:
>
> (define (copy-prefab-struct str)
>    (apply make-prefab-struct (vector->list (struct->vector str))))
>
>
> And this other version works with #:prefab and #:transparent structs
> (and some additional structs when you have the right inspector):
>
> (define (copy-struct str)
>    (define-values (str-struct-info _) (struct-info str))
>    (define str-maker (struct-type-make-constructor str-struct-info))
>    (apply str-maker (cdr (vector->list (struct->vector str)))))
>
>
> On the other hand, these versions do a sallow copy. Only the outer
> struct gets a new instance, it reuses the values of the fields.
> David's version also makes a new instance of all the fields (that are
> not "singletons" like 7, #t, ...).
>
> Gustavo
>
>
>
> On Mon, Nov 17, 2014 at 3:23 PM, David Vanderson
> <david.vanderson at gmail.com> wrote:
>> I ran into the same problem.  Since my structs are all #:prefab, I copy them
>> like this:
>>
>> (define (copy s)
>>    (read (open-input-string (with-output-to-string (lambda () (write s))))))
>>
>> Probably not the best, but works for me.
>>
>> Thanks,
>> Dave
>>
>>
>> On 11/17/2014 12:25 PM, Sam Tobin-Hochstadt wrote:
>>> Unfortunately, you can't really do this in a general way for structs.
>>>
>>> There are a couple possible solutions:
>>>    - use objects/classes and implement a `clone` or a `replace` method
>>>    - use generics, with a `clone` or `replace` generic function
>>>
>>> Sam
>>>
>>> On Mon, Nov 17, 2014 at 12:22 PM, Matthew Butterick <mb at mbtype.com> wrote:
>>>> This seems rudimentary, but I can't figure it out. `struct-copy` requires
>>>> you to specify the id of the struct type, like so:
>>>>
>>>> (define copied-struct (struct-copy struct-type-id instance-of-struct))
>>>>
>>>> The docs for struct-copy say "subtypes can be copied as if they were
>>>> supertypes, but the result is an instance of the supertype". [1]
>>>>
>>>> OK, but suppose I want the opposite behavior: I want to make a
>>>> struct-copying function that accepts instances of a supertype or subtype,
>>>> but outputs a struct that's the same type as the input instance (not the
>>>> supertype).
>>>>
>>>> Possible? Or not possible with structs, because that's what objects &
>>>> classes are for?
>>>>
>>>>
>>>> [1] http://docs.racket-lang.org/reference/struct-copy.html
>>>> ____________________
>>>>     Racket Users list:
>>>>     http://lists.racket-lang.org/users
>>> ____________________
>>>     Racket Users list:
>>>     http://lists.racket-lang.org/users
>>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users


Posted on the users mailing list.