Data types

The following table describes the different data types available in APL. The second column states if the data type is a primitive, or an object. The third column indicates the default value that an uninitialized variable will obtain.

Data typeP/ODef valRangeDescriptionExample
booleanPfalse1 ByteBoolean value (true|false).
boolean aBool=true;
byteP01 Byte, -128 to +127Single byte integer value.
byte aNumber=127;
charP'\0'1 ByteA single character value.
char aCharacter='a';
shortP02 Bytes, -32,768 to +32,767Short integer value.
short aNumber=31000;
intP04 Bytes, -2,147,483,648 to +2,147,483,647

Integer values have normal Java syntax, for instance: 42, 0x2A

An integer literal is always of the most narrow integer type that can contain the value. This normally works as expected, since numeric types can be implicitly converted to any wider numeric type.

int aNumber=2147483640;



floatP0/0

4 Bytes, 1.40129846432481707e-45 to 3.40282346638528860e+38 (positive or negative)

Single-precision floating point.
float aValue=0.5;



doubleP0/08 Bytes, 4.94065645841246544e-324d to 1.79769313486231570e+308d (positive or negative).
Double-precision floating point.

When using floating-point literals, (that is, float (f) or double (d) values) all floating-point literals without trailing d is considered float literals.

Note!

For instance 0.5 and 0.5d will not give identical values

Double types may contain positive or negative infinity.

double aValue=432482943.1;


double POS_INFINITY=1.0/0.0;
double NEG_INFINITY=-1.0/0.0;


longP08 Bytes, -2^63 to +(2^63 -1)Long integer value.
long aNumber=92233720368547;
bigintO0UnlimitedProvides storage for any integer value.
bigint aNumber;
bigdecO0Unlimited

Provides storage for any integer value with a decimal point.

Values assigned to bigdecimal variables in APL must be suffixed with b.

Example

bigdec aNumber = 123.4567b;

bigdec aNumber;
stringOnullUnlimited

Values assigned to string variables in APL must be surrounded with double quotes.

A character preceded by a backslash (\) is an escape sequence and has a special meaning to the compiler. The following sequences are available:

  • \t - Tab
  • \b - Backspace
  • \n - Newline
  • \r - Carriage return
  • \f - Formfeed
  • \' - Single quote character
  • \" - Double quote character
  • \\ - Backslash character

Some string comparison functions use regular expressions. If special characters such as "*", "?" are to be used as characters in the regular expression, they must be escaped with two backslashes in the APL since these strings will be parsed twice. For instance, the following function will return the index of the question mark in the string:
strREIndexOf("Am I right?", "\\?")

String values surrounded with triple double quotes are referred to as multiline strings. You can span the content of these string across line boundaries.

Multiline strings does not support, or need, escape characters. All characters, including double quotes, are assigned as they appear.

string aString = "foobar";
string mlString = """{
 "key1": "value 1",
 "key2": "value 2"
}""";




anyOnull
Can be assigned any value of any type.
any aVar;
aVar = 1;
aVar = "foobar";
bitsetOnull
Represents a bit string that grows as needed. The bits are indexed by non-negative integers.
bitset aBitset;
bytearrayOnull
Bytearray type.
bytearray anArray;
dateOnull
Holds date and time, including the timezone.
date aDate;
ipaddressOnull
Holds IP address information. Both IPv4 and IPv6 are supported.
ipaddress anIp = ipLocalHost();
list <type>Onull

List of objects of the specified type.

If a list of lists is to be declared the ">" characters must be separated by at least one space, not to conflict with the ">>" operator. That is, list<list<int> >intLists;

list<int>intList;



mapOnull
Hash maps allowing key/value pairs to be defined.
map<string, int> aMap =	
mapCreate(string, int);



tableOnull
Special type used to hold table data used by the table commands.
table aTable = 
tableCreate("Default",
anSQL);
UDRTypeOnull
Holds a reference to a UDR. The UDRType must be a defined format or compilation will fail. There is also a special format available for generic UDRs called drudr and is of drudr type.
MyDefinedType aUDR;
drudr anyUDR;
uuidOnull128 bitsImmutable universally unique identifier (UUID).
uuid u=uuidCreateRandom();

The variable types follow Java standard regarding object reference vs. value semantics. All types use value semantics when compared through the '==' and '!=' boolean operators and objects use reference semantics for all other operators, like assignments '='.

Example - Reference Semantics

Two date variables (objects) and two long variables (primitives) are used to illustrate the reference semantics. In the case of date variables, they will always contain the same value regardless of being updated via myDate_A or myDate_B since they point to the same object.

date myDate_A = dateCreateNow();
  date myDate_B = myDate_A;
  long myLong_A = 10;
  long myLong_B = myLong_A;

  if (myDate_A == myDate_B ) {
    // true
  }
  if (myLong_A == myLong_B) {
    // true
  }

  // Change value on A variables
  dateAddHours(myDate_A, 22);
  if (myDate_A == myDate_B) {
     // still true, points to same object
  }
  myLong_A = 55;
  if (myLong_A == myLong_B) {
    // false, primitives always hold their own values
  }
  


Type Casting

It is possible to cast between different types with regular Java syntax. The instanceOf function is used to evaluate dynamic types since an incorrect type conversion will cause the workflow to abort with a runtime error.

Example - Type casting

/* APL code for two UDR types */
consume {
   if( instanceOf( input, UDRType1 ) ) {
     UDRType1 udr1 = (UDRType1) input;
     // Handle UDRType1 ...
   } else {
     UDRType2 udr2 = (UDRType2) input;
     // Handle UDRType2 ...
   }
}


As an extension to the regular conversions, all types may be casted to string type.

Note that some types are subtypes of other types and can be directly assigned. Examples are:

  • All types are subtypes of the any type.

  • int is a subtype (narrowing) of long.

  • All UDR types are subtypes of the general base type drudr.

  • Some UDR types are subtypes of other UDR types (depending on Ultra definitions).

There is also a number of built-in type conversion functions (refer to the section below, Access of UDR Fields).

Access of UDR Fields

UDR fields are accessed with the '.' separator. For instance, to access the field myField within the UDR type variable theUDR, the syntax would be:

theUDR.myField = 5;
debug( theUDR.myField );

If the field name is a variable instead of a string, udrGetValue/udrSetValue can be used to set/get field values dynamically. 

Access of non-present fields will return the default value for the specific type. Field presence is evaluated with udrIsPresent.

When writing to a UDR field on a null object, a NullPointerException will be thrown, see example:

Example - Access UDR fields

myUDR theUDR = null; 
int a = theUDR.myField // Will Not throw NullPointerException
theUDR.myField = 0; // Will throw NullPointerException

To  avoid exceptions, first make sure that the UDR is not a null object:


Example - Check for null value

if( theUDR != null ) {
    theUDR.myField = 0;
}


For further information about UDR related functions, see UDR Functions.

Access of Input UDR

Within the consume block, the incoming UDR can be accessed using the special variable input. The instanceOf function may be useful in case of dealing with several UDR types.