TC-A Samples

Overloaded functions are not supported in regular Tiger.

sizes.tig
let
  function null(i: int) : int    = i = 0
  function null(s: string) : int = s = ""
in
  null("123") = null(123)
end
tc -Xb sizes.tig
$ 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
$ tc -X --overfun-bindings-compute -BA sizes.tig
/* == Abstract Syntax Tree. == */

function _main /* 0x55ee830f9310 */() =
  (
    let
      function null /* 0x55ee830ffb80 */(i /* 0x55ee830ff770 */ : int /* 0 */) : int /* 0 */ =
        i /* 0x55ee830ff770 */ = 0
      function null /* 0x55ee830fc350 */(s /* 0x55ee831015a0 */ : string /* 0 */) : int /* 0 */ =
        s /* 0x55ee831015a0 */ = ""
    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
$ tc -XOBA sizes.tig
/* == Abstract Syntax Tree. == */

function _main /* 0x558abbb7db80 */() =
  (
    let
      function null /* 0x558abbb7e0c0 */(i /* 0x558abbb7d770 */ : int /* 0 */) : int /* 0 */ =
        i /* 0x558abbb7d770 */ = 0
      function null /* 0x558abbb7dfd0 */(s /* 0x558abbb7d450 */ : string /* 0 */) : int /* 0 */ =
        s /* 0x558abbb7d450 */ = ""
    in
      null /* 0x558abbb7dfd0 */("123") = null /* 0x558abbb7e0c0 */(123)
    end;
    ()
  )
$ echo $?
0

There can be ambiguous (overloaded) calls.

over-amb.tig
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
$ 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.

over-duplicate.tig
let
  function foo(i: int) = ()
  function foo(i: int) = ()
in
  foo(42)
end
tc -XO over-duplicate.tig
$ 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.

over-scoped.tig
let
  function foo(i: int) = ()
in
  let
    function foo(i: int) = ()
  in
    foo(51)
  end
end
tc -XOBA over-scoped.tig
$ tc -XOBA over-scoped.tig
/* == Abstract Syntax Tree. == */

function _main /* 0x555c27d41b80 */() =
  (
    let
      function foo /* 0x555c27d420c0 */(i /* 0x555c27d41770 */ : int /* 0 */) =
        ()
    in
      let
        function foo /* 0x555c27d41fd0 */(i /* 0x555c27d41450 */ : int /* 0 */) =
          ()
      in
        foo /* 0x555c27d41fd0 */(51)
      end
    end;
    ()
  )
$ echo $?
0