From 852719340eef6116f1ff9fb68f18b0b32fa9e10f Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Tue, 8 Oct 2024 23:39:10 -0500 Subject: [PATCH 01/24] Record names as reserved_words/Variables and new record definition syntax --- eeps/eep-0072.md | 147 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 eeps/eep-0072.md diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md new file mode 100644 index 0000000..3112909 --- /dev/null +++ b/eeps/eep-0072.md @@ -0,0 +1,147 @@ + Author: Jesse Gumm + Status: Draft + Type: Standards Track + Created: 08-Oct-2024 + Post-History: +**** +EEP 72: Reserved words and Variables as record names, and enhancement to definition syntax +---- + +Abstract +======== + +This EEP loosens some of the restrictions around record names such no longer is +it necessary to quote record names when those records are named with reserved +words (`#if` vs `#'if'`) or words with capitalized first characters (`#Hello` +vs `#'Hello'`). + +```erlang +#'if'{ + +This EEP also proposes to add a new record-like syntax to the record +definitions (also adopting the above syntactical changes), such that the +following record definitions would be identical: + +```erlang +-record('div', {a :: integer(), b :: integer()}). +-record #'div'{a :: integer(), b :: integer()}. +-record #div{a :: integer(), b :: integer()}. +``` + +Motivation +========== + +Record names are atoms. As such, the current Erlang syntax requires the record +names to be consistent with the rest of the language's use of atoms. + +All atoms in Erlang can be denoted with single-quotes. Some examples: + +For example: +```erlang +'foo'. +'FOO'. +'foo-bar`. +``` + +But, conveniently, simple atoms (all alphanumeric, underscores (`_`) or +at-symbols (`@`) with the first character being a lower-case letter and not one +of the 20+ reserved words), in all contexts can be invoked without the +necessary wrapping quotes. Some examples: + +```erlang +foo. + +``` + +Conveniently, this also means that records named with simple atoms can be +invoked and used without having to quote the atoms. For example: + +```erlang +-record(foo, {a, b}). + +go() -> + X = #foo{a = 1, b = 2}, + Y = X#foo{a = something_else}, + Z = Y#foo.a, + ... +``` + +Unfortunately, that also means that records named with anything that doesn't +fit the "simple atom" pattern must be wrapped in quotes in definition and +usage. For example: + +```erlang +-record('div', {a, b}). + +go() -> + X = #'div'{a = 1, b = 2}, + Y = X#'div'{a = something_else}, + Z = Y#'div'.a, + ... +``` + +While this approach is consistent with atom usage in the language, for reserved +words, this makes the record syntax *feel* inconsistent if you have a need for +naming a record with a reserved word (or term with a capital first letter). In +this case, it almost guarantees a user won't use a record named 'if', +'recieve', 'fun', etc even though there may very well be a valid use-case for +such a name. The most common use-case that comes to mind from the Nitrogen Web +Framework. Since HTML has a `div` tag, Nitrogen (which represents HTML tags +using Erlang records) should naturally have a `#div` record, however, due to +'div' being a reserved word, the record `#panel` is used instead to save the +programmer from having to invoke `#'div'`, which feels unnatural and awkward. + +Specification +============= + +This EEP simplifies the above example by + +1. Allowing reserved words and variables to be used without quotes for record + names, and +2. Simplifying the definition such that the syntax between record definition + and record usage becomes more consistent. + +With the changes from this EEP, the above code becomes: + +```erlang +-record #div{a, b}. + +go() -> + X = #div{a = 1, b = 2}, + Y = X#div{a = something_else}, + Z = Y#div.a, + ... +``` + +Implementation +============== + +To update the syntax for using records, we can safely augment the parser to +change `# atom` to `# record_name` and define `record_name` to be either +`atom`, `var`, or `reserved_word`. + +To update the record definition syntax, we can simply add a few new +modifications to the `attribute` Nonterminal. + +Backwards Compatibility +======================= + +As this EEP only adds new syntax, the vast majority existing codebases will +still work, with the possible exception of AST/code analysis tools that are +analyzing code using the new syntax. + +Syntax highlighting and code-completion tools may need to be updated to support +the new syntax if your code uses the new syntax rules. + +Reference Implementation +======================== + +The reference implementation is provided in a form of pull-request on GitHub + + https://github.com/erlang/otp/pull/7873 + +Copyright +========= + +This document has been placed in the public domain. + From adb4ffd20a9178b41d744b00526b1f2877e6831a Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Tue, 8 Oct 2024 23:52:37 -0500 Subject: [PATCH 02/24] Fix small typos --- eeps/eep-0072.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 3112909..5ba6c41 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -15,12 +15,9 @@ it necessary to quote record names when those records are named with reserved words (`#if` vs `#'if'`) or words with capitalized first characters (`#Hello` vs `#'Hello'`). -```erlang -#'if'{ - This EEP also proposes to add a new record-like syntax to the record definitions (also adopting the above syntactical changes), such that the -following record definitions would be identical: +following record definitions would all be valid and identical: ```erlang -record('div', {a :: integer(), b :: integer()}). From a87bc7eb3cc50bfc9f220bf322436dac78d52c21 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Tue, 8 Oct 2024 23:55:55 -0500 Subject: [PATCH 03/24] Fixing more typos --- eeps/eep-0072.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 5ba6c41..d78f064 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -37,7 +37,7 @@ For example: ```erlang 'foo'. 'FOO'. -'foo-bar`. +'foo-bar'. ``` But, conveniently, simple atoms (all alphanumeric, underscores (`_`) or @@ -47,7 +47,8 @@ necessary wrapping quotes. Some examples: ```erlang foo. - +foo_Bar. +'foo-bar'. % still quoted since the term has a non-atomic character in it. ``` Conveniently, this also means that records named with simple atoms can be From 964d9714a10baacedc286467b76ce127879c4c4e Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Wed, 9 Oct 2024 13:14:24 -0500 Subject: [PATCH 04/24] Fix 'receive' typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Valim --- eeps/eep-0072.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index d78f064..d22df05 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -82,7 +82,7 @@ While this approach is consistent with atom usage in the language, for reserved words, this makes the record syntax *feel* inconsistent if you have a need for naming a record with a reserved word (or term with a capital first letter). In this case, it almost guarantees a user won't use a record named 'if', -'recieve', 'fun', etc even though there may very well be a valid use-case for +'receive', 'fun', etc even though there may very well be a valid use-case for such a name. The most common use-case that comes to mind from the Nitrogen Web Framework. Since HTML has a `div` tag, Nitrogen (which represents HTML tags using Erlang records) should naturally have a `#div` record, however, due to From 83ccc12b8d37d99476ba5d6fb8c5900ab32a8e8b Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Wed, 9 Oct 2024 13:15:13 -0500 Subject: [PATCH 05/24] EEP-0072: Fix janky and busted phrasing Co-authored-by: Raimo Niskanen --- eeps/eep-0072.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index d22df05..5ee5bab 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -10,8 +10,8 @@ EEP 72: Reserved words and Variables as record names, and enhancement to definit Abstract ======== -This EEP loosens some of the restrictions around record names such no longer is -it necessary to quote record names when those records are named with reserved +This EEP loosens some of the restrictions around record names to make it +no longer necessary to quote them when they are named with reserved words (`#if` vs `#'if'`) or words with capitalized first characters (`#Hello` vs `#'Hello'`). From 6d24820da0848061e193bf6a4608d11c8121490a Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Wed, 9 Oct 2024 13:34:27 -0500 Subject: [PATCH 06/24] eep-0072: Clarifying language and more examples Co-authored-by: Raimo Niskanen --- eeps/eep-0072.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 5ee5bab..bacfe52 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -24,7 +24,14 @@ following record definitions would all be valid and identical: -record #'div'{a :: integer(), b :: integer()}. -record #div{a :: integer(), b :: integer()}. ``` +The latter two are proposed new syntax. The following would also be valid +and identical since parentheses are optional in attributes: +```erlang +-record 'div', {a :: integer(), b :: integer()}. +-record(#'div'{a :: integer(), b :: integer()}). +-record(#div{a :: integer(), b :: integer()}). +``` Motivation ========== From 8e0e09c64b1841c84474025775716b407f8b742a Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Wed, 9 Oct 2024 13:37:07 -0500 Subject: [PATCH 07/24] Update eeps/eep-0072.md Co-authored-by: Raimo Niskanen --- eeps/eep-0072.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index bacfe52..b01d852 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -93,8 +93,9 @@ this case, it almost guarantees a user won't use a record named 'if', such a name. The most common use-case that comes to mind from the Nitrogen Web Framework. Since HTML has a `div` tag, Nitrogen (which represents HTML tags using Erlang records) should naturally have a `#div` record, however, due to -'div' being a reserved word, the record `#panel` is used instead to save the -programmer from having to invoke `#'div'`, which feels unnatural and awkward. +'div' being a reserved word (the integer division operator), the record `#panel` +is used instead to save the programmer from having to invoke `#'div'`, +which feels unnatural and awkward. Specification ============= From f5d0d3ff5aa41fe53112264d152007fc497b919d Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Wed, 9 Oct 2024 13:37:31 -0500 Subject: [PATCH 08/24] eep-0072: phrasing Co-authored-by: Raimo Niskanen --- eeps/eep-0072.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index b01d852..a7687e8 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -16,7 +16,7 @@ words (`#if` vs `#'if'`) or words with capitalized first characters (`#Hello` vs `#'Hello'`). This EEP also proposes to add a new record-like syntax to the record -definitions (also adopting the above syntactical changes), such that the +definitions (also adopting the above syntactical changes), so that the following record definitions would all be valid and identical: ```erlang From 87a637bc4eb8809c4d1517417c52cb14f17e7f4b Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Wed, 9 Oct 2024 14:29:48 -0500 Subject: [PATCH 09/24] EEP0072-Expand Motivations and specs for definition --- eeps/eep-0072.md | 82 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 7 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index a7687e8..b012c2b 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -32,8 +32,8 @@ and identical since parentheses are optional in attributes: -record(#'div'{a :: integer(), b :: integer()}). -record(#div{a :: integer(), b :: integer()}). ``` -Motivation -========== +Usage Syntax Motivation +======================= Record names are atoms. As such, the current Erlang syntax requires the record names to be consistent with the rest of the language's use of atoms. @@ -87,18 +87,21 @@ go() -> While this approach is consistent with atom usage in the language, for reserved words, this makes the record syntax *feel* inconsistent if you have a need for -naming a record with a reserved word (or term with a capital first letter). In +naming a record with a reserved word (or term with a capital first letter). In this case, it almost guarantees a user won't use a record named 'if', 'receive', 'fun', etc even though there may very well be a valid use-case for -such a name. The most common use-case that comes to mind from the Nitrogen Web -Framework. Since HTML has a `div` tag, Nitrogen (which represents HTML tags +such a name. The most common use-case that comes to mind from the Nitrogen Web +Framework. Since HTML has a `div` tag, Nitrogen (which represents HTML tags using Erlang records) should naturally have a `#div` record, however, due to 'div' being a reserved word (the integer division operator), the record `#panel` is used instead to save the programmer from having to invoke `#'div'`, which feels unnatural and awkward. -Specification -============= +Further, + + +Usage Syntax Specification +========================== This EEP simplifies the above example by @@ -109,6 +112,51 @@ This EEP simplifies the above example by With the changes from this EEP, the above code becomes: +```erlang +-record('div', {a, b}). + +go() -> + X = #div{a = 1, b = 2}, + Y = X#div{a = something_else}, + Z = Y#div.a, + ... +``` + +Definition Syntax Motivation +============================ + +While the updated example in the usage syntax specification makes the *using* +of records cleaner, there remains one more inconsistency that can also be +relatively easily solved. That is the record definition still also needing to +quote record name, as the example above demonstrates (repeated here for +convenience): + +```erlang +-record('div', {a, b}). + +go() -> + X = #div{a = 1, b = 2}, + Y = X#div{a = something_else}, + Z = Y#div.a, + ... +``` +So whereas the record definition needs to be thought of as `'div'`, the record +usage no longer requires the quoted term 'div', which could certainly lead an +Erlang non-veteran to wonder why 'div' needs to be quoted in the definition +while other atom-looking terms don't. + + +Definition Syntax Specification +=============================== + +Conveniently, there is a rather easy solution, and that's to +allow the record usage syntax to also be used as the record definition. + +This EEP also then also adds a new record definition syntax, improving the +symmetry between general record usage and record definition. + +The above example can fully then look like the following: + ```erlang -record #div{a, b}. @@ -139,6 +187,26 @@ analyzing code using the new syntax. Syntax highlighting and code-completion tools may need to be updated to support the new syntax if your code uses the new syntax rules. +Broader Concerns and Points of Discussion +========================================= +While the new definition syntax creates some degree of symmetry around record +usage, there do remain some concerns and inconsistencies: + +1. Other functions that work with records like `is_record/2` or `record_info/1` + are not currently covered by any of the syntactical changes in this EEP, and + as such, it remains necessary to quote record names if they are not simple + atoms. For example: `is_record(X, div)` would still be a syntax error. So + there is still not true 100% symmetry. +2. This EEP introducing a new syntax for record definition could potentially + lead to some to wonder why the language has two rather different syntaxes + for defining records. Since usage of the syntax for getting, setting, + matching, etc (e.g. `#rec{a=x,y=b}`) occurs far more commonly than defining, + it only feels natural that the definition syntax would mirror usage. Thus, I + feel that the symmetry between the usage and the definition would likely + become the default/preferred way, and that the original syntax remain for + backwards compatibility. + + Reference Implementation ======================== From 8036769212f2a88c224129b60bbe018885048237 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Wed, 9 Oct 2024 14:42:39 -0500 Subject: [PATCH 10/24] EEP-0072: Remove excess hyphenation --- eeps/eep-0072.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index b012c2b..6d09d55 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -38,7 +38,7 @@ Usage Syntax Motivation Record names are atoms. As such, the current Erlang syntax requires the record names to be consistent with the rest of the language's use of atoms. -All atoms in Erlang can be denoted with single-quotes. Some examples: +All atoms in Erlang can be denoted with single quotes. Some examples: For example: ```erlang @@ -48,7 +48,7 @@ For example: ``` But, conveniently, simple atoms (all alphanumeric, underscores (`_`) or -at-symbols (`@`) with the first character being a lower-case letter and not one +at symbols (`@`) with the first character being a lowercase letter and not one of the 20+ reserved words), in all contexts can be invoked without the necessary wrapping quotes. Some examples: @@ -89,8 +89,8 @@ While this approach is consistent with atom usage in the language, for reserved words, this makes the record syntax *feel* inconsistent if you have a need for naming a record with a reserved word (or term with a capital first letter). In this case, it almost guarantees a user won't use a record named 'if', -'receive', 'fun', etc even though there may very well be a valid use-case for -such a name. The most common use-case that comes to mind from the Nitrogen Web +'receive', 'fun', etc even though there may very well be a valid use case for +such a name. The most common use case that comes to mind from the Nitrogen Web Framework. Since HTML has a `div` tag, Nitrogen (which represents HTML tags using Erlang records) should naturally have a `#div` record, however, due to 'div' being a reserved word (the integer division operator), the record `#panel` @@ -142,8 +142,8 @@ go() -> ``` So whereas the record definition needs to be thought of as `'div'`, the record usage no longer requires the quoted term 'div', which could certainly lead an -Erlang non-veteran to wonder why 'div' needs to be quoted in the definition -while other atom-looking terms don't. +Erlang beginner to wonder why 'div' needs to be quoted in the definition while +other atom-looking terms don't. Definition Syntax Specification @@ -184,7 +184,7 @@ As this EEP only adds new syntax, the vast majority existing codebases will still work, with the possible exception of AST/code analysis tools that are analyzing code using the new syntax. -Syntax highlighting and code-completion tools may need to be updated to support +Syntax highlighting and code completion tools may need to be updated to support the new syntax if your code uses the new syntax rules. Broader Concerns and Points of Discussion @@ -210,7 +210,7 @@ usage, there do remain some concerns and inconsistencies: Reference Implementation ======================== -The reference implementation is provided in a form of pull-request on GitHub +The reference implementation is provided in a form of pull request on GitHub https://github.com/erlang/otp/pull/7873 From 3ddb0c64ac63e470b99254a7b35ba095d7d9d5b0 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Wed, 9 Oct 2024 15:00:14 -0500 Subject: [PATCH 11/24] EEP-0072: Add note about ASN1 and Corba --- eeps/eep-0072.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 6d09d55..9125f1b 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -97,7 +97,13 @@ using Erlang records) should naturally have a `#div` record, however, due to is used instead to save the programmer from having to invoke `#'div'`, which feels unnatural and awkward. -Further, +Further, applications such as ASN.1 and Corba both have naming conventions that +rely heavily on uppercase record names and as such, they currently must be +quoted as well. You can see this in modules in Erlang's +[`asn1`](https://github.com/erlang/otp/blob/OTP-27.1.1/lib/asn1/src/asn1_records.hrl#L35-L39) +application. (The previous link points to some record definitions in `asn1`, +but you can see the usage scattered across a number of modules in the `asn1` +application). Usage Syntax Specification From 7c28c8a8f817c7237648700d0e51d6b7f6b9cda1 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Thu, 10 Oct 2024 15:19:35 -0500 Subject: [PATCH 12/24] EEP-0072: Attempt to fix spacing to alleviate linter errors --- eeps/eep-0072.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 9125f1b..38997a2 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -24,6 +24,7 @@ following record definitions would all be valid and identical: -record #'div'{a :: integer(), b :: integer()}. -record #div{a :: integer(), b :: integer()}. ``` + The latter two are proposed new syntax. The following would also be valid and identical since parentheses are optional in attributes: @@ -32,6 +33,7 @@ and identical since parentheses are optional in attributes: -record(#'div'{a :: integer(), b :: integer()}). -record(#div{a :: integer(), b :: integer()}). ``` + Usage Syntax Motivation ======================= @@ -105,7 +107,6 @@ application. (The previous link points to some record definitions in `asn1`, but you can see the usage scattered across a number of modules in the `asn1` application). - Usage Syntax Specification ========================== @@ -146,12 +147,12 @@ go() -> Z = Y#div.a, ... ``` + So whereas the record definition needs to be thought of as `'div'`, the record usage no longer requires the quoted term 'div', which could certainly lead an Erlang beginner to wonder why 'div' needs to be quoted in the definition while other atom-looking terms don't. - Definition Syntax Specification =============================== @@ -212,7 +213,6 @@ usage, there do remain some concerns and inconsistencies: become the default/preferred way, and that the original syntax remain for backwards compatibility. - Reference Implementation ======================== @@ -224,4 +224,3 @@ Copyright ========= This document has been placed in the public domain. - From 608739de70a34d60d770e2a87ba727d841efa67a Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Thu, 10 Oct 2024 15:21:33 -0500 Subject: [PATCH 13/24] EEP-wq0072: Add a missed blank line around header --- eeps/eep-0072.md | 1 + 1 file changed, 1 insertion(+) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 38997a2..b5b1933 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -196,6 +196,7 @@ the new syntax if your code uses the new syntax rules. Broader Concerns and Points of Discussion ========================================= + While the new definition syntax creates some degree of symmetry around record usage, there do remain some concerns and inconsistencies: From c838aa42b175ef67435a8fe0864524005f3c49d3 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 12 Oct 2024 12:09:57 -0500 Subject: [PATCH 14/24] EEP-0072: Fix (hopefully) last markdown issue --- eeps/eep-0072.md | 1 + 1 file changed, 1 insertion(+) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index b5b1933..b9f338a 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -43,6 +43,7 @@ names to be consistent with the rest of the language's use of atoms. All atoms in Erlang can be denoted with single quotes. Some examples: For example: + ```erlang 'foo'. 'FOO'. From d60191b5d7756e90aed80e7731ce18197c079c9d Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 12 Oct 2024 12:15:49 -0500 Subject: [PATCH 15/24] Update making the new define syntax more obvious --- eeps/eep-0072.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index b9f338a..ecc2f98 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -21,15 +21,15 @@ following record definitions would all be valid and identical: ```erlang -record('div', {a :: integer(), b :: integer()}). --record #'div'{a :: integer(), b :: integer()}. -record #div{a :: integer(), b :: integer()}. ``` -The latter two are proposed new syntax. The following would also be valid +The latter one is proposed new syntax. The following would also be valid and identical since parentheses are optional in attributes: ```erlang -record 'div', {a :: integer(), b :: integer()}. +-record #'div'{a :: integer(), b :: integer()}. -record(#'div'{a :: integer(), b :: integer()}). -record(#div{a :: integer(), b :: integer()}). ``` From 7cfbd6f72512989fc7f4efaec2ac9f98de2ca840 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 12 Oct 2024 16:43:32 -0500 Subject: [PATCH 16/24] Apply suggestions from code review Co-authored-by: Raimo Niskanen --- eeps/eep-0072.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index ecc2f98..0858101 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -66,11 +66,12 @@ invoked and used without having to quote the atoms. For example: ```erlang -record(foo, {a, b}). +-record(bar, {c}). go() -> X = #foo{a = 1, b = 2}, Y = X#foo{a = something_else}, - Z = Y#foo.a, + Z = #bar{c = Y#foo.a}, ... ``` @@ -80,11 +81,12 @@ usage. For example: ```erlang -record('div', {a, b}). +-record('SET', {c}). go() -> X = #'div'{a = 1, b = 2}, Y = X#'div'{a = something_else}, - Z = Y#'div'.a, + Z = #'SET'{c = Y#'div'.a}, ... ``` @@ -122,11 +124,12 @@ With the changes from this EEP, the above code becomes: ```erlang -record('div', {a, b}). +-record('SET', {c}). go() -> X = #div{a = 1, b = 2}, Y = X#div{a = something_else}, - Z = Y#div.a, + Z = #SET{c = Y#div.a}, ... ``` @@ -179,11 +182,11 @@ Implementation ============== To update the syntax for using records, we can safely augment the parser to -change `# atom` to `# record_name` and define `record_name` to be either -`atom`, `var`, or `reserved_word`. +change its already existing record handling of `'#' atom '{' ... '}'` and `'#' atom '.' atom` into `'#' record_name '{' ... '}'` and `'#' record_name '.' atom`, and define +`record_name` to be `atom`, `var`, or `reserver_word`. To update the record definition syntax, we can simply add a few new -modifications to the `attribute` Nonterminal. +modifications to the `attribute` Nonterminal to allow `'#' record_name` as name for the `record` attribute, instead of `atom` as for generic attributes. Backwards Compatibility ======================= @@ -199,13 +202,18 @@ Broader Concerns and Points of Discussion ========================================= While the new definition syntax creates some degree of symmetry around record -usage, there do remain some concerns and inconsistencies: +usage, perfect symmetry is impossible to achieve, since a record can always +be handled as the atom tagged tuple it actually is. The question is where +to draw the line where the record's true nature shows, and how hard we +should try to hide it. These are remaining concerns and inconsistencies: 1. Other functions that work with records like `is_record/2` or `record_info/1` are not currently covered by any of the syntactical changes in this EEP, and as such, it remains necessary to quote record names if they are not simple atoms. For example: `is_record(X, div)` would still be a syntax error. So - there is still not true 100% symmetry. + there is still not true 100% symmetry. Note that instead of using the + `is_record(X, 'div')` guard, matching on `#div{}` is probably more frequently used, + since it is terser and mostly regarded as more readable. 2. This EEP introducing a new syntax for record definition could potentially lead to some to wonder why the language has two rather different syntaxes for defining records. Since usage of the syntax for getting, setting, From 467ce8ada15a7adc6165a9000c3c9cfb713865f4 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 12 Oct 2024 20:01:30 -0500 Subject: [PATCH 17/24] Fix typo --- eeps/eep-0072.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 0858101..5c6cf82 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -91,7 +91,7 @@ go() -> ``` While this approach is consistent with atom usage in the language, for reserved -words, this makes the record syntax *feel* inconsistent if you have a need for +words and capitalized atoms, this makes the record syntax *feel* inconsistent if you have a need for naming a record with a reserved word (or term with a capital first letter). In this case, it almost guarantees a user won't use a record named 'if', 'receive', 'fun', etc even though there may very well be a valid use case for @@ -183,7 +183,7 @@ Implementation To update the syntax for using records, we can safely augment the parser to change its already existing record handling of `'#' atom '{' ... '}'` and `'#' atom '.' atom` into `'#' record_name '{' ... '}'` and `'#' record_name '.' atom`, and define -`record_name` to be `atom`, `var`, or `reserver_word`. +`record_name` to be `atom`, `var`, or `reserved_word`. To update the record definition syntax, we can simply add a few new modifications to the `attribute` Nonterminal to allow `'#' record_name` as name for the `record` attribute, instead of `atom` as for generic attributes. @@ -222,6 +222,7 @@ should try to hide it. These are remaining concerns and inconsistencies: feel that the symmetry between the usage and the definition would likely become the default/preferred way, and that the original syntax remain for backwards compatibility. +3. Another Reference Implementation ======================== From 6a9c62b48c748cf096a901275a939745fe81a031 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 12 Oct 2024 20:06:04 -0500 Subject: [PATCH 18/24] Fix some length --- eeps/eep-0072.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 5c6cf82..6e198af 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -182,11 +182,14 @@ Implementation ============== To update the syntax for using records, we can safely augment the parser to -change its already existing record handling of `'#' atom '{' ... '}'` and `'#' atom '.' atom` into `'#' record_name '{' ... '}'` and `'#' record_name '.' atom`, and define -`record_name` to be `atom`, `var`, or `reserved_word`. +change its already existing record handling of `'#' atom '{' ... '}'` and +`'#'atom '.' atom` into `'#' record_name '{' ... '}'` and +`'#' record_name '.' atom`, and define `record_name` to be `atom`, `var`, or +`reserved_word`. To update the record definition syntax, we can simply add a few new -modifications to the `attribute` Nonterminal to allow `'#' record_name` as name for the `record` attribute, instead of `atom` as for generic attributes. +modifications to the `attribute` Nonterminal to allow `'#' record_name` as name +for the `record` attribute, instead of `atom` as for generic attributes. Backwards Compatibility ======================= From 6543ec78bf90f41ae1068cfd57773dd500ce6d92 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 12 Oct 2024 21:04:40 -0500 Subject: [PATCH 19/24] Add some notes about the type system --- eeps/eep-0072.md | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 6e198af..0ef65c8 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -210,22 +210,32 @@ be handled as the atom tagged tuple it actually is. The question is where to draw the line where the record's true nature shows, and how hard we should try to hide it. These are remaining concerns and inconsistencies: -1. Other functions that work with records like `is_record/2` or `record_info/1` - are not currently covered by any of the syntactical changes in this EEP, and - as such, it remains necessary to quote record names if they are not simple - atoms. For example: `is_record(X, div)` would still be a syntax error. So - there is still not true 100% symmetry. Note that instead of using the - `is_record(X, 'div')` guard, matching on `#div{}` is probably more frequently used, - since it is terser and mostly regarded as more readable. -2. This EEP introducing a new syntax for record definition could potentially - lead to some to wonder why the language has two rather different syntaxes - for defining records. Since usage of the syntax for getting, setting, - matching, etc (e.g. `#rec{a=x,y=b}`) occurs far more commonly than defining, - it only feels natural that the definition syntax would mirror usage. Thus, I - feel that the symmetry between the usage and the definition would likely - become the default/preferred way, and that the original syntax remain for - backwards compatibility. -3. Another +Auxiliary Record Functions +-------------------------- + +Other functions that work with records like `is_record/2` or `record_info/1` +are not currently covered by any of the syntactical changes in this EEP, and as +such, it remains necessary to quote record names if they are not simple atoms. +For example: `is_record(X, div)` would still be a syntax error. So there is +still not true 100% symmetry. Note that instead of using the +`is_record(X, 'div')` guard, matching on `#div{}` is probably more frequently +used, since it is terser and mostly regarded as more readable. + +Two Definition Syntaxes? +------------------------ + +This EEP introducing a new syntax for record definition could potentially lead +to some to wonder why the language has two rather different syntaxes for +defining records. Since usage of the syntax for getting, setting, matching, etc +(e.g. `#rec{a=x,y=b}`) occurs far more commonly than defining, it only feels +natural that the definition syntax would mirror usage. + +Further, the syntax in Erlang's type system to define records also matches the +newly proposed define syntax. + +Thus, I feel that sharing the existing usage and type syntax with the +definition system would likely become the default/preferred way, and that the +original syntax remain for backwards compatibility. Reference Implementation ======================== From 5250011d67dd7dff6ed04d57e927e376da69df63 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 12 Oct 2024 21:21:04 -0500 Subject: [PATCH 20/24] Update phrasing a bit --- eeps/eep-0072.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 0ef65c8..546cfcd 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -230,8 +230,8 @@ defining records. Since usage of the syntax for getting, setting, matching, etc (e.g. `#rec{a=x,y=b}`) occurs far more commonly than defining, it only feels natural that the definition syntax would mirror usage. -Further, the syntax in Erlang's type system to define records also matches the -newly proposed define syntax. +For more symmetry, the syntax in Erlang's type system to define records also +matches the newly proposed define syntax. Thus, I feel that sharing the existing usage and type syntax with the definition system would likely become the default/preferred way, and that the From 8ef3dcadfac875fa2c92253cff3a5c03201a613b Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 18 Oct 2024 13:36:58 -0500 Subject: [PATCH 21/24] Update eeps/eep-0072.md Co-authored-by: Raimo Niskanen --- eeps/eep-0072.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index 546cfcd..fadb403 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -17,7 +17,7 @@ vs `#'Hello'`). This EEP also proposes to add a new record-like syntax to the record definitions (also adopting the above syntactical changes), so that the -following record definitions would all be valid and identical: +following record definitions would be valid and identical: ```erlang -record('div', {a :: integer(), b :: integer()}). From 4fc7d01daa1dee9d2e856cdc14d35ef3ef7bb523 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 18 Oct 2024 13:37:39 -0500 Subject: [PATCH 22/24] Update eeps/eep-0072.md Co-authored-by: Raimo Niskanen --- eeps/eep-0072.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index fadb403..e1f1406 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -25,7 +25,8 @@ following record definitions would be valid and identical: ``` The latter one is proposed new syntax. The following would also be valid -and identical since parentheses are optional in attributes: +and identical since parentheses are optional in attributes, +and since atoms may be quoted even when not mandatory: ```erlang -record 'div', {a :: integer(), b :: integer()}. From dbfb39e626bc930f6378af45c1375c2599955edb Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 18 Oct 2024 13:42:26 -0500 Subject: [PATCH 23/24] Update variable name phrasing --- eeps/eep-0072.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index e1f1406..cc24064 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -12,8 +12,8 @@ Abstract This EEP loosens some of the restrictions around record names to make it no longer necessary to quote them when they are named with reserved -words (`#if` vs `#'if'`) or words with capitalized first characters (`#Hello` -vs `#'Hello'`). +words (`#if` vs `#'if'`) or words with capitalized first characters (terms that +currently would be treated as variables, for example `#Hello` vs `#'Hello'`). This EEP also proposes to add a new record-like syntax to the record definitions (also adopting the above syntactical changes), so that the From 3164da9b8288f7431de393ae44d85f5c9db1d722 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 18 Oct 2024 13:43:06 -0500 Subject: [PATCH 24/24] Fix some paraphraphs --- eeps/eep-0072.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md index cc24064..8378485 100644 --- a/eeps/eep-0072.md +++ b/eeps/eep-0072.md @@ -10,10 +10,10 @@ EEP 72: Reserved words and Variables as record names, and enhancement to definit Abstract ======== -This EEP loosens some of the restrictions around record names to make it -no longer necessary to quote them when they are named with reserved -words (`#if` vs `#'if'`) or words with capitalized first characters (terms that -currently would be treated as variables, for example `#Hello` vs `#'Hello'`). +This EEP loosens some of the restrictions around record names to make it no +longer necessary to quote them when they are named with reserved words (`#if` +vs `#'if'`) or words with capitalized first characters (terms that currently +would be treated as variables, for example `#Hello` vs `#'Hello'`). This EEP also proposes to add a new record-like syntax to the record definitions (also adopting the above syntactical changes), so that the @@ -24,9 +24,9 @@ following record definitions would be valid and identical: -record #div{a :: integer(), b :: integer()}. ``` -The latter one is proposed new syntax. The following would also be valid -and identical since parentheses are optional in attributes, -and since atoms may be quoted even when not mandatory: +The latter one is proposed new syntax. The following would also be valid and +identical since parentheses are optional in attributes, and since atoms may be +quoted even when not mandatory: ```erlang -record 'div', {a :: integer(), b :: integer()}.