ava/2026/a-slice-of-ava.md

143 lines
4.6 KiB
Markdown

# A Slice of Ava
```
-- Modules are used to organize and distribute code.
module example
--{
Some syntax examples here:
- Multi-line comments
- `[]` used for complex type constructors (declaration)
- `[]` used for complex type constructors (constructing the type)
- `given` used to declare type constructors
- `begin` used to start a block declaration
- `class` used to denote a type class declaration
- `,` (the comma character) used to distinguish enumerated elements
- `fn` used to declare a function
- `:` used to assign a type to some name
- `->` used to define function types
- `()` used for grouping
- `end` used to signify the end of a block declaration.
These will appear over and over throughout this example.
Functions fundamentally accept one input and one output. The `->` syntax and
`()` application syntax work together:
- `->` is left-associative
- `(p1, p2, ... pk)` enumerates function arguments and provides a natural
facade over single-argument functions.
- partial function application is supported
Given some function `ex: A -> B -> C -> D`:
- `ex(a, b)` produces a function `C -> D`
- `ex(a, b, c)` produces a value of type `D`
- `ex(a)(b)` first produces a function `B -> C -> D` which is then evaluted
to produce a function `C -> D`.
}--
given F[*]
begin class Functor
--{
This is an example of function documentation.
@given A The type of data being transformed.
@given B The type of data being emitted.
@param F[A] The input data.
@param (A -> B) The transformation function.
@return The transformed data.
}--
given A, B
fn map: F[A] -> (A -> B) -> F[B]
end class
-- Boolean: The type for Boolean values in Ava
given A
begin class Eq
fn eqv: A -> A -> Boolean
end class
--{
This section introduces new syntax:
- `instance` used to declare a type class instance
- `of` used to denote the type class being implemented
- `for` used to denote the list of type arguments that satisfy the type
class declaration.
- `{}` used to express a function implementation.
- pattern matching used to provide names to function arguments.
- `=>` used to connect the matched pattern of a function implementation to
the code body of the function.
- `.` used to traverse hierarchical elements.
In this case, `.` is used to:
- access the `list` module from the `std` module
- access the `map` function from the `list` module
}--
begin instance of Functor for List
given A, B
begin fn map: List[A] -> (A -> B) -> List[B]
{ list, f => std.list.map(list, f) }
end fn
end instance
--{
Record definitions in Ava are collections of named, typed, parameters.
- Int32: The type for 32-bit integers in Ava.
}--
begin record Foo
x: Int32,
y: Int32,
end record
--{
More unique syntax:
- Record names are types: `Foo`, in this case.
- Infix functions: `==`, `&&`
(These are part of the standard library).
}--
begin instance of Eq for Foo
begin fn eqv: Foo -> Foo -> Boolean
{ foo1, foo2 => (foo1.x == foo2.x) && (foo1.y == foo2.y) }
end fn
end instance
--{
This function begins to use what we have previously declared to do something
real.
- `where` to express a type class dependency for some type
- `requires` to express that the named type requires an instance of some type class.
- `.` used to access `map` from the type class instance for Functor
- `.` used to access `eqv` from the type class instance for Eq
- `{}` used to define an _inline anonymous function_.
Note that type classes implicitly make their functions available to call for
some type that satisfies the first argument of the type class function. Type
classes can _also_ expose their functions by accessing the class directly.
}--
given F[*], A
where F requires Functor
where A requires Eq
begin fn ex1: F[A] -> A -> C[Boolean]
{ f, aa => f.map({ a => Eq[A].eqv(a, aa) }) }
end fn
-- `const` used to denote constant values at the top level.
const MagicNumber: Int32 = 2
--{
- `def` used to declare arbitrary expressions
- `let` used to assign (immutable) data to names
- Constructing record instances by using the natural order
- Constructing record instances by using named parameters
- `[]` for first class list syntax.
- Invoking a function.
`def` is not evaluated until it is invoked, and it is reevaluated every time it
is invoked.
}--
begin def demo: List[Boolean]
let foo1 = Foo(1, MagicNumber)
let foo2 = Foo(1, 3)
let foo3 = Foo(x = 1, y = MagicNumbe)
let stuff = [foo1, foo2]
ex1(stuff, foo3)
end def
```