prakhar1989 / JSJS

A strongly typed language for the web!
http://jsjs-lang.org
MIT License
40 stars 5 forks source link

TAny should type check differently #35

Closed prakhar1989 closed 8 years ago

prakhar1989 commented 8 years ago

The following code raises the type-checking error - Type error: expected value of type 'list any', got a value of type 'list string' instead

val map = /\(fn: (num) -> string, xs: list num): list string => {
  if empty?(xs) then []
  else cons(fn(hd(xs)), map(fn, tl(xs)));
};

Fix this by being liberal in type-checking TAny types.

prakhar1989 commented 8 years ago

Usages of TAny in type-checker -

  1. An empty list [] has a type TList(TAny).
  2. An empty map {} has a type TMap(TAny,TAny).
  3. An empty block has a type TAny. This has been added only to satisfy the type-checker and it is unreachable since {} is recognized by the parser as MapLit and not a Block.
  4. The parser assigns TAny to a value which is not explicitly annotated in the program. Once the type is resolved, the environment is updated with the correct type.
  5. Lastly, TAny is used while building up a generic map in a generic function. E.g. [T, U, Z] are all assigned to be T -> TAny. Check the resolve function for more details.
prakhar1989 commented 8 years ago
val range = /\(start: num, end: num): list num => {
  if start >= end then []
  else start :: range(start+1, end);
};

val rev = /\(xs: list num): list num => {
  val aux = /\(acc: list num, ys: list num): list num => {
    if empty?(ys) then acc
    else aux(hd(ys) :: acc, tl(ys));
  };
  aux([], xs);
};
prakhar1989 commented 8 years ago

Fixed in https://github.com/prakhar1989/JSJS/commit/748c122d9ba6cb43ad98d6597e96cf7340dfa530