
Muldis::D::Dialect::HDMD_Perl5_STD - How to format Perl 5 Hosted Data Muldis D

This document is Muldis::D::Dialect::HDMD_Perl5_STD version 0.80.0.

This document is part of the Muldis D language specification, whose root document is Muldis::D; you should read that root document before you read this one, which provides subservient details.

This document outlines the grammar of the Hosted Data Muldis D dialect named HDMD_Perl5_STD.
The fully-qualified name of this Muldis D dialect,
in combination with the base language spec it is bundled with,
is [ 'Muldis_D',
'http://muldis.com',
'N.N.N',
'HDMD_Perl5_STD' ] (when the bundled base language version is substituted for the N.N.N).
The HDMD_Perl5_STD dialect is defined to be hosted in Perl 5,
and is composed of just|mainly core Perl 5 types.
This dialect is optimized for Perl 5 specifically,
and doesn't try to match the version for Perl 6; you *will* have to reformat any Perl Hosted Data Muldis D when migrating between Perl 5 and Perl 6,
same as with your ordinary Perl code.
This dialect is designed to exactly match the structure of a possible concrete syntax tree,
comprised of native Perl 5 scalar and collection typed values,
resulting from parsing code written in the Muldis D dialect PTMD_STD using Perl 5.
This dialect exists as a convenience to Perl 5 programmers that want to generate or introspect Muldis D code by saving them the difficulty and overhead of escaping and stitching plain text code; it is expected that a Muldis D implementation written in Perl 5 will natively accept input in both the PTMD_STD and HDMD_Perl5_STD dialects.
Furthermore,
the HDMD_Perl5_STD dialect provides additional Muldis D syntax options to Perl 5 programmers besides what PTMD_STD would canonically parse into,
such as the direct use of some Perl 5-only features.
Note that most of the details that the 2 dialects have in common are described just in the PTMD_STD file,
for both dialects; this current file will mainly focus on the differences; you should read the Muldis::D::Dialect::PTMD_STD file before the current one,
so to provide a context for better understanding it.

A HDMD_Perl5_STD Muldis D code file is actually a Perl 5 code file that defines particular multi-dimensional Perl data structures which resemble possible concrete syntax trees (CSTs) from parsing PTMD_STD Muldis D code.
Each component of a CST is called a node or node element,
and roughly corresponds to a capture by the PTMD_STD parser.
A node is typically represened as a Perl array ref,
but could alternately be a Perl scalar or something else,
and so HDMD_Perl5_STD Muldis D code is typically a tree of Perl structures,
called node trees,
with Perl array refs as the central nodes and Perl scalars as the leaf nodes.
Often HDMD_Perl5_STD code is embedded or constructed in one or more files of a larger Perl 5 program that does more than define this code,
such as various non-database-related tasks.
A node tree is just composed using basic Perl data types,
and there are no Muldis D node-specific Perl classes or objects required for doing this.
Note that Perl undefined values are not allowed anywhere in a node in the general case; you must use only defined values instead. This documentation also assumes that only defined values are used, and that supplying a Perl undef will result in an error. The few exceptions to this rule are explicitly stated.
The grammar in this file is informal and consists just of written descriptions of how each kind of node must be composed and how to interpret such Perl data structures as Muldis D code. Every named grammar node is a Perl array ref unless otherwise stated, and every grammar element is an array element; the first node element is the array element at index zero, and so on.
The root grammar node for the entire dialect is bootloader.

A bootloader node has 1..N ordered elements where the first element is a language_name node and then either: 1.
there is exactly one (second) element that is a value node or a depot node; 2.
there are 1..N ordered elements where each is a boot_stmt node; 3.
there are no other elements,
making the bootloader a no-op.
See the pod sections in this file named "LANGUAGE NAME", "VALUE LITERALS AND SELECTORS", "DEPOT DECLARATION", and "BOOTLOADER STATEMENT" for more details about the aforementioned tokens/nodes.
When Muldis D is being compiled and invoked piecemeal,
such as because the Muldis D implementing virtual machine (VM) is attached to an interactive user terminal,
or the VM is embedded in a host language where code in the host language invokes Muldis D code at various times,
the conceptual bootloader is usually split up,
and so not every Muldis D code fragment would then have its own language_name.
Usually a language_name would be supplied to the Muldis D VM just once as a VM configuration step,
which provides a context for further interaction with the VM that just involves Muldis D code that isn't itself qualified with a language_name.

As per the VERSIONING pod section of Muldis::D,
code written in Muldis D must start by declaring the fully-qualified Muldis D language name it is written in.
The HDMD_Perl5_STD dialect formats this name as a language_name node having 4-5 ordered elements:
ln_base_nameThis is the Muldis D language base name; it is simply the Perl character string Muldis_D.
ln_base_authorityThis is the base authority; it is a character string formatted as per a specific-context Name value literal; it is typically the Perl character string http://muldis.com.
ln_base_version_numberThis is the base version number; it is a character string formatted as per ln_base_authority; it is typically a character string like 1.2.3.
ln_dialectThis is the dialect name; it is simply the Perl character string HDMD_Perl5_STD.
ln_extensionsOptional; this is a set of chosen pragma/parser-config options as per a Tuple SCVL; see the "MULDIS D TINY DIALECT PRAGMAS" pod section for more details.
Examples:
[ 'Muldis_D', 'http://muldis.com', '1.2.3', 'HDMD_Perl5_STD' ] [ 'Muldis_D', 'http://muldis.com', '1.2.3', 'HDMD_Perl5_STD', { ... } ]

A value node is a Muldis D value literal, which is a common special case of a Muldis D value selector.
There are 26 main varieties of value node, each of which is a named node kind of its own: Bool, Order, RatRoundMeth, Int, Rat, Blob, Text, Name, NameChain, DeclNameChain, Comment, Instant, Duration, UTCInstant, FloatInstant, UTCDuration, RatRoundRule, String, Scalar, Tuple, Database, Relation, Set, Maybe, Array, Bag.
Fundamentally, the various Muldis D scalar and collection types are represented by their equivalent Perl native scalar and collection types. But since Muldis D is more strongly typed, or at least differently typed, than Perl, each value node is represented by a Perl array ref, whose elements include both the payload Perl literal plus explicit meta-data for how to interpret that Perl literal for mapping to Muldis D.
Every value node is either a GCVL (generic context value literal) or a SCVL (specific context value literal).
Every GCVL has 1-3 ordered elements:
value_kindThis is a character string of the format <[A..Z]> <[ a..z A..Z ]>+; it identifies the data type of the value literal in broad terms and is the only external meta-data of payload generally necessary to interpret the latter; what grammars are valid for payload depend just on value_kind.
Between the various kinds of value node, these 49 values are allowed for value_kind: Bool, Order, RatRoundMeth, [|NN|P]Int, [|NN|P]Rat, [|Octet]Blob, Text, Name, NameChain, DeclNameChain, Comment, Instant, Duration, UTC[Instant|DateTime|Date|Time], Float[Instant|DateTime|Date|Time], UTCDuration, RatRoundRule, [|B|O|UCP]String, [|DH]Scalar, [|DH]Tuple, Database, [|DH]Relation, [|DH]Set, [|DH][Maybe|Single], [|DH]Array, [|DH]Bag.
For just some data types, the value_kind may be omitted; see below.
type_nameOnly when the value node has 3 elements: This is a Muldis D data type name, for example sys.std.Core.Type.Int; it identifies a specific subtype of the generic type denoted by value_kind, and serves as an assertion that the Muldis D value denoted by payload is a member of the named subtype. Its format is a NameChain_payload node. Iff value_kind is [|DH]Scalar then type_name is mandatory; otherwise, type_name is optional for all value, except that type_name must be omitted when value_kind is one of the 2 [Bool, Order]; this isn't because those 2 types can't be subtyped, but because in practice doing so isn't useful.
payloadThis is mandatory for all value. Format varies with value_kind.
For some data types, a GCVL may alternately be just its payload for the sake of brevity. If any Perl value of one of the following types is encountered where a GCVL node is expected, then it is interpreted as a full value node as follows:
Muldis D <- Perl 5
--------------------
Int <- BigInt object or Perl scalar that looks like an integer
Rat <- BigRat|BigNum obj or Perl scal that looks like num but not int
Text <- Perl scalar that doesn't look like a number
Or specifically, Int or Rat is assumed if the Perl value agrees with a canonical payload format according to the Int|Rat node definitions, or the value is otherwise interpreted as Text by default. If your data is such that the assumption might be wrong, then just use a full node to force the desired behaviour.
For GCVL and SCVL examples, see the subsequent documentation sections.

A Bool node represents a logical boolean value. It is interpreted as a Muldis D sys.std.Core.Type.Bool value as follows:
(1 == 0) for Bool:false or (1 == 1) for Bool:true; said values are probably the empty string and number 1, respectively.'false', '0', 0, '', '⊥'] all map to Bool:false, and the Perl value literals ['true', '1', 1, '⊤'] all map to Bool:true.Examples:
['Bool','true']
['Bool',(1 == 0)]
['Bool','⊤']
A Order node represents an order-determination. It is interpreted as a Muldis D sys.std.Core.Type.Cat.Order value as follows:
(1 <=> 2) for Order:increase or (1 <=> 1) for Order:same or (2 <=> 1) for Order:decrease; said values are probably the numbers [-1,0,1], respectively.'increase', '-1', -1] all map to Order:increase, the Perl value literals ['same', '0', 0] all map to Order:same, and the Perl value literals ['decrease', '1', 1] all map to Order:decrease.Examples:
['Order','same']
['Order',(2 <=> 1)]
A RatRoundMeth node represents a rational rounding method. It is interpreted as a Muldis D sys.std.Core.Type.Cat.RatRoundMeth value by directly mapping the payload. The payload must be a Perl character string having one of the 7 values half_down, half_up, half_even, to_floor, to_ceiling, to_zero, to_inf.
Examples:
['RatRoundMeth','half_up']
['RatRoundMeth','to_zero']
An Int node represents an integer numeric value. It is interpreted as a Muldis D sys.std.Core.Type.Int value as follows:
0 or \-?<[1..9]>['_'?<[0..9]>+]* that is interpreted as base 10.bigint object, which is conceptually the closest thing Perl 5 has in core to a "big integer".[ 1..9 A..Z ] character, and the main payload must be a Perl character string of the format 0 or \-?<[ 1..9 A..Z ]>['_'?<[ 0..9 A..Z ]>+]*. The main payload is interpreted as a base-N integer where N might be between 2 and 36, and the given max-col-val says which possible value of N to use. Assuming all column values are between zero and N-minus-one, the max-col-val contains that N-minus-one. So to specify, eg, bases [2,8,10,16], use max-col-val of [1,7,9,F].Examples:
[ 'Int', { 1 => '11001001' } ] # binary #
[ 'Int', { 7 => '0' } ] # octal #
[ 'Int', { 7 => '644' } ] # octal #
-34 # decimal #
42 # decimal #
[ 'Int', { F => 'DEADBEEF' } ] # hexadecimal #
[ 'Int', { Z => '-HELLOWORLD' } ] # base-36 #
[ 'Int', { 3 => '301' } ] # base-4 #
[ 'Int', { B => 'A09B' } ] # base-12 #
A Rat node represents a rational numeric value. It is interpreted as a Muldis D sys.std.Core.Type.Rat value as follows:
0\.['_'?<[0..9]>+]+ or \-?<[1..9]>['_'?<[0..9]>+]*\.['_'?<[0..9]>+]+ that is interpreted as base 10.bigrat|bignum|bigint object, which is conceptually the closest thing Perl 5 has in core to a "big rational".Int node. If the payload has 2 elements, then the rational's value is interpreted as the first element (a numerator) divided by the second (a denominator). If the payload has 3 elements, then the rational's value is interpreted as the first element (a mantissa) multiplied by the result of the second element (a radix) taken to the power of the third (an exponent).[ 1..9 A..Z ] character. If the main payload is a Perl scalar, then the main payload must be a Perl character string of the format 0\.['_'?<[ 0..9 A..Z ]>+]+ or \-?<[ 1..9 A..Z ]>['_'?<[ 0..9 A..Z ]>+]*\.['_'?<[ 0..9 A..Z ]>+]+. The main payload is interpreted as a base-N rational where N might be between 2 and 36, and the given max-col-val says which possible value of N to use. Assuming all column values are between zero and N-minus-one, the max-col-val contains that N-minus-one. So to specify, eg, bases [2,8,10,16], use max-col-val of [1,7,9,F]. If the main payload is a Perl array ref, then the main payload must have exactly 2 or 3 elements, and every pairwise combination of the max-col-val with the elements of the main payload must, when appropriately wrapped in a Perl hash ref, must constitute a valid hash ref payload for an Int node; the meaning of the 2 or 3 main payload elements is the same as the 2 or 3 payload elements mentioned in the previous bullet point.Examples:
[ 'Rat', { 1 => '-1.1' } ]
-1.5 # same val as prev #
3.14159
[ 'Rat', { A => '0.0' } ]
[ 'Rat', { F => 'DEADBEEF.FACE' } ]
[ 'Rat', { Z => '0.000AZE' } ]
[ 'Rat', { 6 => ['500001','1000'] } ]
[ 'Rat', { B => ['A09B','A'] } ]
[ 'Rat', { 1 => ['1011101101','10','-11011'] } ]
[ 'Rat', [45207196,10,37] ]
[ 'Rat', [1,43] ]
[ 'Rat', [314159,10,-5] ]
A Blob node represents a general purpose bit string. It is interpreted as a Muldis D sys.std.Core.Type.Blob value as follows:
[137F] character, and the main payload must be a Perl character string of the format <[ 0..9 A..F ]>*. Each column of the main payload specifies a sequence of one of [1,2,3,4] bits, depending on whether max-col-val is [1,3,7,F].Examples:
[ 'Blob', { 1 => '00101110100010' } ] # binary #
[ 'Blob', { 3 => '' } ]
[ 'Blob', { F => 'A705E' } ] # hexadecimal #
[ 'Blob', { 7 => '523504376' } ]
[ 'Blob', (pack 'H2', 'P') ]
[ 'Blob', (pack 'H2', 'Z') ]
A Text node represents a general purpose character string. It is interpreted as a Muldis D sys.std.Core.Type.Text value by directly mapping the payload. The payload must be just a canonical Perl character string, which is any Perl scalar value (a Muldis D implementation in Perl can ignore the utf-8 flag as Perl itself knows how to treat its strings consistently).
Examples:
[ 'Text', 'Ceres' ]
'サンプル' # note: needs "use utf8;" pragma to work #
''
'Perl'
"\N{LATIN SMALL LETTER OU}\x{263A}".chr(65)
# note: \N{} needs "use charnames ':full';" pragma to work #
A Name node represents a canonical short name for any kind of DBMS entity when declaring it; it is a character string type, that is disjoint from Text. It is interpreted as a Muldis D sys.std.Core.Type.Cat.Name value by directly mapping the payload. The payload must be as per the payload of a Text node.
A NameChain node represents a canonical long name for invoking a DBMS entity in some contexts; it is conceptually a sequence of entity short names. Its payload is a Perl array ref or character string. This node is interpreted as a Muldis D sys.std.Core.Type.Cat.NameChain value as follows:
Name node (that is, any Perl character string). Each element of the payload, in order, defines an element of the array possrep's attribute of a NameChain..) separators) of at least 1 part, where each part can not have any literal period (.) characters (if you want literal periods then you can only use the array ref payload format to express it). The char str format of payload is interpreted by splitting it on the separators into the array ref format, then processed as per the latter. As a special case, if the NameChain payload begins with a period separator, then the first element of the post-split result is treated not as the empty string Name, but rather as the Name value topic; that is, .foo means the same thing as topic.foo (if you want a literal empty string first element, then you can only use the array ref payload format to express it).A DeclNameChain node represents a canonical long name for declaring a DBMS entity in N-depth contexts; the format and interpretation of a DeclNameChain_payload (but as a sys.std.Core.Type.Cat.DeclNameChain value) is the same as a NameChain_payload but that the chain may have as few as zero parts rather than as few as 1 or 2; however, a zero part chain can only be expressed with the array ref payload format; an empty string char str format will be interpreted as having a single element that is the empty string.
Examples:
[ 'Name', 'login_pass' ]
[ 'Name', 'First Name' ]
[ 'NameChain', ['fed','data','the_db','gene','sorted_person_names'] ]
[ 'NameChain', 'fed.data.the_db.stats.samples by order' ]
[ 'NameChain', '.attr' ] # same as [ 'NameChain', 'lex.topic.attr' ] #
[ 'DeclNameChain', ['gene','sorted_person_name'] ]
[ 'DeclNameChain', 'stats.samples by order' ]
[ 'DeclNameChain', [] ]
A Comment node represents the text of a Muldis D code comment; it is a character string type, that is disjoint from both Text and Name. It is interpreted as a Muldis D sys.std.Core.Type.Cat.Comment value by directly mapping the payload. The payload must be as per the payload of a Text node.
Examples:
[ 'Comment', 'This does something.' ]
[ 'Comment', 'So does this.' ]
An Instant node represents a single point in time which is specified in terms of of atomic seconds; it is a rational numeric type, that is disjoint from both Rat and Duration. This node is interpreted as a Muldis D sys.std.Core.Type.Instant value by directly mapping the payload, which must be as per the payload of a Rat node.
A Duration node represents a single amount of time (the difference between two instants) which is specified in terms of of atomic seconds; it is a rational numeric type, that is disjoint from both Rat and Instant. This node is interpreted as a Muldis D sys.std.Core.Type.Duration value by directly mapping the payload, which must be as per the payload of a Rat node.
Examples:
[ 'Instant', 1235556432.0 ]
[ 'Instant', 854309115.0 ]
[ 'Duration', 3600.0 ]
[ 'Duration', -50.0 ]
[ 'Duration', 3.14159 ]
[ 'Duration', { 1 => ['1011101101','10','-11011'] } ]
[ 'Duration', [1,43] ]
A UTCInstant node represents an "instant"/"datetime" value that is affiliated with the UTC time-zone. This node is interpreted as a Muldis D sys.std.Temporal.Type.UTCInstant value whose instant possrep attribute values are defined as follows:
year, month, day, hour, minute, second. For each payload element that Perl considers undefined or defined, the corresponding attribute has the nothing or a Single value, respectively. For each of the first 5 elements, when it is defined, it must qualify as a valid payload for an Int node; for the 6th element, when it is defined, it must qualify as a valid payload for a Rat node.
A defined year may be any integer, each of [month, day] must be a positive integer, each of [hour, minute] must be a non-negative integer, and second must be a non-negative rational number. If all 6 attributes are defined, then the new UTCInstant value is also a UTCDateTime; if just the first 3 or last 3 are defined, then the value is not a UTCDateTime but rather a UTCDate or UTCTime, respectively; if any other combination of attributes are defined, then the value is just a UTCInstant and not of any of the other 3 subtypes.
Int or Rat node's hash ref payload's element's value is interpreted. The interpretation of this payload is the same as for the Perl array ref payload.A FloatInstant node represents an "instant"/"datetime" value that is "floating" / not affiliated with any time-zone. This node is interpreted as a Muldis D sys.std.Temporal.Type.FloatInstant value in an identical fashion to how a UTCInstant node is interpreted, whose format it completely shares. Likewise regarding Float[DateTime|Date|Time].
A UTCDuration node represents a duration value, an amount of time, which is not fixed to any instant in time. This node is interpreted as a Muldis D sys.std.Temporal.Type.UTCDuration value whose duration possrep attribute values are defined as follows:
years, months, days, hours, minutes, seconds. For each payload element that Perl considers undefined or defined, the corresponding attribute has the nothing or a Single value, respectively. For each of the first 5 elements, when it is defined, it must qualify as a valid payload for an Int node; for the 6th element, when it is defined, it must qualify as a valid payload for a Rat node.
A defined [years, months, days, hours, minutes] may be any integer, and seconds may be any rational number. Currently, UTCDuration has no system-defined subtypes, but that may change later.
Int or Rat node's hash ref payload's element's value is interpreted. The interpretation of this payload is the same as for the Perl array ref payload.Examples:
[ 'UTCInstant', [1964,10,16,16,12,47.5] ] # a UTCDateTime #
[ 'UTCInstant', [2002,12,6] ] # a UTCDate #
[ 'UTCInstant', [undef,undef,undef,14,2,29.0] ] # a UTCTime #
[ 'FloatInstant', [2003,4,5,2] ] # min,sec unknown or N/A #
[ 'FloatInstant', [1407] ] # just know its sometime in 1407 #
[ 'UTCDuration', [3,5,1,6,15,45.000012] ]
A RatRoundRule node represents a rational rounding rule. It is interpreted as a Muldis D sys.std.Core.Type.Cat.RatRoundRule value whose attributes are defined by the RatRoundRule_payload. A RatRoundRule_payload must be a Perl array ref with 3 elements, which correspond in order to the 3 attributes: radix (a PInt2_N), min_exp (an Int), and round_meth (a RatRoundMeth). Each of radix and min_exp must qualify as a valid Int_payload, and round_meth must qualify as a valid RatRoundMeth_payload.
Examples:
[ 'RatRoundRule', [10,-2,'half_even'] ]
[ 'RatRoundRule', [2,-7,'to_zero'] ]
A String node represents an integer string value. This node is interpreted as a Muldis D sys.std.Core.Type.Cat.String value as follows:
Int node.Int node.Examples:
[ 'String', [80,101,114,109] ] # Unicode abstract codepoints = 'Perl' #
[ 'String', { F => ['50','65','72','6C'] } ] # same thing #

Note that, with each of the main value selector nodes documented in this main POD section, any occurrences of child expr nodes should be read as being value nodes instead in contexts where instances of the main nodes are being composed beneath value nodes. That is, any expr node options beyond what value options exist are only valid within a depot node or boot_stmt node.
A Scalar node represents a literal or selector invocation for a scalar subtype value. It is interpreted as a Muldis D sys.std.Core.Type.Scalar subtype value whose declared type is specified by the node's (mandatory for Scalar) type_name element and whose attributes are defined by the payload. The payload must be just a Perl array ref having exactly 2 elements, that are designated possrep name and possrep attrs. The possrep name and possrep attrs must be as per the payload of a Name and Tuple node, respectively. The possrep attrs is interpreted specifically as attributes of the declared type's possrep which is specified by the possrep name. Each key+value pair of the possrep attrs defines a named possrep attribute of the new scalar; the pair's key and value are, respectively, a Perl character string that specifies the possrep attribute name, and a expr node that specifies the possrep attribute value.
Examples:
[ 'Scalar', 'sys.std.Core.Type.Rat', [ float => {
mantissa => 45207196,
radix => 10,
exponent => 37,
} ] ]
[ 'Scalar', 'sys.std.Temporal.Type.UTCDateTime', [ datetime => {
year => 2003,
month => 10,
day => 26,
hour => 1,
minute => 30,
second => 0.0,
} ] ]
[ 'Scalar', 'fed.lib.the_db.WeekDay', [ name => {
'' => 'monday',
} ] ]
[ 'Scalar', 'fed.lib.the_db.WeekDay', [ number => {
'' => 5,
} ] ]
A Tuple node represents a literal or selector invocation for a tuple value. It is interpreted as a Muldis D sys.std.Core.Type.Tuple value whose attributes are defined by the payload. The payload must be just a Perl hash ref. Each key+value pair of the payload defines a named attribute of the new tuple; the pair's key and value are, respectively, a Perl character string that specifies the attribute name, and a expr node that specifies the attribute value.
Examples:
[ 'Tuple', {} ]
[ 'Tuple', 'type.tuple_from.var.fed.data.the_db.account.users', {
login_name => 'hartmark',
login_pass => 'letmein',
is_special => ['Bool','true'],
} ]
[ 'Tuple', {
name => 'Michelle',
age => 17,
} ]
A Database node represents a literal or selector invocation for a 'database' value. It is interpreted as a Muldis D sys.std.Core.Type.Database value whose attributes are defined by the payload. The payload must be a just a Perl hash ref. Each key+value pair of the payload defines a named attribute of the new 'database'; the pair's key and value are, respectively, a Perl character string that specifies the attribute name, and a expr node that specifies the attribute value, which must be represent a relation value.
A Relation node represents a literal or selector invocation for a relation value. It is interpreted as a Muldis D sys.std.Core.Type.Relation value whose attributes and tuples are defined by the payload, which is interpreted as follows:
Name node), then it defines the attribute names of a relation having zero tuples.Tuple node), then each element of the payload defines a tuple of the new relation; every tuple-defining element of the payload must be of the same degree and have the same attribute names as its sibling elements; these are the degree and attribute names of the relation as a whole, which is its heading for the current purposes.Name node payload), and the relation body's tuples' attribute values are defined by the payload's second element, which is a Perl array ref of Perl array ref of tuple attribute value defining nodes. This format is meant to be the most compact of the generic relation payload formats, as the attribute names only appear once for the relation rather than repeating for each tuple. As a trade-off, the attribute values per tuple from the payload second element must appear in the same order as their corresponding attribute names appear in the payload first element, as the names and values in the relation literal are matched up by ordinal position here.Examples:
[ 'Relation', [] ] # zero attrs + zero tuples #
[ 'Relation', [ 'x', 'y', 'z' ] ] # 3 attrs + zero tuples #
[ 'Relation', [ {} ] ] # zero attrs + 1 tuple #
[ 'Relation', [
{
login_name => 'hartmark',
login_pass => 'letmein',
is_special => ['Bool','true'],
},
] ] # 3 attrs + 1 tuple #
[ 'Relation', 'fed.lib.the_db.gene.Person', [ [ 'name', 'age' ] => [
[ 'Michelle', 17 ],
] ] ] # 2 attrs + 1 tuple #
A Set node represents a literal or selector invocation for a set value. It is interpreted as a Muldis D sys.std.Core.Type.Set value whose elements are defined by the payload. The payload must be just a Perl array ref. Each element of the payload defines a unary tuple of the new set; each element is a expr node that defines the value attribute of the tuple.
Examples:
[ 'Set', 'fed.lib.the_db.account.Country_Names', [
'Canada',
'Spain',
'Jordan',
'Thailand',
] ]
[ 'Set', [
3,
16,
85,
] ]
A Maybe node represents a literal or selector invocation for a maybe value. It is interpreted as a Muldis D sys.std.Core.Type.Maybe value. If the node payload is missing or undefined, then the node is interpreted as the special value Maybe:nothing, aka nothing, which is the only Maybe value with zero elements. If the node payload is defined then the node is interpreted as a Single whose element is defined by the payload. The payload is a expr node that defines the value attribute of the single tuple of the new 'single'.
Examples:
[ 'Maybe', 'I know this one!' ]
[ 'Maybe', undef ]
A Array node represents a literal or selector invocation for a array value. It is interpreted as a Muldis D sys.std.Core.Type.Array value whose elements are defined by the payload. The payload must be just a Perl array ref. Each element of the payload defines a binary tuple of the new sequence; the element value is a expr node that defines the value attribute of the tuple, and the element index is used as the index attribute of the tuple.
Examples:
[ 'Array', [
'Alphonse',
'Edward',
'Winry',
] ]
[ 'Array', 'fed.lib.the_db.stats.Samples_By_Order', [
57,
45,
63,
61,
] ]
A Bag node represents a literal or selector invocation for a bag value. It is interpreted as a Muldis D sys.std.Core.Type.Bag value whose elements are defined by the payload. The payload is interpreted as follows:
expr node that defines the value attribute of the tuple, and a valid Int node payload that defines the count attribute of the tuple; the count must be a positive integer.expr node that defines the value attribute of the tuple. The bag has 1 tuple for every distinct (after format normalization) element value in the payload, and the count attribute of that tuple says how many instances of said element were in the payload.Examples:
[ 'Bag', 'fed.lib.the_db.inventory.Fruit', [
[ 'Apple' => 500 ],
[ 'Orange' => 300 ],
[ 'Banana' => 400 ],
] ]
[ 'Bag', [
'Foo',
'Quux',
'Foo',
'Bar',
'Baz',
'Baz',
] ]

An expr_name node has 2 ordered elements: The first element is the Perl character string expr_name. The second element is a NameChain_payload.
A named_expr node has 3 ordered elements: The first element is the Perl character string named_expr. The second element is a Name_payload and the third element is an expr node (that isn't a named_expr node); the second element declares an explicit expression node name for the third element.
Examples:
# an expr_name node #
['expr_name','foo_expr']
# a named_expr node #
[ 'named_expr', 'bar_expr',
[ 'func_invo', 'factorial', [ ['expr_name','foo_expr'] ] ] ]
An func_invo node has 2-4 ordered elements: The first element is the Perl character string func_invo. The second element is a NameChain_payload, which names the function to invoke. The last 1-2 elements provide arguments to the function invocation; either or both or none of a Array_payload element and a Tuple_payload element may be given. The Array_payload 3rd/4th element is for any anonymous (and ordered if multiple exist) arguments, and the Tuple_payload 3rd/4th element is for any named arguments; each Array_payload element or Tuple_payload element value is an expr node which is the argument value.
Examples:
# zero params #
[ 'func_invo', 'nothing' ]
# single mandatory param #
[ 'func_invo', 'Integer.median',
[ [ 'Bag', [ 22, 20, 21, 20, 21, 21, 23 ] ] ] ]
# single mandatory param #
[ 'func_invo', 'factorial', { topic => 5 } ]
# two mandatory params #
[ 'func_invo', 'Rational.quotient',
{ dividend => 43.7, divisor => 16.9 } ]
# one mandatory param, two optional #
[ 'func_invo', 'inn.barfunc', [ ['expr_name','mand_arg'] ],
{ oa1 => ['expr_name','opt_arg1'], oa2 => ['expr_name','opt_arg2']
} ]
# a user-defined non-inner function #
[ 'func_invo', 'dep.lib.foodb.bazfunc',
{ a1 => 52, a2 => 'hello world' } ]
# two params named 'topic' and 'other' #
[ 'func_invo', 'is_identical',
[ ['expr_name','foo'], ['expr_name','bar'] ] ]
An if_else_expr node has 2-3 ordered elements: The first element is either of the 2 Perl character strings if_else_expr and ??!!. The optional second element is if_then, a Perl array ref with 0..N elements, each of those being a 2-element Perl array ref, where each element is an expr node; the first element is an if condition expression, and the second element is the associated then result expression. The 3rd/last element of an if_else_expr node is else result expression, which is an expr node.
Examples:
[ 'if_else_expr',
[
[[ 'op', '>', ['expr_name','foo'], 5 ] => ['expr_name','bar']],
],
['expr_name','baz']
]
[ 'if_else_expr',
[
[[ 'op', 'is_empty', ['expr_name','ary'] ]
=> ['expr_name','empty_result']],
],
[ 'op', 'Array.value', ['expr_name','ary'], 0 ]
]
[ 'op', 'T~', [ 'My answer is: ',
[ '??!!', [ [['expr_name','maybe'] => 'yes'] ], 'no' ]
] ]
A given_when_def_expr node has 3-4 ordered elements: The first element is the Perl character string given_when_def_expr. The second element is an expr node which is the given common comparand. The optional third element is when_then, a Perl array ref with 0..N elements, each of those being a 2-element Perl array ref, where each element is an expr node; the first element is a when comparand, and the second element is the associated then result expression. The 4th/last element of an given_when_def_expr node is default result expression, which is an expr node.
Examples:
[ 'given_when_def_expr',
['expr_name','digit'],
[
[ 'T' => 10 ],
[ 'E' => 11 ],
],
['expr_name','digit'],
]
A [func|proc|type|ord_det_func]_ref node has 2 ordered elements: The first element is the Perl character string value [func|proc|type|ord_det_func]_ref. The second element is a NameChain_payload, which names the routine|type to invoke.
Examples:
['func_ref','inn.filter']
['imp_ref','inn.try_block']
['type_ref','inn.foo_type']
['ord_det_func_ref','inn.order_bars']

A func_invo_alt_syntax node has 3-4 ordered elements: The first element is the Perl character string op. The second element is a Perl character string, hereafter referred to as op or keyword, which determines the function to invoke. The third element is (usually) a Perl array ref, hereafter referred to as main op args, which is an ordered list of 1-N mandatory inputs to the function invocation. The (optional) fourth element is a Perl hash ref, hereafter referred to as extra op args, which is a named list of optional function inputs. The number and format of elements of either main op args or extra op args varies depending on op. Note that, when a main op args would just contain a single element, such as when it is for a monadic operator, it may alternately be formatted as what is otherwise just its sole (node) element iff that node is not formatted as a Perl array ref.
A comm_infix_reduce_op_invo node has 2-N main op args, each of which is an expr node.
Examples:
[ 'op', 'and', [ ['Bool','true'], ['Bool','false'], ['Bool','true'] ] ]
[ 'op', 'or', [ ['Bool','true'], ['Bool','false'], ['Bool','true'] ] ]
[ 'op', 'xor', [ ['Bool','true'], ['Bool','false'], ['Bool','true'] ] ]
[ 'op', 'I+', [ 14, 3, -5 ] ]
[ 'op', 'I*', [ -6, 2, 25 ] ]
[ 'op', 'N+', [ 4.25, -0.002, 1.0 ] ]
[ 'op', 'N*', [ 69.3, [ 'Rat', [15,2,6] ], [ 'Rat', [49,23] ] ] ]
[ 'op', '∪', [ [ 'Set', [ 1, 3, 5 ] ],
[ 'Set', [ 4, 5, 6 ] ], [ 'Set', [ 0, 9 ] ] ] ]
[ 'op', '∩', [ [ 'Set', [ 1, 3, 5, 7, 9 ] ],
[ 'Set', [ 3, 4, 5, 6, 7, 8 ] ], [ 'Set', [ 2, 5, 9 ] ] ] ]
A noncomm_infix_reduce_op_invo node has 2-N main op args, each of which is an expr node.
Examples:
[ 'op', '[<=>]', [ ['Order','same'],
['Order','increase'], ['Order','decrease'] ] ]
[ 'op', 'B~', [ [ 'Blob', { F => 'DEAD' } ],
[ 'Blob', { 1 => '10001101' } ], [ 'Blob', { F => 'BEEF' } ] ] ]
[ 'op', 'T~', [ 'hello', ' ', 'world' ] ]
[ 'op', 'A~', [ [ 'Array', [ 24, 52 ] ],
[ 'Array', [ -9 ] ], [ 'Array', [ 0, 11, 24, 7 ] ] ] ]
[ 'op', '//', [ ['expr_name','a'], ['expr_name','b'], 42 ] ]
[ 'op', '//d', [ ['expr_name','a'], ['expr_name','b'],
['type_ref','inn.foo_type'] ] ]
A sym_dyadic_infix_op_invo node has exactly 2 main op args, each of which is an expr node; which function arguments get which main op args isn't significant.
Examples:
[ 'op', '=', [ ['expr_name','foo'], ['expr_name','bar'] ] ]
[ 'op', '≠', [ ['expr_name','foo'], ['expr_name','bar'] ] ]
[ 'op', 'nand', [ ['Bool','false'], ['Bool','true'] ] ]
[ 'op', 'I|-|', [ 15, 17 ] ]
[ 'op', 'N|-|', [ 7.5, 9.0 ] ]
A nonsym_dyadic_infix_op_invo node has exactly 2 main op args, each of which is an expr node; the first and second main op args are lhs and rhs, respectively.
Examples:
[ 'op', 'isa', [ ['expr_name','bar'], ['type_ref','inn.foo_type'] ] ]
[ 'op', '!isa', [ ['expr_name','bar'], ['type_ref','inn.foo_type'] ] ]
[ 'op', 'as', [ ['expr_name','scalar'], ['type_ref','Int'] ] ]
[ 'op', 'asserting', [ ['expr_name','int'],
[ 'op', '≠', [ ['expr_name','int'], 0 ] ] ] ]
[ 'op', 'implies', [ ['Bool','true'], ['Bool','false'] ] ]
[ 'op', 'I-', [ 34, 21 ] ]
[ 'op', 'I/', [ 5, 3 ] ]
[ 'op', '%', [ 5, 3 ] ]
[ 'op', 'I^', [ 2, 63 ] ]
[ 'op', 'N-', [ 9.2, 0.1 ] ]
[ 'op', 'N/', [[ 'Rat', {1 => '101.01'} ], [ 'Rat', {1 => '11.0'} ]] ]
[ 'op', 'Tx', [ '-', 80 ] ]
[ 'op', '∖', [ [ 'Set', [ 8, 4, 6, 7 ] ], [ 'Set', [ 9, 0, 7 ] ] ] ]
[ 'op', '÷', [ [ 'Relation', [ ['x', 'y'] => [ [5, 6], [3, 6] ] ] ],
[ 'Relation', [ { y => 6 } ] ] ] ]
A monadic_prefix_op_invo node has exactly 1 main op arg, which is an expr node.
Examples:
[ 'op', 'd', ['type_ref','inn.foo_type'] ]
[ 'op', 'not', [ ['Bool','true'] ] ]
[ 'op', 'I||', -23 ]
[ 'op', 'N||', -4.59 ]
[ 'op', 'R#', [ [ 'Set', [ 5, -1, 2 ] ] ] ]
[ 'op', 't', [ ['expr_name','relvar'] ] ]
[ 'op', 'r', [ ['expr_name','tupvar'] ] ]
[ 'op', 's', [ [ 'op', 'N+', [
[ 'op', 'v', [ ['expr_name','a'] ] ],
[ 'op', 'v', [ ['expr_name','b'] ] ]
] ] ] ]
A monadic_postfix_op_invo node has exactly 1 main op arg, which is an expr node.
Examples:
[ 'op', '++', 13 ]
[ 'op', '--', 4 ]
[ 'op', '!', 5 ]
A rat_op_invo_with_round node has exactly 2-3 main op args, each of which is an expr node that defines an input value for the operator. When there are 2 main op args, the first and second args are expr and round_rule, respectively. When there are 3 main op args, the first, second and third args are lhs, rhs and round_rule, respectively.
Examples:
[ 'op', 'round', [ ['expr_name','foo'],
[ 'RatRoundRule', [10,-2,'half_even'] ] ] ]
[ 'op', 'N^', [ 2.0, 0.5, [ 'RatRoundRule', [2,-7,'to_zero'] ] ] ]
[ 'op', 'log', [ 309.1, 5.4, [ 'RatRoundRule', [10,-4,'half_up'] ] ] ]
[ 'op', 'e^', [ 6.3, [ 'RatRoundRule', [10,-6,'to_ceiling'] ] ] ]
[ 'op', 'loge', [ 17.0, [ 'RatRoundRule', [3,-5,'to_floor'] ] ] ]
An ord_compare_op_invo node has exactly 2 or 3 or 2-N main op args, depending on the op, each of which is an expr node. When the op requires exactly 2 main op args, the first and second args are lhs and rhs, respectively. When the op requires exactly 2 main op args, the first, second and third args are min, expr, and max, respectively. When the op is N-adic, requiring 2-N main op args, then the order of the main op args isn't significant. Details on the extra op args are pending.
Examples (for now sans any use of extra op args, which are atypical):
[ 'op', '<=>', [ ['expr_name','foo'], ['expr_name','bar'] ] ]
[ 'op', 'min', [ ['expr_name','a'], ['expr_name','b'],
['expr_name','c'] ] ]
[ 'op', 'max', [ ['expr_name','a'], ['expr_name','b'],
['expr_name','c'] ] ]
[ 'op', '<', [ ['expr_name','foo'], ['expr_name','bar'] ] ]
[ 'op', '>', [ ['expr_name','foo'], ['expr_name','bar'] ] ]
[ 'op', '≤', [ ['expr_name','foo'], ['expr_name','bar'] ] ]
[ 'op', '≥', [ ['expr_name','foo'], ['expr_name','bar'] ] ]
[ 'op', '≤≤', [ ['expr_name','min'], ['expr_name','foo'],
['expr_name','max'] ] ]
[ 'op', '≤<', [ ['expr_name','min'], ['expr_name','foo'],
['expr_name','max'] ] ]
[ 'op', '!<≤', [ ['expr_name','min'], ['expr_name','foo'],
['expr_name','max'] ] ]
[ 'op', '!<<', [ ['expr_name','min'], ['expr_name','foo'],
['expr_name','max'] ] ]

TODO: ALL OF THIS HERE MAIN POD SECTION!

TODO/REDO: ALL OF THIS HERE MAIN POD SECTION!
This node specifies one statement of a Muldis D bootloader routine which invokes an imperative routine, such statements being what the entire body of a bootloader is composed of. A bootloader imperative routine call is formatted as a node having the following 4 elements:
boot_stmt.NameChain node.Tuple node except that every hash ref is just a Perl array ref or character string as per the payload of a NameChain node (each value is the name of a global variable).Tuple node.Examples
[ 'boot_stmt', 'sys.std.Core.Cat.create_depot_material', {}, { ... } ]

TODO/REDO: ALL OF THIS HERE MAIN POD SECTION!

Go to Muldis::D for the majority of distribution-internal references, and Muldis::D::SeeAlso for the majority of distribution-external references.

Darren Duncan (perl@DarrenDuncan.net)

This file is part of the formal specification of the Muldis D language.
Muldis D is Copyright © 2002-2009, Muldis Data Systems, Inc.
See the LICENSE AND COPYRIGHT of Muldis::D for details.

The TRADEMARK POLICY in Muldis::D applies to this file too.

The ACKNOWLEDGEMENTS in Muldis::D apply to this file too.