experiment: add do #lab variant blocks and / # narrowing operator#5987
experiment: add do #lab variant blocks and / # narrowing operator#5987
Conversation
Generalize do ? { ... } option blocks to do #lab { ... } for variants.
Inside a do #lab block, ! on a variant extracts the #lab payload and
short-circuits (propagates) all other tags. Also add e / #lab for
narrowing a variant type by removing #lab (trapping if matched).
Made-with: Cursor
Added tests for handling variants with different payload types in do #ok blocks. This includes scenarios for successful extraction of payloads, error propagation, and timeout cases. Updated the desugaring process to support narrowing of variant types by removing specific tags during pattern matching. - Introduced assertions for expected outcomes in new test cases. - Modified desugar.ml to implement type narrowing for variants.
Updated the desugaring process to enhance pattern matching for variants. The changes include the introduction of a temporary variable for capturing variant payloads and simplifying the switch expressions. This refactor improves code clarity and maintains functionality for handling variant types in do blocks.
Modified the representation of BangE to include an optional reference for scoped option/variant projections. This change enhances type safety and consistency in pattern matching, affecting several files including syntax.ml, parser.mly, and various traversal and typing modules. The updates ensure that the BangE expression is correctly processed in the context of variant handling and type inference.
Changed the type of `vd_lab` in `variant_do_ctx` from `string` to `T.lab` for improved type safety and consistency. Additionally, updated the `BangE` expression in `syntax.ml` to reflect this change, ensuring better alignment with the overall type system. These modifications enhance the handling of variant projections and maintain coherence across the typing and syntax modules.
Enhanced the symbol representation in printers.ml by adding handling for the T_DIVHASH token, allowing for proper rendering of the division hash operator. This update improves the completeness of the symbol representation in the frontend.
Updated the pattern and expression representation in desugar.ml to enhance clarity and consistency. The changes involve restructuring the pattern matching cases to use a more uniform format, ensuring that the pattern and expression components are clearly delineated. This refactor aims to improve maintainability and readability of the desugaring process for variant types.
Added support for variant blocks `do #lab { ... }`, which generalize option blocks to handle variant types. The `!` operator now extracts the payload of the success tag and propagates other tags. Introduced the variant narrowing operator `<exp> / #lab` to remove a tag from a variant type, enhancing type safety. Updated documentation and examples to reflect these changes.
Added detailed explanations and examples for the newly introduced variant blocks (`do #lab`) and the variant narrowing operator (`/ #lab`). Clarified how these features enhance error handling and type safety in Motoko, particularly in the context of `Result`-like types. Updated documentation to improve understanding of their usage and behavior.
…ns.md Updated the documentation to provide clearer examples and explanations for the variant blocks (`do #lab`) and the variant narrowing operator (`/ #lab`). Enhanced the section on error handling and type safety in Motoko, particularly focusing on their application with `Result`-like types. This aims to improve user understanding of these features.
| <exp_bin> ::= | ||
| <exp_un> | ||
| <exp_bin> <binop> <exp_bin> | ||
| <exp_bin> DIV'#' <id> |
| <unassign> <exp(ob)> | ||
| <relop> <exp_bin(ob)> | ||
| . <id> | ||
| <binop> <id> |
There was a problem hiding this comment.
This is odd - I wonder why this is now an item? Can't (myself) tell how it follows from the grammar.
There was a problem hiding this comment.
Oh, I see, its the remainder of the production on 221, I guess <exp_bin> <bin_op> <exp_bin> maybe.
|
|
||
| ### Variant narrowing (`/ #lab`) | ||
|
|
||
| The expression `e / #lab` removes tag `#lab` from a variant type, trapping if the value actually carries that tag. This is useful for asserting that a variant is *not* a particular case: |
There was a problem hiding this comment.
Why would we want such an operator? It seems risky to have because it traps.
Also, why is this together with the 'variant blocks'? They seem like two independent features
There was a problem hiding this comment.
yeah, I suggested this operator to the AI as a way to implement ! efficiently, without reconstructing the variant value to propagate (needed when the success payload type changes. I think it would actually be more appropriate at the IR, not source level, to avoid the unchecked cast in desugaring.
But it's not totally silly as a source level feature either, tbh.
There was a problem hiding this comment.
I mean, it traps, but it's not unsafe.
There was a problem hiding this comment.
The idea was that
e ! ~~>
switch e {
#success v -> v
other -> break <lab> (other / #success)
(but the AI doesn't actually use that, it does:
e ! ~~>
switch e {
#success v -> v
other -> break <lab> (Cast<typ, typ / {# success _}> other)
(exploiting our unsafe cast as IR level)
If you can't beat 'em.... experimenting with cursor.
Generalize do ? { ... } option blocks to do #lab { ... } for variants. Inside a do #lab block, ! on a variant extracts the #lab payload and short-circuits (propagates) all other tags. Also add e / #lab for narrowing a variant type by removing #lab (trapping if matched).
Made-with: Cursor
Both exciting and depressing at the same time. But mostly depressing.
[ ] Manually check test output
[ ] Consider add SlashVariant prim to IR.prim, instead of relying on safe use of unsafe cast prim
[ ] Consider removing
e / # labsyntax. It's useful to avoid reallocation, but also trapping. I suggested it to the AI as a means of implementing!efficiently, without necessarily adding it to the surface language (but it preferred casts anyway).Related (old) PR adding option blocks (
do ? ...) #2174