ava/notes/expressions.md

1.8 KiB

Expressions

Expressions are the basis of programming in Ava. An expression is some code that will produce a value when evaluated.

Syntax

Functions contain expressions. Expressions take the form of:

  • Literal Values
  • Variable Definitions
  • Variable References
  • Function Calls
  • Control Structures

Control Structures

If Then

The if/then expression expects an expression that returns a Boolean Value. That expression is evaluated. If it evaluates to true, the then expression is evaluated. Otherwise the else expression is evaluated.

if <boolean expr> then <expr> else <expr>

Match

match <expr>
    case <pattern> => <expr>
end match

Do/Return

The do/return expression allows for imperative composition of monadic expressions. It works with any types that are members of Monad or BiMonad.

Do/Return for Monad

Each step of the do is defined by an expression that produces a Monad. The syntax desugars to fmap calls, where return is a map call.

fn foo: () => Option[Int32]
    1
end fn

fn bar: () => Option[Int32]
    2
end fn

fn baz: () => Option[Int32]
    3
end fn

let example: Option[Int32] :=
    do
        x <- foo()
        y <- bar()
        _ <- baz()
    return
        x + y
    end do

assert(example == Some(3))

Do/Return for BiMonad

The BiMonad is right biased, where the "left" side is assumed to represent some error case. The typical use case for this behavior is the IO[E, A] type.

fn foo: () => IO[String, Int32]
    sync(1)
end fn

fn bar: () => IO[String, Int32]
    sync(2)
end fn

fn baz: () => IO[String, Int32]
    sync(3)
end fn

let program: IO[String, Int32] :=
    do
        x <- foo()
        y <- bar()
        _ <- baz()
    return
        x + y
    end do

program ->
    sum => assert(sum == 3)