Naked list

<< Click to Display Table of Contents >>

Navigation:  Gekko User Manual > User manual introduction >

Naked list

Previous pageReturn to chapter overviewNext page

Naked lists are used to avoid unnecessary typing of parentheses and single quotes, for lists of strings or numbers. Naked lists can only be used on the right-hand side in assignments (typically list or series definitions), or on the right-hand side in FOR loop definitions. If a naked list contains only one element, it must contain a trailing comma (see the 'singletons' section below).

 

Naked list vs. normal list

A naked list always appears on the right-hand side of an assignment statement, it never uses normal parentheses (...), and it always contains at least one comma ,. Examples: #= a, b, c; or #+= 1, 2, 3;. Quotes are omitted for strings.

A normal list can appear anywhere in an expression, it is always enclosed in normal parentheses (...), and it contains at least one comma ,. Examples: #= ('a', 'b', 'c'); or #+= (1, 2, 3);. Quotes must be used for strings.

 

Naked lists are naked in the sense that the normal list definition parentheses (...) are omitted, and strings inside the naked list are stated without single quotes. Therefore, the strict list definition #= ('a', 'b', 'c'); may be replaced by the 'naked' #= a, b, c;, saving a bit of typing. A "naked" list of values can be used to construct either a list of values or a timeseries, cf. #= 1, 2, 3; or = 1, 2, 3;, where #m is a list, and x is a timeseries.
 

Curlies in naked lists

In a naked list definition, if a list #m is present inside {}-curlies, it is the elements of #m that are added, not the list #m itself. For instance:

#m1 = b, c; 

#m2 = a, {#m1}, d;  //result: 'a', 'b', 'c', 'd'

 

So #m2 does not become a nested list ('a', ('b', 'c'), 'd').

 

Example: naked list for strings:

 

#= a, b, c;             //same as #m = ('a', 'b', 'c');
for string %= a, b, c;  //same as ... = ('a', 'b', 'c')
  tell %i;
end;

 

Example: naked list for values:

 

<2010 2012> = 1, 2, 3; //same as ... = (1, 2, 3)

#= 1, 2, 3;            //same as #m = (1, 2, 3);

 

The following elements are legal in naked lists:

 

Normal names like a1, including underscore character (_).

Normal names with bank, frequency and index, like b:a!q[i,j].

Names/words starting with a digit, like 1a or 1e5.

Normal integers like 123

Integers starting with zero, like 007

Floating point values like 1.2 or 1.2e5

Any character(s) may be replaced by {}-curlies, for instance a{%s}b, where the inside of {} may be any mathematical expression.

If a list is present inside {}-curlies, the list items are added one by one, and characters may be prefixed or suffixed. For instance: #m1 = b, c; #m2 = a, {#m1}, d; will create the list 'a', 'b', 'c', 'd', whereas #m1 = b, c; #m2 = a, x{#m1}y, d; will create the list 'a', 'xby', 'xcy', 'd'. (This will also work if the list items are numbers, but the primary use is for strings).

Any element may use a prepended with a minus (-), for instance -a1 or -123 or -1.23.

Any element may be repeated with rep, for instance 1, 2 rep 3, 3 or 1, 2, 3 rep * (rep * is ignored for non-timeseries variables).

Missings: use m() or miss().

 

Special rules:

 

If all elements are either normal integers or contain a decimal point (.), the list becomes a list of values. The elements may contain a minus sign (-). For instance, 1, 2 or 1.2, 3 or 1, 1.2e5 all become lists of values. But beware that a list like 12, 02 will become a list of the strings '12', '02', and a list like 12, 1e5 becomes a list of the strings '12', '1e5'. The reason for this is stated below.

An integer starting with 0 (except the integer 0 itself) is not interpreted as a value in a naked list. So for instance, 01 is not interpreted as the value 1, and 007 not as the value 7.

An element composed of integers + e/E + integers will be interpreted as a string, for instance 1e5 is interpreted as the string '1e5', not the value 100000. On the contrary, 1.0e5 is interpreted as 100000, not '1.0e5'.

A list of integers like 1, 2, 3 will become a list of the values 1, 2, 3, not the strings '1', '2', '3'. But you may easily and without loss transform such a list of integers into the list of strings '1', '2', '3' via the strings() function. For instance: #= 1, 2, 3; #= #m.strings();.

Single-element naked lists can be defined with trailing comma, for instance #= a,;. See the 'singletons' section below.

 

The reason for the above rules is that naked lists are often used to define codes, for instance sequences of 3-character words consisting of alphanumerical characters, such as ab7, 7dy, 638, 02e, 058, 1e5. These are all three-character codes, and may represent, for instance, commodity codes for a large number of commodities. Regarding the last two codes, it would be unfortunate if a naked list consisting of 058, 1e5 was understood as a list of the values 58, 100000, because then it could not be converted back into the list of strings '058', '1e5' via the strings() function. This could lead to subtle hard-to-find bugs. So in a sense, the naked list logic is loss-less. It may spring a surprise that for instance the naked list 483, 582, 3b5 becomes a list of strings, whereas the naked list 483, 582, 385 becomes a list of integers. But these integers can be converted back into corresponding strings without loss or alteration of any kind.

 

To sum up, if you are dealing with lists of codes, you do not need to worry about some codes losing leading zeroes, or some codes being interpreted as mathematical exponents. If your list of codes contain digits only (without leading zeroes), it becomes a list of values, and Gekko will abort with a type error, if you try to use the elements as strings. In that case, you can just convert them into strings with the strings() function.

 

 

Singletons

 

Beware that single-element lists (singletons) are special. The following will not work:

 

#m1 = a;          //error
#m2 = 100;        //error

 

In that case, you can use a trailing comma to indicate that you are defining a list.

 

#m1 = a,;         //or: ('a',) or list('a')
#m2 = 100,;       //or: (100,) or list(100)

 

The use of trailing comma for singleton lists is ugly, but necessary for the clarity of the syntax (the user can always use the comma to spot whether a right-hand side is a list or not). Such an "ugly" trailing comma is not unheard of in programming languages, cf. for instance 1-element tuples in Python.

 

 

Conclusion

 

Regarding naked lists, there are three important things to remember. (1) If an element is an integer with leading superfluous zeroes (for instance 01 or 007), all elements are interpreted as strings. (2) If an element is an integer followed by an e or E followed by an integer (for instance 1e5), all elements are interpreted as strings. These rules are to avoid potential loss of or scrambling of information, for instance if the elements are codes.  (3) If all elements are integers, these are transformed into values. Sometimes codes look like this, for instance 123, 234, 345, but in that case, they can be transformed back into strings (without information loss) via the strings() function.

 

 

Note

 

Naked lists do not allow type symbols % or # (except if they are inside {}-curlies). This is to avoid confusion.

 

A naked list cannot contain elements with differing types, for instance #= a, 1.1;. This will trigger an error, and again this is to avoid confusion.