tc39 / proposal-pattern-matching

Pattern matching syntax for ECMAScript
https://tc39.es/proposal-pattern-matching/
MIT License
5.5k stars 89 forks source link

JSON.parse[@@customMatcher]? #310

Open Jack-Works opened 11 months ago

Jack-Works commented 11 months ago

because tryParse isn't a thing now, I wonder if we can have JSON.parse[@@customMatcher] to allow matches JSON structure inside a string.

({data: '{"x": 1}'}) is { data: JSON.parse({ x: 1 }) }

or if it should be "reflective", it might be on stringify

({data: '{"x": 1}'}) is { data: JSON.stringify({ x: 1 }) }
ljharb commented 11 months ago

The latter seems like it'd be really brittle with various formatting options, and the former seems pretty expensive. Even if we could make it make sense, I'm not sure we'd want to encourage people to do this - also, we should definitely never encourage anyone to hand-write a JSON string.

Jack-Works commented 11 months ago

The latter seems like it'd be really brittle with various formatting options, and the former seems pretty expensive. Even if we could make it make sense, I'm not sure we'd want to encourage people to do this - also, we should definitely never encourage anyone to hand-write a JSON string.

The example is just to clarify what the input is. In real life it might be like this:

const file = await readFile()
const config = match (file) {
    JSON.parse({ let config and isValidConfig }): config;
    Yaml.parse({ let config and isValidYamlConfig }): config;
    default: throw new Error()
}
ljharb commented 11 months ago

that seems like if would attempt to YAML-parse JSON that didn't match the expected schema - i'm not sure this can be shoehorned into pattern matching cleanly tbh.

tabatkins commented 11 months ago

Just for readability, I don't think attaching the custom matcher to .parse() is the way to go. The usual pattern is that extractors should be readable as "constructor, but in reverse" - the pattern in the args should match, roughly, what would have gone into the function call for that argument originally. JSON.parse() takes a string, so that suggests the JSON.parse custom matcher exposes a string as its only iterable value.

I could see installing it on JSON itself, tho. match(someJson) { JSON( {let foo} ): ...; } feels better, to me.

Jack-Works commented 11 months ago

I could see installing it on JSON itself, tho. match(someJson) { JSON( {let foo} ): ...; } feels better, to me.

Yes, but iirc @rbuckton doesn't like it because new JSON(object) isn't a thing, so you should not install the customMatcher on the JSON object.

ljharb commented 11 months ago

While i don’t think we should restrict ourselves to only see matching as the inverse of new - it’s simply not that - a JSON matcher seems the same as tryParse to me, and unless the committee is convinced of that method’s motivations i suspect they wouldn’t be convinced of this matcher’s motivations.