Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

any-wrap: avoid wrapping immutable structs with immutable fields #1333

Open
bennn opened this issue Jun 20, 2023 · 3 comments
Open

any-wrap: avoid wrapping immutable structs with immutable fields #1333

bennn opened this issue Jun 20, 2023 · 3 comments

Comments

@bennn
Copy link
Contributor

bennn commented Jun 20, 2023

When an immutable struct with immutable fields crosses an Any boundary, it shouldn't need a wrapper.

Example program (from #1332 ):

#lang typed/racket

(require/typed contract-profile
               (contract-profile-thunk (-> (-> Any) Any)))

(define-type Fighter Integer)
(define-type Pill Integer)
(struct interactive [{whose-turn : Symbol} {state : State}] #:prefab #:type-name Interactive)
(struct state [{fighters : [Listof Fighter]} {pills : {Listof Pill}}] #:prefab #:type-name State)

(define mk-state
  (let ((ff 0) (pp 0))
    (lambda ()
      (state
        (begin0 (list ff) (set! ff (+ 1 ff)))
        (begin0 (list pp) (set! pp (+ 1 pp)))))))

(define mk-interactive
  (let ((ww 'who))
    (lambda ()
      (interactive
        ww
        (mk-state)))))

(define NN (expt 10 4)) ;; higher value, slower runtime

(define ii*
  (for/list : (Listof Interactive) ((_kk : Natural (in-range NN)))
    (cast (cast (mk-interactive) Any) Interactive)))

(contract-profile-thunk
  (lambda ()
    (for ((ii (in-list ii*)))
      (define st (interactive-state ii))
      (+ (first (state-fighters st))
         (first (state-pills st))))))

The contract profile says 40% of the running time is contracts. But all the checks could happen outside the call to contract-profile-thunk.

For this to work, any-wrap.rkt will need to search through struct fields and the types inside.

(If Pill was a Boxof Integer, then the wrapper would be important.)

@samth
Copy link
Sponsor Member

samth commented Jun 20, 2023

Note that (a) substructures could add mutable fields (and TR's types don't currently track prop:sealed) and (b) functions are "mutable" in this sense.

@mfelleisen
Copy link

mfelleisen commented Jun 20, 2023 via email

@AlexKnauth
Copy link
Member

For any-wrap/c to avoid wrapping these, I don't see why TR's types not tracking prop:sealed should be relevant... any-wrap/c can use runtime reflection operations right?

The important thing would be making sure, at runtime, that a value known to be an instance of an immutable struct A, isn't actually an instance of a mutable struct B that inherits from A.

The 2nd return value of struct-info, skipped?, should be able to determine that, so it should only avoid wrapping it if skipped? is #false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants