if syntax - rocq-prover/rocq GitHub Wiki

Following https://github.com/rocq-prover/rocq/wiki/Rocq-Call-2026-03-17 it was agreed that the current if <term : inductive_with_two_constructos> then term else term syntactic sugar for match should be deprecated (except for (things coercible to) bool). We thus first need a replacement. Please list offers below, with perceived pros and cons, and historical use if any. Please try to keep the "positive" and "negative" offers in the same order when there is a correspondance

Positive case (bindings in first branch)

  • if <term> is <pattern> then <term> else <term>

    • already used in MathComp ecosystem
    • one of the syntax considered for the C++ standard (c.f., https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2392r3.pdf , with context sensitive keyword is )
    • pros:
      • short
      • reads like a sentence
      • <term> and <pattern> in same order as match <term> with <pattern>
    • cons:
      • requires making is a keyword (but CI https://github.com/rocq-prover/rocq/pull/21609 seems to indicate no dramatic effect, except for UniMath that is using is extensively as a variable name)
      • similar to syntaxes for pointers in other languages (but no pointers in Rocq)
  • if <term> .is. <pattern> then <term> else <term> (or other variants like if <term> \is <pattern>...)

    • used in Ada
    • pros:
      • <term> and <pattern> in same order as match <term> with <pattern>
    • cons:
      • longer
      • breaks reading
      • requires making .is. a keyword (but maybe absolutely nobody uses it yet?)
  • if let <pattern> := <term> then <term> else <term>

    • used in Rust and Lean
    • pros:
      • no new keyword
    • cons:
      • let currently indicates an irrefutable pattern, not a switch
      • longer
      • <term> and pattern> in reversed order with respect to the unsugared match construct
      • common prefix with eg if let x := tt in true then ... else ... (which is currently accepted)
  • match <term> with <pattern> then <term> else <term>

    • pros:
      • no new keyword
    • cons:
      • longer
  • if <term> match <pattern> then <term> else <term>

    • one of the syntax considered for the C++ standard (the other one uses context-sensitive keywords is and as)
    • pros:
      • no new keyword
    • cons
      • Rocq already allows match in argument position (contrarily to OCaml where it is a syntax error), so this is slightly ambiguous
      • longer
      • may feel a bit strange to reuse the match keyword with the role of the with keyword in match-with construct

Negative case (bindings in second branch)

  • if <term> isn't <pattern> then <term> else <term>

    • already used in MathComp ecosystem
    • pros:
      • short
      • reads like a sentence
      • <term> and <pattern> in same order as match <term> with <pattern>
    • cons:
      • bindings in second branch may not be obvious
      • requires making isn't a keyword (though CI seems to indicate nobody uses it)
  • unless <term> is <pattern> then <term> else <term>

    • pros:
      • "the pattern matching clause is still framed positively, so it restores, in my mind, the idea that some new variables are bound."
      • reads like a sentence
      • <term> and <pattern> in same order as match <term> with <pattern>
    • cons:
      • requires making unless a keyword
  • let <pattern> := <term> else <term> in <term>

    • similar to Rust
    • pros:
      • indentation would be nice when used in sequence or with a large second branch
    • cons:
      • let currently indicates an irrefutable pattern, not a switch
  • if <term> is <pattern> else <term> then <term>

    • pros:
      • short
      • symmetric to if <term> is <pattern> then <term> else <term>
    • cons:
      • bindings in second branch may not be obvious
      • same other cons as if <term> is <pattern> then <term> else <term>
⚠️ **GitHub.com Fallback** ⚠️