Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2c250c161a | |||
| 66cb0ff1a6 |
2 changed files with 184 additions and 0 deletions
36
2026/README.md
Normal file
36
2026/README.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Ava - 2026
|
||||
|
||||
At the beginning of 2026, extreme stress gave me new motivation to pursue Ava as
|
||||
a research project. It provides mental relief when times are tough. This new
|
||||
revision of Ava uses my time away to revisit concepts from the ground up and
|
||||
helps to take a principles-first approach to language design.
|
||||
|
||||
## Ideas -- Working Towards Core Principles
|
||||
|
||||
### Single-Purpose Syntax
|
||||
|
||||
As much as possible ensure that syntax has only one meaning.
|
||||
|
||||
### Syntax Consistency
|
||||
|
||||
Apply the same patterns everywhere. Make Ava predictable. Do not allow for
|
||||
special cases or exceptions to rules.
|
||||
|
||||
### Explicitness
|
||||
|
||||
Ava should be clear and precise. Accept some deliberate verbosity to achieve
|
||||
this in some cases.
|
||||
|
||||
### Functional
|
||||
|
||||
Ava is a functional programming language.
|
||||
|
||||
### Data Expression
|
||||
|
||||
Data modeling is critical to software development, and Ava must provide a
|
||||
foundational set of tools for expressing data.
|
||||
|
||||
### Types
|
||||
|
||||
Ava is a statically-typed language with support for generic types, higher-kinded
|
||||
types, type constructors, and generally leans into types.
|
||||
148
2026/a-slice-of-ava.md
Normal file
148
2026/a-slice-of-ava.md
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
# 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)
|
||||
-- The first class list construction is not satisfying:
|
||||
-- - It collides with type constructors.
|
||||
-- - It collides with () for grouping.
|
||||
-- How can I resolve this? Maybe look into tuple syntax and other literals
|
||||
-- and see if that provides any ideas. Or give up on first class lists.
|
||||
let stuff = [foo1, foo2]
|
||||
ex1(stuff, foo3)
|
||||
end def
|
||||
```
|
||||
Loading…
Add table
Reference in a new issue