or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel--plugin-proposal-partial-application

Babel plugin that introduces partial application syntax using ? tokens in argument lists to create partially applied functions

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@babel/plugin-proposal-partial-application@7.27.x

To install, run

npx @tessl/cli install tessl/npm-babel--plugin-proposal-partial-application@7.27.0

index.mddocs/

Babel Plugin Proposal Partial Application

This Babel plugin introduces partial application syntax to JavaScript and TypeScript, allowing developers to use the ? token as a placeholder in function argument lists to create partially applied functions. The plugin transforms these placeholders into closures that accept the missing arguments while maintaining proper scope and context.

Package Information

  • Package Name: @babel/plugin-proposal-partial-application
  • Package Type: npm
  • Language: TypeScript/JavaScript
  • Installation: npm install --save-dev @babel/plugin-proposal-partial-application

Core Imports

Since this is a Babel plugin, it's used in Babel configuration rather than imported directly in application code:

{
  "plugins": ["@babel/plugin-proposal-partial-application"]
}

Or with options:

// babel.config.js
module.exports = {
  plugins: [
    ["@babel/plugin-proposal-partial-application", {
      // Plugin options if any
    }]
  ]
};

Basic Usage

The plugin enables partial application syntax in your JavaScript/TypeScript code:

// Basic partial application
const addOne = add(1, ?);
// Equivalent to: const addOne = (x) => add(1, x);

// Method calls
const logMessage = console.log(?);
// Equivalent to: const logMessage = (msg) => console.log(msg);

// Multiple placeholders
const formatter = format(?, "bold", ?);
// Equivalent to: const formatter = (text, color) => format(text, "bold", color);

Architecture

The plugin operates as a Babel AST transformer that:

  • Parser Integration: Adds "partialApplication" parser plugin to enable ? token recognition
  • AST Transformation: Transforms CallExpression nodes containing ArgumentPlaceholder tokens
  • Scope Management: Generates unique identifiers and manages variable scoping
  • Context Preservation: Maintains proper this binding for method calls
  • Immutable Handling: Optimizes transformations by detecting immutable expressions

Capabilities

Plugin Factory Function

The main export is a Babel plugin factory function that returns a plugin configuration object.

// Import pattern for implementation reference
import { declare } from "@babel/helper-plugin-utils";
import { types as t, type Scope } from "@babel/core";

export default declare(api => BabelPlugin);

interface BabelPlugin {
  name: string;
  manipulateOptions: (opts: any, parser: ParserOptions) => void;
  visitor: {
    CallExpression: (path: NodePath<t.CallExpression>) => void;
  };
}

interface ParserOptions {
  plugins: string[];
}

type CallArgsWithoutPlaceholder = Exclude<
  t.CallExpression["arguments"][number],
  t.ArgumentPlaceholder
>[];

Partial Application Syntax Transformation

Transforms call expressions containing ? placeholders into equivalent closure functions.

Simple Function Calls

// Input:
const result = func(1, ?, 3);

// Output:
const result = (function(_argPlaceholder) {
  return func(1, _argPlaceholder, 3);
});

Method Calls with Context Binding

// Input:
const method = obj.doSomething(?, "param");

// Output:
const method = (function(_argPlaceholder) {
  return obj.doSomething.call(obj, _argPlaceholder, "param");
});

Multiple Placeholders

// Input:
const multiArg = func(?, "middle", ?);

// Output:
const multiArg = (function(_argPlaceholder, _argPlaceholder2) {
  return func(_argPlaceholder, "middle", _argPlaceholder2);
});

Complex Member Expressions

// Input:
const nested = a.b.c.method(?, value);

// Output:
const nested = (function(_argPlaceholder) {
  const _receiver = a.b.c;
  const _method = _receiver.method;
  return _method.call(_receiver, _argPlaceholder, value);
});

Spread Elements Support

// Input:
const withSpread = func(a, ...args, ?);

// Output:
const withSpread = (function(_argPlaceholder) {
  return func(a, ...args, _argPlaceholder);
});

Plugin Configuration

The plugin provides the following configuration properties:

interface PluginConfiguration {
  /** Plugin identifier name */
  name: "proposal-partial-application";
  
  /** 
   * Configures the parser to recognize partial application syntax
   * @param opts - Babel options (unused)
   * @param parser - Parser configuration object
   */
  manipulateOptions: (opts: any, parser: ParserOptions) => void;
  
  /** 
   * AST visitor methods for transforming partial application syntax
   */
  visitor: {
    /**
     * Transforms CallExpression nodes containing ArgumentPlaceholder tokens
     * @param path - NodePath for the CallExpression
     */
    CallExpression: (path: NodePath<t.CallExpression>) => void;
  };
}

Internal Helper Functions

These are private implementation details exposed for completeness:

/**
 * Checks if a call expression contains ArgumentPlaceholder tokens
 * @param node - CallExpression node to check
 * @returns Boolean indicating presence of placeholders
 */
function hasArgumentPlaceholder(node: t.CallExpression): boolean;

/**
 * Processes and unwraps arguments, handling immutable values and scope
 * @param callExpr - Object destructuring CallExpression arguments
 * @param scope - Babel scope for identifier generation
 * @returns Array of assignment expressions for argument initialization
 */
function unwrapArguments(
  { arguments: args }: t.CallExpression,
  scope: Scope,
): t.AssignmentExpression[];

/**
 * Replaces ArgumentPlaceholder tokens with generated parameter identifiers  
 * @param node - CallExpression containing placeholders
 * @param scope - Babel scope for identifier generation
 * @returns Tuple of [placeholder parameters, processed arguments]
 */
function replacePlaceholders(
  node: t.CallExpression, 
  scope: Scope
): [t.Identifier[], CallArgsWithoutPlaceholder];

Syntax Features

Supported Patterns

  1. Function Calls: func(?, arg)(x) => func(x, arg)
  2. Method Calls: obj.method(?)(x) => obj.method(x)
  3. Multiple Arguments: func(?, ?, arg)(x, y) => func(x, y, arg)
  4. Mixed Positions: func(arg1, ?, arg3, ?)(x, y) => func(arg1, x, arg3, y)
  5. Spread Elements: func(...args, ?)(x) => func(...args, x)
  6. Nested Access: a.b.c.method(?)(x) => a.b.c.method(x)
  7. Chained Calls: fn1(?)(fn2(?))(x) => fn1(x)(fn2)

Parser Plugin

The plugin automatically adds the "partialApplication" parser plugin to enable ? token recognition:

/**
 * Parser plugin identifier for partial application syntax
 */
type ParserPlugin = "partialApplication";

Error Handling

The plugin handles various edge cases:

  • Immutable Expressions: Optimizes by not wrapping immutable values
  • Scope Conflicts: Generates unique identifiers to avoid variable collisions
  • Context Preservation: Maintains proper this binding for method calls
  • Spread Element Processing: Correctly handles spread syntax in argument lists

Dependencies

  • @babel/helper-plugin-utils: Plugin utilities for Babel plugin creation
  • @babel/core: Babel core types and AST manipulation utilities

Transformation Examples

Simple Transformation

// Before transformation:
const foo = bar(?);

// After transformation:
var _bar;
const foo = (_bar = bar, function bar(_argPlaceholder) {
  return _bar(_argPlaceholder);
});

Method Call Transformation

// Before transformation:
const g = o.f(?, x, 1);

// After transformation:
var _o, _o$f, _x;
const g = (_o = o, _o$f = _o.f, _x = x, function f(_argPlaceholder) {
  return _o$f.call(_o, _argPlaceholder, _x, 1);
});

Multiple Placeholders

// Before transformation:
const h = p.b(1, y, x, 2, ?);

// After transformation:
var _p, _p$b, _y, _x2; 
const h = (_p = p, _p$b = _p.b, _y = y, _x2 = x, function b(_argPlaceholder2) {
  return _p$b.call(_p, 1, _y, _x2, 2, _argPlaceholder2);
});

This plugin enables functional programming patterns in JavaScript by providing a concise syntax for partial application, reducing the need for manual wrapper functions and improving code readability in functional-style codebases.