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
Allowable Types for Constants
Slice allows you to define constants for the following types:
- An integral type (
bool,byte,short,int,long) - A floating point type (
floatordouble) - string
- enum
Here are a few examples:
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
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
Integer literals can be specified in decimal, octal, or hexadecimal notation.
For example:
const byte TheAnswer = 42;const byte TheAnswerInOctal = 052;const byte TheAnswerInHex = 0x2A; // or 0x2aBe 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.
Floating-Point Literals
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:
const float P1 = -3.14f; // Integer & fraction, with suffixconst float P2 = +3.1e-3; // Integer, fraction, and exponentconst float P3 = .1; // Fraction part onlyconst float P4 = 1.; // Integer part onlyconst float P5 = .9E5; // Fraction part and exponentconst float P6 = 5e2; // Integer part and exponentFloating-point literals must be within the range of the constant type (float or double); otherwise, the compiler will issue a diagnostic.
String Literals
Slice string literals support the following escape sequences:
| Escape Sequence | Name | Corresponding ASCII or Unicode Code Point | Notes |
|---|---|---|---|
\' | 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:
const string AnOrdinaryString = "Hello World!";
const string DoubleQuote = "\"";const string TwoSingleQuotes = "'\'"; // ' and \' are OKconst 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 \aconst string HexEscape1 = "\x07"; // Dittoconst string HexEscape2 = "\x41F"; // Same as AFconst string Universal1 = "\u0041"; // Same as Aconst string Universal2 = "\U00000041"; // Ditto
const string EuroSign1 = "€"; // Euro sign (U+20AC)// Euro sign as a short universal character nameconst string EuroSign2 = "\u20AC";// Euro sign as a long universal character nameconst string EuroSign3 = "\U000020ac";// Euro sign in UTF-8 encoding, using hex escape sequencesconst string EuroSign4 = "\xe2\x82\xAC";// Euro sign in UTF-8 encoding, using octal escape sequencesconst string EuroSign5 = "\342\202\254";// Euro sign in UTF-8 encoding, using a mix or hex and octal escape sequencesconst string EuroSign6 = "\342\x82\254";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.
Constant Expressions
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:
const int SIZE = 500;
const int DEFAULT_SIZE = SIZE; // OKconst short SHORT_SIZE = SIZE; // OKconst byte BYTE_SIZE = SIZE; // ERRORThe 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.
Language Mapping
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:
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:
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:
const string Egg = "œuf";is mapped to:
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:
const ["cpp:type:wstring"] string LargeEgg = "gros œuf";is mapped to:
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:
const string Heart = "c\u0153ur";const ["cpp:type:wstring"] string BigHeart = "grand c\u0153ur";const ["cpp:type:wstring"] string Banana = "\U0001F34C";is mapped to:
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:
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:
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:
const string Egg = "œuf";const string Heart = "c\u0153ur";const string Banana = "\U0001F34C";is mapped to:
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:
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:
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:
const string Egg = "œuf";const string Heart = "c\u0153ur";const string Banana = "\U0001F34C";is mapped to:
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:
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:
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:
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:
const string Egg = "œuf";const string Heart = "c\u0153ur";const string Banana = "\U0001F34C";is mapped to:
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:
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:
classdef AppendByDefault properties(Constant) value logical = true endend
classdef LowerNibble properties(Constant) value uint8 = 15 endend
classdef Advice properties(Constant) value char = sprintf('Don''t Panic!') endend
classdef TheAnswer properties(Constant) value int16 = 42 endend
classdef PI properties(Constant) value double = 3.1416 endend
classdef FavoriteFruit properties(Constant) value = Fruit.Pear endendAs 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:
const string Egg = "œuf";const string Heart = "c\u0153ur";const string Banana = "\U0001F34C";is mapped to:
classdef Egg properties(Constant) value char = sprintf('\x0153uf') endend
classdef Heart properties(Constant) value char = sprintf('c\x0153ur') endend
classdef Banana properties(Constant) value char = sprintf('\xd83c\xdf4c') endendThe 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:
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:
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:
module M{ const string Egg = "œuf"; const string Heart = "c\u0153ur"; const string Banana = "\U0001F34C";}is mapped to:
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:
$ans = \M\TheAnswer;Here are the constant definitions once more:
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:
AppendByDefault = TrueLowerNibble = 15Advice = "Don't Panic!"TheAnswer = 42PI = 3.1416FavoriteFruit = Fruit.PearAs 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:
const string Egg = "œuf";const string Heart = "c\u0153ur";const string Banana = "\U0001F34C";is mapped to:
Egg = "\u0153uf"Heart = "c\u0153ur"Banana = "\U0001F34C"Here are the constant definitions once more:
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:
AppendByDefault = trueLowerNibble = 15Advice = "Don't Panic!"TheAnswer = 42PI = 3.1416FavoriteFruit = Fruit::PearAs 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:
const string Egg = "œuf";const string Heart = "c\u0153ur";const string Banana = "\U0001F34C";is mapped to:
Egg = "\u{153}uf"Heart = "c\u{153}ur"Banana = "\u{1f34c}"Slice constant definitions map to corresponding Swift constant definitions. For 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;Here are the generated Swift definitions for these constants:
public let AppendByDefault: Bool = truepublic let LowerNibble: UInt8 = 15public let Advice: String = "Don't Panic!"public let TheAnswer: Int16 = 42public let PI: Double = 3.1416
public enum Fruit: UInt8 { ... }public let FavoriteFruit: Fruit = Fruit.PearSlice string literals that contain non-ASCII characters or universal character names are mapped to Swift string literals with Unicode escape sequences. For example:
const string Egg = "œuf";const string Heart = "c\u0153ur";const string Banana = "\U0001F34C";is mapped to:
public let Egg: String = "\u{153}uf"public let Heart: String = "c\u{153}ur"public let Banana: String = "\u{1f34c}"