+// ♓🌟 Piscēs ∷ function.js
+// ====================================================================
+//
+// Copyright © 2022 Lady [@ Lady’s Computer].
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
+
+import { defineOwnProperty, isObject } from "./object.js";
+
+/**
+ * Creates a bound function from the provided function using the
+ * provided this value and arguments list.
+ *
+ * ☡ As with call and construct, the arguments must be passed as an
+ * array.
+ */
+export const bind = (() => {
+ const callBind = Function.prototype.call.bind(
+ Function.prototype.bind,
+ );
+ const bind = ($, boundThis, boundArgs) =>
+ callBind($, boundThis, ...boundArgs);
+ return bind;
+})();
+
+/**
+ * Calls the provided function with the provided this value and
+ * arguments list.
+ *
+ * ☡ This is an alias for Reflect.apply—the arguments must be passed
+ * as an array.
+ */
+export const call = Reflect.apply;
+
+/**
+ * Constructs the provided function with the provided arguments list
+ * and new target.
+ *
+ * ☡ This is an alias for Reflect.construct—the arguments must be
+ * passed as an array.
+ */
+export const construct = Reflect.construct;
+
+/** Returns whether the provided value is a constructor. */
+export const isConstructor = ($) => {
+ if (!isObject($)) {
+ // The provided value is not an object.
+ return false;
+ } else {
+ // The provided value is an object.
+ try {
+ construct(
+ function () {},
+ [],
+ $,
+ ); // will throw if $ is not a constructor
+ return true;
+ } catch {
+ return false;
+ }
+ }
+};
+
+/**
+ * Returns a new function which calls the provided function with its
+ * first argument as the `this` value and the remaining arguments
+ * passed through.
+ *
+ * ※ This is effectively an alias for Function.prototype.call.bind.
+ */
+export const makeCallable = (() => {
+ const functionCall = Function.prototype.call;
+ const callable = ($) => defineOwnProperty(
+ bind(functionCall, $, []),
+ "length",
+ { value: $.length + 1 },
+ );
+ return callable;
+})();
+
+/**
+ * Returns whether the provided object inherits from the prototype of
+ * the provided function.
+ */
+export const ordinaryHasInstance = makeCallable(
+ Function.prototype[Symbol.hasInstance],
+);