Skip to content
This repository has been archived by the owner on Sep 7, 2023. It is now read-only.

Expression sub-language for modifying state #143

Closed
jeromesimeon opened this issue May 11, 2018 · 18 comments
Closed

Expression sub-language for modifying state #143

jeromesimeon opened this issue May 11, 2018 · 18 comments

Comments

@jeromesimeon
Copy link
Member

When changing the state, one has currently to rebuild the whole state each time. It might be useful to have expressions specifically designed to modify the state. For instance:

set status to "BREACHED" in state;
add new PaymentObligation to obligations in state;
remove notice in obligations from state;
return ...
@jeromesimeon jeromesimeon added the Type: Feature Request 🛍️ New feature or request label May 11, 2018
@jeromesimeon jeromesimeon added this to the Contract support milestone May 11, 2018
@jeromesimeon jeromesimeon changed the title Update sub-language for modifying state Expression sub-language for modifying state May 11, 2018
@mttrbrts
Copy link
Member

mttrbrts commented Dec 27, 2018

How about something like ...

set state.status to "BREACHED";
add new PaymentObligation to state.obligations;
remove notice from state.obligations;
return

@jeromesimeon
Copy link
Member Author

jeromesimeon commented Dec 27, 2018

I like it! One issue is what does remove mean, for which there are several options:

  • is remove based on value equality (i.e., notice is an obligation object and your compare the structure)
  • is remove based on a kind of identity (we never use identifiers anywhere at the moment)
  • is remove based on another kind of criteria

We could imagine something like the following, which would provide a lot more flexibility as to how the user specifies what to remove:

remove x from state.obligations where x.kind = "notice";
remove x from state.obligations where x.id = "5555-3562-1412";
return ...

@jeromesimeon
Copy link
Member Author

Another question, is whether those new operations should replace the current set state statement altogether (i.e., remove the current set state).

@dselman
Copy link
Contributor

dselman commented Jan 2, 2019

For types that have identified by in the model (basically everything except concepts and enums) I think it would be natural to use the modelled identifier for equality. For concepts I guess we either have to use value-based equality, or allow the user to specify an identified by expression to the call to remove.

I do like the where expressions for selection as well however.

How about update state to contrast with set state?

@jeromesimeon
Copy link
Member Author

@dselman I am not sure if we have a mechanism to check the unicity of identifiers at the moment? And they aren't distinguished from other attributes in Ergo (yet?) -- technically there isn't any object equality in Ergo, only value equality.

You could easily use the where form to handle it as well:

remove x from state.obligations where x.id = notice_id;

If we keep both forms, I think the update state and set state distinction may help, but isn't required.

@jeromesimeon
Copy link
Member Author

For the records, @kach had suggested the nice and compact:

state.status <- BREACHED;

And add/remove can technically be handled using array operations:

state.obligations <- arrayAdd(state.obligations, [new PaymentObligation{ ... }]);
state.obligations <- arraySubtract(state.obligations, notice);

@mttrbrts
Copy link
Member

mttrbrts commented Jan 2, 2019

I like the brevity of this suggestion, but would rather avoid introducing another operator.

With this in mind what about ... ?

set state.status = BREACHED;

This aligns the syntax for state assignment with assignment in let expressions.

@otawakkil
Copy link

There is a nice syntax in F# (OCaml Dotnet variant) that does something like this
set state { state with status = "STARTED" }
It is aligned with the "immutability" mindset.
the expression is like
{ objReference 'with' fieldAssignmentList }

@jeromesimeon
Copy link
Member Author

I like the idea of conveying cloning since this could be used outside of setting state. I don’t know why I didn’t think of this. And of course the ocaml/f# syntax is quite nice for that.

Note that things are a bit more difficult in Ergo since we need those operations to be aware of the “class hierarchy”, not just records as in OCaml.

A branch is tracking this, but I still need to work through the typing ramifications.

@otawakkil
Copy link

Is there a level of meta-programming or reflection on types ?

@jeromesimeon
Copy link
Member Author

Not in Ergo itself if I understand your question correctly. Although you can use match expression on type names which are declared as part of the hierarchy.

@jeromesimeon
Copy link
Member Author

jeromesimeon commented Mar 8, 2019

In JavaScript, we can use the spread operator for cloning. This might be a good syntax in Ergo as well?

set state { ...state, "status": "BREACHED" }

@otawakkil
Copy link

Nice. You can even save typing by using & instead

@dselman
Copy link
Contributor

dselman commented Mar 8, 2019

In JavaScript, we can use the spread operator for cloning. This might be a good syntax in Ergo as well?

set state { ...state, "status": "BREACHED" }

Doesn't seem that obvious to a less technical user. update state ?

@jeromesimeon
Copy link
Member Author

@dselman that was also the impression on the Ergo call this morning.

I do find a syntax for cloning appealing since it can be applied to things other than the state, but it's maybe something to wait on.

@otawakkil
Copy link

The logic is to be able to clone and override any type not just the state.
let myObj = {...someBojOfSameType, overridenFieldList }

state being here just one case of it.

@jeromesimeon
Copy link
Member Author

I like the brevity of this suggestion, but would rather avoid introducing another operator.

With this in mind what about ... ?

set state.status = BREACHED;

This aligns the syntax for state assignment with assignment in let expressions.

This is the proposal that has been implemented in #667

Note that this new feature is specific to the state, this does not include support for things like spread operator.

jeromesimeon added a commit that referenced this issue Oct 8, 2019
jeromesimeon added a commit to jeromesimeon/ergo that referenced this issue Oct 8, 2019
jeromesimeon added a commit to jeromesimeon/ergo that referenced this issue Oct 8, 2019
jeromesimeon added a commit to jeromesimeon/ergo that referenced this issue Oct 13, 2019
@jeromesimeon
Copy link
Member Author

Implemented in the 0.20 branch. Tested in Cicero and Cicero template library.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants