Introduction Welcome Getting Started My First Program     Troubleshooting and Distributing Transforming Data Interactive Programs     Programming Exercises     Making Games
Documentation Declarations     Procedures     Variables Statements     Flow Control Expressions Libraries     Print     IO     Random     Game Engine
Tutorials Complete Tutorials     Introduction to Programming     Quick Start     Programming Exercises     Programming Games

DECLARATIONS


All About Declarations in Vizzcode





What are Declarations?

Declarations are a language feature in Vizzcode. It allow names to be associated with identifiers and then be referenced in the program.

For example: you can declare a procedure and then reference that procedure using its name (like calling it):

What does a declaration look in Vizzcode

proc
:: () {

}
Declaration of a procedure called "proc"


Calling a procedure in Vizzcode

...
proc
();
Calling the procedure by its name




Kinds of Declarations

There are a few kinds of declarations inside of Vizzcode.
Knowing them well will allow you to express your ideas and solutions better while programming.

Here are the kinds of declarations:

Variable Declarations

A variable declaration is the association of a name to a type-safe piece of memory.
In text, variable declarations contain a name and a colon :
In visual nodes, variable declarations are green nodes.
For example, you can declare a variable of type integer called var like this:

How to declare a variable in Vizzcode
var :
int
;


In Vizzcode, all variables must have their type known at compile time. This means the compiler must know the type of every variable at declaration. This is called strongly-typed or statically typed.

You can also assign a value to the variable at declaration like this:

How to declare and assign a variable in Vizzcode
var :
int
=
7
;

If you are assigning a value to a variable you can leave the type implicit and the compiler will automatically set its type based on the type of the value you are assigning it to.
The following code declares a variable of type int and value 7.

How to declare a variable of an implicit type in Vizzcode
var :=
7
;


Variables can be declared in the global scope or a local scope.

You can learn all about variables here.


Procedure Declarations

Procedures are bodies of code you can call by name. By calling a procedure, you start executing that procedure body's instructions.
Here is an example of a declaration of a procedure called proc:

How to declare a procedure in Vizzcode

proc
:: () {

}
And the same thing in Visual nodes:

This procedure can be called from inside another procedure like this:


How to call a procedure in Vizzcode

other_proc
:: () {
    
proc
();
}

You can pass multiple parameters as well as receive multiple return values when calling a procedure:

Declaring and calling procedures with parameters and return values

proc
:: (a :
int
, b :=
5.6
) ->
int
,
float
{

}

other_proc
:: () {
    
proc
(
0
);
}

Procedures must be declared in global scope and called from inside local scopes.

You can access the complete procedure documentation page here.


Hash Declaration: Library Import

Hash Declarations are a special kind of declaration you make by specifying the # symbol in text code.
You can make a hash declaration specifying that you would like to import a pre-made library's declarations.

For example, by importing the library Print you can access its declared procedures (print, print_int, print_float and print_bool):

How to use hash declarations to import a library in Vizzcode
#import
"Print"

How to use hash declarations in real programs
#import
"Print"


main
:: () {
    
print
();
}

Libraries must be included in the global scope.

You can learn all about the libraries that are available in Vizzcode here.




Node Declarations

It's very easy to create declarations in the Visual Panel. You can just drag off another node's execution pin and insert either a Variable, Procedure or Library Import declarations.

All declarations must be properly named, like so:

Diagram showing the names of declarations
(You can learn about naming identifiers here).




Hash Declarations

Hash Declarations are a special kind of declaration made in the global scope.
They always contain a # in the beginning of the declaration in the text code.

You can use Library Import Hash Declaration to import pre-made libraries in your program. Like so:

How to use hash declarations to import a library in Vizzcode
#import
"Print"




Naming Declarations

All declarations' names must follow the following rule:
A name must only contain the letters A-Z and a-z, numbers 0-9 and underscore _
A name must not start with numbers.

A name must not be the same as the pre-defined reserved keywords in the language:
  • true
  • false
  • if
  • else
  • while
  • for
  • break
  • continue
  • return
A name must not be the same as a type. Here are the default types in the language:
  • void
  • int
  • float
  • string
  • bool
For example, these are valid declaration names:
  • var
  • this_varible
  • myVariable
  • ALLCAPS
  • __very_important
  • var5
These are invalid declaration names:
  • 4var (starts with a number)
  • The Variable (contains a 'space')
  • variável (contains a character other than A-Z and a-z: á)
  • break (is a reserve keyword)
  • string (is a type)
Even though you can use whatever naming convention you want, it's usually beneficial to be consistent with your naming (at least between the same kinds of declaration).
Some of the more used naming conventions are: snake_case, UpperCaseCamelCase and lowerCaseCamelCase. Choose whichever you think is more readable.




Redefinition

When you make a declaration, it exists for as longs as its scope exists.

With that in mind, if you name a declaration the same way another valid declaration (accessible from that place in the code) is named, there will be an identifier redefinition error because the compiler won't know what declaration you are referring to with that name.

The following examples are invalid because they redefine a valid identifier:
main
:: () {
    var :=
4
;
    var :=
6
;
}
var :=
4
;
main
:: () {
    var :=
6
;
}
main
:: () {
    var :=
4
;
    
if
true
 var :=
6
;
}


The following examples are valid because they don't use a name that's already used in that scope:

main
:: () {
    var :=
4
;
    var2 :=
6
;
}
var :=
4
;
main
:: () {
    var1 :=
6
;
}
main
:: () {
    
if
true
 var :=
6
;
    var :=
4
;
}

You can read more about scopes in the following section.




Scopes

A scope is a block of declarations and statements.
They are usually defined by { } in text code.
The following section talks about node scopes.

All declarations created inside a certain scope can only be accessed inside that same scope (and its sub-scopes).

The global scope covers the entire program. All declarations made directly inside the global scope are accessible anywhere in the program. The order of the declarations inside the global scope doesn't matter.
Consider the following program:
main
:: () {

}

global_variable :=
23
;
other_variable :
string
=
"Hello!"
;

proc
:: () {

}
All the declared identifiers inside the global scope (global_variable, main, other_variable and proc) are available anywhere in the program. This is because declarations in the global scope are order-independent.
This program is valid despite using the identifier before they are declared:
main
:: () {
    
proc
();
    a := other_variable;
    b :=
5
+ global_variable;
}

global_variable :=
23
;
other_variable :
string
=
"Hello!"
;

proc
:: () {
    global_variable +=
4
;
    other_variable =
"Changed!"
;
}
Local scopes are scopes defined inside other scopes.
For example, when you declare a procedure, its block is a local scope. If you create further blocks inside of it, they will be local scopes of their own.

In the following code, there are three scopes: the global scope, the main procedure block scope and the if scope.
main
:: () {
    var1 :=
3
;
    
if
true
{
        var2 := var1;
    }
}

The main procedure is declared in the global scope, so it's available in that scope (and all its sub-scopes), so anywhere in the program.
The var1 variable is declared in the main's scope, so it's only available in that scope (and all its sub-scopes).
The var2 variable is declared in the if block's scope, so it's only available in that scope (and all its sub-scopes).

The following code contains an error, can you spot it?
main
:: () {
    var1 :=
3
;
    
if
true
{
        var2 := var1;
    }
    var1 = var2;
}

The error is that var2 is not accessible outside the scope it was created. So you can't assign its value to var1 after the if's block scope exited.

When you create a block and only add one statement or declaration inside of it, you don't need to place that statement or declaration inside { }.
For example:
main
:: () {
    
if
true

        var1 :=
5
;
    var2 :=
6
;
}
The variable var1 is created inside of the if block's scope (and thus will only be executed if the condition is true) and var2 is created inside of main's scope (and thus will be executed no matter the condition).
That is because the if block didn't contain the { symbol, signalling that the next declaration or statement belongs to that scope.
That is the exact equivalent of typing:
main
:: () {
    
if
true
{
        var1 :=
5
;
    }
    var2 :=
6
;
}
Additional notes:
  • The for statement declares an iterator variable inside its scope.
  • Procedures' parameters are variables declared in that procedure's scope (but their values come from the caller or their default value).
  • Procedures' return values, even if named, are not declarations and can't be accessed like variables.




Node Scopes

Scopes in the Visual Panel work just like normal scopes.
Here is how the global scope looks in the Visual panel: (You can just follow the while line down from its start in the Global Scope Start node)

What does the Global Scope look like in Vizzcode

Local scopes are while lines that start from the right of certain nodes and move down:

What do Local Scopes look like in Vizzcode

The same rules of text scopes apply: order-independence in the global scope, variables only being accessible from inside the scope they were created in (and their sub-scopes) and so on.

In the following example, there are three scopes: the global scope, the main procedure block scope and the if's true scope.

An example program to show the different scopes in the Visual Code

The main procedure is declared in the global scope, so it's available in that scope (and all its sub-scopes), therefore anywhere in the program.
The var1 variable is declared in the main's scope, so it's only available in that scope (and all its sub-scopes).
The var2 variable is declared in the if block's scope, so it's only available in that scope (and all its sub-scopes).

The following code contains an error, can you spot it?

An example program to show an error caused by wrong use of a varible's scopes

The error is that var2 is not accessible outside the scope it was created. So you can't assign its value to var1 after the if's block scope exited.





Compound Declarations

You may declare (and assign) multiple variables at once this way:

How to use compound declarations in Vizzcode
var1, var2, var3 :=
10
;

That example declares three independent variables var1, var2 and var3; and assign them all to 10.

Compound declarations are specially useful when dealing with a procedure's multiple return values.
In the following example, the procedure proc returns three values (one int, one string and one float):

A procedure that returns multiple values
proc
:: () ->
int
,
string
,
float
{
    
return
10
,
"Hello!"
,
3.14
;
}


You may call the procedure ignoring it's return values:

Calling a procedure and ignoring its return values
proc
();


Or you may declare variables and assign them the return's values:

Calling a procedure and using the first return value with a normal declaration
var1 :=
proc
();



Calling a procedure and using the first two return values with a Compound Declaration
var1, var2 :=
proc
();



Calling a procedure and using all its return values with a Compound Declaration
var1, var2, var3 :=
proc
();


In these examples, var1 is an int, var2 is a string and var3 is a float.
Because you are creating variables of different types in the same compound declaration, you must leave their type implicit.




Deleted Declarations in Nodes

Some nodes refer to a declaration.
For example, in this code, the node var refers to the declaration of the variable var:

An example of a node that depends on another

If you were to delete the declaration, you invalidate the var node and it must be deleted as well.

A program with a node that has an invalid dependency

The same thing happens if you delete a library import. By doing this, you invalidade all of the calls to the procedures declared in that library:

A program with a node that has an invalid dependency on a library