TC-A Samples
Overloaded functions are not supported in regular Tiger.
let
function null(i: int) : int = i = 0
function null(s: string) : int = s = ""
in
null("123") = null(123)
end
$ tc -Xb sizes.tig
sizes.tig:3.3-41: redefinition: null
sizes.tig:2.3-40: first definition
$ echo $?
4
Instead of regular binding, overloaded binding binds each function call to the set of active function definitions. Unfortunately displaying this set is not implemented, so we cannot see them in the following example.
$ tc -X --overfun-bindings-compute -BA sizes.tig
/* == Abstract Syntax Tree. == */
function _main /* 0x560fd5c661a0 */() =
(
let
function null /* 0x560fd5c685a0 */(i /* 0x560fd5c66770 */ : int /* 0 */) : int /* 0 */ =
i /* 0x560fd5c66770 */ = 0
function null /* 0x560fd5c66310 */(s /* 0x560fd5c66450 */ : string /* 0 */) : int /* 0 */ =
s /* 0x560fd5c66450 */ = ""
in
null /* 0 */("123") = null /* 0 */(123)
end;
()
)
$ echo $?
0
The selection of the right binding cannot be done before type-checking, since precisely overloading relies on types to distinguish the actual function called. Therefore it is the type checker that finishes the binding.
$ tc -XOBA sizes.tig
/* == Abstract Syntax Tree. == */
function _main /* 0x55ea80986290 */() =
(
let
function null /* 0x55ea80986450 */(i /* 0x55ea80986770 */ : int /* 0 */) : int /* 0 */ =
i /* 0x55ea80986770 */ = 0
function null /* 0x55ea809861a0 */(s /* 0x55ea80986310 */ : string /* 0 */) : int /* 0 */ =
s /* 0x55ea80986310 */ = ""
in
null /* 0x55ea809861a0 */("123") = null /* 0x55ea80986450 */(123)
end;
()
)
$ echo $?
0
There can be ambiguous (overloaded) calls.
let
type foo = {}
function empty(f: foo) : int = f = nil
type bar = {}
function empty(b: bar) : int = b = nil
in
empty(foo {});
empty(bar {});
empty(nil)
end
$ tc -XO over-amb.tig
over-amb.tig:9.3-12: nil ambiguity calling `empty'
matching declarations:
empty @
{
f : foo =
{
}
}
empty @
{
b : bar =
{
}
}
$ echo $?
5
The spirit of plain Tiger is kept, a chunk is not allowed to redefine a function with the same signature.
let
function foo(i: int) = ()
function foo(i: int) = ()
in
foo(42)
end
$ tc -XO over-duplicate.tig
over-duplicate.tig:3.3-27: function complete redefinition: foo
over-duplicate.tig:2.3-27: first definition
$ echo $?
5
But a signature can be defined twice in different blocks of function definitions, in which case the last defined function respecting the calling signature is used.
let
function foo(i: int) = ()
in
let
function foo(i: int) = ()
in
foo(51)
end
end
$ tc -XOBA over-scoped.tig
/* == Abstract Syntax Tree. == */
function _main /* 0x55c1c5c31a60 */() =
(
let
function foo /* 0x55c1c5c2f450 */(i /* 0x55c1c5c2f770 */ : int /* 0 */) =
()
in
let
function foo /* 0x55c1c5c2f1a0 */(i /* 0x55c1c5c2f310 */ : int /* 0 */) =
()
in
foo /* 0x55c1c5c2f1a0 */(51)
end
end;
()
)
$ echo $?
0