|
|
| ||||||
| 10.3 Declarations | ||||||||
A declaration translates to one or more type, constant, function or variable declarations as described for the various kinds of declarations.
If the declaration occurs in a class expression, the declarations are placed at the outermost level.
Declarations from local expressions are included in-line when they are only variables and constant values. Otherwise they are placed in a separate namespace outside the definition where the local expression occurred: see section 10.8.23.
Type declarations are always placed in the header file.
To accommodate C++'s requirement of declaration before use the
produced declarations are
sorted according to kind in the following order:
type definitions (including those from embedded objects)
embedded objects (in namespaces)
constants and functions
variables
test cases
Apart from the top level module, schemes are only translated when they are instantiated as objects. So a scheme that is instantiated several times will therefore be translated several times. This may appear wasteful, but it only affects the size of the C++ source, not the final object code, and saves the need for the restrictions on scheme parameters that would be needed if templates were used for schemes.
An object translates as its translated declarations placed within a namespace of the same name as the object.
An object definition in RSLC++ cannot have a formal array parameter.
A type declaration translates to one or more type definitions for each type definition in its type definition list. Several type definitions generate C++ class definitions with member functions for test of equality and so on and accompanied by the specified constructor, destructor and reconstructor functions. These type definitions include short record definitions, variant definitions and abbreviation definitions that name product types. Recursive data structures may be specified by means of record variants, which translate to dynamic structures. All classes are declared public as structures, which are prototype declared in front of the definitions proper. All produced type definitions are placed in the header part.
A sort definition translates to an almost empty C++ struct in order to support hand-translation.
| type Sort | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gives a warning message and translates to (input/output operators omitted):
struct Sort/*INCOMPLETE: abstract type*/{
bool operator==(const Sort& RSL_v) const{
return true;
}
bool operator!=(const Sort& RSL_v) const{
return false;
}
};
A variant definition translates to a struct containing a tag field identifying the variant-choice and a pointer to the record variant. Allocation and deallocation of record variant structures are handled by the various constructor and member functions by means of reference counts. The following struct is the base class of all record variants
struct RSL_class {
int refcnt;
RSL_class () {refcnt = 1;}
};
The variant
| type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| V == | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Vconst | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Vint(Int) | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Vrec(d1Vrec : Int ↔ r1Vrec, d2Vrec : V ↔ r2Vrec) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
translates to (input/output operators included)
// From the .h file ...
// type and constant declarations and inline functions
static const int RSL_Vconst_tag = 1;
static const int RSL_Vint_tag = 2;
static const int RSL_Vrec_tag = 3;
struct RSL_Vint_type;
struct RSL_Vrec_type;
struct V{
int RSL_tag;
RSL_class* RSL_ptr;
V(const int RSL_p0 = 0){
RSL_tag = RSL_p0;
RSL_ptr = 0;
}
V(const RSL_Vint_type* RSL_v){
RSL_tag = RSL_Vint_tag;
RSL_ptr = (RSL_class*)RSL_v;
}
V(const RSL_Vrec_type* RSL_v){
RSL_tag = RSL_Vrec_tag;
RSL_ptr = (RSL_class*)RSL_v;
}
void RSL_destructor();
~V(){
RSL_destructor();
}
V(const V& RSL_v);
const V& operator=(const V& RSL_v);
bool operator==(const V& RSL_v) const;
bool operator!=(const V& RSL_v) const{
return !operator==(RSL_v);
}
};
extern string RSL_to_string(const V& RSL_v);
#ifdef RSL_io
extern ostream& operator<<(ostream& RSL_os, const V& RSL_v);
extern istream& operator>>(istream& RSL_is, V& RSL_v);
#endif //RSL_io
static const V Vconst(RSL_Vconst_tag);
struct RSL_Vint_type : RSL_class, RSLProduct1<int, RSL_constructor_fun>{
RSL_Vint_type(){}
RSL_Vint_type(const int RSL_p1) :
RSL_class(), RSLProduct1<int, RSL_constructor_fun>::RSLProduct1(RSL_p1){}
};
extern V Vint(const int RSL_p1);
struct RSL_Vrec_type : RSL_class, RSLProduct2<int, V, RSL_constructor_fun>{
RSL_Vrec_type(){}
RSL_Vrec_type(const int RSL_p1, const V& RSL_p2) :
RSL_class(),
RSLProduct2<int, V, RSL_constructor_fun>::RSLProduct2(RSL_p1, RSL_p2){}
};
extern V Vrec(const int RSL_p1, const V& RSL_p2);
inline int d1Vrec(const V& RSL_v){
#ifdef RSL_pre
if (RSL_v.RSL_tag != RSL_Vrec_tag)
{
RSL_fail("V.rsl:6:10: Destructor d1Vrec applied to wrong variant");
}
#endif //RSL_pre
return ((RSL_Vrec_type*)RSL_v.RSL_ptr)->RSL_f1;
}
inline V d2Vrec(const V& RSL_v){
#ifdef RSL_pre
if (RSL_v.RSL_tag != RSL_Vrec_tag)
{
RSL_fail("V.rsl:6:35: Destructor d2Vrec applied to wrong variant");
}
#endif //RSL_pre
return ((RSL_Vrec_type*)RSL_v.RSL_ptr)->RSL_f2;
}
extern V r1Vrec(const int RSL_p0, const V& RSL_v);
extern V r2Vrec(const V& RSL_p0, const V& RSL_v);
The templates RSLProductn (1≤n≤10) are defined in
RSL_Prod.h. Each takes as arguments the n types
making the product plus a function generating a string for a
constructor. This function is RSL_constructor_fun (which
generates the empty string) for products and variant components, and a
function generating "mk_T" for a record type T.
// From the .cc file ...
// RSL constructor, destructor and reconstructor functions
void V::RSL_destructor(){
switch (RSL_tag) {
case RSL_Vint_tag:
if (--(RSL_ptr->refcnt) == 0)
{
delete (RSL_Vint_type*)RSL_ptr;
}
break;
case RSL_Vrec_tag:
if (--(RSL_ptr->refcnt) == 0)
{
delete (RSL_Vrec_type*)RSL_ptr;
}
break;
}
}
V::V(const V& RSL_v){
switch (RSL_v.RSL_tag) {
case RSL_Vint_tag:
case RSL_Vrec_tag:
RSL_v.RSL_ptr->refcnt++;
}
RSL_tag = RSL_v.RSL_tag;
RSL_ptr = RSL_v.RSL_ptr;
}
const V& V::operator=(const V& RSL_v){
if (this == &RSL_v)
{
return RSL_v;
}
switch (RSL_v.RSL_tag) {
case RSL_Vint_tag:
case RSL_Vrec_tag:
RSL_v.RSL_ptr->refcnt++;
}
RSL_destructor();
RSL_tag = RSL_v.RSL_tag;
RSL_ptr = RSL_v.RSL_ptr;
return *this;
}
bool V::operator==(const V& RSL_v) const{
if (RSL_tag != RSL_v.RSL_tag)
{
return false;
}
switch (RSL_tag) {
case RSL_Vint_tag:
return *(RSL_Vint_type*)RSL_ptr == *(RSL_Vint_type*)RSL_v.RSL_ptr;
case RSL_Vrec_tag:
return *(RSL_Vrec_type*)RSL_ptr == *(RSL_Vrec_type*)RSL_v.RSL_ptr;
default:
return true;
}
}
string RSL_to_string(const V& RSL_v){
string RSL_Temp_0;
switch (RSL_v.RSL_tag) {
case RSL_Vconst_tag:
RSL_Temp_0 = "Vconst";
break;
case RSL_Vint_tag:
RSL_Temp_0 = "Vint" + RSL_to_string(*(RSL_Vint_type*)RSL_v.RSL_ptr);
break;
case RSL_Vrec_tag:
RSL_Temp_0 = "Vrec" + RSL_to_string(*(RSL_Vrec_type*)RSL_v.RSL_ptr);
break;
default:
RSL_Temp_0 = "Unknown variant value";
break;
}
return RSL_Temp_0;
}
#ifdef RSL_io
ostream& operator<<(ostream& RSL_os, const V& RSL_v){
switch (RSL_v.RSL_tag) {
case RSL_Vconst_tag:
RSL_os << "Vconst";
break;
case RSL_Vint_tag:
RSL_os << "Vint" << *(RSL_Vint_type*)RSL_v.RSL_ptr;
break;
case RSL_Vrec_tag:
RSL_os << "Vrec" << *(RSL_Vrec_type*)RSL_v.RSL_ptr;
break;
default:
RSL_os << "Unknown variant value";
break;
}
return RSL_os;
}
const RSL_input_token_type RSL_Vconst_token = Token_StartIndex + 1;
const RSL_input_token_type RSL_Vint_token = Token_StartIndex + 2;
const RSL_input_token_type RSL_Vrec_token = Token_StartIndex + 3;
static void RSL_input_token_V(istream& RSL_is, RSL_input_token_type& RSL_token){
char RSL_buf[128];
RSL_fetch_token(RSL_is, RSL_token, RSL_buf);
if (RSL_token == RSL_constructor_token)
{
if (RSL_streq(RSL_buf, "Vconst"))
{
RSL_token = RSL_Vconst_token;
return;
}
if (RSL_streq(RSL_buf, "Vint"))
{
RSL_token = RSL_Vint_token;
return;
}
if (RSL_streq(RSL_buf, "Vrec"))
{
RSL_token = RSL_Vrec_token;
return;
}
RSL_token = RSL_error_token;
}
}
istream& operator>>(istream& RSL_is, V& RSL_v){
RSL_input_token_type RSL_token;
V RSL_temp;
RSL_class* RSL_ptr = 0;
RSL_input_token_V(RSL_is, RSL_token);
switch (RSL_token) {
case RSL_Vconst_token:
RSL_temp = V(RSL_Vconst_tag);
break;
case RSL_Vint_token:
RSL_ptr = new RSL_Vint_type;
RSL_is >> *(RSL_Vint_type*)RSL_ptr;
if (RSL_is)
{
RSL_temp = V((RSL_Vint_type*)RSL_ptr);
}
break;
case RSL_Vrec_token:
RSL_ptr = new RSL_Vrec_type;
RSL_is >> *(RSL_Vrec_type*)RSL_ptr;
if (RSL_is)
{
RSL_temp = V((RSL_Vrec_type*)RSL_ptr);
}
break;
default:
RSL_is.clear(ios::badbit);
break;
}
if (RSL_is)
{
RSL_v = RSL_temp;
}
else
{
RSL_is.clear(ios::badbit);
}
return RSL_is;
}
#endif //RSL_io
V Vint(const int RSL_p1){
RSL_Vint_type* RSL_v = new RSL_Vint_type(RSL_p1);
if (!RSL_v)
{
abort();
}
return V(RSL_v);
}
V Vrec(const int RSL_p1, const V& RSL_p2){
RSL_Vrec_type* RSL_v = new RSL_Vrec_type(RSL_p1, RSL_p2);
if (!RSL_v)
{
abort();
}
return V(RSL_v);
}
V r1Vrec(const int RSL_p0, const V& RSL_v){
#ifdef RSL_pre
if (RSL_v.RSL_tag != RSL_Vrec_tag)
{
RSL_fail("V.rsl:6:27: Reconstructor r1Vrec applied to wrong variant");
}
#endif //RSL_pre
return Vrec(RSL_p0, ((RSL_Vrec_type*)RSL_v.RSL_ptr)->RSL_f2);
}
V r2Vrec(const V& RSL_p0, const V& RSL_v){
#ifdef RSL_pre
if (RSL_v.RSL_tag != RSL_Vrec_tag)
{
RSL_fail("V.rsl:6:50: Reconstructor r2Vrec applied to wrong variant");
}
#endif //RSL_pre
return Vrec(((RSL_Vrec_type*)RSL_v.RSL_ptr)->RSL_f1, RSL_p0);
}
Constructors, destructors and reconstructors translate as the identifier or operator does. Wildcard constructors are not accepted.
When the translated code is compiled with the RSL_io flag, a handwritten C++ compilation unit can perform input/output of variant values. For example:
void main(){
V aV, anotherV;
aV = Vint(42);
cout << "First value: " << aV << "\n";
cout << "Give a value of type V:\n";
cin >> anotherV;
cout << "Second value: " << anotherV << "\n";
}
The following is an example of an execution of this program (user
lines are marked with #):
First value: Vint(42) Give a value of type V: Vrec(1957, Vint(1969)) # Second value: Vrec(1957,Vint(1969))
Not accepted.
A short record definition translates to a C++ class definition including member functions and function definitions that implement the constructor, destructor and reconstructor functions. Note that a short record translates differently from a variant definition -- the short record translates without the use of pointers.
| type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Complex :: re: Real ↔ r im: Real ↔ i | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
translates to
// from the .h file ...
char* RSL_mk_Complex_fun(){
return "mk_Complex";
}
typedef RSLProduct2<double, double, RSL_mk_Complex_fun> Complex;
inline Complex mk_Complex(const double RSL_p1, const double RSL_p2){
return Complex(RSL_p1, RSL_p2);
}
inline double re(const Complex& RSL_v){
return RSL_v.RSL_f1;
}
inline double im(const Complex& RSL_v){
return RSL_v.RSL_f2;
}
extern Complex r(const double RSL_p0, const Complex& RSL_v);
extern Complex i(const double RSL_p0, const Complex& RSL_v);
// from the .cc file ...
Complex r(const double RSL_p0, const Complex& RSL_v){
return Complex(RSL_p0, RSL_v.RSL_f2);
}
Complex i(const double RSL_p0, const Complex& RSL_v){
return Complex(RSL_v.RSL_f1, RSL_p0);
}
An abbreviation definition translates to a type definition of a universal type whose name is derived from the structure of the type (see section 10.12 on universal types), plus a definition of the identifier as the universal type. For each translation there is at most one definition of each universal type.
| type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| B = C × C, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| C = {| n : Int • n ∈ {0..7} |}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| D = Nat × Int, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| E = D → D, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| F = C × D → D | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
translates to
typedef int C; typedef RSLProduct2<int, int, RSL_constructor_fun> RSL_IxI; typedef RSL_IxI D; typedef RSL_IxI (* RSL_IxIfIxI)(const RSL_IxI ); typedef RSL_IxIfIxI E; typedef RSL_IxI (* RSL_Ix6IxI9fIxI)(const int , const RSL_IxI ); typedef RSL_Ix6IxI9fIxI F; typedef RSL_IxI B;
Typings are accepted with a warning that they are incomplete
An explicit value definition translates to a constant declared in the header file and defined in the body file. For example
| value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| low: Int = 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| high: Int = low + 100, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| max : Int = Max(low, high), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| p : Int × Bool = (7, true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
translates to
// Header file: extern const int low; extern const int high; extern const int max; extern const RSL_IxB p;
// Body file: const int low = 0; const int high = low + 100; const int max = Max(low, high); const RSL_IxB p = RSL_IxB(7, true);
Additional code, included if RSL_pre is defined, is generated if any constant types are subtypes, to check that the values of the constants are in the subtypes.
An explicit value definition which defines a function translates by means of a C++ pointer to function type. E.g.
| value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f : Int × Int → Int = Max | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
translates to
// Header file: typedef int (* RSL_IxIfI)(const int , const int ); extern const RSL_IxIfI f;
// Body file: const RSL_IxIfI f = Max;
Implicit value definitions are accepted with a warning that they are incomplete.
An explicit function definition translates to a C++ function definition.
As an example
| value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sqr : Real → Real | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sqr(x) ≡ x*x, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + : V × Int → V | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| v + i ≡ Vrec(i, v) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(in the context of the type V defined earlier) translates to
double sqr(const double x_38B){
return x_38B * x_38B;
}
V RSL_PLUS_op(const V& v_4B3, const int i_4B7){
return Vrec(i_4B7, v_4B3);
}
Note that a user-defined operator translates into a function with a name derived from the operator name rather than into an operator. This eases the translation of such operators. In particular it makes them all translatable. The names are given below.
| Operator | Function name |
| = | RSL_EQ_op |
| ≠ | RSL_NOTEQ_op |
| == | RSL_EQEQ_op |
| > | RSL_GT_op |
| < | RSL_LT_op |
| ≥ | RSL_GEQ_op |
| ≤ | RSL_LEQ_op |
| ⊃ | RSL_PSUP_op |
| ⊂ | RSL_PSUB_op |
| ⊇ | RSL_SUP_op |
| ⊆ | RSL_SUB_op |
| ∈ | RSL_ISIN_op |
| ∉ | RSL_NOTISIN_op |
| \ | RSL_MOD_op |
| ^ | RSL_CONC_op |
| ∪ | RSL_UNION_op |
| † | RSL_OVER_op |
| * | RSL_AST_op |
| / | RSL_DIV_op |
| # | RSL_HASH_op |
| ∩ | RSL_INTER_op |
| ↑ | RSL_EXP_op |
| abs | RSL_ABS_op |
| int | RSL_INT_op |
| real | RSL_REAL_op |
| card | RSL_CARD_op |
| len | RSL_LEN_op |
| inds | RSL_INDS_op |
| elems | RSL_ELEMS_op |
| hd | RSL_HD_op |
| tl | RSL_TL_op |
| dom | RSL_DOM_op |
| rng | RSL_RNG_op |
| + | RSL_PLUS_op |
| - | RSL_MINUS_op |
Additional code, included if RSL_pre is defined, is generated if any parameter types are subtypes or if the function has a precondition.
Access descriptors are ignored. The kind of function arrow (→ or -~->) does not matter.
Only one formal function parameter is accepted. It is not possible to translate
| f : Int → Int → Int | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f(x)(y) ≡ ... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
It is not required that the number of parameters matches the number of components in the domain of the function's type expression. For example, the following are all accepted:
| type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| U = Int × Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f1: Int × Bool → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f1(x, y) ≡ ..., | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f2: (Int × Bool) → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f2(x, y) ≡ ..., | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f3: U → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f3(x, y) ≡ ..., | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f4: U × Int → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f4(x, y) ≡ ..., | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f5: (Int × Bool) × Int → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f5(x, y) ≡ ... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f6: (Int × Bool) × Int → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f6(x) ≡ ... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f7: Int × Bool → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f7(x) ≡ ..., | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f8: (Int × Bool) → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f8(x) ≡ ..., | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f9: U → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f9(x) ≡ ..., | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f10: U × Int → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f10((x, y), z) ≡ ..., | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f11: (Int × Bool) × Bool → Bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f11((x, y), z) ≡ ... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Implicit function definitions are accepted with a warning that they are incomplete.
| 10.3 Declarations | ||||||||
|
|
| ||||||