func Zip(_ context.Context, args ...core.Value) (core.Value, error) {
	err := core.ValidateArgs(args, 2, 2)
	if err != nil {
		return values.None, err
	}
	for _, arg := range args {
		err = core.ValidateType(arg, types.Array)
		if err != nil {
			return values.None, err
		}
	}
	keys := args[0].(*values.Array)
	vals := args[1].(*values.Array)
	if keys.Length() != vals.Length() {
		return values.None, core.Error(
			core.ErrInvalidArgument,
			fmt.Sprintf("keys and values must have the same length. got keys: %d, values: %d",
				keys.Length(), vals.Length(),
			),
		)
	}
	err = validateArrayOf(types.String, keys)
	if err != nil {
		return values.None, err
	}
	zipped := values.NewObject()
	var k values.String
	var val core.Value
	var exists bool
	keyExists := map[values.String]bool{}
	keys.ForEach(func(key core.Value, idx int) bool {
		k = key.(values.String)
		if _, exists = keyExists[k]; exists {
			return true
		}
		keyExists[k] = true
		val = vals.Get(values.NewInt(idx))
		cloneable, ok := val.(core.Cloneable)
		if ok {
			val = cloneable.Clone()
		}
		zipped.Set(k, val)
		return true
	})
	return zipped, nil
}
Zip returns an object assembled from the separate parameters keys and values.
Keys and values must be arrays and have the same length.
@params keys (Array of Strings) - an array of strings, to be used as key names in the result.
@params values (Array of Objects) - an array of core.Value, to be used as key values.
@returns (Object) - an object with the keys and values assembled.
package objects
import (
	"context"
	"fmt"
	"github.com/MontFerret/ferret/pkg/runtime/core"
	"github.com/MontFerret/ferret/pkg/runtime/values"
	"github.com/MontFerret/ferret/pkg/runtime/values/types"
)