Skip to content

Latest commit

 

History

History
521 lines (483 loc) · 49.6 KB

reference.md

File metadata and controls

521 lines (483 loc) · 49.6 KB

Morel language reference

Grammar

This reference is based on Andreas Rossberg's grammar for Standard ML. While the files have a different notation, they are similar enough to the two languages.

Differences between Morel and SML

Morel aims to be compatible with Standard ML. It extends Standard ML in areas related to relational operations. Some of the features in Standard ML are missing, just because they take effort to build. Contributions are welcome!

In Morel but not Standard ML:

  • from expression with in, join, where, distinct, group, compute, into, order, skip, take, through, yield clauses
  • union, except, intersect, elem, notelem operators
  • "lab =" is optional in exprow
  • identifiers may be quoted (for example, `an identifier`)

In Standard ML but not in Morel:

  • word constant
  • longid identifier
  • references (ref and operators ! and :=)
  • exceptions (raise, handle, exception)
  • while loop
  • data type replication (type)
  • withtype in datatype declaration
  • abstract type (abstype)
  • modules (structure and signature)
  • local declarations (local)
  • operator declarations (nonfix, infix, infixr)
  • open
  • before and o operators

Constants

con  int                       integer
    | float                     floating point
    | char                      character
    | string                    string
int → [~]num                    decimal
    | [~]0xhex                  hexadecimal
float → [~]num.num              floating point
    | [~]num[.num]e[~]num
                                scientific
char#"ascii"                 character
string"ascii*"               string
numdigit digit*              number
hex → (digit | letter) (digit | letter)*
                                hexadecimal number (letters
                                may only be in the range A-F)
ascii → ...                     single non-" ASCII character
                                or \-headed escape sequence

Identifiers

idletter (letter | digit | ''' | _)*
                                alphanumeric
    | symbol symbol*            symbolic (not allowed for type
                                variables or module language
                                identifiers)
symbol!
    | %
    | &
    | $
    | #
    | +
    | -
    | /
    | :
    | <
    | =
    | >
    | ?
    | @
    | \
    | ~
    | `
    | ^
    | '|'
    | '*'
var → '''(letter | digit | ''' | _)*
                                unconstrained
      ''''(letter | digit | ''' | _⟩*
                                equality
labid                        identifier
      num                       number (may not start with 0)

Expressions

expcon                       constant
    | [ op ] id                 value or constructor identifier
    | exp1 exp2                 application
    | exp1 id exp2              infix application
    | '(' exp ')'               parentheses
    | '(' exp1 , ... , expn ')' tuple (n ≠ 1)
    | { [ exprow ] }            record
    | #lab                      record selector
    | '[' exp1 , ... , expn ']' list (n ≥ 0)
    | '(' exp1 ; ... ; expn ')' sequence (n ≥ 2)
    | let dec in exp1 ; ... ; expn end
                                local declaration (n ≥ 1)
    | exp : type                type annotation
    | exp1 andalso exp2         conjunction
    | exp1 orelse exp2          disjunction
    | if exp1 then exp2 else exp3
                                conditional
    | case exp of match         case analysis
    | fn match                  function
    | from [ scan1 , ... , scans ] step*
                                relational expression (s ≥ 0)
exprowexprowItem [, exprowItem ]*
                                expression row
exprowItem → [ lab = ] exp
matchmatchItem [ '|' matchItem ]*
                                match
matchItempat => exp
scanpat in exp [ on exp ]    iteration
    | pat = exp [ on exp ]      single iteration
    | var                       unbounded variable
stepwhere exp                filter clause
    | join scan1 [ , ... , scans ]
                                join clause
    | distinct                  distinct clause
    | group groupKey1 , ... , groupKeyg
      [ compute agg1 , ... , agga ]
                                group clause (g ≥ 0, a ≥ 1)
    | compute agg1 , ... , agga
                                compute clause (a > 1)
    | order orderItem1 , ... , orderItemo
                                order clause (o ≥ 1)
    | skip exp                  skip clause
    | take exp                  take clause
    | into exp                  into clause
    | through pat in exp        through clause
    | yield exp                 yield clause
groupKey → [ id = ] exp
agg → [ id = ] exp [ of exp ]
orderItemexp [ desc ]

Patterns

patcon                       constant
    | _                         wildcard
    | [ op ] id                 variable
    | [ op ] id [ pat ]         construction
    | pat1 id pat2              infix construction
    | '(' pat ')'               parentheses
    | '(' pat1 , ... , patn ')' tuple (n ≠ 1)
    | { [ patrow ] }            record
    | '[' pat1 , ... , patn ']' list (n ≥ 0)
    | pat : type                type annotation
    | id as pat                 layered
patrow → '...'                  wildcard
    | lab = pat [, patrow]      pattern
    | id [, patrow]             label as variable

Types

typvar                       variable
    | [ typ ] id                constructor
    | '(' typ [, typ ]* ')' id  constructor
    | '(' typ ')'               parentheses
    | typ1 -> typ2              function
    | typ1 '*' ... '*' typn     tuple (n ≥ 2)
    | { [ typrow ] }            record
typrowlab : typ [, typrow]   type row

Declarations

decvals valbind              value
    | fun vars funbind          function
    | datatype datbind          data type
    | empty
    | dec1 [;] dec2              sequence
valbindpat = exp [ and valbind ]*
                                destructuring
    | rec valbind               recursive
funbindfunmatch [ and funmatch ]*
                                clausal function
funmatchfunmatchItem [ '|' funmatchItem ]*
funmatchItem → [ op ] id pat1 ... patn [ : type ] = exp
                                nonfix (n ≥ 1)
    | pat1 id pat2 [ : type ] = exp        infix
    | '(' pat1 id pat2 ')' pat'1 ... pat'n [ : type ] = exp
                                infix (n ≥ 0)
datbinddatbindItem [ and datbindItem ]*
                                data type
datbindItemvars id = conbind
conbindconbindItem [ '|' conbindItem ]*
                                data constructor
conbindItemid [ of typ ]
valsval
    | '(' val [, val]* ')'
varsvar
    | '(' var [, var]* ')'

Notation

This grammar uses the following notation:

Syntax Meaning
symbol Grammar symbol (e.g. con)
keyword Morel keyword (e.g. if) and symbol (e.g. ~, "(")
[ term ] Option: term may occur 0 or 1 times
[ term1 | term2 ] Alternative: term1 may occur, or term2 may occur, or neither
term* Repetition: term may occur 0 or more times
's' Quotation: Symbols used in the grammar — ( ) [ ] | * ... — are quoted when they appear in Morel language

Built-in operators

Operator Precedence Meaning
* infix 7 Multiplication
/ infix 7 Division
div infix 7 Integer division
mod infix 7 Modulo
intersect infix 7 List intersect
+ infix 6 Plus
- infix 6 Minus
^ infix 6 String concatenate
union infix 6 List union
except infix 6 List difference
~ prefix 6 Negate
:: infixr 5 List cons
@ infixr 5 List append
<= infix 4 Less than or equal
< infix 4 Less than
>= infix 4 Greater than or equal
> infix 4 Greater than
= infix 4 Equal
<> infix 4 Not equal
elem infix 4 Member of list
notelem infix 4 Not member of list
:= infix 3 Assign
o infix 3 Compose
andalso infix 2 Logical and
orelse infix 1 Logical or

Built-in types

Primitive: bool, char, int, real, string, unit

Datatype:

  • datatype 'a list = nil | :: of 'a * 'a list (in structure List)
  • datatype 'a option = NONE | SOME of 'a (in structure Option)
  • datatype 'a order = LESS | EQUAL | GREATER (in structure General)

Eqtype:

  • eqtype 'a vector = 'a vector (in structure Vector)

Exception:

  • Empty (in structure List)
  • Option (in structure Option)
  • Size (in structure General)
  • Subscript (in structure General)

Built-in functions

Name Type Description
true bool Literal true.
false bool Literal false.
not bool → bool "not b" returns the logical inverse of b.
abs int → int "abs n" returns the absolute value of n.
General.ignore α → unit "ignore x" always returns unit. The function evaluates its argument but throws away the value.
General.op o (β → γ) (α → β) → α → γ "f o g" is the function composition of f and g. Thus, (f o g) a is equivalent to f (g a).
Interact.use string → unit "use f" loads source text from the file named f.
Interact.useSilently string → unit "useSilently f" loads source text from the file named f, without printing to stdout.
Int op * int * int → int "i * j" is the product of i and j. It raises Overflow when the result is not representable.
Int op + int * int → int "i + j" is the sum of i and j. It raises Overflow when the result is not representable.
Int op - int * int → int "i - j" is the difference of i and j. It raises Overflow when the result is not representable.
Int op div int * int → int "i div j" returns the greatest integer less than or equal to the quotient of i by j, i.e., floor(i / j). It raises Overflow when the result is not representable, or Div when j = 0. Note that rounding is towards negative infinity, not zero.
Int op mod int * int → int "i mod j" returns the remainder of the division of i by j. It raises Div when j = 0. When defined, (i mod j) has the same sign as j, and (i div j) * j + (i mod j) = i.
Int op < int * int → bool "i < j" returns true if i is less than j.
Int op <= int * int → bool "i < j" returns true if i is less than or equal to j.
Int op > int * int → bool "i < j" returns true if i is greater than j.
Int op >= int * int → bool "i < j" returns true if i is greater than or equal to j.
Int op ~ int → int "~ i" returns the negation of i.
Int.abs int → int "abs i" returns the absolute value of i.
Int.compare int * int → order "compare (i, j)" returns LESS, EQUAL, or GREATER according to whether its first argument is less than, equal to, or greater than the second.
Int.fromInt, int int → int "fromInt i" converts a value from type int to the default integer type. Raises Overflow if the value does not fit.
Int.fromString string → int option "fromString s" scans a int value from a string. Returns SOME (r) if a int value can be scanned from a prefix of s, ignoring any initial whitespace; otherwise, it returns NONE. Equivalent to StringCvt.scanString (scan StringCvt.DEC).
Int.max int * int → int "max (i, j)" returns the larger of the arguments.
Int.maxInt int "maxInt" is the maximal (most positive) integer representable by int. If a value is NONE, int can represent all positive integers, within the limits of the heap size. If precision is SOME (n), then we have maxInt = 2(n-1) - 1.
Int.min int * int → int "min (i, j)" returns the smaller of the arguments.
Int.minInt int "minInt" is the minimal (most negative) integer representable by int. If a value is NONE, int can represent all negative integers, within the limits of the heap size. If precision is SOME (n), then we have minInt = -2(n-1).
Int.mod int * int → int "mod (i, j)" returns the remainder of the division of i by j. It raises Div when j = 0. When defined, (i mod j) has the same sign as j, and (i div j) * j + (i mod j) = i`.
Int.precision int "precision" is the precision. If SOME (n), this denotes the number n of significant bits in type int, including the sign bit. If it is NONE, int has arbitrary precision. The precision need not necessarily be a power of two.
Int.quot int * int → int "quot (i, j)" returns the truncated quotient of the division of i by j, i.e., it computes (i / j) and then drops any fractional part of the quotient. It raises Overflow when the result is not representable, or Div when j = 0. Note that unlike div, quot rounds towards zero. In addition, unlike div and mod, neither quot nor rem are infix by default; an appropriate infix declaration would be infix 7 quot rem. This is the semantics of most hardware divide instructions, so quot may be faster than div.
Int.rem int * int → int "rem (i, j)" returns the remainder of the division of i by j. It raises Div when j = 0. (i rem j) has the same sign as i, and it holds that (i quot j) * j + (i rem j) = i. This is the semantics of most hardware divide instructions, so rem may be faster than mod.
Int.sameSign int * int → bool "sameSign (i, j)" returns true if i and j have the same sign. It is equivalent to (sign i = sign j).
Int.sign int → int "sign i" returns ~1, 0, or 1 when i is less than, equal to, or greater than 0, respectively.
Int.toInt int → int "toInt i" converts a value from the default integer type to type int. Raises Overflow if the value does not fit.
Int.toString int → string "toString i" converts a int into a string; equivalent to (fmt StringCvt.DEC r).
List.nil α list "nil" is the empty list.
List.null α list → bool "null l" returns true if the list l is empty.
List.length α list → int "length l" returns the number of elements in the list l.
List.op @ α list * α list → α list "l1 @ l2" returns the list that is the concatenation of l1 and l2.
List.at α list * α list → α list "at (l1, l2)" is equivalent to "l1 @ l2".
List.hd α list → α "hd l" returns the first element of l. Raises Empty if l is nil.
List.tl α list → α list "tl l" returns all but the first element of l. Raises Empty if l is nil.
List.last α list → α "last l" returns the last element of l. Raises Empty if l is nil.
List.getItem α list → * (α * α list) option "getItem l" returns NONE if the list is empty, and SOME (hd l, tl l) otherwise. This function is particularly useful for creating value readers from lists of characters. For example, Int.scan StringCvt.DEC getItem has the type (int, char list) StringCvt.reader and can be used to scan decimal integers from lists of characters.
List.nth α list * int → α "nth (l, i)" returns the i(th) element of the list l, counting from 0. Raises Subscript if i < 0 or ilength l. We have nth(l, 0) = hd l, ignoring exceptions.
List.take α list * int → α list "take (l, i)" returns the first i elements of the list l. Raises Subscript if i < 0 or i > length l. We have take(l, length l) = l.
List.drop α list * int → α list "drop (l, i)" returns what is left after dropping the first i elements of the list l. Raises Subscript if i < 0 or i > length l.

It holds that take(l, i) @ drop(l, i) = l when 0 ≤ ilength l. We also have drop(l, length l) = [].
List.rev α list → α list "rev l" returns a list consisting of l's elements in reverse order.
List.concat α list list → α list "concat l" returns the list that is the concatenation of all the lists in l in order. concat [l1, l2, ... ln] = l1 @ l2 @ ... @ ln
List.revAppend α list * α list → α list "revAppend (l1, l2)" returns (rev l1) @ l2.
List.app (α → unit) → α list → unit "app f l" applies f to the elements of l, from left to right.
List.map (α → β) → α list → β list "map f l" applies f to each element of l from left to right, returning the list of results.
List.mapPartial (α → β option) → α list → β list "mapPartial f l" applies f to each element of l from left to right, returning a list of results, with SOME stripped, where f was defined. f is not defined for an element of l if f applied to the element returns NONE. The above expression is equivalent to ((map valOf) o (filter isSome) o (map f)) l.
List.find (α → bool) → α list → α option "find f l" applies f to each element x of the list l, from left to right, until f x evaluates to true. It returns SOME (x) if such an x exists; otherwise it returns NONE.
List.filter (α → bool) → α list → α list "filter f l" applies f to each element x of l, from left to right, and returns the list of those x for which f x evaluated to true, in the same order as they occurred in the argument list.
List.partition (α → bool) → α list → α list * α list "partition f l" applies f to each element x of l, from left to right, and returns a pair (pos, neg) where pos is the list of those x for which f x evaluated to true, and neg is the list of those for which f x evaluated to false. The elements of pos and neg retain the same relative order they possessed in l.
List.foldl (α * β → β) → β → α list → β "foldl f init [x1, x2, ..., xn]" returns f(xn, ... , f(x2, f(x1, init))...) or init if the list is empty.
List.foldr (α * β → β) → β → α list → β "foldr f init [x1, x2, ..., xn]" returns f(x1, f(x2, ..., f(xn, init)...)) or init if the list is empty.
List.exists (α → bool) → α list → bool "exists f l" applies f to each element x of the list l, from left to right, until f(x) evaluates to true; it returns true if such an x exists and false otherwise.
List.all (α → bool) → α list → bool "all f l" applies f to each element x of the list l, from left to right, f(x) evaluates to false; it returns false if such an x exists and true otherwise. It is equivalent to not(exists (not o f) l)).
List.tabulate int * (int → α) → α list "tabulate (n, f)" returns a list of length n equal to [f(0), f(1), ..., f(n-1)], created from left to right. Raises Size if n < 0.
List.collate (α * α → order) → α list * α list → order "collate f (l1, l2)" performs lexicographic comparison of the two lists using the given ordering f on the list elements.
Math.acos real → real "acos x" returns the arc cosine of x. acos is the inverse of cos. Its result is guaranteed to be in the closed interval [0, pi]. If the magnitude of x exceeds 1.0, returns NaN.
Math.asin real → real "asin x" returns the arc sine of x. asin is the inverse of sin. Its result is guaranteed to be in the closed interval [-pi / 2, pi / 2]. If the magnitude of x exceeds 1.0, returns NaN.
Math.atan real → real "atan x" returns the arc tangent of x. atan is the inverse of tan. For finite arguments, the result is guaranteed to be in the open interval (-pi / 2, pi / 2). If x is +infinity, it returns pi / 2; if x is -infinity, it returns -pi / 2.
Math.atan2 real * real → real "atan2 (y, x)" returns the arc tangent of (y / x) in the closed interval [-pi, pi], corresponding to angles within +-180 degrees. The quadrant of the resulting angle is determined using the signs of both x and y, and is the same as the quadrant of the point (x, y). When x = 0, this corresponds to an angle of 90 degrees, and the result is (real (sign y)) * pi / 2.0.
Math.cos real → real "cos x" returns the cosine of x, measured in radians. If x is an infinity, returns NaN.
Math.cosh real → real "cosh x" returns the hyperbolic cosine of x, that is, (e(x) + e(-x)) / 2. Among its properties, cosh +-0 = 1, cosh +-infinity = +-infinity.
Math.e real "e" is base e (2.718281828...) of the natural logarithm.
Math.exp real → real "exp x" returns e(x), i.e., e raised to the xth power. If x is +infinity, returns +infinity; if x is -infinity, returns 0.
Math.ln real → real "ln x" returns the natural logarithm (base e) of x. If x < 0, returns NaN; if x = 0, returns -infinity; if x is infinity, returns infinity.
Math.log10 real → real "log10 x" returns the decimal logarithm (base 10) of x. If x < 0, returns NaN; if x = 0, returns -infinity; if x is infinity, returns infinity.
Math.pi real "pi" is the constant pi (3.141592653...).
Math.pow real * real → real "pow (x, y)" returns x(y), i.e., x raised to the yth power. For finite x and y, this is well-defined when x > 0, or when x < 0 and y is integral.
Math.sin real → real "sin x" returns the sine of x, measured in radians. If x is an infinity, returns NaN.
Math.sinh real → real "sinh x" returns the hyperbolic sine of x, that is, (e(x) - e(-x)) / 2. Among its properties, sinh +-0 = +-0, sinh +-infinity = +-infinity.
Math.sqrt real → real "sqrt x" returns the square root of x. sqrt (~0.0) = ~0.0. If x < 0, returns NaN.
Math.tan real → real "tan x" returns the tangent of x, measured in radians. If x is an infinity, returns NaN. Produces infinities at various finite values, roughly corresponding to the singularities of the tangent function.
Math.tanh real → real "tanh x" returns the hyperbolic tangent of x, that is, (sinh x) / (cosh x). Among its properties, tanh +-0 = +-0, tanh +-infinity = +-1.
Option.app (α → unit) → α option → unit "app f opt" applies the function f to the value v if opt is SOME v, and otherwise does nothing
Option.compose (α → β) * (γ → α option) → γ → β option "compose (f, g) a" returns NONE if g(a) is NONE; otherwise, if g(a) is SOME v, it returns SOME (f v).
Option.composePartial (α → β option) * (γ → α option) → γ → β option "composePartial (f, g) a" returns NONE if g(a) is NONE; otherwise, if g(a) is SOME v, returns f(v).
Option.map α → β) → α option → β option "map f opt" maps NONE to NONE and SOME v to SOME (f v).
Option.mapPartial α → β option) → α option → β option "mapPartial f opt" maps NONE to NONE and SOME v to f(v).
Option.getOpt α option * α → α "getOpt (opt, a)" returns v if opt is SOME (v); otherwise returns a.
Option.isSome α option → bool "isSome opt" returns true if opt is SOME v; otherwise returns false.
Option.filter (α → bool) → α → α option "filter f a" returns SOME a if f(a) is true, NONE otherwise.
Option.join α option option → α option "join opt" maps NONE to NONE and SOME v to v.
Option.valOf α option → α "valOf opt" returns v if opt is SOME v, otherwise raises Option.
Real op * real * real → real "r1 * r2" is the product of r1 and r2. The product of zero and an infinity produces NaN. Otherwise, if one argument is infinite, the result is infinite with the correct sign, e.g., -5 * (-infinity) = infinity, infinity * (-infinity) = -infinity.
Real op + real * real → real "r1 + r2" is the sum of r1 and r2. If one argument is finite and the other infinite, the result is infinite with the correct sign, e.g., 5 - (-infinity) = infinity. We also have infinity + infinity = infinity and (-infinity) + (-infinity) = (-infinity). Any other combination of two infinities produces NaN.
Real op - real * real → real "r1 - r2" is the difference of r1 and r2. If one argument is finite and the other infinite, the result is infinite with the correct sign, e.g., 5 - (-infinity) = infinity. We also have infinity + infinity = infinity and (-infinity) + (-infinity) = (-infinity). Any other combination of two infinities produces NaN.
Real op / real * real → real "r1 / r2" is the quotient of r1 and r2. We have 0 / 0 = NaN and +-infinity / +-infinity = NaN. Dividing a finite, non-zero number by a zero, or an infinity by a finite number produces an infinity with the correct sign. (Note that zeros are signed.) A finite number divided by an infinity is 0 with the correct sign.
Real op < real * real → bool "x < y" returns true if x is less than y. Return false on unordered arguments, i.e., if either argument is NaN, so that the usual reversal of comparison under negation does not hold, e.g., a &lt; b is not the same as not (a &gt;= b).
Real op <= real * real → bool As "<"
Real op > real * real → bool As "<"
Real op >= real * real → bool As "<"
Real op ~ real → real "~ r" returns the negation of r.
Real.abs real → real "abs r" returns the absolute value of r.
Real.ceil real → int "floor r" produces ceil(r), the smallest int not less than r.
Real.checkFloat real → real "checkFloat x" raises Overflow if x is an infinity, and raises Div if x is NaN. Otherwise, it returns its argument.
Real.compare real * real → order "compare (x, y)" returns LESS, EQUAL, or GREATER according to whether its first argument is less than, equal to, or greater than the second. It raises IEEEReal.Unordered on unordered arguments.
Real.copySign real * real → real "copySign (x, y)" returns x with the sign of y, even if y is NaN.
Real.floor real → int "floor r" produces floor(r), the largest int not larger than r.
Real.fromInt, real int → real "fromInt i" converts the integer i to a real value. If the absolute value of i is larger than maxFinite, then the appropriate infinity is returned. If i cannot be exactly represented as a real value, uses current rounding mode to determine the resulting value.
Real.fromManExp {exp:int, man:real} → real "fromManExp r" returns {man, exp}, where man and exp are the mantissa and exponent of r, respectively.
Real.fromString string → real option "fromString s" scans a real value from a string. Returns SOME (r) if a real value can be scanned from a prefix of s, ignoring any initial whitespace; otherwise, it returns NONE. This function is equivalent to StringCvt.scanString scan.
Real.isFinite real → bool "isFinite x" returns true if x is neither NaN nor an infinity.
Real.isNan real → bool "isNan x" returns true if x NaN.
Real.isNormal real → bool "isNormal x" returns true if x is normal, i.e., neither zero, subnormal, infinite nor NaN.
Real.max real * real → real "max (x, y)" returns the larger of the arguments. If exactly one argument is NaN, returns the other argument. If both arguments are NaN, returns NaN.
Real.maxFinite real "maxFinite" is the maximum finite number.
Real.min real * real → real "min (x, y)" returns the smaller of the arguments. If exactly one argument is NaN, returns the other argument. If both arguments are NaN, returns NaN.
Real.minNormalPos real "minNormalPos" is the minimum non-zero normalized number.
Real.minPos real "minPos" is the minimum non-zero positive number.
Real.negInf real "negInf" is the negative infinity value.
Real.posInf real "posInf" is the positive infinity value.
Real.precision int "precision" is the number of digits, each between 0 and radix - 1, in the mantissa. Note that the precision includes the implicit (or hidden) bit used in the IEEE representation (e.g., the value of Real64.precision is 53).
Real.radix int "radix" is the base of the representation, e.g., 2 or 10 for IEEE floating point.
Real.realCeil real → real "realCeil r" produces ceil(r), the smallest integer not less than r.
Real.realFloor real → real "realFloor r" produces floor(r), the largest integer not larger than r.
Real.realMod real → real "realMod r" returns the fractional parts of r; realMod is equivalent to #frac o split.
Real.realRound real → real "realRound r" rounds to the integer-valued real value that is nearest to r. In the case of a tie, it rounds to the nearest even integer.
Real.realTrunc real → real "realTrunc r" rounds r towards zero.
Real.rem real * real → real "rem (x, y)" returns the remainder x - n * y, where n = trunc (x / y). The result has the same sign as x and has absolute value less than the absolute value of y. If x is an infinity or y is 0, rem returns NaN. If y is an infinity, rem returns x.
Real.round real → int "round r" yields the integer nearest to r. In the case of a tie, it rounds to the nearest even integer.
Real.sameSign real * real → bool "sameSign (r1, r2)" returns true if and only if signBit r1 equals signBit r2.
Real.sign real → int "sign r" returns ~1 if r is negative, 0 if r is zero, or 1 if r is positive. An infinity returns its sign; a zero returns 0 regardless of its sign. It raises Domain on NaN.
Real.signBit real → bool "signBit r" returns true if and only if the sign of r (infinities, zeros, and NaN, included) is negative.
Real.split real → {frac:real, whole:real} "split r" returns {frac, whole}, where frac and whole are the fractional and integral parts of r, respectively. Specifically, whole is integral, and abs frac < 1.0.
Real.trunc real → int "trunc r" rounds r towards zero.
Real.toManExp real → {man:real, exp:int} "toManExp r" returns {man, exp}, where man and exp are the mantissa and exponent of r, respectively.
Real.toString real → string "toString r" converts a real into a string; equivalent to (fmt (StringCvt.GEN NONE) r)
Real.unordered real * real → bool "unordered (x, y)" returns true if x and y are unordered, i.e., at least one of x and y is NaN.
Relational.count, count int list → int "count list" returns the number of elements in list. Often used with group, for example from e in emps group e.deptno compute countId = count.
Relational.exists α list → bool "exists list" returns whether the list has at least one element, for example from d in depts where exists (from e where e.deptno = d.deptno).
Relational.notExists α list → bool "notExists list" returns whether the list is empty, for example from d in depts where notExists (from e where e.deptno = d.deptno).
Relational.only α list → α "only list" returns the sole element of list, for example from e in emps yield only (from d where d.deptno = e.deptno).
Relational.max, max α list → α "max list" returns the greatest element of list. Often used with group, for example from e in emps group e.deptno compute maxId = max of e.id.
Relational.min, min α list → α "min list" returns the least element of list. Often used with group, for example from e in emps group e.deptno compute minId = min of e.id.
Relational.sum, sum int list → int "sum list" returns the sum of the elements of list. Often used with group, for example from e in emps group e.deptno compute sumId = sum of e.id.
String.concat string list → string "concat l" is the concatenation of all the strings in l. This raises Size if the sum of all the sizes is greater than maxSize.
String.concatWith string → string list → string "concatWith s l" returns the concatenation of the strings in the list l using the string s as a separator. This raises Size if the size of the resulting string would be greater than maxSize.
String.explode string → char list "explode s" is the list of characters in the string s.
String.extract string * int * int option → string "extract (s, i, NONE)" and "extract (s, i, SOME j)" return substrings of s. The first returns the substring of s from the i(th) character to the end of the string, i.e., the string s[i..|s|-1]. This raises Subscript if i < 0 or |s| < i.

The second form returns the substring of size j starting at index i, i.e., the string s[i..i+j-1]. Raises Subscript if i < 0 or j < 0 or |s| < i + j. Note that, if defined, extract returns the empty string when i = |s|.
String.implode char list → string "implode l" generates the string containing the characters in the list l. This is equivalent to concat (List.map str l). This raises Size if the resulting string would have size greater than maxSize.
String.isPrefix string → string → bool "isPrefix s1 s2" returns true if the string s1 is a prefix of the string s2. Note that the empty string is a prefix of any string, and that a string is a prefix of itself.
String.isSubstring string → string → bool "isSubstring s1 s2" returns true if the string s1 is a substring of the string s2. Note that the empty string is a substring of any string, and that a string is a substring of itself.
String.isSuffix string → string → bool "isSuffix s1 s2" returns true if the string s1 is a suffix of the string s2. Note that the empty string is a suffix of any string, and that a string is a suffix of itself.
String.map (char → char) → string → string "map f s" applies f to each element of s from left to right, returning the resulting string. It is equivalent to implode(List.map f (explode s)).
String.maxSize int The longest allowed size of a string.
String.size string → int "size s" returns |s|, the number of characters in string s.
String.str char → string "str c" is the string of size one containing the character c.
String.sub string * int → char "sub (s, i)" returns the i(th) character of s, counting from zero. This raises Subscript if i < 0 or |s| ≤ i.
String.substring string * int * int → string "substring (s, i, j)" returns the substring s[i..i+j-1], i.e., the substring of size j starting at index i. This is equivalent to extract(s, i, SOME j).
String.translate (char → string) → string → string "translate f s" returns the string generated from s by mapping each character in s by f. It is equivalent to concat(List.map f (explode s)).
Sys.env, env unit → string list "env ()" prints the environment.
Sys.plan unit → string "plan ()" print the plan of the most recently executed expression.
Sys.set string * α → unit "set (property, value)" sets the value of property to value. (See Properties below.)
Sys.show string → string option "show property" returns the current the value of property, as a string, or NONE if unset.
Sys.unset string → unit "unset property" clears the current the value of property.
Vector.all
Vector.app (α → unit) → α vector → unit "app f vec" applies the function f to the elements of a vector in left to right order (i.e., in order of increasing indices)
Vector.appi (int * α → unit) → α vector → unit "appi f vec" applies the function f to the elements of a vector in left to right order (i.e., in order of increasing indices)
Vector.collate
Vector.concat α vector list → α vector "concat l" returns the vector that is the concatenation of the vectors in the list l. Raises Size if the total length of these vectors exceeds maxLen
Vector.exists
Vector.find (α → bool) → α vector → α option "find f vec" applies f to each element x of the vector vec, from left to right, until f(x) evaluates to true. It returns SOME (x) if such an x exists; otherwise it returns NONE.
Vector.findi (int * α → bool) → α vector → (int * α) option "findi f vec" applies f to each element x and element index i of the vector vec, from left to right, until f(i, x) evaluates to true. It returns SOME (i, x) if such an x exists; otherwise it returns NONE.
Vector.foldl (α * β → β) → β → α vector → β "foldl f init vec" folds the function f over all the elements of vector vec, left to right, using the initial value init
Vector.foldli (int * α * β → β) → β → α vector → β "foldli f init vec" folds the function f over all the (index, element) pairs of vector vec, left to right, using the initial value init
Vector.foldr (α * β → β) → β → α vector → β "foldr f init vec" folds the function f over all the elements of vector vec, right to left, using the initial value init
Vector.foldri (int * α * β → β) → β → α vector → β "foldri f init vec" folds the function f over all the (index, element) pairs of vector vec, right to left, using the initial value init
Vector.fromList α list → α vector "fromList l" creates a new vector from l, whose length is length l and with the ith element of l used as the ith element of the vector. Raises Size if maxLen < n.
Vector.length α vector → int "length v" returns the number of elements in the vector v.
Vector.map (α → β) → α vector → β vector "map f vec" applies the function f to the elements of the argument vector vec
Vector.mapi (int * α → β) → α vector → β vector "mapi f vec" applies the function f to the elements of the argument vector vec, supplying the vector index and element as arguments to each call.
Vector.maxLen int "maxLen" returns the maximum length of vectors supported in this implementation.
Vector.sub α vector * int → α "sub (vec, i)" returns the ith element of vector vec. Raises Subscript if i < 0 or size veci.
Vector.tabulate int * (int → α) → α vector "tabulate (n, f)" returns a vector of length n equal to [f(0), f(1), ..., f(n-1)], created from left to right. Raises Size if n < 0 or maxLen < n.
Vector.update α vector * int * α → α vector "update (vec, i, x)" returns a new vector, identical to vec, except the ith element of vec is set to x. Raises Subscript if i < 0 or size veci.

Not yet implemented

Name Type Description
Int.fmt StringCvt.radix → int → string "fmt radix i" returns a string containing a representation of i with #"~" used as the sign for negative numbers. Formats the string according to radix; the hexadecimal digits 10 through 15 are represented as #"A" through #"F", respectively. No prefix "0x" is generated for the hexadecimal representation.
Int.scan scan radix getc strm Returns SOME (i,rest) if an integer in the format denoted by radix can be parsed from a prefix of the character stream strm after skipping initial whitespace, where i is the value of the integer parsed and rest is the rest of the character stream. NONE is returned otherwise. This function raises Overflow when an integer can be parsed, but is too large to be represented by type int.
Real op != real * real → bool "x != y" is equivalent to not o op == and the IEEE ?<> operator.
Real op *+ real * real * real → real "*+ (a, b, c)" returns a * b + c. Its behavior on infinities follows from the behaviors derived from addition and multiplication.
Real op *- real * real * real → real "*- (a, b, c)" returns a * b - c. Its behavior on infinities follows from the behaviors derived from subtraction and multiplication.
Real op == real * real → bool "x == y" returns true if and only if neither y nor x is NaN, and y and x are equal, ignoring signs on zeros. This is equivalent to the IEEE = operator.
Real op ?= real * real → bool "?= (x, y)" returns true if either argument is NaN or if the arguments are bitwise equal, ignoring signs on zeros. It is equivalent to the IEEE ?= operator.
Real.class real → IEEEReal.float_class "class x" returns the IEEEReal.float_class to which x belongs.
Real.compareReal real * real → IEEEReal.real_order "compareReal (x, y)" behaves similarly to Real.compare except that the values it returns have the extended type IEEEReal.real_order and it returns IEEEReal.UNORDERED on unordered arguments.
Real.fmt StringCvt.realfmt → real → string "fmt spec r" converts a real into a string according to by spec; raises Size when fmt spec is evaluated if spec is an invalid precision
Real.fromDecimal IEEEReal.decimal_approx → real "fromDecimal d" converts decimal approximation to a real
Real.fromLarge IEEEReal.rounding_mode → real → real "toLarge r" converts a value of type real to type LargeReal.real. If r is too small or too large to be represented as a real, converts it to a zero or an infinity.
Real.fromLargeInt IntInf.int → real See "fromInt"
Real.nextAfter real * real → real "nextAfter (r, t)" returns the next representable real after r in the direction of t. Thus, if t is less than r, nextAfter returns the largest representable floating-point number less than r.
Real.scan (char,'a) StringCvt.reader → (real,'a) StringCvt.reader "scan getc strm" scans a real value from character source. Reads from ARG/strm/ using reader getc, ignoring initial whitespace. It returns SOME (r, rest) if successful, where r is the scanned real value and rest is the unused portion of the character stream strm. Values of too large a magnitude are represented as infinities; values of too small a magnitude are represented as zeros.
Real.toDecimal real → IEEEReal.decimal_approx "toDecimal r" converts a real to a decimal approximation
Real.toInt real → IEEEReal.rounding_mode → int "toInt mode x" converts the argument x to an integral type using the specified rounding mode. It raises Overflow if the result is not representable, in particular, if x is an infinity. It raises Domain if the input real is NaN.
Real.toLarge real → real "toLarge r" convert a value of type real to type LargeReal.real.
Real.toLargeInt real → IEEEReal.rounding_mode → IntInf.int See "toInt"

Properties

Each property is set using the function Sys.set (name, value), displayed using Sys.show name, and unset using Sys.unset name.

Name Type Default Description
hybrid bool false Whether to try to create a hybrid execution plan that uses Apache Calcite relational algebra.
inlinePassCount int 5 Maximum number of inlining passes.
lineWidth int 79 When printing, the length at which lines are wrapped.
matchCoverageEnabled bool true Whether to check whether patterns are exhaustive and/or redundant.
printDepth int 5 When printing, the depth of nesting of recursive data structure at which ellipsis begins.
printLength int 12 When printing, the length of lists at which ellipsis begins.
stringDepth int 70 When printing, the length of strings at which ellipsis begins.