6. Function definition

6.1. Syntax to define function

Let’s write a function f to triple the argument.

1
2
3
4
5
6
(* File: func_syntax.dats *)
#include "share/atspre_staload.hats"

fun f (x:int): int = 3 * x

implement main0 () = println! (f 4)
$ patscc func_syntax.dats
$ ./a.out
12

The function f is typed as following figure that explains the argument x is typed with int and the return value is also typed with int. The function f is typed with (int) -> int.

_images/func_syntax.png

A function having two arguments can be written with following:

1
2
3
4
5
6
(* File: two_arguments.dats *)
#include "share/atspre_staload.hats"

fun g (x:int, y:int): int = x * x + y * y - 4

implement main0 () = println! (g (3, 2))
$ patscc two_arguments.dats
$ ./a.out
9

The function g is typed with following figure, and it’s not curried form. However, currying is rarely used at ATS programming.

_images/two_arguments.png

Note

Exercise: Write a function bmi that takes a meter tall and a kilogram weight then returns the body mass index (BMI). The BMI is calculated with dividing the kilogram weight by the square of the meter tall.

6.2. Typechecking

What happen if the function f takes a value typed double?

1
2
3
4
5
6
7
8
9
(* File: f_takes_double.dats *)
#include "share/atspre_staload.hats"

fun f (x:int): int = 3 * x

implement main0 () = {
  val r  = f 4.0
  val () = println! r
}
$ patscc f_takes_double.dats
/home/kiwamu/doc/ATS_Foundations/source/code/function_definition/f_takes_double.dats: 135(line=7, offs=14) -- 138(line=7, offs=17): error(3): the dynamic expression cannot be assigned the type [S2Eapp(S2Ecst(g0int_t0ype); S2Ecst(int_kind))].
/home/kiwamu/doc/ATS_Foundations/source/code/function_definition/f_takes_double.dats: 135(line=7, offs=14) -- 138(line=7, offs=17): error(3): mismatch of static terms (tyleq):
The actual term is: S2Eapp(S2Ecst(g0float_t0ype); S2Ecst(double_kind))
The needed term is: S2Eapp(S2Ecst(g0int_t0ype); S2Ecst(int_kind))
patsopt(TRANS3): there are [1] errors in total.
exit(ATS): uncaught exception: _2home_2kiwamu_2src_2ATS_2dPostiats_2src_2pats_error_2esats__FatalErrorExn(1025)

A compile error occurs at the code val r  = f 4.0 while typechecking. It means the function f takes double type that not match type of f as following figure:

_images/f_takes_double.png

You should create a new function f2 to maintain double type on the function f.

1
2
3
4
5
6
7
8
9
(* File: f_takes_double2.dats *)
#include "share/atspre_staload.hats"

fun f2 (x:double): double = 3 * x

implement main0 () = {
  val r  = f2 4.0
  val () = println! r
}
$ patscc f_takes_double2.dats
$ ./a.out
12.000000

The code f_takes_double2.dats can be compiled. The function f2 is typed as following figure:

_images/f_takes_double2.png

Note

Exercise: Write a function that takes a number of cranes and returns the total of their legs. (Crane has two legs.)

Note

Exercise: Write a function that takes a number of tortoises and returns the total of their legs. (Tortoise has four legs.)

Note

Exercise: Finally, write a function that takes the total of cranes and tortoises and the total of their legs, and return the total of the cranes.