Work in progress!
fn main() => println("Hello, world!")
The main main is the start of the program. Here we are calling the println function (from the std library which is included by default), with the string "Hello, world".
# This is a comment!
In Taly, comments starts with a # symbol. There is no multi-line comment.
Here is the generic syntax to define a function:
fn name(arg0: Type0, arg1: Type1, ...): ReturnType => # body
Let's now look at an example:
fn add(lhs: I32, rhs: I32): I32 => lhs + rhs
This add function takes two parameter: an I32 named lhs and another I32 named rhs, it returns an I32. Essentially this function computes the sum of two I32.
Let's now look at a more complicated example, the factorial function:
fn factorial(n: U8): U64 =>
if n <= 1 then 1
else factorial(n - 1) end
You can see in this function the use of an if statement, we will discuss that in Section 2.7.
The return keyword can be used to return earlier out of a function. We could rewrite the factorial function like this:
fn factorial(n: U8): U64 =>
if n <= 1 then
return 1
end
factorial(n - 1)
It is also possible to define parameters with default value.
fn factorial(n: U8 = 1): U64 => # body
This would allow us to call the factorial function without giving it an argument. In this case the default value will be used.
factorial()
That is the same as this:
factorial(1)
Be careful: Default parameters must be defined last!
It is possible to pass parameters in a different order than the one defined:
fn subI32(lhs: I32, rhs: I32): I32 => lhs - rhs
subI32(1, 2) # 1 - 2 = -1
subI32(rhs: 1, lhs: 2) # 2 - 1 = 1
subI32(rhs: 1, 2) # The last parameter can be inferred
There are two ways of storing data:
- the first one is storing in into a constant.
- the second one is storing in into a variable.
Constants are immutable, that means that their values cannot be changed.
const PI: F32 = 3.1415
var x = PI + 2
You can also see for the second variables no types have been specified, this is because the compiler is smart enough to determine which type it should be.
Type | Description |
---|---|
I8 | Signed 8-bit integer |
I16 | Signed 16-bit integer |
I32 | Signed 32-bit integer |
I64 | Signed 64-bit integer |
ISize | Signed arch integer |
U8 | Unsigned 8-bit integer |
U16 | Unsigned 16-bit integer |
U32 | Unsigned 32-bit integer |
U64 | Unsigned 64-bit integer |
USize | Unsigned arch integer |
Bool | Boolean (true or false) |
Char | Character (e.g. 'a') |
String | Boolean (e.g. "Hello") |
var my_opt: Option[I8] = None
my_opt = 2
Options can either be None or contains a value (in this case an I8). This allows you to have variables with no value, but we will discuss more about those later.
const my_array: Array[I8] = [0, 1, 2]
Arrays are a datatype that can contains multiple data of the same type, however they cannot be extended nor shrank.
var x: I32 = 10
const x_ptr: Pointer[I32] = x.pointer()
Pointers are mainly used to communicate with a library in c. The pointer function is defined for every type (even custom type).
var my_tuple: (String, I32) = ("Hello", 10)
var long_tuple: (F32, String, I32) = (9.3, "Hello", 10)
Tuples are datatypes that can contains multiple data of different types.
type StringI32 = (String, I32)
fn main() =>
const foo: StringI32 = ("hello", 16)
Operator | description |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Remainder |
Here is an example on how to use them:
const a = 3 + 4
const b = 12 - 4
const c = 6 * 2
const d = 6 / 2
const e = 7 % 2
Operator | description |
---|---|
and | Boolean AND |
or | Boolean OR |
xor | Boolean XOR |
not | Boolean Not (Unary) |
Here is an example on how to use them:
const a = true and false
const b = true or false
const c = true xor false
const d = not true
Operator | description |
---|---|
== | Is equal to |
!= | Is not equal to |
< | Is less than |
<= | Is less or equal than |
> | Is greater than |
>= | Is greater or equal than |
Here is an example on how to use them:
const a = 5 == 5
const b = 3 != 4
const c = 9 < 12
const c = 2 <= 3
const c = 8 > 7
const c = 1 >= 1
Operator | description |
---|---|
is | Type is |
isnt | Type is not |
extends | Type extends |
Here is an example on how to use them:
const a: I32 = 13
const b = a is I32
const c = a isnt I64
const d = a extends IAdd
if condition then
# body
elif condition then
# body
else
# body
end
If statements can have has many elif branch as you need but only one else branch.
while condition do
# body
end
Break statement allow you to exit a loop.
var i: I32 = 0
while i < 10 do
if i == 8 then break end
i += 1
end
In this case the loop will stop once i reaches 8.
Break statement allow you go to the next iteration (skipping the current one).
var i: I32 = 0
while i < 10 do
if i == 8 then
i += 1
continue
end
# body
i += 1
end
In this case the loop will skip the iteration when i reaches 8.