internal/core: allow variable arg functions

This is mostly to allow os-dependent functions
that are convenient, yet still hermetic.

E.g. path.Base(str, path.Unix)

Most of the files in this CL are generated.
Only files not starting with pkg/ and
pkg/internal/builtin.go are relevant.

The basic idea is that to intead of just specifying
the kind of paramter, to also allow a default value.
As this is just a CUE value, this will also allow
for constraints down the line. The old shim
implementation in pkg/internal/builtin.go keeps
it simple, though. Builtins with default values
will have to be hand-coded later on.

Change-Id: I184d672a8704f4ec6c53491d08caddd1f774bda2
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7842
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
diff --git a/internal/core/adt/expr.go b/internal/core/adt/expr.go
index 1ed374f..16a7ec9 100644
--- a/internal/core/adt/expr.go
+++ b/internal/core/adt/expr.go
@@ -937,7 +937,7 @@
 // A Builtin is a value representing a native function call.
 type Builtin struct {
 	// TODO:  make these values for better type checking.
-	Params []Kind
+	Params []Param
 	Result Kind
 	Func   func(c *OpContext, args []Value) Expr
 
@@ -947,6 +947,23 @@
 	Const string
 }
 
+type Param struct {
+	Name  Feature // name of the argument; mostly for documentation
+	Value Value   // Could become Value later, using disjunctions for defaults.
+}
+
+func (p Param) Kind() Kind {
+	return p.Value.Kind()
+}
+
+func (p Param) Default() Value {
+	d, ok := p.Value.(*Disjunction)
+	if !ok || d.NumDefaults != 1 {
+		return nil
+	}
+	return d.Values[0]
+}
+
 func (x *Builtin) WriteName(w io.Writer, c *OpContext) {
 	_, _ = fmt.Fprintf(w, "%s.%s", x.Package.StringValue(c), x.Name)
 }
@@ -956,7 +973,7 @@
 	if len(x.Params) == 0 {
 		return BottomKind
 	}
-	return x.Params[0]
+	return x.Params[0].Kind()
 }
 
 func (x *Builtin) validate(c *OpContext, v Value) *Bottom {
@@ -984,24 +1001,28 @@
 		// We have a custom builtin
 		return &BuiltinValidator{call, x, args}
 	}
-	switch {
-	case len(x.Params) < len(args):
+	if len(args) > len(x.Params) {
 		c.addErrf(0, call.Rparen,
 			"too many arguments in call to %s (have %d, want %d)",
 			call.Fun, len(args), len(x.Params))
 		return nil
-	case len(x.Params) > len(args):
-		c.addErrf(0, call.Rparen,
-			"not enough arguments in call to %s (have %d, want %d)",
-			call.Fun, len(args), len(x.Params))
-		return nil
+	}
+	for i := len(args); i < len(x.Params); i++ {
+		v := x.Params[i].Default()
+		if v == nil {
+			c.addErrf(0, call.Rparen,
+				"not enough arguments in call to %s (have %d, want %d)",
+				call.Fun, len(args), len(x.Params))
+			return nil
+		}
+		args = append(args, v)
 	}
 	for i, a := range args {
-		if x.Params[i] != BottomKind {
+		if x.Params[i].Kind() != BottomKind {
 			if b := bottom(a); b != nil {
 				return b
 			}
-			if k := kind(a); x.Params[i]&k == BottomKind {
+			if k := kind(a); x.Params[i].Kind()&k == BottomKind {
 				code := EvalError
 				b, _ := args[i].(*Bottom)
 				if b != nil {
@@ -1009,7 +1030,7 @@
 				}
 				c.addErrf(code, pos(a),
 					"cannot use %s (type %s) as %s in argument %d to %s",
-					a, k, x.Params[i], i+1, call.Fun)
+					a, k, x.Params[i].Kind(), i+1, call.Fun)
 				return nil
 			}
 		}
@@ -1038,7 +1059,7 @@
 }
 
 func (x *BuiltinValidator) Kind() Kind {
-	return x.Builtin.Params[0]
+	return x.Builtin.Params[0].Kind()
 }
 
 func (x *BuiltinValidator) validate(c *OpContext, v Value) *Bottom {
diff --git a/internal/core/compile/builtin.go b/internal/core/compile/builtin.go
index 352235f..7a0af90 100644
--- a/internal/core/compile/builtin.go
+++ b/internal/core/compile/builtin.go
@@ -26,9 +26,16 @@
 
 const supportedByLen = adt.StructKind | adt.BytesKind | adt.StringKind | adt.ListKind
 
+var (
+	stringParam = adt.Param{Value: &adt.BasicType{K: adt.StringKind}}
+	structParam = adt.Param{Value: &adt.BasicType{K: adt.StructKind}}
+	listParam   = adt.Param{Value: &adt.BasicType{K: adt.ListKind}}
+	intParam    = adt.Param{Value: &adt.BasicType{K: adt.IntKind}}
+)
+
 var lenBuiltin = &adt.Builtin{
 	Name:   "len",
-	Params: []adt.Kind{supportedByLen},
+	Params: []adt.Param{{Value: &adt.BasicType{K: supportedByLen}}},
 	Result: adt.IntKind,
 	Func: func(c *adt.OpContext, args []adt.Value) adt.Expr {
 		v := args[0]
@@ -74,7 +81,7 @@
 
 var closeBuiltin = &adt.Builtin{
 	Name:   "close",
-	Params: []adt.Kind{adt.StructKind},
+	Params: []adt.Param{structParam},
 	Result: adt.StructKind,
 	Func: func(c *adt.OpContext, args []adt.Value) adt.Expr {
 		s, ok := args[0].(*adt.Vertex)
@@ -92,7 +99,7 @@
 
 var andBuiltin = &adt.Builtin{
 	Name:   "and",
-	Params: []adt.Kind{adt.ListKind},
+	Params: []adt.Param{listParam},
 	Result: adt.IntKind,
 	Func: func(c *adt.OpContext, args []adt.Value) adt.Expr {
 		list := c.Elems(args[0])
@@ -109,7 +116,7 @@
 
 var orBuiltin = &adt.Builtin{
 	Name:   "or",
-	Params: []adt.Kind{adt.ListKind},
+	Params: []adt.Param{listParam},
 	Result: adt.IntKind,
 	Func: func(c *adt.OpContext, args []adt.Value) adt.Expr {
 		d := []adt.Disjunct{}
@@ -141,7 +148,7 @@
 
 var divBuiltin = &adt.Builtin{
 	Name:   "div",
-	Params: []adt.Kind{adt.IntKind, adt.IntKind},
+	Params: []adt.Param{intParam, intParam},
 	Result: adt.IntKind,
 	Func: func(c *adt.OpContext, args []adt.Value) adt.Expr {
 		const name = "argument to div builtin"
@@ -152,7 +159,7 @@
 
 var modBuiltin = &adt.Builtin{
 	Name:   "mod",
-	Params: []adt.Kind{adt.IntKind, adt.IntKind},
+	Params: []adt.Param{intParam, intParam},
 	Result: adt.IntKind,
 	Func: func(c *adt.OpContext, args []adt.Value) adt.Expr {
 		const name = "argument to mod builtin"
@@ -163,7 +170,7 @@
 
 var quoBuiltin = &adt.Builtin{
 	Name:   "quo",
-	Params: []adt.Kind{adt.IntKind, adt.IntKind},
+	Params: []adt.Param{intParam, intParam},
 	Result: adt.IntKind,
 	Func: func(c *adt.OpContext, args []adt.Value) adt.Expr {
 		const name = "argument to quo builtin"
@@ -174,7 +181,7 @@
 
 var remBuiltin = &adt.Builtin{
 	Name:   "rem",
-	Params: []adt.Kind{adt.IntKind, adt.IntKind},
+	Params: []adt.Param{intParam, intParam},
 	Result: adt.IntKind,
 	Func: func(c *adt.OpContext, args []adt.Value) adt.Expr {
 		const name = "argument to rem builtin"
diff --git a/pkg/crypto/md5/pkg.go b/pkg/crypto/md5/pkg.go
index 29ee896..e4bbcda 100644
--- a/pkg/crypto/md5/pkg.go
+++ b/pkg/crypto/md5/pkg.go
@@ -24,8 +24,10 @@
 		Name:  "BlockSize",
 		Const: "64",
 	}, {
-		Name:   "Sum",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Sum",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
diff --git a/pkg/crypto/sha1/pkg.go b/pkg/crypto/sha1/pkg.go
index 7d5076a..9792024 100644
--- a/pkg/crypto/sha1/pkg.go
+++ b/pkg/crypto/sha1/pkg.go
@@ -24,8 +24,10 @@
 		Name:  "BlockSize",
 		Const: "64",
 	}, {
-		Name:   "Sum",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Sum",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
diff --git a/pkg/crypto/sha256/pkg.go b/pkg/crypto/sha256/pkg.go
index 37c291a..92d851d 100644
--- a/pkg/crypto/sha256/pkg.go
+++ b/pkg/crypto/sha256/pkg.go
@@ -27,8 +27,10 @@
 		Name:  "BlockSize",
 		Const: "64",
 	}, {
-		Name:   "Sum256",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Sum256",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
@@ -37,8 +39,10 @@
 			}
 		},
 	}, {
-		Name:   "Sum224",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Sum224",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
diff --git a/pkg/crypto/sha512/pkg.go b/pkg/crypto/sha512/pkg.go
index 50c2a80..607da47 100644
--- a/pkg/crypto/sha512/pkg.go
+++ b/pkg/crypto/sha512/pkg.go
@@ -33,8 +33,10 @@
 		Name:  "BlockSize",
 		Const: "128",
 	}, {
-		Name:   "Sum512",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Sum512",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
@@ -43,8 +45,10 @@
 			}
 		},
 	}, {
-		Name:   "Sum384",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Sum384",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
@@ -53,8 +57,10 @@
 			}
 		},
 	}, {
-		Name:   "Sum512_224",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Sum512_224",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
@@ -63,8 +69,10 @@
 			}
 		},
 	}, {
-		Name:   "Sum512_256",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Sum512_256",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
diff --git a/pkg/encoding/base64/pkg.go b/pkg/encoding/base64/pkg.go
index 4f881b6..12f791c 100644
--- a/pkg/encoding/base64/pkg.go
+++ b/pkg/encoding/base64/pkg.go
@@ -18,8 +18,11 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "EncodedLen",
-		Params: []adt.Kind{adt.TopKind, adt.IntKind},
+		Name: "EncodedLen",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			encoding, n := c.Value(0), c.Int(1)
@@ -28,8 +31,11 @@
 			}
 		},
 	}, {
-		Name:   "DecodedLen",
-		Params: []adt.Kind{adt.TopKind, adt.IntKind},
+		Name: "DecodedLen",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			encoding, x := c.Value(0), c.Int(1)
@@ -38,8 +44,11 @@
 			}
 		},
 	}, {
-		Name:   "Encode",
-		Params: []adt.Kind{adt.TopKind, adt.BytesKind | adt.StringKind},
+		Name: "Encode",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			encoding, src := c.Value(0), c.Bytes(1)
@@ -48,8 +57,11 @@
 			}
 		},
 	}, {
-		Name:   "Decode",
-		Params: []adt.Kind{adt.TopKind, adt.StringKind},
+		Name: "Decode",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			encoding, s := c.Value(0), c.String(1)
diff --git a/pkg/encoding/csv/pkg.go b/pkg/encoding/csv/pkg.go
index 7bf550c..f5c5482 100644
--- a/pkg/encoding/csv/pkg.go
+++ b/pkg/encoding/csv/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Encode",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "Encode",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Value(0)
@@ -28,8 +30,10 @@
 			}
 		},
 	}, {
-		Name:   "Decode",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Decode",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			r := c.Reader(0)
diff --git a/pkg/encoding/hex/pkg.go b/pkg/encoding/hex/pkg.go
index 3e00667..5918fe0 100644
--- a/pkg/encoding/hex/pkg.go
+++ b/pkg/encoding/hex/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "EncodedLen",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "EncodedLen",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			n := c.Int(0)
@@ -28,8 +30,10 @@
 			}
 		},
 	}, {
-		Name:   "DecodedLen",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "DecodedLen",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Int(0)
@@ -38,8 +42,10 @@
 			}
 		},
 	}, {
-		Name:   "Decode",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Decode",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -48,8 +54,10 @@
 			}
 		},
 	}, {
-		Name:   "Dump",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Dump",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
@@ -58,8 +66,10 @@
 			}
 		},
 	}, {
-		Name:   "Encode",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Encode",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			src := c.Bytes(0)
diff --git a/pkg/encoding/json/pkg.go b/pkg/encoding/json/pkg.go
index a44d0bf..aacd27a 100644
--- a/pkg/encoding/json/pkg.go
+++ b/pkg/encoding/json/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Valid",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Valid",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
@@ -28,8 +30,10 @@
 			}
 		},
 	}, {
-		Name:   "Compact",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Compact",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			src := c.Bytes(0)
@@ -38,8 +42,12 @@
 			}
 		},
 	}, {
-		Name:   "Indent",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind, adt.StringKind, adt.StringKind},
+		Name: "Indent",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			src, prefix, indent := c.Bytes(0), c.String(1), c.String(2)
@@ -48,8 +56,10 @@
 			}
 		},
 	}, {
-		Name:   "HTMLEscape",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "HTMLEscape",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			src := c.Bytes(0)
@@ -58,8 +68,10 @@
 			}
 		},
 	}, {
-		Name:   "Marshal",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "Marshal",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			v := c.Value(0)
@@ -68,8 +80,10 @@
 			}
 		},
 	}, {
-		Name:   "MarshalStream",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "MarshalStream",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			v := c.Value(0)
@@ -78,8 +92,10 @@
 			}
 		},
 	}, {
-		Name:   "Unmarshal",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Unmarshal",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.TopKind,
 		Func: func(c *internal.CallCtxt) {
 			b := c.Bytes(0)
@@ -88,8 +104,11 @@
 			}
 		},
 	}, {
-		Name:   "Validate",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind, adt.TopKind},
+		Name: "Validate",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			b, v := c.Bytes(0), c.Value(1)
diff --git a/pkg/encoding/yaml/pkg.go b/pkg/encoding/yaml/pkg.go
index 03f73e6..8792e33 100644
--- a/pkg/encoding/yaml/pkg.go
+++ b/pkg/encoding/yaml/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Marshal",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "Marshal",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			v := c.Value(0)
@@ -28,8 +30,10 @@
 			}
 		},
 	}, {
-		Name:   "MarshalStream",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "MarshalStream",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			v := c.Value(0)
@@ -38,8 +42,10 @@
 			}
 		},
 	}, {
-		Name:   "Unmarshal",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind},
+		Name: "Unmarshal",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+		},
 		Result: adt.TopKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Bytes(0)
@@ -48,8 +54,11 @@
 			}
 		},
 	}, {
-		Name:   "Validate",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind, adt.TopKind},
+		Name: "Validate",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			b, v := c.Bytes(0), c.Value(1)
@@ -58,8 +67,11 @@
 			}
 		},
 	}, {
-		Name:   "ValidatePartial",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind, adt.TopKind},
+		Name: "ValidatePartial",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			b, v := c.Bytes(0), c.Value(1)
diff --git a/pkg/gen/gen.go b/pkg/gen/gen.go
index 7ceb8cb..ba2b9bd 100644
--- a/pkg/gen/gen.go
+++ b/pkg/gen/gen.go
@@ -309,7 +309,11 @@
 		}
 	}
 
-	fmt.Fprintf(g.w, "Params: []adt.Kind{%s},\n", strings.Join(kind, ", "))
+	fmt.Fprintf(g.w, "Params: []internal.Param{\n")
+	for _, k := range kind {
+		fmt.Fprintf(g.w, "{Kind: %s},\n", k)
+	}
+	fmt.Fprintf(g.w, "\n},\n")
 	result := g.goToCUE(x.Type.Results.List[0].Type)
 	fmt.Fprintf(g.w, "Result: %s,\n", result)
 	argList := strings.Join(args, ", ")
diff --git a/pkg/html/pkg.go b/pkg/html/pkg.go
index b611b65..b68bed6 100644
--- a/pkg/html/pkg.go
+++ b/pkg/html/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Escape",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Escape",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -28,8 +30,10 @@
 			}
 		},
 	}, {
-		Name:   "Unescape",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Unescape",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
diff --git a/pkg/internal/builtin.go b/pkg/internal/builtin.go
index 9523754..29c94e7 100644
--- a/pkg/internal/builtin.go
+++ b/pkg/internal/builtin.go
@@ -48,12 +48,18 @@
 type Builtin struct {
 	Name   string
 	Pkg    adt.Feature
-	Params []adt.Kind
+	Params []Param
 	Result adt.Kind
 	Func   func(c *CallCtxt)
 	Const  string
 }
 
+type Param struct {
+	Kind    adt.Kind
+	Value   adt.Value // input constraint
+	Default adt.Value // may be nil
+}
+
 type Package struct {
 	Native []*Builtin
 	CUE    string
@@ -104,8 +110,23 @@
 }
 
 func toBuiltin(ctx *adt.OpContext, b *Builtin) *adt.Builtin {
+	params := make([]adt.Param, len(b.Params))
+	for i, p := range b.Params {
+		// TODO: use Value.
+		params[i].Value = &adt.BasicType{K: p.Kind}
+		if p.Default != nil {
+			params[i].Value = &adt.Disjunction{
+				NumDefaults: 1,
+				Values: []*adt.Vertex{
+					adt.ToVertex(p.Default),
+					adt.ToVertex(params[i].Value),
+				},
+			}
+		}
+	}
+
 	x := &adt.Builtin{
-		Params:  b.Params,
+		Params:  params,
 		Result:  b.Result,
 		Package: b.Pkg,
 		Name:    b.Name,
diff --git a/pkg/list/pkg.go b/pkg/list/pkg.go
index db30ee4..c5f74e3 100644
--- a/pkg/list/pkg.go
+++ b/pkg/list/pkg.go
@@ -18,8 +18,11 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Drop",
-		Params: []adt.Kind{adt.ListKind, adt.IntKind},
+		Name: "Drop",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			x, n := c.List(0), c.Int(1)
@@ -28,8 +31,11 @@
 			}
 		},
 	}, {
-		Name:   "FlattenN",
-		Params: []adt.Kind{adt.TopKind, adt.IntKind},
+		Name: "FlattenN",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			xs, depth := c.Value(0), c.Int(1)
@@ -38,8 +44,11 @@
 			}
 		},
 	}, {
-		Name:   "Take",
-		Params: []adt.Kind{adt.ListKind, adt.IntKind},
+		Name: "Take",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			x, n := c.List(0), c.Int(1)
@@ -48,8 +57,12 @@
 			}
 		},
 	}, {
-		Name:   "Slice",
-		Params: []adt.Kind{adt.ListKind, adt.IntKind, adt.IntKind},
+		Name: "Slice",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			x, i, j := c.List(0), c.Int(1), c.Int(2)
@@ -58,8 +71,11 @@
 			}
 		},
 	}, {
-		Name:   "MinItems",
-		Params: []adt.Kind{adt.ListKind, adt.IntKind},
+		Name: "MinItems",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			a, n := c.List(0), c.Int(1)
@@ -68,8 +84,11 @@
 			}
 		},
 	}, {
-		Name:   "MaxItems",
-		Params: []adt.Kind{adt.ListKind, adt.IntKind},
+		Name: "MaxItems",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			a, n := c.List(0), c.Int(1)
@@ -78,8 +97,10 @@
 			}
 		},
 	}, {
-		Name:   "UniqueItems",
-		Params: []adt.Kind{adt.ListKind},
+		Name: "UniqueItems",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			a := c.List(0)
@@ -88,8 +109,11 @@
 			}
 		},
 	}, {
-		Name:   "Contains",
-		Params: []adt.Kind{adt.ListKind, adt.TopKind},
+		Name: "Contains",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			a, v := c.List(0), c.Value(1)
@@ -98,8 +122,10 @@
 			}
 		},
 	}, {
-		Name:   "Avg",
-		Params: []adt.Kind{adt.ListKind},
+		Name: "Avg",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			xs := c.DecimalList(0)
@@ -108,8 +134,10 @@
 			}
 		},
 	}, {
-		Name:   "Max",
-		Params: []adt.Kind{adt.ListKind},
+		Name: "Max",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			xs := c.DecimalList(0)
@@ -118,8 +146,10 @@
 			}
 		},
 	}, {
-		Name:   "Min",
-		Params: []adt.Kind{adt.ListKind},
+		Name: "Min",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			xs := c.DecimalList(0)
@@ -128,8 +158,10 @@
 			}
 		},
 	}, {
-		Name:   "Product",
-		Params: []adt.Kind{adt.ListKind},
+		Name: "Product",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			xs := c.DecimalList(0)
@@ -138,8 +170,12 @@
 			}
 		},
 	}, {
-		Name:   "Range",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind, adt.NumKind},
+		Name: "Range",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			start, limit, step := c.Decimal(0), c.Decimal(1), c.Decimal(2)
@@ -148,8 +184,10 @@
 			}
 		},
 	}, {
-		Name:   "Sum",
-		Params: []adt.Kind{adt.ListKind},
+		Name: "Sum",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			xs := c.DecimalList(0)
@@ -158,8 +196,11 @@
 			}
 		},
 	}, {
-		Name:   "Sort",
-		Params: []adt.Kind{adt.ListKind, adt.TopKind},
+		Name: "Sort",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			list, cmp := c.List(0), c.Value(1)
@@ -168,8 +209,11 @@
 			}
 		},
 	}, {
-		Name:   "SortStable",
-		Params: []adt.Kind{adt.ListKind, adt.TopKind},
+		Name: "SortStable",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			list, cmp := c.List(0), c.Value(1)
@@ -178,8 +222,10 @@
 			}
 		},
 	}, {
-		Name:   "SortStrings",
-		Params: []adt.Kind{adt.ListKind},
+		Name: "SortStrings",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			a := c.StringList(0)
@@ -188,8 +234,11 @@
 			}
 		},
 	}, {
-		Name:   "IsSorted",
-		Params: []adt.Kind{adt.ListKind, adt.TopKind},
+		Name: "IsSorted",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			list, cmp := c.List(0), c.Value(1)
@@ -198,8 +247,10 @@
 			}
 		},
 	}, {
-		Name:   "IsSortedStrings",
-		Params: []adt.Kind{adt.ListKind},
+		Name: "IsSortedStrings",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			a := c.StringList(0)
diff --git a/pkg/math/bits/pkg.go b/pkg/math/bits/pkg.go
index 1b69513..d3f1e40 100644
--- a/pkg/math/bits/pkg.go
+++ b/pkg/math/bits/pkg.go
@@ -18,8 +18,11 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Lsh",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "Lsh",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x, n := c.BigInt(0), c.Uint(1)
@@ -28,8 +31,11 @@
 			}
 		},
 	}, {
-		Name:   "Rsh",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "Rsh",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x, n := c.BigInt(0), c.Uint(1)
@@ -38,8 +44,11 @@
 			}
 		},
 	}, {
-		Name:   "At",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "At",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x, i := c.BigInt(0), c.Uint(1)
@@ -48,8 +57,12 @@
 			}
 		},
 	}, {
-		Name:   "Set",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind, adt.IntKind},
+		Name: "Set",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x, i, bit := c.BigInt(0), c.Int(1), c.Uint(2)
@@ -58,8 +71,11 @@
 			}
 		},
 	}, {
-		Name:   "And",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "And",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			a, b := c.BigInt(0), c.BigInt(1)
@@ -68,8 +84,11 @@
 			}
 		},
 	}, {
-		Name:   "Or",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "Or",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			a, b := c.BigInt(0), c.BigInt(1)
@@ -78,8 +97,11 @@
 			}
 		},
 	}, {
-		Name:   "Xor",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "Xor",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			a, b := c.BigInt(0), c.BigInt(1)
@@ -88,8 +110,11 @@
 			}
 		},
 	}, {
-		Name:   "Clear",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "Clear",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			a, b := c.BigInt(0), c.BigInt(1)
@@ -98,8 +123,10 @@
 			}
 		},
 	}, {
-		Name:   "OnesCount",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "OnesCount",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.BigInt(0)
@@ -108,8 +135,10 @@
 			}
 		},
 	}, {
-		Name:   "Len",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "Len",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.BigInt(0)
diff --git a/pkg/math/pkg.go b/pkg/math/pkg.go
index 4c2c086..dd758ff 100644
--- a/pkg/math/pkg.go
+++ b/pkg/math/pkg.go
@@ -54,8 +54,11 @@
 		Name:  "Above",
 		Const: "1",
 	}, {
-		Name:   "Jacobi",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "Jacobi",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x, y := c.BigInt(0), c.BigInt(1)
@@ -67,8 +70,10 @@
 		Name:  "MaxBase",
 		Const: "62",
 	}, {
-		Name:   "Floor",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Floor",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -77,8 +82,10 @@
 			}
 		},
 	}, {
-		Name:   "Ceil",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Ceil",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -87,8 +94,10 @@
 			}
 		},
 	}, {
-		Name:   "Trunc",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Trunc",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -97,8 +106,10 @@
 			}
 		},
 	}, {
-		Name:   "Round",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Round",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -107,8 +118,10 @@
 			}
 		},
 	}, {
-		Name:   "RoundToEven",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "RoundToEven",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -117,8 +130,11 @@
 			}
 		},
 	}, {
-		Name:   "MultipleOf",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind},
+		Name: "MultipleOf",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			x, y := c.Decimal(0), c.Decimal(1)
@@ -127,8 +143,10 @@
 			}
 		},
 	}, {
-		Name:   "Abs",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Abs",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -137,8 +155,10 @@
 			}
 		},
 	}, {
-		Name:   "Acosh",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Acosh",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -147,8 +167,10 @@
 			}
 		},
 	}, {
-		Name:   "Asin",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Asin",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -157,8 +179,10 @@
 			}
 		},
 	}, {
-		Name:   "Acos",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Acos",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -167,8 +191,10 @@
 			}
 		},
 	}, {
-		Name:   "Asinh",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Asinh",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -177,8 +203,10 @@
 			}
 		},
 	}, {
-		Name:   "Atan",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Atan",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -187,8 +215,11 @@
 			}
 		},
 	}, {
-		Name:   "Atan2",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind},
+		Name: "Atan2",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			y, x := c.Float64(0), c.Float64(1)
@@ -197,8 +228,10 @@
 			}
 		},
 	}, {
-		Name:   "Atanh",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Atanh",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -207,8 +240,10 @@
 			}
 		},
 	}, {
-		Name:   "Cbrt",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Cbrt",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -250,8 +285,11 @@
 		Name:  "Log10E",
 		Const: "0.43429448190325182765112891891660508229439700580366656611445378",
 	}, {
-		Name:   "Copysign",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind},
+		Name: "Copysign",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x, y := c.Decimal(0), c.Decimal(1)
@@ -260,8 +298,11 @@
 			}
 		},
 	}, {
-		Name:   "Dim",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind},
+		Name: "Dim",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x, y := c.Decimal(0), c.Decimal(1)
@@ -270,8 +311,10 @@
 			}
 		},
 	}, {
-		Name:   "Erf",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Erf",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -280,8 +323,10 @@
 			}
 		},
 	}, {
-		Name:   "Erfc",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Erfc",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -290,8 +335,10 @@
 			}
 		},
 	}, {
-		Name:   "Erfinv",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Erfinv",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -300,8 +347,10 @@
 			}
 		},
 	}, {
-		Name:   "Erfcinv",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Erfcinv",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -310,8 +359,10 @@
 			}
 		},
 	}, {
-		Name:   "Exp",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Exp",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -320,8 +371,10 @@
 			}
 		},
 	}, {
-		Name:   "Exp2",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Exp2",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -330,8 +383,10 @@
 			}
 		},
 	}, {
-		Name:   "Expm1",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Expm1",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -340,8 +395,10 @@
 			}
 		},
 	}, {
-		Name:   "Gamma",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Gamma",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -350,8 +407,11 @@
 			}
 		},
 	}, {
-		Name:   "Hypot",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind},
+		Name: "Hypot",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			p, q := c.Float64(0), c.Float64(1)
@@ -360,8 +420,10 @@
 			}
 		},
 	}, {
-		Name:   "J0",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "J0",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -370,8 +432,10 @@
 			}
 		},
 	}, {
-		Name:   "Y0",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Y0",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -380,8 +444,10 @@
 			}
 		},
 	}, {
-		Name:   "J1",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "J1",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -390,8 +456,10 @@
 			}
 		},
 	}, {
-		Name:   "Y1",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Y1",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -400,8 +468,11 @@
 			}
 		},
 	}, {
-		Name:   "Jn",
-		Params: []adt.Kind{adt.IntKind, adt.NumKind},
+		Name: "Jn",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			n, x := c.Int(0), c.Float64(1)
@@ -410,8 +481,11 @@
 			}
 		},
 	}, {
-		Name:   "Yn",
-		Params: []adt.Kind{adt.IntKind, adt.NumKind},
+		Name: "Yn",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			n, x := c.Int(0), c.Float64(1)
@@ -420,8 +494,11 @@
 			}
 		},
 	}, {
-		Name:   "Ldexp",
-		Params: []adt.Kind{adt.NumKind, adt.IntKind},
+		Name: "Ldexp",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			frac, exp := c.Float64(0), c.Int(1)
@@ -430,8 +507,10 @@
 			}
 		},
 	}, {
-		Name:   "Log",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Log",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -440,8 +519,10 @@
 			}
 		},
 	}, {
-		Name:   "Log10",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Log10",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -450,8 +531,10 @@
 			}
 		},
 	}, {
-		Name:   "Log2",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Log2",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -460,8 +543,10 @@
 			}
 		},
 	}, {
-		Name:   "Log1p",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Log1p",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -470,8 +555,10 @@
 			}
 		},
 	}, {
-		Name:   "Logb",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Logb",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -480,8 +567,10 @@
 			}
 		},
 	}, {
-		Name:   "Ilogb",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Ilogb",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -490,8 +579,11 @@
 			}
 		},
 	}, {
-		Name:   "Mod",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind},
+		Name: "Mod",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x, y := c.Float64(0), c.Float64(1)
@@ -500,8 +592,11 @@
 			}
 		},
 	}, {
-		Name:   "Pow",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind},
+		Name: "Pow",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x, y := c.Decimal(0), c.Decimal(1)
@@ -510,8 +605,10 @@
 			}
 		},
 	}, {
-		Name:   "Pow10",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "Pow10",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			n := c.Int32(0)
@@ -520,8 +617,11 @@
 			}
 		},
 	}, {
-		Name:   "Remainder",
-		Params: []adt.Kind{adt.NumKind, adt.NumKind},
+		Name: "Remainder",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x, y := c.Float64(0), c.Float64(1)
@@ -530,8 +630,10 @@
 			}
 		},
 	}, {
-		Name:   "Signbit",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Signbit",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Decimal(0)
@@ -540,8 +642,10 @@
 			}
 		},
 	}, {
-		Name:   "Cos",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Cos",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -550,8 +654,10 @@
 			}
 		},
 	}, {
-		Name:   "Sin",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Sin",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -560,8 +666,10 @@
 			}
 		},
 	}, {
-		Name:   "Sinh",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Sinh",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -570,8 +678,10 @@
 			}
 		},
 	}, {
-		Name:   "Cosh",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Cosh",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -580,8 +690,10 @@
 			}
 		},
 	}, {
-		Name:   "Sqrt",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Sqrt",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -590,8 +702,10 @@
 			}
 		},
 	}, {
-		Name:   "Tan",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Tan",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
@@ -600,8 +714,10 @@
 			}
 		},
 	}, {
-		Name:   "Tanh",
-		Params: []adt.Kind{adt.NumKind},
+		Name: "Tanh",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			x := c.Float64(0)
diff --git a/pkg/net/pkg.go b/pkg/net/pkg.go
index 4cf23a3..8c164ee 100644
--- a/pkg/net/pkg.go
+++ b/pkg/net/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "SplitHostPort",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "SplitHostPort",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -28,8 +30,11 @@
 			}
 		},
 	}, {
-		Name:   "JoinHostPort",
-		Params: []adt.Kind{adt.TopKind, adt.TopKind},
+		Name: "JoinHostPort",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			host, port := c.Value(0), c.Value(1)
@@ -38,8 +43,10 @@
 			}
 		},
 	}, {
-		Name:   "FQDN",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "FQDN",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -54,8 +61,10 @@
 		Name:  "IPv6len",
 		Const: "16",
 	}, {
-		Name:   "ParseIP",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "ParseIP",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -64,8 +73,10 @@
 			}
 		},
 	}, {
-		Name:   "IPv4",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "IPv4",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -74,8 +85,10 @@
 			}
 		},
 	}, {
-		Name:   "IP",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "IP",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -84,8 +97,10 @@
 			}
 		},
 	}, {
-		Name:   "LoopbackIP",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "LoopbackIP",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -94,8 +109,10 @@
 			}
 		},
 	}, {
-		Name:   "MulticastIP",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "MulticastIP",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -104,8 +121,10 @@
 			}
 		},
 	}, {
-		Name:   "InterfaceLocalMulticastIP",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "InterfaceLocalMulticastIP",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -114,8 +133,10 @@
 			}
 		},
 	}, {
-		Name:   "LinkLocalMulticastIP",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "LinkLocalMulticastIP",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -124,8 +145,10 @@
 			}
 		},
 	}, {
-		Name:   "LinkLocalUnicastIP",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "LinkLocalUnicastIP",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -134,8 +157,10 @@
 			}
 		},
 	}, {
-		Name:   "GlobalUnicastIP",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "GlobalUnicastIP",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -144,8 +169,10 @@
 			}
 		},
 	}, {
-		Name:   "UnspecifiedIP",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "UnspecifiedIP",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -154,8 +181,10 @@
 			}
 		},
 	}, {
-		Name:   "ToIP4",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "ToIP4",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -164,8 +193,10 @@
 			}
 		},
 	}, {
-		Name:   "ToIP16",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "ToIP16",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
@@ -174,8 +205,10 @@
 			}
 		},
 	}, {
-		Name:   "IPString",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "IPString",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			ip := c.Value(0)
diff --git a/pkg/path/pkg.go b/pkg/path/pkg.go
index 87abd8c..5446870 100644
--- a/pkg/path/pkg.go
+++ b/pkg/path/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Split",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Split",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			path := c.String(0)
@@ -28,8 +30,11 @@
 			}
 		},
 	}, {
-		Name:   "Match",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Match",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern, name := c.String(0), c.String(1)
@@ -38,8 +43,10 @@
 			}
 		},
 	}, {
-		Name:   "Clean",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Clean",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			path := c.String(0)
@@ -48,8 +55,10 @@
 			}
 		},
 	}, {
-		Name:   "Ext",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Ext",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			path := c.String(0)
@@ -58,8 +67,10 @@
 			}
 		},
 	}, {
-		Name:   "Base",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Base",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			path := c.String(0)
@@ -68,8 +79,10 @@
 			}
 		},
 	}, {
-		Name:   "IsAbs",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "IsAbs",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			path := c.String(0)
@@ -78,8 +91,10 @@
 			}
 		},
 	}, {
-		Name:   "Dir",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Dir",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			path := c.String(0)
diff --git a/pkg/regexp/pkg.go b/pkg/regexp/pkg.go
index cd484b4..1c2f8b8 100644
--- a/pkg/regexp/pkg.go
+++ b/pkg/regexp/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Valid",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Valid",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern := c.String(0)
@@ -28,8 +30,11 @@
 			}
 		},
 	}, {
-		Name:   "Find",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Find",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern, s := c.String(0), c.String(1)
@@ -38,8 +43,12 @@
 			}
 		},
 	}, {
-		Name:   "FindAll",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind, adt.IntKind},
+		Name: "FindAll",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern, s, n := c.String(0), c.String(1), c.Int(2)
@@ -48,8 +57,11 @@
 			}
 		},
 	}, {
-		Name:   "FindSubmatch",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "FindSubmatch",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern, s := c.String(0), c.String(1)
@@ -58,8 +70,12 @@
 			}
 		},
 	}, {
-		Name:   "FindAllSubmatch",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind, adt.IntKind},
+		Name: "FindAllSubmatch",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern, s, n := c.String(0), c.String(1), c.Int(2)
@@ -68,8 +84,11 @@
 			}
 		},
 	}, {
-		Name:   "FindNamedSubmatch",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "FindNamedSubmatch",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StructKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern, s := c.String(0), c.String(1)
@@ -78,8 +97,12 @@
 			}
 		},
 	}, {
-		Name:   "FindAllNamedSubmatch",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind, adt.IntKind},
+		Name: "FindAllNamedSubmatch",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern, s, n := c.String(0), c.String(1), c.Int(2)
@@ -88,8 +111,11 @@
 			}
 		},
 	}, {
-		Name:   "Match",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Match",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			pattern, s := c.String(0), c.String(1)
@@ -98,8 +124,10 @@
 			}
 		},
 	}, {
-		Name:   "QuoteMeta",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "QuoteMeta",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
diff --git a/pkg/strconv/pkg.go b/pkg/strconv/pkg.go
index 80c9c64..8278ad2 100644
--- a/pkg/strconv/pkg.go
+++ b/pkg/strconv/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Unquote",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Unquote",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -28,8 +30,10 @@
 			}
 		},
 	}, {
-		Name:   "ParseBool",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "ParseBool",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			str := c.String(0)
@@ -38,8 +42,10 @@
 			}
 		},
 	}, {
-		Name:   "FormatBool",
-		Params: []adt.Kind{adt.BoolKind},
+		Name: "FormatBool",
+		Params: []internal.Param{
+			{Kind: adt.BoolKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			b := c.Bool(0)
@@ -48,8 +54,11 @@
 			}
 		},
 	}, {
-		Name:   "ParseFloat",
-		Params: []adt.Kind{adt.StringKind, adt.IntKind},
+		Name: "ParseFloat",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.NumKind,
 		Func: func(c *internal.CallCtxt) {
 			s, bitSize := c.String(0), c.Int(1)
@@ -61,8 +70,12 @@
 		Name:  "IntSize",
 		Const: "64",
 	}, {
-		Name:   "ParseUint",
-		Params: []adt.Kind{adt.StringKind, adt.IntKind, adt.IntKind},
+		Name: "ParseUint",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s, base, bitSize := c.String(0), c.Int(1), c.Int(2)
@@ -71,8 +84,12 @@
 			}
 		},
 	}, {
-		Name:   "ParseInt",
-		Params: []adt.Kind{adt.StringKind, adt.IntKind, adt.IntKind},
+		Name: "ParseInt",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s, base, bitSize := c.String(0), c.Int(1), c.Int(2)
@@ -81,8 +98,10 @@
 			}
 		},
 	}, {
-		Name:   "Atoi",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Atoi",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -91,8 +110,13 @@
 			}
 		},
 	}, {
-		Name:   "FormatFloat",
-		Params: []adt.Kind{adt.NumKind, adt.IntKind, adt.IntKind, adt.IntKind},
+		Name: "FormatFloat",
+		Params: []internal.Param{
+			{Kind: adt.NumKind},
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			f, fmt, prec, bitSize := c.Float64(0), c.Byte(1), c.Int(2), c.Int(3)
@@ -101,8 +125,11 @@
 			}
 		},
 	}, {
-		Name:   "FormatUint",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "FormatUint",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			i, base := c.Uint64(0), c.Int(1)
@@ -111,8 +138,11 @@
 			}
 		},
 	}, {
-		Name:   "FormatInt",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "FormatInt",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			i, base := c.Int64(0), c.Int(1)
@@ -121,8 +151,10 @@
 			}
 		},
 	}, {
-		Name:   "Quote",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Quote",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -131,8 +163,10 @@
 			}
 		},
 	}, {
-		Name:   "QuoteToASCII",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "QuoteToASCII",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -141,8 +175,10 @@
 			}
 		},
 	}, {
-		Name:   "QuoteToGraphic",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "QuoteToGraphic",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -151,8 +187,10 @@
 			}
 		},
 	}, {
-		Name:   "QuoteRune",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "QuoteRune",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			r := c.Rune(0)
@@ -161,8 +199,10 @@
 			}
 		},
 	}, {
-		Name:   "QuoteRuneToASCII",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "QuoteRuneToASCII",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			r := c.Rune(0)
@@ -171,8 +211,10 @@
 			}
 		},
 	}, {
-		Name:   "QuoteRuneToGraphic",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "QuoteRuneToGraphic",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			r := c.Rune(0)
@@ -181,8 +223,10 @@
 			}
 		},
 	}, {
-		Name:   "IsPrint",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "IsPrint",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			r := c.Rune(0)
@@ -191,8 +235,10 @@
 			}
 		},
 	}, {
-		Name:   "IsGraphic",
-		Params: []adt.Kind{adt.IntKind},
+		Name: "IsGraphic",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			r := c.Rune(0)
diff --git a/pkg/strings/pkg.go b/pkg/strings/pkg.go
index fb43360..b8b9ceb 100644
--- a/pkg/strings/pkg.go
+++ b/pkg/strings/pkg.go
@@ -18,8 +18,11 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "ByteAt",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind, adt.IntKind},
+		Name: "ByteAt",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			b, i := c.Bytes(0), c.Int(1)
@@ -28,8 +31,12 @@
 			}
 		},
 	}, {
-		Name:   "ByteSlice",
-		Params: []adt.Kind{adt.BytesKind | adt.StringKind, adt.IntKind, adt.IntKind},
+		Name: "ByteSlice",
+		Params: []internal.Param{
+			{Kind: adt.BytesKind | adt.StringKind},
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BytesKind | adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			b, start, end := c.Bytes(0), c.Int(1), c.Int(2)
@@ -38,8 +45,10 @@
 			}
 		},
 	}, {
-		Name:   "Runes",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Runes",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -48,8 +57,11 @@
 			}
 		},
 	}, {
-		Name:   "MinRunes",
-		Params: []adt.Kind{adt.StringKind, adt.IntKind},
+		Name: "MinRunes",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s, min := c.String(0), c.Int(1)
@@ -58,8 +70,11 @@
 			}
 		},
 	}, {
-		Name:   "MaxRunes",
-		Params: []adt.Kind{adt.StringKind, adt.IntKind},
+		Name: "MaxRunes",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s, max := c.String(0), c.Int(1)
@@ -68,8 +83,10 @@
 			}
 		},
 	}, {
-		Name:   "ToTitle",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "ToTitle",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -78,8 +95,10 @@
 			}
 		},
 	}, {
-		Name:   "ToCamel",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "ToCamel",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -88,8 +107,12 @@
 			}
 		},
 	}, {
-		Name:   "SliceRunes",
-		Params: []adt.Kind{adt.StringKind, adt.IntKind, adt.IntKind},
+		Name: "SliceRunes",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s, start, end := c.String(0), c.Int(1), c.Int(2)
@@ -98,8 +121,11 @@
 			}
 		},
 	}, {
-		Name:   "Compare",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Compare",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			a, b := c.String(0), c.String(1)
@@ -108,8 +134,11 @@
 			}
 		},
 	}, {
-		Name:   "Count",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Count",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s, substr := c.String(0), c.String(1)
@@ -118,8 +147,11 @@
 			}
 		},
 	}, {
-		Name:   "Contains",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Contains",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s, substr := c.String(0), c.String(1)
@@ -128,8 +160,11 @@
 			}
 		},
 	}, {
-		Name:   "ContainsAny",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "ContainsAny",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s, chars := c.String(0), c.String(1)
@@ -138,8 +173,11 @@
 			}
 		},
 	}, {
-		Name:   "LastIndex",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "LastIndex",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s, substr := c.String(0), c.String(1)
@@ -148,8 +186,11 @@
 			}
 		},
 	}, {
-		Name:   "IndexAny",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "IndexAny",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s, chars := c.String(0), c.String(1)
@@ -158,8 +199,11 @@
 			}
 		},
 	}, {
-		Name:   "LastIndexAny",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "LastIndexAny",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s, chars := c.String(0), c.String(1)
@@ -168,8 +212,12 @@
 			}
 		},
 	}, {
-		Name:   "SplitN",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind, adt.IntKind},
+		Name: "SplitN",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			s, sep, n := c.String(0), c.String(1), c.Int(2)
@@ -178,8 +226,12 @@
 			}
 		},
 	}, {
-		Name:   "SplitAfterN",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind, adt.IntKind},
+		Name: "SplitAfterN",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			s, sep, n := c.String(0), c.String(1), c.Int(2)
@@ -188,8 +240,11 @@
 			}
 		},
 	}, {
-		Name:   "Split",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Split",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			s, sep := c.String(0), c.String(1)
@@ -198,8 +253,11 @@
 			}
 		},
 	}, {
-		Name:   "SplitAfter",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "SplitAfter",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			s, sep := c.String(0), c.String(1)
@@ -208,8 +266,10 @@
 			}
 		},
 	}, {
-		Name:   "Fields",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Fields",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.ListKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -218,8 +278,11 @@
 			}
 		},
 	}, {
-		Name:   "Join",
-		Params: []adt.Kind{adt.ListKind, adt.StringKind},
+		Name: "Join",
+		Params: []internal.Param{
+			{Kind: adt.ListKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			elems, sep := c.StringList(0), c.String(1)
@@ -228,8 +291,11 @@
 			}
 		},
 	}, {
-		Name:   "HasPrefix",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "HasPrefix",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s, prefix := c.String(0), c.String(1)
@@ -238,8 +304,11 @@
 			}
 		},
 	}, {
-		Name:   "HasSuffix",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "HasSuffix",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s, suffix := c.String(0), c.String(1)
@@ -248,8 +317,11 @@
 			}
 		},
 	}, {
-		Name:   "Repeat",
-		Params: []adt.Kind{adt.StringKind, adt.IntKind},
+		Name: "Repeat",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s, count := c.String(0), c.Int(1)
@@ -258,8 +330,10 @@
 			}
 		},
 	}, {
-		Name:   "ToUpper",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "ToUpper",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -268,8 +342,10 @@
 			}
 		},
 	}, {
-		Name:   "ToLower",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "ToLower",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -278,8 +354,11 @@
 			}
 		},
 	}, {
-		Name:   "Trim",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Trim",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s, cutset := c.String(0), c.String(1)
@@ -288,8 +367,11 @@
 			}
 		},
 	}, {
-		Name:   "TrimLeft",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "TrimLeft",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s, cutset := c.String(0), c.String(1)
@@ -298,8 +380,11 @@
 			}
 		},
 	}, {
-		Name:   "TrimRight",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "TrimRight",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s, cutset := c.String(0), c.String(1)
@@ -308,8 +393,10 @@
 			}
 		},
 	}, {
-		Name:   "TrimSpace",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "TrimSpace",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -318,8 +405,11 @@
 			}
 		},
 	}, {
-		Name:   "TrimPrefix",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "TrimPrefix",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s, prefix := c.String(0), c.String(1)
@@ -328,8 +418,11 @@
 			}
 		},
 	}, {
-		Name:   "TrimSuffix",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "TrimSuffix",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s, suffix := c.String(0), c.String(1)
@@ -338,8 +431,13 @@
 			}
 		},
 	}, {
-		Name:   "Replace",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind, adt.StringKind, adt.IntKind},
+		Name: "Replace",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s, old, new, n := c.String(0), c.String(1), c.String(2), c.Int(3)
@@ -348,8 +446,11 @@
 			}
 		},
 	}, {
-		Name:   "Index",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Index",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s, substr := c.String(0), c.String(1)
diff --git a/pkg/struct/pkg.go b/pkg/struct/pkg.go
index 3456c4a..9807c35 100644
--- a/pkg/struct/pkg.go
+++ b/pkg/struct/pkg.go
@@ -18,8 +18,11 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "MinFields",
-		Params: []adt.Kind{adt.StructKind, adt.IntKind},
+		Name: "MinFields",
+		Params: []internal.Param{
+			{Kind: adt.StructKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			object, n := c.Struct(0), c.Int(1)
@@ -28,8 +31,11 @@
 			}
 		},
 	}, {
-		Name:   "MaxFields",
-		Params: []adt.Kind{adt.StructKind, adt.IntKind},
+		Name: "MaxFields",
+		Params: []internal.Param{
+			{Kind: adt.StructKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			object, n := c.Struct(0), c.Int(1)
diff --git a/pkg/text/tabwriter/pkg.go b/pkg/text/tabwriter/pkg.go
index fc60e66..2fd711b 100644
--- a/pkg/text/tabwriter/pkg.go
+++ b/pkg/text/tabwriter/pkg.go
@@ -18,8 +18,10 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Write",
-		Params: []adt.Kind{adt.TopKind},
+		Name: "Write",
+		Params: []internal.Param{
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			data := c.Value(0)
diff --git a/pkg/text/template/pkg.go b/pkg/text/template/pkg.go
index 16aa21f..c61f0a7 100644
--- a/pkg/text/template/pkg.go
+++ b/pkg/text/template/pkg.go
@@ -18,8 +18,11 @@
 
 var pkg = &internal.Package{
 	Native: []*internal.Builtin{{
-		Name:   "Execute",
-		Params: []adt.Kind{adt.StringKind, adt.TopKind},
+		Name: "Execute",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.TopKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			templ, data := c.String(0), c.Value(1)
@@ -28,8 +31,10 @@
 			}
 		},
 	}, {
-		Name:   "HTMLEscape",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "HTMLEscape",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -38,8 +43,10 @@
 			}
 		},
 	}, {
-		Name:   "JSEscape",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "JSEscape",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
diff --git a/pkg/time/pkg.go b/pkg/time/pkg.go
index 23c9415..8054464 100644
--- a/pkg/time/pkg.go
+++ b/pkg/time/pkg.go
@@ -36,8 +36,10 @@
 		Name:  "Hour",
 		Const: "3600000000000",
 	}, {
-		Name:   "Duration",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Duration",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -46,8 +48,10 @@
 			}
 		},
 	}, {
-		Name:   "ParseDuration",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "ParseDuration",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.IntKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -152,8 +156,10 @@
 		Name:  "Saturday",
 		Const: "6",
 	}, {
-		Name:   "Time",
-		Params: []adt.Kind{adt.StringKind},
+		Name: "Time",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			s := c.String(0)
@@ -162,8 +168,11 @@
 			}
 		},
 	}, {
-		Name:   "Format",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Format",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.BoolKind,
 		Func: func(c *internal.CallCtxt) {
 			value, layout := c.String(0), c.String(1)
@@ -172,8 +181,11 @@
 			}
 		},
 	}, {
-		Name:   "Parse",
-		Params: []adt.Kind{adt.StringKind, adt.StringKind},
+		Name: "Parse",
+		Params: []internal.Param{
+			{Kind: adt.StringKind},
+			{Kind: adt.StringKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			layout, value := c.String(0), c.String(1)
@@ -182,8 +194,11 @@
 			}
 		},
 	}, {
-		Name:   "Unix",
-		Params: []adt.Kind{adt.IntKind, adt.IntKind},
+		Name: "Unix",
+		Params: []internal.Param{
+			{Kind: adt.IntKind},
+			{Kind: adt.IntKind},
+		},
 		Result: adt.StringKind,
 		Func: func(c *internal.CallCtxt) {
 			sec, nsec := c.Int64(0), c.Int64(1)