Let's try some examples

You have already installed Welly and run it in a terminal. Let's start programing! You can copy the code snippets and paste them into your terminal to try them out.

Values

>>>> "Hello World!"
"Hello World!": str

In the above example, when you enter "Hello World!", Welly understands it as a value, and prints it out. Welly also prints its type, which in this case is str (a string).

"Hello, world!" is a string literal. Welly recognises string literals by the presence of double quotes. The word "literal" in this context means that the code literally represents a Welly value. Here are some other kinds of literal:

>>>> 3
3: int

>>>> 3.14159
3.14159: float

>>>> '3'
51: int

>>>> '\u0003'
3: int

>>>> true
true: bool

>>>> [1, 2, 3]
[1, 2, 3]: array const int

>>>> (1, "2", 3.14159)
(1, "2", 3.14159): struct(int, str, float)

>>>> fn() { return 3 }
unprintable: fn(): (int)

>>>> FREE
FREE(): union {FREE()}

The first four are numbers. The first is an integer literal, and the second is a floating-point literal. The next two, enclosed in single quotes, are examples of unicode character literals. 51 is the ASCII code for the digit "3". After them, true is a Boolean value; the only other Boolean value is false. Next, the one in square brackets is an array, and the one in round brackets is a struct (sometimes called a tuple). The difference is that the array type allows any length, whereas the struct type allows the values inside to have different types. The one beginning fn is a function literal; Welly can handle it internally, but does not have a way of displaying it. Finally, the one spelt entirely in capital letters is an algebraic value, which is useful for representing certain kinds of data.

You'll see all these again in this tutorial; for now the points are:

  • There are lots of different types of value.
  • When you enter a value, Welly prints it out with its type.
  • Sometimes (as in the fn example) the text we type in, and in this case the text that Welly prints out, is inadequate to fully represent the value, which is something abstract inside the computer.

Expressions

>>>> 2 + 3
5: int

In this example, we typed something that is not a literal. Welly had to do some work to turn 2 + 3 into 5. However, the result is a value, so Welly printed it out with its type. We can use Welly as a calculator!

A piece of code that computes a value is called an expression. Here are some other kinds of expression:

>>>> 2.0 * 3.14159
6.28318: float

>>>> "Hello" + "world"
"Helloworld": str

>>>> true & false
false: bool

>>>> ~ -6
5: int

>>>> [1, 2, 3].length
3: int

>>>> (1, "2", 3.14159)[0]
1: int

The first one is a multiplication, which is spelt *. The second is a concatenation, which is spelt the same as addition; + means addition for integers and floating-point numbers, but concatenation for strings and arrays. Notice that we forgot the space; you might like to fix that. The third example shows the Boolean "and" operation, spelt &. The fourth shows a bitwise operation: the ~ (tilde) inverts all the bits of the binary encoding of -6, which gives the binary encoding of 5. The fifth shows how to find the length of an array. The sixth shows a way to extract a value from a struct; the same syntax works for arrays too.

You'll see plenty of expressions in this tutorial. For now, the points are:

  • There are lots of ways of combining values to make other values.
  • Welly will reduce an expression to a value before printing it out.
  • Sometimes (as in the + example) the same syntax means different things depending on the types of the values involved.

Variables

>>>> var three = 3
>>>> three = three + 3
>>>> three
6: int

In the example we have created a storage location. The line beginning with the var keyword declares a new variable, and names it, in this case poorly. three is the name we chose, and 3 is the initial value of the variable.

The next line has similar syntax, but there is no var keyword, so it does not create a new variable; it modifies one that already exists. We modified the variable named three, setting its value to that of the expression three + 3.

On the third line, we just wrote the name of the variable: three. A variable name is an expression, so Welly prints out its value: 6. This shows that the previous line, despite not printing anything, did something internally.

Constants

>>>> const x = 3
>>>> x = x + 3
ConstnessVMError: can only assign to "var" locations

The const keyword is similar to the var keyword. It also declares a new variable, names it, and gives it an initial value. The difference is that it tells Welly not to allow the value to be changed. Attempting to change it, as on the second line, is an error.

In other respects, x behaves just like any other variable:

>>>> x + x
6: int

>>>> x
3: int

>>>> var y = x - x
>>>> y
0: int

You can perform any operation on a constant that does not affect the value of the constant. In the above example, the addition operation is performed on x and the result is printed, but the original value stays unchanged.

Choosing between const and var

If you use const, then the value you define can be used by all parts of your program without any risk that they interfere with each other. It is as if they each have a private copy of the variable. Your program may also go faster, because the compiler can generate better code in some cases.

If you use var, then you will be able to change the value of the variable. Sometimes this is the simplest way to express your intention.

You can read more about variables and constants here.

Statements

Let's look at this part again:
>>>> var three = 3
>>>> three = three + 3

Note that Welly does not print anything out after these two lines, because they are statements as opposed to expressions. The first is an example of a variable declaration, and the second is an example of an assignment.

Here's another kind of a statement: a procedure call:

>>>> print("Hello, world!\n")
Hello, world!

This does print something, but because we asked it to, not because it is an expression. The print procedure takes a value of type str and prints out its contents. Compare this to the very first example at the top of the page, and notice some differences:

  • Note that the print procedure prints out the actual characters in the string; it does not print out the double quotes, as Welly would if it were displaying the value, nor does it print a type.
  • Note also the special syntax \n inside the string literal. This is a way of writing a newline character; it is an example of an escape sequence. It looks like Welly didn't print it out, but it did. Try removing it.

You will see several other kinds of statement in this tutorial.