# ACC&PA Team Distribution and Language Idea
## Useful Links
* Github repository: [link](https://github.com/mcflydesigner/lambda-interpreter)
## Very Hard-Typed Kind of Functional Language
| Team member | Role |
| -------- | -------- |
| Maxim Ksenofontov | Team leader, interpreter developer |
| Dmitrii Polushin | QA engineer, technical writer(documentation |
| Vladislav Levchenko | Lexer analyzer, Syntax analyzer developer, tests |
| Vladislav Lamzenkov | Interpreter developer |
## Language Ideas
Our language syntax and semantics are going to be similar to functional language. It should be used as a first language to study functional programming. At the same time, it should be a typed language, so students are able to infer type by themselves. It would be verified by the type-checker that is the part of the interpreter.
## Language List of Features
| Features | Approximate Difficulty Points |
| -------- | -------- |
Type Checker | 0 |
Base Types (integer, real, boolean, string, unit) | 0 |
User-defined Terms and Types (records and type aliase) | 0 |
Standard Library (e.g. arithmetic, logical) | 0 |
First-class functions (anonymous functions) | 0 |
Nested Definitions (nested functions, local variables) | 0 |
Simple Constraint-Based Type Inference (e.g. support auto types) | 0 |
Functions with multiple (but fixed amount) arguments | 1 |
General Recursion | 2 |
Simple modules and imports | 3 |
Records | 3 |
Subtyping | 4 |
**Difficulty Result** | **13** |
## Description of a Demo Program
Basic calculator with engineering functions that will be implemented as modules in our language.
*We show all features of our language as code snippets provided in the documentation.*
**For now, examples of programs may be found in the section "#Examples of features" :)**
## Formal Grammar
Defining the grammar of our functional language is [here](https://github.com/mcflydesigner/lambda-interpreter/blob/feature/interpreter/bnf/doc/hardtyped.pdf)!
## Examples of features
**Base Types**
```shell=bash
-| std.nk
let n: Integer = 5;
let r: Real = 10.5;
let b: Boolean = true;
let s: String = "Simple string";
let u: Unit = print (s);
```
**Local and Global declarations**
```
// TODO
```
**Comments**
```
// One-line comment
/*
Multi-line comments
*/
```
**Simple modules and imports**
```shell=bash
-| std.nk
-| math.nk as math
let n = 5 in math.sqrt(n);
```
**First-class functions (anonymous functions)**
```shell=bash
-| std.nk
let concat = /\ x: String. y: String. {
x + y
}
concat ("Hello,", "World");
```
**User-defined types and subtyping**
```shell=bash
-| std.nk
-| math.nk
// Creating a vector of x, y, z
let Vector3d = {x1: Real, x2: Real, x3: Real};
let length3d = /\ v: Vector3d. {
math.sqrt (math.sqr (v.x1) + math.sqr (v.x2) + math.sqr (v.x3))
} in
length3d ({x1 = 1.1, x2 = 5.5, x3 = 10.0, x4 = 1.7});
```
**Nested function**
```shell=bash
-| std.nk
/\ x: String. {
print (x);
/\ y: String. {
print (y)
} (x);
}
```
**Function with multiple arguments**
```shell=bash
-| std.nk
/\ name: String. surname: String. {
print (name);
print (surname);
};
```
**General recursion**
```shell=bash
-| std.nk
letrec factorial =
/\ n: Nat. {
| (n == 1): n
|: n * factorial (n-1)
};
```
**Type ascription**
```shell=bash
-| std.nk
let n = 5 as Integer;
```
**Built-in lists**
```shell=bash
-| std.nk
let l1 = [1, 3, 2] in
letrec print_list = /\ l: []. {
print (head l1);
print_list (tail l1);
} in print_list (l1);
```
**Built-in records**
```shell=bash
-| std.nk
let r1 = {a = 1, b = 2, c = 3} in
let print_record_elements = /\ r: {a: Nat, b: Nat, c: Nat}. {
print (r.a);
| (r.b == 1): print (r.b);
print (r.c);
} in print_record_elements (r1);
```
## Brief description of the operations and semantics.
### Addition operation(+)
```
Integer + Integer -> Integer
Integer + Real -> Real
Real + Integer -> Real
Real + Real -> Real
String + String -> String (string concatenation)
Record + Record -> Record (record concatenation)
List + List -> List (list concatenation)
```
Other types of operands are not allowed.
### Substraction operation(-)
```
Integer - Integer -> Integer
Integer - Real -> Real
Real - Integer -> Real
Real - Real -> Real
```
Other types of operands are not allowed.
### Multiplication operation(*)
```
Integer * Integer -> Integer
Integer * Real -> Real
Real * Integer -> Real
Real * Real -> Real
```
Other types of operands are not allowed.
### Division operation(/)
```
Integer / Integer -> Integer (round down)
Integer / Real -> Real
Real / Integer -> Real
Real / Real -> Real
```
Other types of operands are not allowed.
### Comparisons(<, >, <=, >=, =, /=)
```
Integer op Integer -> Boolean
Integer op Real -> Boolean
Real op Integer -> Boolean
Real op Real -> Boolean
```
Other types of operands are not allowed.
### Unary addition and subtraction(op = {+, -})
```
op Integer -> Integer
op Real -> Real
```
Other types of operands are not allowed.
### Logical operations
```
Boolean and Boolean -> Boolean
Boolean or Boolean -> Boolean
not Boolean -> Boolean
```
Other types of operands are not allowed.
## Examples of correct and incorrect programs
```shell=bash
// The following program is incorrent
n: Integer = 5;
r: Real = 10.5;
b: Bool = True;
s: String = "Simple string";
u: Unit = print (s);
// The correct way of declaration
let n: Integer = 5;
let r: Real = 10.5;
let b: Bool = True;
let s: String = "Simple string";
let u: Unit = print (s);
```
```shell=bash
// Incorrect import
import math.nk as math
// Correct import
-| math.nk as math
```
```shell=bash
-| std.nk
-| math.nk as math
// Correct way
let n = 5 in // type inference
math.sqrt (n);
// Incorrect way: declarations without "let" are not allowed
n = 5;
math.sqrt (n);
```
```shell=bash
-| std.nk
// Incorrect way to define a function
let concat = func (x: String, y: String) {
x + y
};
// Correct way to define a function
let concat = /\ x: String. y: String. {
x + y
};
concat ("Hello,", "World");
```
```shell=bash
-| std.nk
-| math.nk
// Incorrect way to define a record
let Vector3d = (x1: Real, x2: Real, x3: Real);
// Correct way to define a record
let Vector3d = {x1: Real, x2: Real, x3: Real};
//Incorrectly calling a function: wrong argument,
//the vector "{x1 = 1.1, x2 = 5.5, x4 = 1.7}" must have identifier "x3"
let length3d = /\ v: Vector3d. {
math.sqrt (math.sqr (v.x1) + math.sqr (v.x2) + math.sqr (v.x3))
} ({x1 = 1.1, x2 = 5.5, x4 = 1.7});
//Correct way
let length3d = /\ v: Vector3d. {
math.sqrt (math.sqr (v.x1) + math.sqr (v.x2) + math.sqr (v.x3))
} ({x1 = 1.1, x2 = 5.5, x3 = 1.5, x4 = 1.7});
```