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

Extend IPLD schema to support inline types #262

Open
Gozala opened this issue Jan 5, 2023 · 2 comments
Open

Extend IPLD schema to support inline types #262

Gozala opened this issue Jan 5, 2023 · 2 comments

Comments

@Gozala
Copy link

Gozala commented Jan 5, 2023

At the moment IPLD only supports inline definitions for

  • maps
  • lists
  • links

"InlineDefn": {
"union": {
"members": [
"TypeDefnMap",
"TypeDefnList",
"TypeDefnLink"
],
"representation": {
"keyed": {
"map": "TypeDefnMap",
"list": "TypeDefnList",
"link": "TypeDefnLink"
}
}
}
},

Which means you can not inline

  • variants a.k.a unions and enums
  • records a.k.a structs

Which seems like a good idea when schemas are authored by hand (because it encourages clear names and reuse), yet pretty unfortunate limitation when schemas are generated by programs.

Here is our concrete use case web3-storage/ucanto#107 we have UCAN + IPLD base RPC system, something along the lines of GraphQL. We would like a service to be able to describe it's protocol via IPLD schema, however there's no good way to name individual records and variants forcing use to either:

  1. Use some other schema (or perhaps an extension of IPLD schema).
  2. Enforce manual naming, which would both degrade library API and is prone to collisions (as host language won't help you there)
  3. Generate names from hashes (I actually like this approach, but it imposes asynchrony in JS which is not great)

Proposal

  1. Lift this limitation and allow inlining unions and structs in IPLD schema.
  2. Allow CID based referencing of types

That way we could simply generate schema with inline types defs and optionally optimize it by lifting inline definitions and referring to them via CIDs. That way type names simply become petnames and only for the convenience

@Gozala
Copy link
Author

Gozala commented Jan 5, 2023

Digging bit more into this, I see the note on why this limitation had been put in place

## UnionMemberInlineDefn is a very similar purpose to InlineDefn,
## but found specifically within UnionMember.
## It only allows describing a link type (and not maps nor lists, as InlineDefn does),
## which is a constraint applied to union membership largely to make sure
## if there are errors in processing unions, we can make legible messages about it!

## TypeNameOrInlineDefn also isn't used to describe members in Unions -- this is a choice
## aimed to limit syntactical complexity (both at type definition authoring
## time, as well as for the sake of error messaging during typechecking).

## InlineDefn should look *exactly the same* as the top-level type declarations...
## it's just that within an InlineDefn, we're restricted to a subset of the members.

It looks like my intuition about rational for this limitation was correct and it is mostly in place to make things (like schemas and validation errors) more readable. However I would argue that we could generate good error messages by specifying full path to the cause (in fact we do that already in the ucanto) which can be a lot more informative than messaging a (type), especially if those are generated.

That is to say I think IPLD schema could support inline types even if ipldsch syntax does not.

@RangerMauve
Copy link
Contributor

Could you post some examples of your "dream DSL/DMT" for what this would look like in practice? Maybe also what the error messages could look like VS what is there right now?

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