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

Feature request: "Try parse" family of functions #7032

Open
TreeOfLearning opened this issue Mar 11, 2024 · 2 comments
Open

Feature request: "Try parse" family of functions #7032

TreeOfLearning opened this issue Mar 11, 2024 · 2 comments

Comments

@TreeOfLearning
Copy link

Currently, both direct casting and the to_* family of functions throw an error if the value to be converted is not valid for the type being converted to. This makes a lot of sense given the highly typed nature of EdgeDB. However, sometimes it can be useful to try to cast from one type to another, or similarly, to try to parse a string to another type, and to fail gracefully if such a conversion is not possible. For example, one may have a type in one's schema with a string property, and may wish to have a computed property that tries to parse that string to another type, such as a datetime or float64, and if this is not successful, returns a null object instead. Example schema pseudocode:

type SomeType {
  required value: str;
  required numeric_value := try_to_float64(.value);
}

And what the returned results might look like:

[
  {
    "id": "79ae1d30-df9c-11ee-94a9-6b08d824cfdd",
    "value": "123.4",
    "numeric_value": 123.4
  },
  {
    "id": "8823c96e-df9c-11ee-94a9-3b2eaee6ce4e",
    "value": "abc",
    "numeric_value": {}
  }
]

Typically, other languages handle this by either not throwing an error when an invalid conversion is attempted (see javascript and typescript, where NaN is returned for invalid calls to parseInt and parseFloat), or by providing "TryParse" functions (see for example .NET).

It would be good to have a family of functions that handle this gracefully: either just returning {} if a conversion fails, or possibly allowing a user-specified fallback value: some_property := try_to_float64(.value, -1). This isn't limited to just floats, of course; I can see potential use cases with date strings, etc.

@TreeOfLearning
Copy link
Author

Discord thread (for completeness; there isn't any more info there than in this issue)

@TreeOfLearning TreeOfLearning changed the title "Try parse" family of functions Feature request: "Try parse" family of functions Mar 11, 2024
@nervetattoo
Copy link

I'd suggest a wrapper to intercept exceptions. It would have more usages and not increase the API surface.
Naming can lean on std::assert(input, options):

Function name could be any of suppress, catch, throws ... I feel like suppress best describes the intention

result := std::suppress(
  to_float64(.str),
  catch := <float64>{}
)

I'm not sure its possible to default an empty set here based on the passed first args return type? If so the default should be an empty set of the inferred type.
The good thing is that this would allow having more logic if you know you have a mixed set where you need different handlers.
Ofc this could be achieved with regex matching and ifs too.

result := std::suppress(
  to_float64(.str),
  catch := (to_float64(str_split("foo#12", "#")[1]))
)

Another option would be to use if-then-else syntax with keywords, which tbh might be the most idiomatic.

result := try to_float64(.str) catch <float64>{}

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