Variables

Scott Waldron Updated by Scott Waldron

Variables in Dino must be declared, using the var keyword, followed by an identifier, followed by the = sign, then an expression.

var x = 0;
var a, b, c = null; // declare all null at once
y = 20; // error, unknown symbol y

The assignment part of a declaration is optional. If it is omitted, the variable will be initialized to the special null value.

var a;
var a = null; // same as above

Variables can be private or public. Private variables are visible only in the current script; they are not defined in imports. Public variables are pulled into other scripts when imported. If no visibility modifier is supplied, variables are assumed to be public. Public and private are covered in depth in the Symbol Visibility (public, private) section.

var x = 0; // visible when imported to another script, public is implied
public var y = 0; // visible when imported to another script
private var z = 0; // private, visible only in this script

Symbol Names

Symbols (variables and custom function names) are declared with an identifier. An identifier can start with @ or _ or any letter, and after that, can contain any number of @ or _ or alphanumeric characters.

var @ = 0; // legal, but not wise - some systems use @ as a 'host' symbol
var @x = 0;
var @@x@ = 0;
var xyz = 0;
var a1 = 0;
var 1a = 0; // error, cannot start with digit
var _a = 0;
var a* = 0; // error, cannot contain special characters other than @ or _

Constants

Variables can also be declared as constants. A constant must have its value set at the time it is declared, and it cannot be reassigned after that.

const ZERO = 0;
ZERO = 2; // error, cannot reassign const
ZERO++; // error, cannot reassign const
ZERO += 3 // error, cannot reassign const

Note that unlike some platforms, Dino allows any type of object to be declared a const. What this means is that you can have const lists, dictionaries, etc. You can modify the state of these const values, but you cannot reassign the const variable itself.

private const ADMINS = list('admin', 'amy', 'joe');

def hasAccess(user){
if not 'susan' in ADMINS {
ADMINS.Add('susan'); // ok, add to list
}
ADMINS = list(); // error, cannot reassign const

return user in ADMINS;
}

Constant values can be declared in any scope. They have the same scoping rules as regular variables.

def foo(){
const LIMIT = 10;
}

var a = LIMIT; // error, unknown symbol LIMIT

Constant values in Dino behave exactly like variables declared as readonly in C# or final in Java. You can change their internal state, but you cannot reassign a new value to the variable.

Lazy Assignment

Sometimes you set a variable, but don't immediately need the value. Lazy assignment can help with efficiency by deferring evaluation of a variable until it is first used.

Consider a situation where we have a repository that calls to the database or web service. We want to load all the products, but we don't want to do it immediately upon rebuilding the script. In such a case, we can use the lazy keyword to defer the evaluation.

lazy var _products = Product.GetRepository().FindAll();

def getBoats(){
return _products.Where(x => x.Category == 'Boats');
}

In the previous example, the expression that will be assigned (the right-hand side of the assignment statement) will not be evaluated. However, when other code calls getBoats(), the _products variable will have the value just as if it was assigned as normal.

Lazy may be combined with private and public, but it must come after those keywords.

private lazy const _products = Product.GetRepository().FindAll();

Lazy evaluation has no effect inside a def statement.

def foo(){
lazy var x = 10; // no effect, lazy is ignored
}

Normal Assignment, Lazy Assignment, or Function?

It can be tricky to figure out what strategy to use when assigning variables. Follow these general rules for the best performance.

  • Literal assignments (numbers, strings, etc.) Just use regular syntax. Lazy would simply be unnecessary overhead.
  • Dynamic values Write a function (def). You potentially want different results each time you call the function, so a variable with a value inappropriate. Consider the product repository example: if you always want the latest list of products, it should be returned from a function, not set to a variable, even if that variable is lazily assigned.
  • Rarely-changing expensive assignments. Use lazy. By doing this, you avoid loading up a list of products (for example) until it is needed.
  • External values (From a database or web service). Use lazy for performance.

Normal variable assignment.

const _limit = 10;

A function, because we always want the latest list, and it changes often.

def getSales(){
return OpenSale.GetRepository().FindAll();
}

Doesn't change very often.

lazy const _products = Product.GetRepository().FindAll();

How did we do?

Keywords

Blocks and Scopes

Contact