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

Are recursive types supported? #40

Open
rulatir opened this issue Jan 17, 2021 · 5 comments
Open

Are recursive types supported? #40

rulatir opened this issue Jan 17, 2021 · 5 comments

Comments

@rulatir
Copy link

rulatir commented Jan 17, 2021

Is it possible to define a type e.g. "segment" that is either a string, a number, or an array of segments (recursive definition)? If not, please consider it a feature request.

Something like:

const segment = ducktype.indirect();
segment.that = ducktype(String, Number, [segment]);

or even:

const segment = ducktype.recursive(self => ducktype(String, Number, [self]));

Basically I need to validate that all "leaves" of a non-flat array are of a particular union type. I cannot flatten the array before validating because it is nested in a bigger data structure that I want to validate as a whole (as opposed to picking these arrays out of it for flattening and validation), and the nesting structure within the array is meaningful.

@josdejong
Copy link
Owner

Thanks for your suggestion @rulatir .

I'm not sure whether I understand you correctly, but creating circular references in your data model doesn't sound as something you should do in general. Can you explain your use case a bit more?

@rulatir
Copy link
Author

rulatir commented Jan 18, 2021

My use case is something like a parse tree of an arbitrarily deeply nested expression. It is impossible to express actual cyclic references in the DSL, so there is no risk that an object containing cyclic references would be passed to a validator of a self-referential type. My proposal would allow specifying the type of an object that might directly or indirectly refer to or contain other objects of the same type. I understand that a naïve implementation of such a validator will choke on actual reference cycles, but sometimes it is guaranteed that this will never be the case.

@josdejong
Copy link
Owner

I think you're right. Would be neat indeed to support recursive types.

I do like your second proposal a lot, this looks very clean:

ducktype.recursive(self => ducktype(String, Number, [self]));

Would you be interested in creating a pull request for this?

@rulatir
Copy link
Author

rulatir commented Jan 20, 2021

I already have a naïve implementation working, but I have reservations about offering this footgun to the public; not without a clear warning in the docs, that goes without saying.

I'm thinking about the feasibility of cycle checking. A DFS variant capable of detecting/avoiding cycles requires passing some shared context around, so it would be a major change in the algorithm.

@josdejong
Copy link
Owner

Sounds good 👍

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

No branches or pull requests

2 participants