From 675c819701dc432ef206600736ed508e293e1128 Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Tue, 24 Dec 2019 13:37:37 +0000 Subject: [PATCH 1/8] Add optional chaining + nullish coalescing example --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index dca0fb6e..6605ba07 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,8 @@ assert(record1.a === 1); assert(record1["a"] === 1); assert(record1 !== record2); assert(record2 === #{ a: 1, c: 3, b: 5 }); +assert(record1?.a === 1); +assert(record1?.d ?? 5 === 5); ``` #### `Tuple` From 275bdf810694053834a71195e8d78e444f84db0c Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Tue, 24 Dec 2019 13:45:23 +0000 Subject: [PATCH 2/8] Add JSON.parseImmutable --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 6605ba07..b1058100 100644 --- a/README.md +++ b/README.md @@ -328,6 +328,12 @@ JSON.stringify(#{ a: #[1, 2, 3] }); // '{"a":[1,2,3]}' JSON.stringify(#[true, #{ a: #[1, 2, 3] }]); // '[true,{"a":[1,2,3]}]' ``` +## JSON.parseImmutable + +We propose to add `JSON.parseImmutable` so we can extract a Record/Tuple type out of a JSON string instead of an Object/Array. + +The signature of `JSON.parseImmutable` is identical to `JSON.parse` with the only change being in the return type that is now a Record or a Tuple. + ## `Record` prototype The `Record` prototype is an empty object. From 018789a947652912ff2c5a77e0d4ab9d118bc4c5 Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Tue, 24 Dec 2019 13:50:06 +0000 Subject: [PATCH 3/8] Add parse time errors --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index b1058100..1600ce33 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,14 @@ At runtime, attempting to create a `Record` with a key that is not a `string` or At runtime, it is a `TypeError` to add a value to a `Record` or `Tuple` of any type except the following: `Record`, `Tuple`, `string`, `number`, `symbol`, `boolean`, `bigint`, `undefined`, or `null`. +However whenever the engine can figure out at parse time that something is wrong, it should fail at that moment: + +```js +const r1 = { obj: {} }; // fails at parse time because an object declaration in a record is obviously going to be an error +const r2 = { obj: true ? {} : #{} }; // will fail at runtime as it's not obvious from the parser's perspective that we should fail +const r3 = { method() {} }; // fails at parse time +``` + # Equality Instances of `Record` and `Tuple` are deeply immutable, so their equality works like that of other JS primitive value types like `boolean` and `string` instances: From cbb65d2d9946bcb29cd01d9b52fdae9ee4371bba Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Sat, 28 Dec 2019 11:00:38 +0100 Subject: [PATCH 4/8] Apply suggestions from code review Adds # on each parsing/runtime error example Co-Authored-By: Jordan Harband --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1600ce33..1372becd 100644 --- a/README.md +++ b/README.md @@ -156,9 +156,9 @@ At runtime, it is a `TypeError` to add a value to a `Record` or `Tuple` of any t However whenever the engine can figure out at parse time that something is wrong, it should fail at that moment: ```js -const r1 = { obj: {} }; // fails at parse time because an object declaration in a record is obviously going to be an error -const r2 = { obj: true ? {} : #{} }; // will fail at runtime as it's not obvious from the parser's perspective that we should fail -const r3 = { method() {} }; // fails at parse time +const r1 = #{ obj: {} }; // fails at parse time because an object declaration in a record is obviously going to be an error +const r2 = #{ obj: true ? {} : #{} }; // will fail at runtime as it's not obvious from the parser's perspective that we should fail +const r3 = #{ method() {} }; // fails at parse time ``` # Equality From 11293d77c958dbb94de008882d5c65a40454e70c Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Sat, 28 Dec 2019 11:03:12 +0100 Subject: [PATCH 5/8] Add example with optional chaining only --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1372becd..33d7c5be 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ assert(record1["a"] === 1); assert(record1 !== record2); assert(record2 === #{ a: 1, c: 3, b: 5 }); assert(record1?.a === 1); +assert(record1?.d === undefined); assert(record1?.d ?? 5 === 5); ``` From 3ca5777841fd8bbc2da345267d8d06471841e77c Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Sat, 28 Dec 2019 11:05:01 +0100 Subject: [PATCH 6/8] Optional chaining and nullish coalescing on the LHS --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 33d7c5be..fc10d135 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,10 @@ assert(record1["a"] === 1); assert(record1 !== record2); assert(record2 === #{ a: 1, c: 3, b: 5 }); assert(record1?.a === 1); +assert(1 === record1?.a); assert(record1?.d === undefined); assert(record1?.d ?? 5 === 5); +assert(3 === record1?.d ?? 3); ``` #### `Tuple` From 603eb4c5aeda43ab051b4d7e4c5a07b07f3aea44 Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Mon, 6 Jan 2020 10:14:04 +0000 Subject: [PATCH 7/8] Apply remarks --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc10d135..391fe454 100644 --- a/README.md +++ b/README.md @@ -72,10 +72,9 @@ assert(record1["a"] === 1); assert(record1 !== record2); assert(record2 === #{ a: 1, c: 3, b: 5 }); assert(record1?.a === 1); -assert(1 === record1?.a); assert(record1?.d === undefined); assert(record1?.d ?? 5 === 5); -assert(3 === record1?.d ?? 3); +assert(record1.d?.a === undefined); ``` #### `Tuple` @@ -345,6 +344,10 @@ We propose to add `JSON.parseImmutable` so we can extract a Record/Tuple type ou The signature of `JSON.parseImmutable` is identical to `JSON.parse` with the only change being in the return type that is now a Record or a Tuple. +## JSON.stringify + +Stringifying a record or a tuple should output object or array syntax that corresponds recursively. + ## `Record` prototype The `Record` prototype is an empty object. From 525c8d5b0969e1d74e93ee61b71759514e8dd97d Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Mon, 6 Jan 2020 16:46:47 +0000 Subject: [PATCH 8/8] Remove contested parts and clarify --- README.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/README.md b/README.md index 391fe454..56850745 100644 --- a/README.md +++ b/README.md @@ -155,13 +155,7 @@ At runtime, attempting to create a `Record` with a key that is not a `string` or At runtime, it is a `TypeError` to add a value to a `Record` or `Tuple` of any type except the following: `Record`, `Tuple`, `string`, `number`, `symbol`, `boolean`, `bigint`, `undefined`, or `null`. -However whenever the engine can figure out at parse time that something is wrong, it should fail at that moment: - -```js -const r1 = #{ obj: {} }; // fails at parse time because an object declaration in a record is obviously going to be an error -const r2 = #{ obj: true ? {} : #{} }; // will fail at runtime as it's not obvious from the parser's perspective that we should fail -const r3 = #{ method() {} }; // fails at parse time -``` +If you try to use a method definitions as part of a Record, the same behavior is expected, it should fail at runtime (even if we could fail at compile time). # Equality @@ -344,10 +338,6 @@ We propose to add `JSON.parseImmutable` so we can extract a Record/Tuple type ou The signature of `JSON.parseImmutable` is identical to `JSON.parse` with the only change being in the return type that is now a Record or a Tuple. -## JSON.stringify - -Stringifying a record or a tuple should output object or array syntax that corresponds recursively. - ## `Record` prototype The `Record` prototype is an empty object.