lang: types, funcs: Add simple polymorphic function API

This adds a simple API for adding static, polymorphic, pure functions.
This lets you define a list of type signatures and the associated
implementations to overload a particular function name. The internals of
this API then do all of the hard work of matching the available
signatures to what statically type checks, and then calling the
appropriate implementation.

While this seems as if this would only work for function polymorphism
with a finite number of possible types, while this is mostly true, it
also allows you to add the `variant` "wildcard" type into your
signatures which will allow you to match a wider set of signatures.

A canonical use case for this is the len function which can determine
the length of both lists and maps with any contained type. (Either the
type of the list elements, or the types of the map keys and values.)

When using this functionality, you must be careful to ensure that there
is only a single mapping from possible type to signature so that the
"dynamic dispatch" of the function is unique.

It is worth noting that this API won't cover functions which support an
arbitrary number of input arguments. The well-known case of this,
printf, is implemented with the more general function API which is more
complicated.

This patch also adds some necessary library improvements for comparing
types to partial types, and to types containing variants.

Lastly, this fixes a bug in the `NewType` parser which parsed certain
complex function types wrong.
This commit is contained in:
James Shubin
2018-02-23 22:37:40 -05:00
parent 40dcd6ec99
commit 80784bb8f1
9 changed files with 983 additions and 6 deletions

9
examples/lang/len0.mcl Normal file
View File

@@ -0,0 +1,9 @@
$x1 = ["a", "b", "c", "d",]
print "print4" {
msg => printf("length is: %d", len($x1)),
}
$x2 = {"a" => 1, "b" => 2, "c" => 3,}
print "print3" {
msg => printf("length is: %d", len($x2)),
}