Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add syntax support for record updates #1642

Closed
jonaprieto opened this issue Nov 22, 2022 · 3 comments · Fixed by #2263
Closed

Add syntax support for record updates #1642

jonaprieto opened this issue Nov 22, 2022 · 3 comments · Fixed by #2263
Assignees
Labels
Milestone

Comments

@jonaprieto
Copy link
Collaborator

type A (B : Type) :=
  constructorName {
    cfield1 : X1;
    cfield2 : X2;
 };

An update for A is written as follows:

f : A B;
f := constructorName { cfield1 := x; cfield2 := y};

g : A B -> A B;
g r := r { cfield1 := x};
@jonaprieto jonaprieto added this to the 0.3 milestone Nov 22, 2022
@lukaszcz lukaszcz modified the milestones: 0.3, 0.5 Jan 24, 2023
@lukaszcz
Copy link
Collaborator

lukaszcz commented May 26, 2023

The above record update syntax doesn't play well with the proposed syntax for named arguments:

Named arguments automatically provide record creation syntax:

constructorName (cfield1 := x; cfield2 := y)

is just

constructorName x y

But then

r {cfield1 := x}

would desugar to

r {x}

and this conflicts with the record update syntax.

I propose to introduce a keyword with for record updates:

r with {cfield1 := x}

@lukaszcz
Copy link
Collaborator

lukaszcz commented May 26, 2023

I think it would be convenient, especially in combination with traits, to also allow with for record creation, and allow full top-level declaration syntax including optional signatures inside the braces on the right. Then given a trait:

trait
type Encoding (A : Type) := MkEncoding {
  encode : A -> Field;
  decode : Field -> A;
};

one could write:

type E (A : Type) := 
| C1 : A -> E 
| C2 : E;

instance 
encoding : {A : Type} -> {{Encoding A}} -> Encoding (E A);
encoding := MkEncoding with {
  encode : E A -> Field;
  encode (C1 x) := encode x + 1;
  encode C2 := 0;

  decode : Field -> E A;
  decode zero := C2; 
  decode (suc x) := C1 (decode x);
};

@janmasrovira
Copy link
Collaborator

janmasrovira commented May 29, 2023

I think adding the with keyword to remove ambiguity is reasonable.
I also like the proposal to allow inline function definitions in record creation/update.

@paulcadman paulcadman modified the milestones: 0.4.1, 0.4.2 Jun 23, 2023
@lukaszcz lukaszcz modified the milestones: 0.4.2, 0.5 Jun 27, 2023
@janmasrovira janmasrovira self-assigned this Jul 27, 2023
lukaszcz pushed a commit that referenced this issue Aug 7, 2023
- Closes #1642.

This pr introduces syntax for convenient record updates.
Example:
```
type Triple (A B C : Type) :=
  | mkTriple {
      fst : A;
      snd : B;
      thd : C;
    };

main : Triple Nat Nat Nat;
main :=
  let
    p : Triple Nat Nat Nat := mkTriple 2 2 2;
    p' :
      Triple Nat Nat Nat :=
        p @triple{
          fst := fst + 1;
          snd := snd * 3
        };
    f : Triple Nat Nat Nat -> Triple Nat Nat Nat := (@triple{fst := fst * 10});
  in f p';
```
We write `@InductiveType{..}` to update the contents of a record. The
`@` is used for parsing. The `InductiveType` symbol indicates the type
of the record update. Inside the braces we have a list of `fieldName :=
newValue` items separated by semicolon. The `fieldName` is bound in
`newValue` with the old value of the field. Thus, we can write something
like `p @triple{fst := fst + 1;}`.

Record updates `X@{..}` are parsed as postfix operators with higher
priority than application, so `f x y @x{q := 1}` is equivalent to `f x
(y @x{q := 1})`.

It is possible the use a record update with no argument by wrapping the
update in parentheses. See `f` in the above example.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants