V Programming Language


Introduction

V (codename) is a new general-purpose, high-level programming language in development since mid-2015.

Summary:

Goals:

Components

Design Principles

Synopsis

All the following samples are valid V code and currently supported.

The print operator automatically appends a newline:

print "Hello world";  // writes "Hello world\n" to stdout

The assert operator works at either compile time or run time:

assert 2 + 2 == 4;  // removed during parsing
assert 2 + 2 == 5;  // aborts parsing
assert 2 + 2 == x;  // checked at run time

Integers are arbitrary-width by default:

var i = 9876543210;
var ii = i * i;  // --> 97546105778997104100
var iii = i^3;   // --> 963418328693495609108518161000

Type annotations are optional, but enforced:

var s (string) = 12345;        // nope
var i (int) = "not a number";  // NO
var j (int) = "12345";         // also no

A list is just a sequence of values. Lists interpolate into other lists; they can't be nested:

var x = 1, 2, 3;  // --> (1, 2, 3)
var y = x, 4, 5;  // --> (1, 2, 3, 4, 5)

A list value can be assigned to a list of variables (of the same length and compatible types) to unpack it:

var params = "J. Random Hacker", 31337;
var name (string), var id (int) = params;
var a, var b, var c = params;            // this fails
var a, var b, var c = 1, 2, 3, 4;        // this assigns (3, 4) to c for now
var a, var b, var c (int) = 1, 2, 3, 4;  // but this also fails

The = operator does duplication, or strict assignment. A postcondition of a = b is a == b:

var x (i32) = 1234567890;
var y (i64) = x;   // no run time check required
var z (i16) = x;   // fails at run time for x > 32767 and x < -32768

The := operator does approximation, or loose assignment, silently truncating operands that don't fit the result type:

var x (i16) := 1234567890;  // --> 722
var y (u8)  := x;           // --> 210
var z (i8)  := x;           // --> -46

Consecutive string literals are joined during parsing. A list of string values can be coerced to string type to concatenate its elements:

var x = "foo" "bar";         // --> "foobar"
var y = "foo", "bar";        // --> ("foo", "bar")
var z (string) = y, "baz";   // error, can't assign a plural list to a string
var z (string) := y, "baz";  // --> "foobarbaz"

Square brackets will generate an array from a list:

var a = [1, 2, 3];

Like lists, arrays are also heterogenous by default — but they can be contained in lists (and therefore other arrays):

var a = [2, "bar"];  // --> [2, "bar"]
var b = a, "baz";    // --> [2, "bar"], "baz"
var c = ["foo", b];  // --> ["foo", [2, "bar"], "baz"]

Braces generate an anonymous code block:

var hello = { print "Hello world" };
do hello;                    // prints "Hello world"
do { print "Hello world" };  // so does this
{ print "Hello world" };     // this does nothing

The result of executing a block is the result of the last statement executed in the block. Note that semicolons separate rather than terminate statements, so a final semicolon is followed by an empty statement:

var x;
do { x = 1, 2, 3; };  // --> nothing
do { x = 4, 5, 6 };   // --> (4, 5, 6)

Blocks can be passed a list of arguments using parentheses, lexically stored in _:

var square = { _ * _ };
square( 7 );                // --> 49
var repeat = { _, _ };
repeat( "test", 1, 2, 3 );  // --> ("test", 1, 2, 3, "test", 1, 2, 3)

Blocks can have named parameters by unpacking _:

var is_pythagorean_triple =
{
    var a, var b, var c = _;

    a * a + b * b == c * c
};

[TODO: Functions]

A list (or array) can contain mappings:

var mappings = "+" => {sum(_)}, "*" => {product(_)}, "," => {_};

An alternative mapping operator exists that automatically quotes a preceding bareword:

var bools = true: true, false: false;  // --> ("true" => true, "false" => false)

[TODO: Maps]

[TODO: Parser directives]