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

Language idea: Function contracts #32

Open
alexrp opened this issue Feb 20, 2023 · 2 comments
Open

Language idea: Function contracts #32

alexrp opened this issue Feb 20, 2023 · 2 comments
Labels
area: language Issues related to the design of the language. state: deliberation Issues that require design work and/or discussion.
Milestone

Comments

@alexrp
Copy link
Member

alexrp commented Feb 20, 2023

It would be interesting to see if there's something we can do in this space. We have the assert statement currently, but I think there's room for a more principled feature here.

The feature would need to support preconditions and postconditions (with access to the return value). Preconditions would run before any code in the function, while postconditions would need to run after any defer and use statements in the function. Postconditions would only run when an error is not raised from the function.

Compile-time contract checking would be out of scope initially, but could always be done on a best-effort basis later down the line.

I have no idea what the syntax would look like yet.

@alexrp alexrp added state: deliberation Issues that require design work and/or discussion. type: feature area: language Issues related to the design of the language. labels Feb 20, 2023
@alexrp alexrp added this to the v2.0 milestone Feb 20, 2023
@alexrp alexrp self-assigned this Feb 20, 2023
@alexrp
Copy link
Member Author

alexrp commented Mar 18, 2023

One possibility:

contract ::= contract-precondition contract-result-postcondition? contract-error-postcondition? |
             contract-result-postcondition contract-error-postcondition? |
             contract-error-postcondition
contract-precondition ::= 'in' block-expression
contract-result-postcondition ::= 'out' ('as' lower-identifier)? block-expression
contract-error-postcondition ::= 'err' ('as' lower-identifier)? block-expression

contract-statement ::= contract

statement ::= ... |
              contract-statement

Semantics:

  • Contracts are only allowed as the first statement in the top-level block of a function declaration (no lambdas).
  • Contracts can access the function's parameter bindings.
  • Contracts cannot access surrounding local bindings in the function.
  • Contracts can mutate the result/error values (e.g. if they have mutable fields). This is unfortunate but would be very hard to prevent. A lint pass could catch obvious cases.
  • Contracts cannot ret, raise, or do error-propagating calls.

@alexrp
Copy link
Member Author

alexrp commented May 19, 2023

It would be better if we could incorporate contracts into function declaration and function type syntax in a similar way to what we did for result type and error type syntax...

@alexrp alexrp modified the milestones: v2.0, Future Jan 1, 2024
@alexrp alexrp removed their assignment Jan 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: language Issues related to the design of the language. state: deliberation Issues that require design work and/or discussion.
Development

No branches or pull requests

1 participant