From e3167da0f068a51da3721368f0120bcfa56bb5b8 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Wed, 31 Mar 2021 17:50:08 +0800 Subject: [PATCH 1/7] enum abstract over enum --- 0000-template.md | 78 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/0000-template.md b/0000-template.md index 78aac08..07fc8d5 100644 --- a/0000-template.md +++ b/0000-template.md @@ -1,41 +1,85 @@ # Feature name * Proposal: [HXP-NNNN](NNNN-filename.md) -* Author: [Haxe Developer](https://github.com/haxedev) +* Author: [Kevin Leung](https://github.com/kevinresol) ## Introduction -Short description of the proposed feature. Keep it short, so the reader -can quickly get what's it all about. +`enum abstract` is basically a mechansim to define a subset from a superset. +For example, when used over `Int`, it creates a finite subset from a infinite superset which consists of all integers. (Well, techinically it is not really infinite because it is limited by computer memory) + +Therefore in theory, it should also be used over ordinary `enum`, to create a subset of its constructors. ## Motivation -Describe the problems adressed by this feature. If a similar effect -can be achieved without it with some workarounds, describe the drawbacks -of the workaround. If it's something completely new, show how it will -help developers write better Haxe code or how it will improve the generation -of target code by the compiler. +1. Expose `enum` partially + +```haxe +enum CRUD { + Create(id:String, data:Any); + Read(id:String); + Update(id:String, data:Any); + Delete(id:String); +} + +enum abstract ReadAndUpdate(CRUD) to CRUD { + final ReadData = Read; + final UpdateData = Update; +} + +function doAdminTask(task:CRUD):Void { + // perform the task +} + +function doEditorTask(task:ReadAndUpdate):Void { + return doAdminTask(task); +} +``` + +In the above example, we can expose a limited set of operations to restricted users via the `doEditorTask` + +2. Reuse existing `enum` to reduce code size + +```haxe +enum abstract Status(Option) to Option { + final Continue = Some; + final End = None; +} +``` + +Since at runtime `Status` does not exists and it will be represented by `Option`. We saved the code size for it. + ## Detailed design -Describe the proposed design in details the way language user can understand -and compiler developer can implement. Show corner cases, provide usage examples, -describe how this solution is better than current workarounds. +To start simple, we should only allow declaring an alias to the underlying enum constructor. Since the type of the abstract fields is just the same as the underlying aliased enum constructor, pattern matching should just work with minimal work. + +#### Futher developments: + +- Partial/full application of enum constructors: + +```haxe +enum abstract Status(Option) to Option { + final Continue = Some(1); + final End = None; +} +``` + +This may be handled in conjunction with other evolution proposals such as https://github.com/HaxeFoundation/haxe-evolution/pull/86 ## Impact on existing code -What impact this change will have on existing code? Will it break compilation? -Will it compile, but break in run-time? How easy it is to migrate existing Haxe code? +Since the abstract fields are no longer a primitive value, it may affect macro code that tries to obtain the literal value at compile time. +But since the feature is new, such breakage will only happen when a abstract-enum-over-enum is passed to such macros. ## Drawbacks -Describe the drawbacks of the proposed design worth consideration. This doesn't include -breaking changes, since that's described in the previous section. +To be discussed. ## Alternatives -What alternatives have you considered to address the same problem, why the proposed solution is better? +One can always declare a separate ordinary enum as a subset of another enum, but that would require manual traslation to its superset. Also it incurs extra generated code size. ## Unresolved questions -Which parts of the design in question is still to be determined? +To be discussed. From 307254b8186fd243d392b60075fd0f50da8c80a0 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Wed, 31 Mar 2021 17:54:46 +0800 Subject: [PATCH 2/7] Fix typo --- 0000-template.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/0000-template.md b/0000-template.md index 07fc8d5..55bc4f6 100644 --- a/0000-template.md +++ b/0000-template.md @@ -8,7 +8,7 @@ `enum abstract` is basically a mechansim to define a subset from a superset. For example, when used over `Int`, it creates a finite subset from a infinite superset which consists of all integers. (Well, techinically it is not really infinite because it is limited by computer memory) -Therefore in theory, it should also be used over ordinary `enum`, to create a subset of its constructors. +Therefore in theory, it could also be used over ordinary `enum`, to create a subset of its constructors. ## Motivation @@ -47,7 +47,7 @@ enum abstract Status(Option) to Option { } ``` -Since at runtime `Status` does not exists and it will be represented by `Option`. We saved the code size for it. +Since at runtime `Status` does not exist and it will be represented by `Option`. We saved the code size for it. ## Detailed design @@ -59,9 +59,11 @@ To start simple, we should only allow declaring an alias to the underlying enum - Partial/full application of enum constructors: ```haxe -enum abstract Status(Option) to Option { - final Continue = Some(1); - final End = None; +enum abstract MaybeValue(Option) to Option { + final One = Some(1); + final Two = Some(2); + final Other = Some; + final Nothing = None; } ``` From 974235a737c6ecc144e8a7bb8df327772d6cfce1 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Wed, 31 Mar 2021 17:58:51 +0800 Subject: [PATCH 3/7] Mention #10 --- 0000-template.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/0000-template.md b/0000-template.md index 55bc4f6..aa25ea7 100644 --- a/0000-template.md +++ b/0000-template.md @@ -49,6 +49,10 @@ enum abstract Status(Option) to Option { Since at runtime `Status` does not exist and it will be represented by `Option`. We saved the code size for it. +3. Enable enum instance/static fields + +We get https://github.com/HaxeFoundation/haxe-evolution/issues/10 for free + ## Detailed design From ed8c746ba0a406ed6cd32f07d66342cd49662ce5 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Wed, 31 Mar 2021 18:00:07 +0800 Subject: [PATCH 4/7] Formatting --- 0000-template.md | 78 ++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/0000-template.md b/0000-template.md index aa25ea7..018d8e9 100644 --- a/0000-template.md +++ b/0000-template.md @@ -14,44 +14,44 @@ Therefore in theory, it could also be used over ordinary `enum`, to create a sub 1. Expose `enum` partially -```haxe -enum CRUD { - Create(id:String, data:Any); - Read(id:String); - Update(id:String, data:Any); - Delete(id:String); -} - -enum abstract ReadAndUpdate(CRUD) to CRUD { - final ReadData = Read; - final UpdateData = Update; -} - -function doAdminTask(task:CRUD):Void { - // perform the task -} - -function doEditorTask(task:ReadAndUpdate):Void { - return doAdminTask(task); -} -``` - -In the above example, we can expose a limited set of operations to restricted users via the `doEditorTask` + ```haxe + enum CRUD { + Create(id:String, data:Any); + Read(id:String); + Update(id:String, data:Any); + Delete(id:String); + } + + enum abstract ReadAndUpdate(CRUD) to CRUD { + final ReadData = Read; + final UpdateData = Update; + } + + function doAdminTask(task:CRUD):Void { + // perform the task + } + + function doEditorTask(task:ReadAndUpdate):Void { + return doAdminTask(task); + } + ``` + + In the above example, we can expose a limited set of operations to restricted users via the `doEditorTask` 2. Reuse existing `enum` to reduce code size -```haxe -enum abstract Status(Option) to Option { - final Continue = Some; - final End = None; -} -``` + ```haxe + enum abstract Status(Option) to Option { + final Continue = Some; + final End = None; + } + ``` -Since at runtime `Status` does not exist and it will be represented by `Option`. We saved the code size for it. + Since at runtime `Status` does not exist and it will be represented by `Option`. We saved the code size for it. 3. Enable enum instance/static fields -We get https://github.com/HaxeFoundation/haxe-evolution/issues/10 for free + We get https://github.com/HaxeFoundation/haxe-evolution/issues/10 for free ## Detailed design @@ -62,14 +62,14 @@ To start simple, we should only allow declaring an alias to the underlying enum - Partial/full application of enum constructors: -```haxe -enum abstract MaybeValue(Option) to Option { - final One = Some(1); - final Two = Some(2); - final Other = Some; - final Nothing = None; -} -``` + ```haxe + enum abstract MaybeValue(Option) to Option { + final One = Some(1); + final Two = Some(2); + final Other = Some; + final Nothing = None; + } + ``` This may be handled in conjunction with other evolution proposals such as https://github.com/HaxeFoundation/haxe-evolution/pull/86 From d3852b810fc8e48e55396ded3e5f8a5c677e150a Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Wed, 31 Mar 2021 18:00:49 +0800 Subject: [PATCH 5/7] More formatting --- 0000-template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0000-template.md b/0000-template.md index 018d8e9..9af20c5 100644 --- a/0000-template.md +++ b/0000-template.md @@ -71,7 +71,7 @@ To start simple, we should only allow declaring an alias to the underlying enum } ``` -This may be handled in conjunction with other evolution proposals such as https://github.com/HaxeFoundation/haxe-evolution/pull/86 + This may be handled in conjunction with other evolution proposals such as https://github.com/HaxeFoundation/haxe-evolution/pull/86 ## Impact on existing code From 2f0485e4f0252a4984c5c30395eaebce1011bc5a Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Wed, 31 Mar 2021 18:01:51 +0800 Subject: [PATCH 6/7] Most importantly... --- 0000-template.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/0000-template.md b/0000-template.md index 9af20c5..277e57f 100644 --- a/0000-template.md +++ b/0000-template.md @@ -1,4 +1,4 @@ -# Feature name +# `enum abstract` over `enum * Proposal: [HXP-NNNN](NNNN-filename.md) * Author: [Kevin Leung](https://github.com/kevinresol) @@ -84,7 +84,7 @@ To be discussed. ## Alternatives -One can always declare a separate ordinary enum as a subset of another enum, but that would require manual traslation to its superset. Also it incurs extra generated code size. +One can always declare a separate ordinary enum as a subset of another enum, but that would require manual translation to its superset. Also it incurs extra generated code size. ## Unresolved questions From c2e8728fbfb030074de40c888b68470b68baec74 Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Wed, 31 Mar 2021 18:02:18 +0800 Subject: [PATCH 7/7] I should be less hasted --- 0000-template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0000-template.md b/0000-template.md index 277e57f..5f7d293 100644 --- a/0000-template.md +++ b/0000-template.md @@ -1,4 +1,4 @@ -# `enum abstract` over `enum +# `enum abstract` over `enum` * Proposal: [HXP-NNNN](NNNN-filename.md) * Author: [Kevin Leung](https://github.com/kevinresol)