Skip to content

RFC Implementation: Unify JSFunction and JSObject for consistent type system #420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Aug 22, 2025

This PR implements the RFC to unify JSFunction and JSObject, addressing fundamental design issues in the inheritance hierarchy and aligning the type system with JavaScript's dynamic callability semantics.

Problem

The existing architecture had several critical issues:

  1. Mismatch with JavaScript semantics: In JavaScript, any object can be callable through Proxy traps or other mechanisms, but our type system treated functions and objects as mutually exclusive
  2. Complex inheritance hierarchy: JSFunction inheriting from JSObject created unnecessary complexity
  3. Inconsistent closure hierarchy: JSClosure inherited from JSFunction while JSOneshotClosure inherited from JSObject
  4. Type system gap: JSObject.global.Function.function!.new returns a JSObject that should be callable but wasn't in our type system

Solution

This implementation unifies the architecture while maintaining complete backward compatibility:

1. Unified Callability

All JSObject instances now support function call operations:

// Before: Only JSFunction could be called
let func: JSFunction = JSObject.global.alert.function!
func("Hello")

// After: JSObject is directly callable
let obj: JSObject = JSObject.global.alert
obj("Hello")  // Works directly

2. Consistent Inheritance

Both closure types now consistently inherit from JSObject:

// Before: Inconsistent hierarchy
JSClosure: JSFunction  // Inherited from JSFunction
JSOneshotClosure: JSObject  // Inherited from JSObject

// After: Unified hierarchy
JSClosure: JSObject  // Both inherit from JSObject
JSOneshotClosure: JSObject

3. Unified JSValue Representation

Functions are now represented as objects internally:

// JavaScript functions come in as .object(JSFunction) instead of .function(JSFunction)
// The .function property intelligently detects callable objects

Implementation Details

  • Phase 1: Added complete callability functionality to JSObject, including callAsFunction, new, and all argument overloads
  • Phase 2: Updated JSValue conversion to represent functions as objects while maintaining the .function property for backward compatibility
  • Phase 3: Made JSClosure inherit from JSObject instead of JSFunction for consistency
  • Added comprehensive documentation with migration guidance and deprecation notices

Backward Compatibility

All existing code continues to work unchanged:

  • The .function property now intelligently checks both .function and .object cases
  • JSFunction class remains available with full functionality
  • All existing APIs maintain their behavior

Benefits

  • Aligned with JavaScript semantics: Objects can be callable, matching JavaScript's dynamic nature
  • Simplified architecture: Reduced inheritance complexity
  • Consistent closure model: Both closure types follow the same pattern
  • Future-ready: Prepared for JavaScript features like callable objects and Proxy traps
  • Unified API surface: Developers can work with a single object model

Fixes #402.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copy link
Author

Copilot AI commented Aug 22, 2025

@kateinoigakukun 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

@Copilot Copilot AI changed the title [WIP] RFC: Unify JSFunction and JSObject RFC Implementation: Unify JSFunction and JSObject for consistent type system Aug 22, 2025
@Copilot Copilot AI requested a review from kateinoigakukun August 22, 2025 10:34
Copilot finished work on behalf of kateinoigakukun August 22, 2025 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RFC: Unify JSFunction and JSObject
2 participants