Standard Features

A list of all the standard features that Sprig offers

Most programming languages offer a standard set of functionality - here's a list of Sprig offers:

Variables

Sprig allows you to declare variables in three different ways: const, var and let.

const name = "Amy"
name = "Allan" 
// Error: Cannot reassign value of const variable 'name'
const name = "Allan" 
// Error: Variable 'name' is already defined
var name = "Amy"
name = "Allan" 
// No error, var variables can be reassigned
var name = "Allan" 
// Error: Variable 'name' is already defined
let name = "Amy"
name = "Allan" 
// No error, let variables can be reassigned
let name = "Allan" 
// No error, let variables can be redefined

Branching

Sprig offers a familiar approach to branching logic.

const x = 100

if (x < 50) {
    print("a")
} else if (x < 80) {
    print("b")
} else {
    print("c")
}

// c

Loops

Sprig offers multiple types of loops: for, loop, while.

for (<List>, [optional] value, [optional] index)

These are the most common loops found in Sprig code.

const arr = [1, 2, 3]

for (arr, value, index) {
    print(`{{value}}: {{index}}`)
}

/*
1: 0
2: 1
3: 2
*/

loop (<let decl>, <end check>, <expr>)

These follow the traditional for loop approach.

loop (let i = 0, i <= 3, i += 1) {
    print(i)
}

/*
0
1
2
*/

while (<expr>)

These follow the traditional while loop approach.

while (x < 3) {
    print(x)
    x += 1
}

/*
0
1
2
*/

Objects

Sprig allows the construction of objects.

const key = "id"
const person = {
    token: "_-_",
    nums: (1...3),
    bloop: {
        a: 10 + 4,
        b: 20,
        c: (1...4),
        d: (const d = 1200) + (const e = 1.4)
    },
    [key]: 3.14
}

person.nums[0] = 100
person.bloop.c[0] = person.token * person.bloop.a
person.bloop.e = person.bloop.d + d

print(person.token) // _-_
print(person.id) // 3.14
print(person.bloop.e) // 2401.4
print(person.bloop.d) // 1201.4

Objects can be merged together through addition.

const merged = { name: "Jack", age: 34 } + { id: "0001" }
print(merged) // { name: "Jack", age: 34, id: "0001" }

Objects can be constructed using shorthand syntax.

const name = "Jack"
const age = 34

const person = { name, age, id: "0001" }
print(person) // { name: "Jack", age: 34, id: "0001" }

Object properties can be deleted.

const person = { name: "Jack", age: 34, id: "0001" }
person->delete("id")

print(person) // { name: "Jack", age: 34 }

Lists

Sprig allows the construction of lists.

const arr = [1, 2, 3 + 5]
print(arr) // [1, 2, 8]

Sprig provides common list functionality to the global scope.

const arr = [1, 2, 3]
arr->append(10)->print // [1, 2, 3, 10]
arr->insert(20)->print // [20, 1, 2, 3, 10]
arr->insert(100, 1)->print // [20, 100, 1, 2, 3, 10]
arr->remove(2)->print // [20, 100, 2, 3, 10]

Lists can be created dynamically through the range operators.

const arrInclusive = 0...5 // [0, 1, 2, 3, 4, 5]
const arrExclusive = 0..5 // [0, 1, 2, 3, 4]

Lists can be merged by either addition or through the spread operator.

const arr1 = 1...10
const arr2 = 20...30

print(arr1 + arr2)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

print([0, ...arr2, ...arr1, 0])
// [0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0]

Functional methods are also provided globally.

const arr = [1, 2, 3]

arr->forEach((/* optional */ value, /* optional */ index) => {
    print(`{{value}}: {{index}}`)
})

/*
1: 0
2: 1
3: 2
*/

const doubleArr = arr->map((value) => value * 2)
doubleArr->print // [2, 4, 6]

const filteredArr = arr->filter((value) => value % 2 == 0)
filteredArr->print // [2]

const sum = arr->reduce((a, b) => a + b, /* optional: initial_value */)
sum->print // 6

arr->includes(2)->print // true
arr->includes(20)->print // false

Functions

Sprig allows you to define your own functions.

const add = (a, b) => a + b
add(10, 20)->print // 30

Functions can have default parameters.

const add = (a, b = 100) => a + b
add(10)->print // 110

Functions can have a catch-all parameter. The arguments provided are turned into a List.

const printStuff = (a, b, ...args) => args->print
printStuff(1, 2, 3, "hi") // [3, hi]

When calling functions, we can provide the parameter names to be more verbose.

const blah = (a, b) => {
    print(a)
    print(b)
}

blah(b: 1, a: 2)

/*
2
1
*/

Functions have an implicit return, meaning they return the last thing on the stack (unless a return is explicitly defined).

const thisReturns5 = () => {
    5
}

// is the same as

const thisReturns5 = () => {
    return 5
}

// and

const thisReturns5 = () => 5

Coroutines

Sprig allows you to create coroutines. Coroutines are functions that can suspend their execution, yield a value and resume execution at a later point.

Any function that contains a yield statement is automatically identified as a coroutine.

const coro = () => {
    var x = 0
    while (true) {
        yield x += 1
    }
}

const c1 = coro();

while ((let c = c1()) <= 10) {
    // do nothing
}

print(c) // 11

const coroAdvanced = (init, value) => {
    var x = init
    while (true) {
        yield x += value
    }
}

const cAdvanced = coroAdvanced(100);
const res = cAdvanced(20)

print(res) // 120

Last updated