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

Add MATCH statement for type-conditional expressions #4855

Open
PastelStoic opened this issue Dec 28, 2022 · 2 comments
Open

Add MATCH statement for type-conditional expressions #4855

PastelStoic opened this issue Dec 28, 2022 · 2 comments

Comments

@PastelStoic
Copy link

One user asked if there was a more concise way to write this query:

property normalized_data := (
  SELECT (
      array_join(.data[is learning::StringCollectionUnit].string_collection_value, ',') IF .data is learning::StringCollectionUnit ELSE
      array_join(<array<str>>.data[is learning::NumberCollectionUnit].number_collection_value, ',') IF .data is learning::NumberCollectionUnit ELSE
      <str>.data[is learning::NumberUnit].number_value IF .data is learning::NumberUnit ELSE
      .data[is learning::StringUnit].string_value
  )
)

A match statement would allow the above query to be written as such:

property normalized_data := (
  SELECT (MATCH .data (
    learning::StringCollectionUnit: array_join(.data.string_collection_value, ','),
    learning::NumberCollectionUnit: array_join(<array<str>>.data.number_collection_value, ','),
    learning::NumberUnit: <str>.data.number_value,
    learning::StringUnit: .data.string_value
  ))
)

"Match" was chosen purely due to Rust. "Switch" or "Case" would also be valid names for this feature.

I also feel that the : syntax might not be clear enough - a more traditional => might work better.

Modality inference might also be a challenge, as the compiler would need to know whether every possible subtype had been provided to determine whether the expression always returns a value.

@aljazerzen
Copy link
Contributor

This is a good idea with potential for drastic improvements to brevity in some queries.

We'll discuss it with the compiler team.

@aljazerzen
Copy link
Contributor

I've written an RFC for match statement, but it currently only allows comparisons with ==, not is as you suggested.

The RFC will probably evolve into proper pattern matching & deconstructing, but because this is very complicated on the implementation side, it surly won't make it into 3.0.

If we decide to implement RFC as is for 3.0, this would be workaround for your example:

property normalized_data := (
  SELECT match true {
      .data is learning::StringCollectionUnit -> array_join(.data[is learning::StringCollectionUnit].string_collection_value, ','),
      .data is learning::NumberCollectionUnit -> array_join(<array<str>>.data[is learning::NumberCollectionUnit].number_collection_value, ','),
      .data is learning::NumberUnit -> <str>.data[is learning::NumberUnit].number_value,
      .data is learning::StringUnit -> .data[is learning::StringUnit].string_value,
  }
)

... which is not much more readable than the original.

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