Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a copy of an instance in Racket?

Tags:

object

racket

Suppose that I have an instance of a class,

  1. How do a make a separate, identical instance?
  2. Is there an easy syntax for overriding the initialization arguments in this copy?

Something like this:

(define a (new A% [:x 1] [:y 2] )) ;; A's have two fields initiaized at construction
(define b (copy a)) ;; just make an independent copy
(define c (copy a [:y 4])) ;; copy but override one (or more) initialization argument.

Neither chapters 6 nor 13 of the online documentation seem to cover these use-cases.

like image 263
Dave Avatar asked Oct 23 '25 17:10

Dave


1 Answers

define does not make copies of class instances, but only a copy of the reference, just like for structs. For example:

#lang racket

(define A% 
  (class object%
    (init-field a)
    (super-new)))

(define a1 (new A% [a 6]))
(define a2 a1)
(get-field a a1) ; 6
(get-field a a2) ; 6
(set-field! a a2 2)
(get-field a a2) ; 2
(get-field a a1) ; 2

which means that (define a2 a1) actually makes a copy of the reference, just like for structs.

The usual way to make copies for classes is to implement a clone method (that can be refined in subclasses). It is then easy to have default arguments:

#lang racket

(define B%
  (class object%
    (init-field b)
    (define/public (clone #:b [b b])
      (new B% [b b]))
    (super-new)))

(define b1 (new B% [b 3]))
(define b2 (send b1 clone))
(define b3 (send b1 clone #:b 5))
(get-field b b1) ; 3
(get-field b b2) ; 3
(get-field b b3) ; 5
(set-field! b b1 4)
(get-field b b1) ; 4
(get-field b b2) ; 3
(get-field b b3) ; 5
like image 146
Metaxal Avatar answered Oct 26 '25 15:10

Metaxal