Introduction to Programming in ATS: | ||
---|---|---|
Prev | Chapter 17. From Genericity to Late-Binding |
When asked about the meaning of object-oriented programming (OOP), Alan Kay once said that OOP to him meant only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.
In ATS, function templates can provide a highly flexible approach to supporting late-binding (of function calls). Let us first take a look at a simple example to see why late-binding can be so desirable. The following code declares a datatype intfloat such that each value of this declared type represents either an integer or a floating point number (of double precision):
In order to print values of the type intfloat, we can implement print_intfloat as follows:// fun print_intfloat (x: intfloat): void = ( case+ x of | INT(int) => print_int(int) | FLOAT(float) => print_double(float) ) //
// fun fprint_intfloat ( x: intfloat , print_int: int -> void , print_double: double -> void ) : void = ( case+ x of | INT(int) => print_int(int) | FLOAT(float) => print_double(float) ) //
Instead of using higher-order functions, we can rely on template functions to support late-binding (of function calls). For example, the following code implements a template function tprint_intfloat for printing values of the type intfloat:
// extern fun{} tprint_int(int): void extern fun{} tprint_double(double): void extern fun{} tprint_intfloat(intfloat): void // (* ****** ****** *) // implement tprint_int<> (x) = print_int(x) implement tprint_double<> (x) = print_double(x) // (* ****** ****** *) // implement tprint_intfloat<> (x) = ( case+ x of | INT(int) => tprint_int<> (int) | FLOAT(float) => tprint_double<> (float) ) //
// val () = ( tprint_intfloat<> (INT(0)); print_newline() ) (* end of [val] *) // val () = ( tprint_intfloat<> (FLOAT(1.0)); print_newline() ) (* end of [val] *) //
local // implement tprint_int<> (x) = print! ("INT(", x, ")") implement tprint_double<> (x) = print! ("FLOAT(", x, ")") // in (* in-of-local *) // val () = ( tprint_intfloat<> (INT(0)); print_newline() ) (* end of [val] *) // val () = ( tprint_intfloat<> (FLOAT(1.0)); print_newline() ) (* end of [val] *) // end // end of [local]
Please find on-line the file intfloat.dats containing the entirety of the code presented in this section plus some testing code.