Compare commits

..

2 commits

Author SHA1 Message Date
2c250c161a
notes on an obvious deficiency 2026-01-16 22:38:43 -06:00
66cb0ff1a6
a slice of ava in 2026 2026-01-16 22:35:45 -06:00
2 changed files with 184 additions and 0 deletions

36
2026/README.md Normal file
View 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
View 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
```