]> Lady’s Gitweb - Pisces/blobdiff - function.js
Add buffer getters and setters to binary.js
[Pisces] / function.js
index 0b9ebcc5510a4caaa767622b60427d5d536d4e2e..5f397a92d2708331cddc63bef2b82d0cdc72eb68 100644 (file)
 // ♓🌟 Piscēs ∷ function.js
 // ====================================================================
 //
-// Copyright © 2022 Lady [@ Lady’s Computer].
+// Copyright © 2022‐2023 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";
+import { ITERATOR } from "./value.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;
+export const {
+  /**
+   * 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.
+   */
+  bind,
+
+  /**
+   * 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::call.bind`.
+   */
+  makeCallable,
+} = (() => {
+  // ☡ Because these functions are used to initialize module constants,
+  // they can’t depend on imports from elsewhere.
+  const {
+    bind: functionBind,
+    call: functionCall,
+  } = Function.prototype;
+  const callBind = Reflect.apply(functionBind, functionCall, [
+    functionBind,
+  ]);
+  const {
+    create: objectCreate,
+    defineProperty: defineOwnProperty,
+    getPrototypeOf: getPrototype,
+  } = Object;
+  const { [ITERATOR]: arrayIterator } = Array.prototype;
+  const {
+    next: arrayIteratorNext,
+  } = getPrototype([][ITERATOR]());
+  const argumentIterablePrototype = {
+    [ITERATOR]() {
+      return {
+        next: callBind(
+          arrayIteratorNext,
+          call(arrayIterator, this.args, []),
+        ),
+      };
+    },
+  };
+  return {
+    bind: ($, boundThis, boundArgs) =>
+      callBind(
+        $,
+        boundThis,
+        ...objectCreate(
+          argumentIterablePrototype,
+          { args: { value: boundArgs } },
+        ),
+      ),
+    makeCallable: ($) =>
+      defineOwnProperty(
+        callBind(functionCall, $),
+        "length",
+        { value: $.length + 1 },
+      ),
+  };
 })();
 
-/**
- * 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;
+export const {
+  /**
+   * 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 arraylike.
+   */
+  apply: call,
+
+  /**
+   * 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 arraylike.
+   */
+  construct,
+} = Reflect;
 
 /**
- * Constructs the provided function with the provided arguments list
- * and new target.
+ * Returns the provided value.
  *
- * ☡ This is an alias for Reflect.construct—the arguments must be
- * passed as an array.
+ * ※ This function can be called as a constructor. When used in an
+ * `extends` clause and called via `super`, it will set the value of
+ * `this` to the provided value, enabling it to be extended with
+ * private class features.
  */
-export const construct = Reflect.construct;
+export const identity = function ($) {
+  return $;
+};
+
+/** Returns whether the provided value is callable. */
+export const isCallable = ($) => typeof $ === "function";
 
 /** Returns whether the provided value is a constructor. */
 export const isConstructor = ($) => {
-  if (!isObject($)) {
-    // The provided value is not an object.
+  // The provided value is an object.
+  try {
+    // Try constructing a new object with the provided value as its
+    // `new.target`. This will throw if the provided value is not a
+    // constructor.
+    construct(
+      function () {},
+      [],
+      $,
+    );
+    return true;
+  } catch {
+    // The provided value was not a constructor.
     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],
+  Function.prototype[Symbol.hasInstance],
 );
This page took 0.024221 seconds and 4 git commands to generate.