Skip to content

Validation: if/then/else #180

Closed
Closed
@epoberezkin

Description

@epoberezkin

This can be seen as the extension of #31 and #64. I see it as the syntax sugar for existing boolean/compound keywords.

The validation process is very simple:

  • if the schema in if is valid, than the schema in then should be validated and its outcome determines the instance validation.
  • if the schema in if is invalid then the schema in else should be validated and its outcome determines the instance validation.
  • if if is not present then the schema itself is invalid (metaschema validation will fail).
  • if neither then nor else is present - the same as above

As I've written in some issue the schema with if/then/else:

{
  "if": {"$ref": "condition" },
  "then": {"$ref": "schema1"},
  "else": {"$ref": "schema2"}
}

is a boolean operation and it is equivalent to the schema below that is possible now:

{
  "anyOf": [
    { "allOf": [ {"$ref": "condition" }, {"$ref": "schema1"} ] },
    { "allOf": [ {"not": {"$ref": "condition" } }, {"$ref": "schema2"} ] }
  ]
}

so if/then/else is as declarative as existing keywords but it provides a more convenient, clear and performance efficient alternative ("condition" will never be validated twice) for a quite common validation scenario.

Using if/then/else the problem in #31/#64 is also solved.

Activity

handrews

handrews commented on Dec 5, 2016

@handrews
Contributor

so if/then/else is as declarative as existing keywords

While Wikipedia is not always the best resource, this article is well-cited and the following definition is what I usually hear for declarative programming:

In computer science, declarative programming is a programming paradigm—a style of building the structure and elements of computer programs—that expresses the logic of a computation without describing its control flow.

So if/then/else is by definition not declarative. The distinction between declarative and imperative is control flow. If/then/else is control flow. Imperative vs declarative has nothing to do with whether the outcome is the same- all programming styles can produce the same output. It's about how things are processed.

It is certainly worth discussing if we want to add this imperative construct to JSON Schema, but it is the very definition of an imperative construct.

changed the title [-]v7 validation: if/then/else[/-] [+]Validation: if/then/else[/+] on Dec 5, 2016
epoberezkin

epoberezkin commented on Dec 5, 2016

@epoberezkin
MemberAuthor

I am not sure why implication is more imperative than and/or/negation - they are all operations from boolean algebra. The fact that the evaluation of implication can be short-circuited (i.e. when "if" is false then "then" doesn't need to be evaluated) desn't make it more imperative than "and" and "or" - they also can be short-circuited.

Also there are languages that use if/then/else as expression, not as a control flow statement. If you don't like the keywords, some other can be used.

Please see this article: https://en.wikipedia.org/wiki/Material_conditional

I am talking about boolean operation p => q (ignoring else here for simplicity, as it is an additional sugar really) which has the following truth table:

p q p=>q
False False True
False True True
True False False
True True False

What makes you think it to be more imperative than and/or/xor/not that we alreay have?

epoberezkin

epoberezkin commented on Dec 5, 2016

@epoberezkin
MemberAuthor

that expresses the logic of a computation without describing its control flow.

That's exactly what is the table above - the logic without control flow.

handrews

handrews commented on Dec 5, 2016

@handrews
Contributor

Because there is a widely accepted plain-english definition that says so. "imperative programming" and "declarative programming" have well-defined meanings, which are not about whether things can be expressed in terms of logical predicates. Go find a credible definition of "declarative programming" that includes an if statement and I'll discuss that definition with you. But making up your own approaches to these terms undercuts your primary argument.

epoberezkin

epoberezkin commented on Dec 5, 2016

@epoberezkin
MemberAuthor

As I said, I don't mind what the keywords are. Let's use "ante" (from "antecedent", the term for "p" in p=>q) and "cons" ("consequent").

epoberezkin

epoberezkin commented on Dec 5, 2016

@epoberezkin
MemberAuthor

@handrews I can refer you back to the same article you quote: https://en.wikipedia.org/wiki/Declarative_programming#Constraint_programming

Subparadigms
Declarative programming is an umbrella term that includes a number of better-known programming paradigms.
Functional programming, and in particular purely functional programming, attempts to minimize or eliminate side effects, and is therefore considered declarative.

Many functional languages support if/then/else construct as its result is pure - it doesn't have side effects and it is not dependent on the order of execution, it's determined by truth table, same as allOf/anyOf/oneOf (and/or/xor).

Also see https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Declarative_languages

Many languages in this list support conditionals.

handrews

handrews commented on Dec 5, 2016

@handrews
Contributor

Very few systems are purely one style or another. And maybe JSON Schema ends up not being purely declarative in the sense I am advocating. Ultimately, whether if-then-else is "declarative" or not (by whoever's definition) is less important than whether you can convince more people here that it is the right direction for JSON Schema.

epoberezkin

epoberezkin commented on Dec 6, 2016

@epoberezkin
MemberAuthor

An alternative for for the same would be:

{
  "conditional": [
    {"$ref": "condition" },
    {"$ref": "schema1"},
    {"$ref": "schema2"}
  ]
}

There should be exactly 2 or 3 items in this array, more or less should make it invalid.

See also #168 (comment)

I think it can be more preferable as it doesn't look imperative at all to me.

HotelDon

HotelDon commented on Dec 6, 2016

@HotelDon

I would prefer this suggestion to the switch keyword, at the very least. I kept having problems with switch behaving in unexpected ways, usually because of the way "then" and "continue" interact. This feels much simpler, and harder to trip yourself over.

epoberezkin

epoberezkin commented on Dec 6, 2016

@epoberezkin
MemberAuthor

@HotelDon I agree. I never actually used continue. And you can achieve everything the switch gives you (without continue) by combining the above with the existing keywords.

Relequestual

Relequestual commented on Dec 6, 2016

@Relequestual
Member

To be honest, I don't really care what paradigm it falls under. I'm not even sure you can clasify JSON Schema under any paradigm, but that's a different debate ("We" don't even all agree if it is code or not anyway).

Things I care about when looking at adding new functionality:

Is there a use case?
Yup, I can think of a few.

Does it make JSON Schema easier to use?
Yup, the example clearly shows.

Does it cause problems for implementors?
I can't answer that one, but considering it's possible that implementors may already be intelegantly asessing anyOf to construct the same logic structure, by looking at for the structure style shown in the example, leads me to think probably not.

I'd also much prefer this to a switch, as, as mentioned, it could be unclear or confusing.

@handrews unless you can think of a reason why this would be a BAD thing, them I'm for it.

epoberezkin

epoberezkin commented on Dec 6, 2016

@epoberezkin
MemberAuthor

By the way, would you prefer conditional or if/then/else? I think I like conditional more, not because it's less imperative looking but because it's a single keyword.

handrews

handrews commented on Dec 6, 2016

@handrews
Contributor

As I said before:

Ultimately, whether if-then-else is "declarative" or not (by whoever's definition) is less important than whether you can convince more people here that it is the right direction for JSON Schema.

People seem to be for this, so I'll go with that. It's not about my personal preference.

We all seem to agree that switch was too complicated. And yes, too imperative, while if/then/else falls into this "it depends on how you think about it" zone. Having given it a rest overnight, I do see @epoberezkin's point of view here even if it is not my preferred way to consider it.

By the way, would you prefer conditional or if/then/else? I think I like conditional more, not because it's less imperative looking but because it's a single keyword.

I prefer if/then/else because it is just more obvious. I suspect it's because I just woke up but I had to think for a second to realize that the 2nd and 3rd schemas in the "conditional" list behave as "then" and "else" respectively.


There is one property I would like to make sure we preserve, which gets to the real-world implications of declarative vs imperative: I want to make sure that it is always safe to evaluate all schema branches. Right now I believe that is true because in general JSON Schema validation is purely functional, without state or side effects. As long as that remains true, it should be safe to (for instance) pass each subschema off to separate threads or co-routines and decide what to do with the results later.

If it's always safe to evaluate both the "then" and the "else" no matter how the "if" validates, then this really is identical to using the existing boolean keywords but more clear. It should also always be safe to only evaluate either the "then" or the "else" depending on the result of the "if" validation. This is the same as saying that you can either short-circuit "allOf", etc. or you can check all branches even if you know that since one fails the overall result will be a failure. It's up to the implementation to decide.

Does this property make sense? Do others agree it is desirable?

86 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @awwright@jdesrosiers@Relequestual@britishtea@dlax

        Issue actions

          Validation: if/then/else · Issue #180 · json-schema-org/json-schema-spec