Skip to main content

Random thoughts on a new programming language

Β· 4 min read

I'm just putting together some random thoughts that I wish to turn into a new programming language. These are notations I often use in comments for C++ algorithms. A lot of the syntax may have been realized by mathematical languages like Mathematica or Python.

Update: I've created a repo πŸ‘‰ https://github.com/jc-verse/caroline πŸ‘ˆ and it has changed a lot from my design below. Feel free to star & follow the latest progress of this language!

Data types

This is a language mainly used for algorithms and maths. The data types are:

  • Number -1.6, 1/3;
  • Boolean true;
  • String "Hello";
  • Set {1, 2, 3} (no duplicate value; no order);
  • Matrix ((1, 2, 3), (4, 5, 6)) (supports matrix operations; vectors are special names for nΓ—1 or 1Γ—n matrices);
  • Function.

Arithmetic

Apart from the typical integer and decimal types, number types also include fractions, irrational numbers, and complex numbers. The special number infty is used for sequence and function limits, as well as the result of division by zero.

Since fractions preserve more precision than decimals, whenever a fraction is involved in an expression, the result will be a fraction. Integers are special fractions with denominator of 1.

num a := 1.6;
num b := 1/3;
num c := a * b; // c = 8/15
num d := 1.6 / 3; // d = 8/15

Some operations are:

  • Addition: +;
  • Subtraction: -;
  • Multiplication: *;
  • Division: /;
  • Exponentiation: ^;
  • Assignment: :=;
  • Equality: =, ==;
  • Inequality: >, <, >=, <=, !=.

Any function with two parameters can be used as a binary operator.

squaresum := (num a, num b) => a^2 + b^2;

num c := 1 squaresum 2; // c = 5

A number literal followed by a variable is infered to be a multiplication.

num x := 2;
num a := 3x^2 + 2x + 1; // a = 17

Declaring sequences

seq a := i => i^2; // a = 0, 1, 4, 9, 16, ...

Sequences are functions. More specifically, a sequence is defined as

type seq := (num) => T;

where the only parameter is the subscript. Unlike vectors, sequences contain an infinite number of items. a_i is just a syntax sugar to a(i) as in a function. For collections of finite number of objects, use vectors.

Iterating sequences

The syntax i...j returns an iterator from i to j, inclusive. This is akin to range(i, j) in Python.

When an iterator is used in the index, it also returns an iterator.

seq a := i => i;
for (k in a_(1...3)) {
print(k); // Out: 1 2 3
}

Matrix operations

Any typical matrix operation is supported. Moreover mathematical functions treat square matrices the same as numbers.

mat a := ((1, 2, 3), (4, 5, 6), (7, 8, 9));
mat b := cos(a);
/**
b = (( 0.38017732968947, βˆ’0.3738301457419 , βˆ’0.12783762117329),
(βˆ’0.53120649276402, 0.39010533372492, βˆ’0.68858283978612),
(βˆ’0.44259031521749, βˆ’0.84595918680825, βˆ’0.24932805839901))
*/

Expressions

Expressions are syntax sugars for functions.

type expr := (...T) => T;

This is to reduce the cumbersome typing. A type like (num, vec) => num can now be simply expr. However, I'm not sure how robustness / type safety can be achieved in this case.

Mathematical functions

In mathematics, parameters used in functions often appear like currying to me. For example, βˆ‘k=010k2\sum_{k=0}^{10}k^2 is just a function βˆ‘k=010\sum_{k=0}^{10} applied to an expression k2k^2.

I propose the angle brackets be used to pass parameters to functions that return a function, while round brackets are for functions that return a value.

sum := <num i, num j> => {
return (expr f) => {
num s := 0;
for (x in i...j) {
s += f(x);
}
return s;
}
}

num a = sum<1, 10>(x => x^2); // a = 385

Immutability

Although appearing to be a functional programming language, everything is by default mutable. Immutable objects have const modifiers.