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

How to get struct-type? #1783

Closed
zaoqi opened this issue Aug 26, 2017 · 14 comments
Closed

How to get struct-type? #1783

zaoqi opened this issue Aug 26, 2017 · 14 comments

Comments

@zaoqi
Copy link
Contributor

zaoqi commented Aug 26, 2017

(struct-type-of v) → (or/c struct-type? #f)
Returns #f if (struct? v) is #f

@shhyou
Copy link
Collaborator

shhyou commented Aug 26, 2017

@zaoqi
Copy link
Contributor Author

zaoqi commented Aug 26, 2017

@shhyou

> (struct s (v))
> (struct-info (s 0))
#f
#t
> 

@bennn
Copy link
Contributor

bennn commented Aug 26, 2017

Right, but you need a more powerful inspector:

#lang racket/base

(struct s (v) #:inspector (make-inspector))
(struct-info (s 0))
;; #<struct-type:s>
;; #f

The page @shhyou linked to explains inspectors:
https://docs.racket-lang.org/reference/inspectors.html

@zaoqi
Copy link
Contributor Author

zaoqi commented Aug 26, 2017

@bennn How do I change a defined structure?

@bennn
Copy link
Contributor

bennn commented Aug 26, 2017

I'm not sure what you mean.

Do you want to get the struct type of a struct that's defined in another file & doesn't use #:inspector ? I'm not sure how to do that. If you could:

  1. save (current-inspector)
  2. set (current-inspector (make-inspector))
  3. evaluate the struct definitions

then it'd be possible to use the saved inspector with struct-type. But I really don't know how to do step 3.

@jackfirth
Copy link
Sponsor Contributor

jackfirth commented Aug 26, 2017

If you're using a #:transparent struct instead of an opaque one, you don't need a more powerful inspector:

> (struct s (v) #:transparent)
> (struct-info (s 0))
#<struct-type:s>
#f

If your struct isn't transparent, you probably shouldn't be reflecting over it with struct-type unless you're making something like a debugger or other program instrumentation tool. But if you are, using a more powerful inspector is a reasonable approach.

@zaoqi
Copy link
Contributor Author

zaoqi commented Aug 27, 2017

I'm implementing a DSL that needs to compare the two struct types.

@zaoqi
Copy link
Contributor Author

zaoqi commented Aug 27, 2017

@bennn

> (current-inspector (make-inspector))
> (struct x (a))
> (x 0)
#<x>
> (struct-info (x 0))
#f
#t
> 

@mflatt
Copy link
Member

mflatt commented Aug 27, 2017

@zaoqi Here's how to do steps 1 and 4 in @bennn's suggestion:

> (define insp (current-inspector))
> (current-inspector (make-inspector))
> (struct x (a))
> (struct-info (x 0))
#f
#t
> (parameterize ([current-inspector insp])
     (struct-info (x 0)))
#<struct-type:x>
#f

@shhyou
Copy link
Collaborator

shhyou commented Aug 27, 2017

@zaoqi Why not just use #:transparent for your structs?

@shhyou
Copy link
Collaborator

shhyou commented Aug 27, 2017

Or perhaps provide your own struct to the user in the library

@zaoqi
Copy link
Contributor Author

zaoqi commented Aug 28, 2017

@shhyou Can I redifine struct?

@shhyou
Copy link
Collaborator

shhyou commented Aug 28, 2017

Something like this (simply shadows the struct binding from #lang)

; my-lib.rkt
#lang racket
(provide (rename-out [my-struct struct]))
(define-syntax my-struct
  (syntax-rules ()
    [(_ x ...) (struct x ... #:transparent)]))
#lang racket
(require "my-lib.rkt")
(struct x ())
(struct-info (x))

@zaoqi
Copy link
Contributor Author

zaoqi commented Aug 28, 2017

@shhyou

(define (struct-type-eq? x y)
  (let-values ([(tx _x) (struct-info x)] [(ty _y) (struct-info y)])
    (equal? tx ty)))

Can I define it like this?

@zaoqi zaoqi closed this as completed Aug 30, 2017
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

5 participants