# 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 ```