Gleam: Number comparisons in case clause guards

Created on 14 Apr 2020  路  7Comments  路  Source: gleam-lang/gleam

Currently we can check for equality in case clause guards

let y = z
case x {
  1 if x == y -> True
  _ -> False
}

It would be useful to also be able to test for ordering

let y = z
case x {
  1 if x > y -> True
  _ -> False
}

Add support for Int ordering opereators, starting with > in the first PR.

  • [x] GtInt >
  • [x] GtEqInt >=
  • [x] LtInt <
  • [x] LtEqInt <=
  • [x] GtFloat >.
  • [x] GtEqFloat >=.
  • [x] LtFloat <.
  • [x] LtEqFloat <=.

Implementation hints

See this PR for an example: https://github.com/gleam-lang/gleam/pull/458

New AST

The data structure that represents clause guards are defined in the compiler here: https://github.com/gleam-lang/gleam/blob/d35c51843362cf7bd4e173bc9a3afa86a0e28123/src/ast.rs#L292

We would want to add an GtInt variant, similar to the Equals one.

Basic guard methods would need to be updated for this new variant here: https://github.com/gleam-lang/gleam/blob/d35c51843362cf7bd4e173bc9a3afa86a0e28123/src/ast.rs#L292

Erlang code generation

Erlang code generation would need to be updated to support the new variant here: https://github.com/gleam-lang/gleam/blob/d35c51843362cf7bd4e173bc9a3afa86a0e28123/src/erl.rs#L487

Type checking

The type checker would need to be updated to support the new variant here: https://github.com/gleam-lang/gleam/blob/d35c51843362cf7bd4e173bc9a3afa86a0e28123/src/typ.rs#L2328

The new type checker code would be very similar to the code for ClauseGuard::And _except_ it would also unify left and right with int() to ensure that Int's are being compared by the > operator.

Parsing

The lalrpop parser will need to be updated to parse the new syntax here: https://github.com/gleam-lang/gleam/blob/d35c51843362cf7bd4e173bc9a3afa86a0e28123/src/grammar.lalrpop#L284-L310

The ClauseGuard4 statement will need to be renamed to ClauseGuard5, and a new ClauseGuard4 will need to be created by copying ClauseGuard3, incrementing the numbers in it, and adding the new operator.

Testing

I would like to see a test case for when the left hand side is not an int, and another for the right hand side, here: https://github.com/gleam-lang/gleam/blob/master/src/typ/tests.rs#L663-L670

I would like to see a test for the Erlang code generation here: https://github.com/gleam-lang/gleam/blob/master/src/erl/tests.rs#L1499-L1525

help wanted

Most helpful comment

Hi @lpil would like to tackle this problem. Thanks a lot for the comprehensive description.

All 7 comments

Hi @lpil would like to tackle this problem. Thanks a lot for the comprehensive description.

Hi @lpil I tried to push a new branch.

user@pc:~/gleam$ git push --set-upstream origin greater-than-guard
ERROR: Permission to gleam-lang/gleam.git denied to chouzar.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Do I need access to push new branches?
Or maybe I have credential problems :thinking:

You don't have push access to my repo, so you'll need to create a fork and push to that. The fork button is in the top right of the repo home page, and then you can run something like this:

git remote add chouzar [email protected]:chouzar/gleam.git
git push chouzar greater-than-guard

Right! 馃槷 my git knowledge is showing 馃槥. Will do just that, thanks!

No worries! We all know different things :)

@lpil would it be helpful to add an example (examples?) of these guards to the docs? In the checking equality in patterns section I would assume. I'm happy to create a PR for it if so.

That's a great idea! Please make the PR into this branch rather than master as this feature has not been released yet -> https://github.com/gleam-lang/website/pull/new/gleam-0.8

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lpil picture lpil  路  5Comments

CrowdHailer picture CrowdHailer  路  4Comments

lpil picture lpil  路  6Comments

lpil picture lpil  路  7Comments

pd-andy picture pd-andy  路  4Comments