Tutorial #0 Basic syntax

The sources of argentum programming language are organized in modules.
Modules are text files with extension ag residing in the same directory. They are always in UTF-8 encoding.

On compiler invocation one of modules is passed to it as a starting module. This module contains application specific classes and functions, entry point and the list of all used modules.

Example:

using string;                           // 1
using sys { log, String, StrBuilder  }  // 2

class Point {                     // 3
   x = 0;                         // 4
   y = 1;
}
fn square(a int) int {            // 5
    a * a                         // 6
}
fn itos(val int) String {
    StrBuilder.putInt(val).toStr()   // 7
}

p = Point;                        // 8
p.x := 3;                         // 9
p.y += p.x;                       // 10

log(itos(square(p.x + p.y)))      // 11

This example contains:

  • Module usage and name import declarations
  • Class and functions declarations
  • Main application code.

Module usage and name import declarations

  • Line {1} declares a dependency on the string module. This module contains multiple string utilities that are now accessible to our code by names starting with string_*.
  • Line {2} does the same for the sys module. But there is more here. If we list names in curly braces, all these names from that module will be accessible in our module by short name. So we not only declared dependency on the sys module, we also imported a StrBuilder class out of it. Technically speaking we don't have to add dependency on sys module because it's a built-in one, it's accessible anyway. We are doing so here just to import the String and StrBuilder classes to make them accessible by short names i.e. String instead of sys_String.

Class and functions declarations

  • Line {3} is a class declaration. Our class has no methods. But it has two integer fields x and y {4} that have initial values 0 and 1 respectively.
  • Line {5} defines a function that takes an integer argument and produces an integer result. Function body is a sequence of expression separated with ";". If the last expression in the sequence also has the trailing ";", the function result will be void. Otherwise this last expression produces the result of the function. Our function in line {6} consists of just one expression of type int, it has no trailing ';' that makes the function return value of a*a expression.
  • Line {6} defines another function, that converts int to String. In Line {7} we create a StrBuilder instance, call its method putInt (this method returns this-object), and call its toStr method that creates a String out of the StrBuilder. Alternatively string interpolation can be used (which in turn is just a syntax sugar around the StrBuilder object). This statemen would look like:
fn itos(int val) String { "{val}"}

Main application code

  • The main application code starts at line {8}, because it's the first line that does not contain class or function definitions. This line is a declaration of the local variable 'p' of type Point initialized with a newly created Point instance.
  • Line {9} is the assignment to the object field. The assignment operator has classic ":=" form. Why not "="?
    • Because it's mathematically incorrect to use equality operator to connect not equal operands.
    • Because the ":=" operator is aligned with all other data modification operators ("+=", "<<=", "&=" etc.)
    • Because the "a=b" syntax is already used for local variable declarations (where it is mathematically correct).
    • The ":=" operator is a data mutation operator, and since all data mutations is a dangerous action (like goto), they need special attention. It's good to give it a special unique symbol, not overloaded by other meanings.
    • It is a widespread practice among both experienced and novice programmers to repurpose a variable by assigning new, loosely related values to it, instead of creating a new variable. In order to combat this habit, Argentum has introduced a syntax that makes it easier to create a new variable rather than reassigning an existing one.
  • Line {10} demonstrates another mutation operator combined with access to the object fields.
  • Line {11} combines multiple function calls.

Leave a Reply

Your email address will not be published. Required fields are marked *