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

Support methods for runtime struct creation #2142

Closed
pmatos opened this issue Jun 18, 2018 · 2 comments
Closed

Support methods for runtime struct creation #2142

pmatos opened this issue Jun 18, 2018 · 2 comments

Comments

@pmatos
Copy link
Collaborator

pmatos commented Jun 18, 2018

When creating new struct types at runtime using make-struct-type at the moment it doesn't seem to be possible to define generic methods on it (half-confirmed by @samth on Slack).

This is a serious shortcoming on anyone relying on generic methods to design interfaces. Can we get this supported?

I have noticed that in:

[(eq? '#:methods (syntax-e (car p)))

#:methods seem be converted into #:property using some syntax like generic-property which is not exported. Can we a new methods argument in make-struct-type that uses this internally to transform the methods into properties?

@LiberalArtist
Copy link
Contributor

The problem with what you suggest is that make-struct-type is a plain function that evaluates its arguments. The #:methods block uses scope in some fairly nuanced and, from the sound of it, brittle ways. Just writing the contents of a #:methods block as general runtime definitions/expressions would not produce the value needed for the internal struct-type property for the generic interface, and it would not follow the scoping rules for a #:methods block.

You'll also note that this addresses only the value half of the syntax property. An identifier like gen:dict is bound to compile-time information and is not an expression: struct extracts syntax for the internal struct-type property from the compile-time information. By doing this in #:methods, the library enforces the invariant that the methods table go with the right property statically. I don't know what would be involved in trying to check this at runtime.

There's some discussion at #1647 about providing a public interface for third-party libraries to do this sort of thing, but there wasn't consensus that it should be done, and I don't know that there's been any movement on it.

More broadly, make-struct-type is rather low-level. I believe it is only needed if you need to create a struct type not only at runtime (all non-prefab struct types are created at runtime, or the runtime of the phase at which they exist), but dynamically, e.g. when the number of fields in the struct must be computed at runtime.

Even in that rare case, I believe you could use make-struct-type to dynamically create a struct type with the right shape, then use it as the supertype for a struct form that adds no additional fields but attaches a generic interface with #:methods, and returns only the struct type created by struct. That would seem to give you all of the dynamic expressiveness that could possibly be supported without very significant changes to the design of the racket/generic library.

@pmatos
Copy link
Collaborator Author

pmatos commented Jun 19, 2018

@LiberalArtist Thanks for the very detailed explanation of the issue and the reference to #1647. I will go ahead and close this, which in any case is a duplicate.

I noticed to my surprise that struct can be used within a functions scope, which is what I needed and what I thought make-struct-type was supposed to provide.

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

2 participants