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

Clarify whether repeated type references are allowed for the sum-type constraints #53

Closed
popematt opened this issue Oct 29, 2021 · 1 comment
Labels
requires new version Something that should be considered for next version of the Ion Schema Specification

Comments

@popematt
Copy link
Contributor

popematt commented Oct 29, 2021

The spec defines the behavior of the sum-type constraints (one_of, any_of, all_of) in terms of Types, without any particular mention of the behavior in relation to TYPE_REFERENCEs (ie. the grammar of the constraint argument). This is a non-obvious distinction, but I think most people would instantly be familiar with it when framed a different way.

// An example based on some classic parenting humor
// When your child doesn't like the response you gave and asks for another option...
type::{
  name: things_to_do_when_it_is_bedtime,
  any_of: [
    /*1*/ go_to_bed,
    /*2*/ go_to_bed,
  ]
}

There are two choices (type references) presented here, but they point to the same thing (type).

The Ion Schema spec does not mention whether the type references may be repeated or how an implementation should handle a repeated type reference for one of these constraints.

As of ion-schema-kotlin-1.1, the schema system will allow you to repeat a type reference in the argument for all_of, one_of, and any_of . For example, in the ion-schema-kotlin implementation, both of these are valid type definitions:

type::{
  name: car_or_truck_1,
  any_of: [
    car,
    truck,
  ]
}

type::{
  name: car_or_truck_2,
  any_of: [
    car,
    truck,
    car,
    truck,
  ]
}

In this case, they are functionally equivalent in ion-schema-kotlin. It would also be functionally equivalent to do the same thing with all_of. However, repeated type references in one_of actually lead to unsatisfiable conditions in ion-schema-kotlin. For example:

type::{
  name: train_or_truck,
  one_of: [
    train,
    train,
    truck
  ]
}

type::{
  name: car_or_boat,
  one_of: [
    car,
    boat,
    car,
    boat
  ]
}

In this case, train_or_truck will only be satisfied if the value matches truck—if it were to match train it would match two type references and be invalid for the one_of constraint. The type car_or_boat is completely unsatisfiable because all values will match either 0 or 2 of the type references (or 4 type references if it's an Amphicar).

So, for any_of and all_of, repeated type references are redundant but harmless, whereas for one_of they change the satisfiability of the constraint.

Why does this matter?
There is no legitimate use case for having repeated type references in any of these three constraints, so if someone is adding repeated type references to one of these constraints, they have made a mistake. Since it is always considered a mistake, something should be done to prevent or mitigate this mistake, especially in the case of one_of.

The spec should be updated to say that the argument for the sum-type constraints is a set of type references, but that it's modeled as a list because Ion does not have any set type. In addition, the spec should...

  1. state that repeated type references are not allowed and require that schema systems throw an exception (or issue a warning) if repeated type references occur for the sum-type constraints
  2. OR state that repeated type references are allowed and require schema systems to deduplicate list elements when loading a schema
@popematt popematt added the requires new version Something that should be considered for next version of the Ion Schema Specification label Dec 15, 2021
@popematt
Copy link
Contributor Author

popematt commented Apr 4, 2022

Given that there can be two aliases for the same type or two types with different definitions that have the same effect, it would be nearly impossible to cover all cases here. Determining conclusively if any two arbitrary types are equivalent is not practical since the problem is at least in PSPACE, so it makes more sense for this to be a best-effort linter rule for #60.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
requires new version Something that should be considered for next version of the Ion Schema Specification
Projects
None yet
Development

No branches or pull requests

1 participant