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

Allow assignment as last expression #1000

Closed
wants to merge 3 commits into from
Closed

Conversation

KtorZ
Copy link
Member

@KtorZ KtorZ commented Aug 20, 2024

  • Allow expect as last (or only) expression in function body, when clauses and if branches. Such expressions unify with Void. Fundamentally, we merely desugar last expect into a sequence of expect ... + Void as follows:

    expressiondesugar into
    fn expect_bool(data: Data) -> Void {
      expect _: Bool = data
    }
    
    fn expect_bool(data: Data) -> Void {
      expect _: Bool = data
      Void
    }
    
  • allow tests to return Void. Tests that return Void are treated the same as tests that return True. This changes works well in combination with the previous one, obviously. But it also work with arbitrary functions calls in tests that would return Void (assuming that those calls contain assertions doing validations as side-effects).

    fn some_validations(fixture) -> Void {
      expect ...
      expect ...
    }
    
    test foo() {
      some_validation(my_fixture)
    }
    

  This is debatable, but I would argue that it's been sufficiently
  annoying for people and such a low-hanging fruit that we ought to do
  something about it.

  The strategy here is simple: when we find a sequence of expression
  that ends with an assignment (let or expect), we can simply desugar it
  into two expressions: the assignment followed by either `Void` or a
  boolean.

  The latter is used when the assignment pattern is itself a boolean;
  the next boolean becomes the expected value. The former, `Void`, is
  used for everything else. So said differently, any assignment
  implicitly _returns Void_, except for boolean which return the actual
  patterned bool.

  <table>
  <thead><tr><th>expression</th><th>desugar into</th></tr></thead>
  <tbody>
  <tr>
  <td>

  ```aiken
  fn expect_bool(data: Data) -> Void {
    expect _: Bool = data
  }
  ```
  </td>
  <td>

  ```aiken
  fn expect_bool(data: Data) -> Void {
    expect _: Bool = data
    Void
  }
  ```
  </td>
  </tr>
  <tr>
  <td>

  ```aiken
  fn weird_maths() -> Bool {
    expect 1 == 2
  }
  ```
  </td>
  <td>

  ```aiken
  fn weird_maths() -> Bool {
    expect True = 1 == 2
    True
  }
  ```
  </td>
  </tr>
  </tbody>
  </table>
@KtorZ KtorZ requested a review from a team as a code owner August 20, 2024 12:31
@KtorZ KtorZ self-assigned this Aug 20, 2024
  - We now consistently desugar an expect in the last position as
    `Void`. Regardless of the pattern. Desugaring to a boolean value is
    deemed too confusing.

  - This commit also removes the desugaring for let-binding. It's only
    ever allowed for _expect_ which then behaves like a side effect.

  - We also now allow tests to return either `Bool` or `Void`. A test
    that returns `Void` is treated the same as a test returning `True`.
@KtorZ KtorZ closed this Aug 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ In Next Release
Development

Successfully merging this pull request may close these issues.

1 participant