jfecher / ante

A safe, easy systems language
http://antelang.org
MIT License
1.89k stars 79 forks source link

Implement Named Constructor syntax #163

Open jfecher opened 1 year ago

jfecher commented 1 year ago

Ante should be able to construct struct values while naming each field in any order. The syntax should be as follows:

MyStruct with
    field1 = expr1
    field2 = expr2
    ...
    fieldN = exprN

If no indent is provided, fields can also be given on the same line, separated by commas:

MyStruct with field1 = expr1, field2 = expr2, ..., fieldN = exprN

Note that in this form, constructing tuple values will require parenthesis. Expressions can also be omitted if they are syntactically a variable with the same name as the field. That is, the following:

Foo with bar, baz

Is equivalent to

Foo with bar = bar, baz = baz
jfecher commented 1 year ago

If a contributor wants to work on this issue, feel free to tackle it in chunks. E.g. adding parser support first. Then in a later PR add name resolution support. During name resolution, we can desugar to a normal constructor expression with positional fields so that no later pass will need to handle these expressions.

MyStruct with field1 = expr1, ..., fieldN = exprN

Can be desugared to

_v1 = expr1
_v2 = expr2
MyStruct _v1 _v2

Where an outer block expression holds variable definitions for each field to preserve order of operations in case the fields need to be rearranged for the constructor expression. The fresh names generated for each variable should also be names that cannot clash with user's variable names. An easy way to achieve this is by prefixing the name with a symbol like $.

jfecher commented 9 months ago

The remaining work on this issue is to implement name resolution, type checking, and monomorphization for named constructors. It's likely that after name resolution we'll be able to desugar named constructors into regular constructors, e.g:

MyConstructor with
    field3 = expr3
    field2 = expr2
    field1 = expr1

Will desugar to:

// Fields are brought out into Definitions to preserve evaluation order.
// They're given a name guaranteed not to clash with any identifier in the source program.
$field3 = expr3
$field2 = expr2
$field1 = expr1
MyConstructor $field1 $field2 $field3