Skip to content

feat: add array/complex-factory#11272

Open
udaykakade25 wants to merge 8 commits intostdlib-js:developfrom
udaykakade25:complexFactory
Open

feat: add array/complex-factory#11272
udaykakade25 wants to merge 8 commits intostdlib-js:developfrom
udaykakade25:complexFactory

Conversation

@udaykakade25
Copy link
Copy Markdown
Contributor

Resolves none.

Description

What is the purpose of this pull request?

This pull request:

  • Adds array/complex-factory package.

Related Issues

Does this pull request have any related issues?

This pull request has the following related issues:

  • None

Questions

Any questions for reviewers of this pull request?

No.

Other

Any other information relevant to this pull request? This may include screenshots, references, and/or implementation notes.

No.

Checklist

Please ensure the following tasks are completed before submitting this pull request.

AI Assistance

When authoring the changes proposed in this PR, did you use any kind of AI assistance?

  • Yes
  • [] No

If you answered "yes" above, how did you use AI assistance?

  • Code generation (e.g., when writing an implementation or fixing a bug)
  • Test/benchmark generation
  • Documentation (including examples)
  • Research and understanding

Disclosure

If you answered "yes" to using AI assistance, please provide a short disclosure indicating how you used AI assistance. This helps reviewers determine how much scrutiny to apply when reviewing your contribution. Example disclosures: "This PR was written primarily by Claude Code." or "I consulted ChatGPT to understand the codebase, but the proposed changes were fully authored manually by myself.".

I used Claude during my R&D by taking references from array/complex128, array/complex64, array/fix-endian-factory. Later used Claude to automate some of repetitive tasks in docs and benchmark files.


@stdlib-js/reviewers

@stdlib-bot stdlib-bot added the Needs Review A pull request which needs code review. label Apr 2, 2026
@udaykakade25 udaykakade25 changed the title feat; add array/complex-factory feat: add array/complex-factory Apr 2, 2026
@udaykakade25
Copy link
Copy Markdown
Contributor Author

/stdlib update-copyright-years

@stdlib-bot stdlib-bot added the bot: In Progress Pull request is currently awaiting automation. label Apr 2, 2026
@stdlib-bot stdlib-bot removed the bot: In Progress Pull request is currently awaiting automation. label Apr 2, 2026
@github-actions github-actions bot mentioned this pull request Apr 3, 2026
udaykakade25 and others added 3 commits April 3, 2026 09:43
Signed-off-by: Uday Kakade <141299403+udaykakade25@users.noreply.github.com>
Signed-off-by: Uday Kakade <141299403+udaykakade25@users.noreply.github.com>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file should not be modified in this PR. It is okay that there are spellcheck lint warnings. If we want to update this, it should be in a separate PR. TL;DR: PRs should, more or less, follow our Git commit message conventions, which means following conventional commits. Which means that PRs should be single-focused. By making updates to lint configuration, you are mixing concerns.

fromArray = makeFromArray( getReal, getImag );


// FUNCTIONS //
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section headers do not go in function bodies.

* @throws {RangeError} must provide valid arguments
* @returns {Function} complex number array constructor
*/
function factory( dtype, FloatArray, ComplexScalar, getReal, getImag, reinterpret ) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we forcing users to provide anything other than the dtype? Couldn't we have all the above in a look-up table internally? What is the design philosophy/rationale here?

Comment on lines +122 to +123
typeof value._length === 'number' && // eslint-disable-line no-underscore-dangle
typeof value._buffer === 'object' // eslint-disable-line no-underscore-dangle
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This alone is too weak a check. There is a reason why we check the constructor name in, e.g., array/complex128.

Comment on lines +139 to +141
typeof value === 'function' &&
typeof value.BYTES_PER_ELEMENT === 'number' &&
value.BYTES_PER_ELEMENT > 0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also too weak a check. Why are we not comparing against the constructor name?

if ( !isComplexArray( this ) ) {
throw new TypeError( 'invalid invocation. `this` is not a complex number array.' );
}
// eslint-disable-next-line no-warning-comments
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't disable this lint rule. See these lint warnings during linting is desirable.

tmp.push( getComplex( buf, i ) );
}
tmp.sort( compareFcn );
return new ComplexArray( tmp );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we still using new ComplexArray here rather than this.constructor? Currently, you thwart subclassing.

// MAIN //

/**
* Returns a complex number array constructor.
Copy link
Copy Markdown
Member

@kgryte kgryte Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following is a general comment that is more intended for discussion rather than providing something actionable...

The factory approach does work and it will reduce bundle sizes as the implementation would now be centralized.

That said, the factory approach does suffer from one drawback, which is it doesn't allow for inheritance from a parent constructor (e.g., ComplexArray -> Complex128Array). This lack of inheritance means that brand checks are more expensive (i.e., for many operations, we don't care which type of complex typed array we were given; we just want a complex typed array). If we had a parent class, we could simply check x instanceof ComplexArray (i.e., is this value an instance of the parent class?). With the factory approach, we cannot do that, as each ComplexXXArray is a separate class with no common inheritance.

Furthermore, separate classes are treated as objects having different hidden shapes. This then results in JS optimizing compilers treating input arrays as distinct and thus leading the compiler to mark a function as polymorphic. This can degrade performance. This is also true of built-in arrays, so we are not an outlier here, but the factory approach does introduce a potential performance cliff.

I am not sure that a parent class approach is actually feasible, but I at least wanted to document that there are trade-offs associated with a factory approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs Review A pull request which needs code review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants