Constants and Literals

9 min read

9 min read

9 min read

8 min read

9 min read

8 min read

8 min read

8 min read

8 min read

Slice allows you to define constants for the following types:

Here are a few examples:

Slice
module M
{
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;
}

Boolean constants can only be initialized with the keywords false and true. (You cannot use 0 and 1 to represent false and true.)

Integer literals can be specified in decimal, octal, or hexadecimal notation.

For example:

Slice
const byte TheAnswer = 42;
const byte TheAnswerInOctal = 052;
const byte TheAnswerInHex = 0x2A; // or 0x2a

Be aware that, if you interpret byte as a number instead of a bit pattern, you may get different results in different languages. For example, for C++, byte maps to std::uint8_t whereas, for Java, byte maps to byte, which is a signed type.

The value of an integer literal must be within the range of its constant type, as shown in the Built-In Basic Types table; otherwise the compiler will issue a diagnostic.

A floating-point literal has an integer part, a fractional part after a period, or both, followed by an optional exponent. A literal without a period requires an exponent. A floating-point literal can end with an f or F suffix, which the Slice compiler ignores.

Here are a few examples:

Slice
const float P1 = -3.14f; // Integer & fraction, with suffix
const float P2 = +3.1e-3; // Integer, fraction, and exponent
const float P3 = .1; // Fraction part only
const float P4 = 1.; // Integer part only
const float P5 = .9E5; // Fraction part and exponent
const float P6 = 5e2; // Integer part and exponent

Floating-point literals must be within the range of the constant type (float or double); otherwise, the compiler will issue a diagnostic.

Slice string literals support the following escape sequences:

Escape SequenceNameCorresponding ASCII or Unicode Code PointNotes
\'
single quote
0x27
\"
double quote
0x22
\?
question mark
0x3f
\\
backslash
0x5c
\a
audible bell
0x07
\b
backspace
0x08
\f
form feed
0x0c
\n
line feed
0x0a
\r
carriage return
0x0d
\t
horizontal tab
0x09
\v
vertical tab
0x0b
\nnn
octal escape sequence
1 to 3 octal digits (0-7) that represent a byte value between 0 and 255
\xnn
hexadecimal escape sequence
1 to 2 hexadecimal digits (0-9, a-f, A-F)
\unnnn
universal character name
U+nnnn
Exactly 4 hexadecimal digits.Use the \Unnnnnnnn notation for astral characters.
\Unnnnnnnn
universal character name
U+nnnnnnnn
Exactly 8 hexadecimal digits.

A backslash () followed by another character is simply preserved as is.

Octal and hexadecimal escape sequences can represent ASCII characters (ordinal value 0 to 127) or the UTF-8 encoding of non-ASCII characters.

A string literal can contain printable ASCII characters (including the escape sequences presented above) and non-ASCII characters; non-printable ASCII characters (such as an unescaped tab) are not allowed.

Here are some examples:

Slice
const string AnOrdinaryString = "Hello World!";
const string DoubleQuote = "\"";
const string TwoSingleQuotes = "'\'"; // ' and \' are OK
const string QuestionMark = "\?";
const string Backslash = "\\";
const string AudibleBell = "\a";
const string Backspace = "\b";
const string FormFeed = "\f";
const string Newline = "\n";
const string CarriageReturn = "\r";
const string HorizontalTab = "\t";
const string VerticalTab = "\v";
const string OctalEscape = "\007"; // Same as \a
const string HexEscape1 = "\x07"; // Ditto
const string HexEscape2 = "\x41F"; // Same as AF
const string Universal1 = "\u0041"; // Same as A
const string Universal2 = "\U00000041"; // Ditto
const string EuroSign1 = "€"; // Euro sign (U+20AC)
// Euro sign as a short universal character name
const string EuroSign2 = "\u20AC";
// Euro sign as a long universal character name
const string EuroSign3 = "\U000020ac";
// Euro sign in UTF-8 encoding, using hex escape sequences
const string EuroSign4 = "\xe2\x82\xAC";
// Euro sign in UTF-8 encoding, using octal escape sequences
const string EuroSign5 = "\342\202\254";
// Euro sign in UTF-8 encoding, using a mix or hex and octal escape sequences
const string EuroSign6 = "\342\x82\254";
Slice
const string NullString = null; // Illegal!

Null strings simply do not exist in Slice and, therefore, do not exist as a legal value for a string anywhere in the Ice platform.

A constant definition may also refer to another constant. It is not necessary for both constants to have the same Slice type, but the value of the existing constant must be compatible with the type of the constant being defined.

Consider the examples below:

Slice
const int SIZE = 500;
const int DEFAULT_SIZE = SIZE; // OK
const short SHORT_SIZE = SIZE; // OK
const byte BYTE_SIZE = SIZE; // ERROR

The DEFAULT_SIZE constant is legal because it has the same type as SIZE, and SHORT_SIZE is legal because the value of SIZE (500) is within the range of the Slice short type. However, BYTE_SIZE is illegal because the value of SIZE is outside the range of the byte type.

Slice constant definitions map to corresponding C++ constant definitions. Slice constants are mapped to constexpr constants whenever possible, and to const constants otherwise. For example:

Slice
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;

Here are the generated C++ definitions for these constants:

C++
constexpr bool AppendByDefault = true;
constexpr std::uint8_t LowerNibble = 15;
const std::string Advice = "Don't Panic!";
constexpr std::int16_t TheAnswer = 42;
constexpr double PI = 3.1416;
enum class Fruit : std::uint8_t { Apple, Pear, Orange };
std::ostream& operator<<(std::ostream& os, Fruit value);
constexpr Fruit FavoriteFruit = Fruit::Pear;

All constants are initialized directly in the header file, so they are compile-time constants and can be used in contexts where a compile-time constant expression is required, such as to dimension an array or as the case label of a switch statement.

A Slice string literal that contains non-ASCII characters is mapped by default to a narrow C++ string literal with the non-ASCII characters replaced by the octal escape sequences for the characters' UTF-8 encoding. For example:

Slice
const string Egg = "œuf";

is mapped to:

C++
const std::string Egg = "\305\223uf";

If you map a string constant to a std::wstring, the non-ASCII characters in the string literal are replaced by universal character names. For example:

Slice
const ["cpp:type:wstring"] string LargeEgg = "gros œuf";

is mapped to:

C++
const std::wstring LargeEgg = L"gros \u0153uf";

A Slice string literal that contains universal character names is mapped to a narrow C++ string with one ore more octal escape sequences or to a wide C++ string with the universal character names preserved. For example:

Slice
const string Heart = "c\u0153ur";
const ["cpp:type:wstring"] string BigHeart = "grand c\u0153ur";
const ["cpp:type:wstring"] string Banana = "\U0001F34C";

is mapped to:

C++
const std::string Heart = "c\305\223ur";
const std::wstring BigHeart = L"grand c\u0153ur";
const std::wstring Banana = L"\U0001F34C";

Here are the sample constant definitions once more:

Slice
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;

Here are the generated definitions for these constants:

C#
public abstract class AppendByDefault
{
public const bool value = true;
}
public abstract class LowerNibble
{
public const byte value = 15;
}
public abstract class Advice
{
public const string value = "Don't Panic!";
}
public abstract class TheAnswer
{
public const short value = 42;
}
public abstract class PI
{
public const double value = 3.1416;
}
public enum Fruit { Apple, Pear, Orange }
public abstract class FavoriteFruit
{
public const Fruit value = Fruit.Pear;
}

As you can see, each Slice constant is mapped to a class with the same name as the constant. The class contains a field named value that holds the value of the constant.

Slice string literals that contain non-ASCII characters or universal character names are mapped to C# string literals with universal character names. For example:

Slice
const string Egg = "œuf";
const string Heart = "c\u0153ur";
const string Banana = "\U0001F34C";

is mapped to:

C#
public abstract class Egg
{
public const string value = "\u0153uf";
}
public abstract class Heart
{
public const string value = "c\u0153ur";
}
public abstract class Banana
{
public const string value = "\ud83c\udf4c";
}

Here are the sample constant definitions once more:

Slice
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;

Here are the generated definitions for these constants:

Java
public interface AppendByDefault {
boolean value = true;
}
public interface LowerNibble {
byte value = 15;
}
public interface Advice {
String value = "Don't Panic!";
}
public interface TheAnswer {
short value = 42;
}
public interface PI {
double value = 3.1416;
}
public interface FavoriteFruit {
Fruit value = Fruit.Pear;
}

As you can see, each Slice constant is mapped to a Java interface with the same name as the constant. The interface contains a field named value that holds the value of the constant.

Slice string literals that contain non-ASCII characters or universal character names are mapped to Java string literals with universal character names. For example:

Slice
const string Egg = "œuf";
const string Heart = "c\u0153ur";
const string Banana = "\U0001F34C";

is mapped to:

Java
public interface Egg {
String value = "\u0153uf";
}
public interface Heart {
String value = "c\u0153ur";
}
public interface Banana {
String value = "\ud83c\udf4c";
}

Here are the sample constant definitions once more:

Slice
module Example
{
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;
}

For each constant, the JavaScript mapping generates a read-only property with the same name in the JavaScript object corresponding to the enclosing module:

JavaScript
Object.defineProperty(Example, 'AppendByDefault', {value: true});
Object.defineProperty(Example, 'LowerNibble', {value: 15});
Object.defineProperty(Example, 'Advice', {value: "Don't Panic!"});
Object.defineProperty(Example, 'TheAnswer', {value: 42});
Object.defineProperty(Example, 'PI', {value: 3.1416});
Object.defineProperty(Example, 'FavoriteFruit', {value: Fruit.Pear});

The corresponding TypeScript declarations are:

TypeScript
const AppendByDefault:boolean;
const LowerNibble:number;
const Advice:string;
const TheAnswer:number;
const PI:number;
const FavoriteFruit:Fruit;

Slice string literals that contain non-ASCII characters or universal character names are mapped to JavaScript string literals with universal character names. For example:

Slice
const string Egg = "œuf";
const string Heart = "c\u0153ur";
const string Banana = "\U0001F34C";

is mapped to:

JavaScript
Object.defineProperty(Example, 'Egg', {value: "\u0153uf"});
Object.defineProperty(Example, 'Heart', {value: "c\u0153ur"});
Object.defineProperty(Example, 'Banana', {value: "\ud83c\udf4c"});

Here are the sample constant definitions once more:

Slice
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;

Here are the generated definitions for these constants:

MATLAB
classdef AppendByDefault
properties(Constant)
value logical = true
end
end
classdef LowerNibble
properties(Constant)
value uint8 = 15
end
end
classdef Advice
properties(Constant)
value char = sprintf('Don''t Panic!')
end
end
classdef TheAnswer
properties(Constant)
value int16 = 42
end
end
classdef PI
properties(Constant)
value double = 3.1416
end
end
classdef FavoriteFruit
properties(Constant)
value = Fruit.Pear
end
end

As you can see, each Slice constant is mapped to a MATLAB class with the same name as the constant. The class contains a constant property named value that holds the value of the constant.

Slice string literals that contain non-ASCII characters or universal character names are mapped to MATLAB string literals with UTF-16 character codes. For example:

Slice
const string Egg = "œuf";
const string Heart = "c\u0153ur";
const string Banana = "\U0001F34C";

is mapped to:

MATLAB
classdef Egg
properties(Constant)
value char = sprintf('\x0153uf')
end
end
classdef Heart
properties(Constant)
value char = sprintf('c\x0153ur')
end
end
classdef Banana
properties(Constant)
value char = sprintf('\xd83c\xdf4c')
end
end

The mapping uses the sprintf function to convert escaped strings into native MATLAB character arrays.

A Slice constant maps to a PHP constant. Consider the following definitions:

Slice
module M
{
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange };
const Fruit FavoriteFruit = Pear;
}

The mapping for these constants is shown below:

PHP
namespace M
{
define(__NAMESPACE__ . '\\AppendByDefault', true);
define(__NAMESPACE__ . '\\LowerNibble', 15);
define(__NAMESPACE__ . '\\Advice', "Don't Panic!");
define(__NAMESPACE__ . '\\TheAnswer', 42);
define(__NAMESPACE__ . '\\PI', 3.1416);
define(__NAMESPACE__ . '\\FavoriteFruit', \M\Fruit::Pear);
}

Slice string literals that contain non-ASCII characters or universal character names are mapped to PHP string literals with these characters replaced by their UTF-8 encoding as octal escapes. For example:

Slice
module M
{
const string Egg = "œuf";
const string Heart = "c\u0153ur";
const string Banana = "\U0001F34C";
}

is mapped to:

PHP
namespace M
{
define(__NAMESPACE__ . '\\Egg', "\305\223uf");
define(__NAMESPACE__ . '\\Heart', "c\305\223ur");
define(__NAMESPACE__ . '\\Banana', "\360\237\215\214");
}

Slice constants are mapped to PHP constants in the enclosing namespace:

PHP
$ans = \M\TheAnswer;

Here are the constant definitions once more:

Slice
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;

The generated definitions for these constants are shown below:

Python
AppendByDefault = True
LowerNibble = 15
Advice = "Don't Panic!"
TheAnswer = 42
PI = 3.1416
FavoriteFruit = Fruit.Pear

As you can see, each Slice constant is mapped to a Python attribute with the same name as the constant.

Slice string literals that contain non-ASCII characters or universal character names are mapped to Python string literals with \u or \U escape sequences. For example:

Slice
const string Egg = "œuf";
const string Heart = "c\u0153ur";
const string Banana = "\U0001F34C";

is mapped to:

Python
Egg = "\u0153uf"
Heart = "c\u0153ur"
Banana = "\U0001F34C"

Here are the constant definitions once more:

Slice
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;

The generated definitions for these constants are shown below:

Ruby
AppendByDefault = true
LowerNibble = 15
Advice = "Don't Panic!"
TheAnswer = 42
PI = 3.1416
FavoriteFruit = Fruit::Pear

As you can see, each Slice constant is mapped to a Ruby constant with the same name.

Slice string literals that contain non-ASCII characters or universal character names are mapped to Ruby string literals with these characters by Unicode escape sequences. For example:

Slice
const string Egg = "œuf";
const string Heart = "c\u0153ur";
const string Banana = "\U0001F34C";

is mapped to:

Ruby
Egg = "\u{153}uf"
Heart = "c\u{153}ur"
Banana = "\u{1f34c}"

Slice constant definitions map to corresponding Swift constant definitions. For example:

Slice
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;
enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;

Here are the generated Swift definitions for these constants:

Swift
public let AppendByDefault: Bool = true
public let LowerNibble: UInt8 = 15
public let Advice: String = "Don't Panic!"
public let TheAnswer: Int16 = 42
public let PI: Double = 3.1416
public enum Fruit: UInt8 { ... }
public let FavoriteFruit: Fruit = Fruit.Pear

Slice string literals that contain non-ASCII characters or universal character names are mapped to Swift string literals with Unicode escape sequences. For example:

Slice
const string Egg = "œuf";
const string Heart = "c\u0153ur";
const string Banana = "\U0001F34C";

is mapped to:

Swift
public let Egg: String = "\u{153}uf"
public let Heart: String = "c\u{153}ur"
public let Banana: String = "\u{1f34c}"