Skip to content

Conversation

@perminder-17
Copy link
Collaborator

@perminder-17 perminder-17 commented Oct 26, 2025

Resolves #8156

Changes:

  • The no-argument usage of createVector() to be marked for deprecation.
  • FES to suggest not using createVector without arguments
  • Prevent NaN from appearing when a createVector() is subject to any operations.
  • Add unit tests and improve documentation.

Screenshots of the change:

PR Checklist

@perminder-17 perminder-17 linked an issue Oct 26, 2025 that may be closed by this pull request
4 tasks
@perminder-17 perminder-17 marked this pull request as draft October 26, 2025 15:58
@perminder-17 perminder-17 marked this pull request as ready for review October 26, 2025 20:07
const matrix = this._renderer.getWorldToScreenMatrix();

if (screenPosition.dimensions === 2) {
if (origDimension === 2 || screenToWorldArgs === 2) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The logic here is, when we are padding 0's to the other components of vector to prevent NaN, the screenToWorld breaks because it the count here changes and maybe it projects the z components as well.

So, when we see screenPosition.dimensions always comes out to 3 since we are storing other component with 0. Here I am preserving the count with original arguments and makes the test pass. Since it's not the actual fix and tends to be a workaround for the future release, I think this should work, Let me know if there's any objection @davepagurek

Copy link
Contributor

Choose a reason for hiding this comment

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

Let me know if I'm understanding the flow here correctly:

  • If you pass two numbers into screenToWorld (e.g. screenToWorld(width/2, height/2)) or if you pass a single vector in that was created with two numbers (e.g. screenToWorld(createVector(1, 2))), we want to generate a z value
  • We can directly check the arguments length, but when the arg is a single vector, its values get padded to length 3, so we don't know directly how many arguments were manually provided
  • We store a global dimension value corresponding to the number of args passed to the last createVector call

That sounds like it works. I wonder if it might be a little more direct, instead of using global state, to edit createVector to instead set a secret internal property on the vector before returning it, like _origDimension, so then we could check if that exists on any vector?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, you are right. I am using _origDimension now, if screenToWorld(width/2, height/2) we take the argument from there, and if we have not a number (probably a vector) we fetch the _origDimension, other logic are same? Also, now we are not using global state. Do you think it's correct for now?

@GregStanton
Copy link
Collaborator

GregStanton commented Oct 28, 2025

Hi @perminder-17 and @davepagurek!

Thanks so much for working on this. I'm really glad we're trying to figure out how to accommodate the 1.x createVector() usage.

Since I've been organizing the p5.Vector stabilization work (#8149), I wanted to check in on this PR to see how it would interact with the other open issues. I took a quick look at the implementation, and I'm concerned that the current approach—padding all 1D/2D vectors to 3D—is much broader than the "targeted patch" that was proposed and may have major, unintended side effects.

This implementation seems to revert p5.Vector to the 1.x model, which prevents 2.x from having true 1D or 2D vectors. This would unfortunately block or break most of the community's other stabilization work.

Here are the key conflicts I've identified:

  1. Breaks current 2.x behavior: This PR would break valid 2.x features. For example, toString() on a 2D vector currently (and correctly) returns two components. This change would either break the toString() contract or create a confusing state where users don't know whether to trust vec.z or toString(). (See #8153.)

  2. Blocks the broadcasting policy: This change would make the widely-supported broadcasting policy (#8159) impossible to implement. That policy requires us to distinguish 2D and 3D vectors to throw correct errors (e.g., on vec2.add(vec3)). If all vectors are 3D or higher, we lose this ability, which means more complex documentation for features like add(), sub(), mult(), div(), and rem().

  3. Blocks other core fixes: The simple fixes for cross() (#8210), heading() (#8214), and setHeading() (#8215) all depend on being able to distinguish true 2D vectors from 3D vectors. This PR would prevent those fixes.

  4. Violates user expectations: This violates the principle of least astonishment. In 2.x, a user writing createVector(2, 3) correctly expects the vector's components to be [2, 3] (as currently reported by toString()), not [2, 3, 0]. Finding that vec.z is 0 or that vec.toString() reports three components would confuse them.

  5. Propagates 1.x complexity: This padding logic forces other functions like set() to retain confusing side effects from 1.x (e.g., v.set(1, 1) on [1.01, 1.01, 5] becoming [1, 1, 0]). This blocks the simpler, powerful broadcasting solution we've been working on in #8189.

A Real-Time Example of This Complexity

This PR's discussion of the screenToWorld bug is a perfect example of this complexity in action.

To fix the bug this patch created, a new "secret internal" _origDimension property was needed to track the intended state versus the actual (padded) state. This forced a kind of kludge, which creates technical debt: It's brittle and will likely break if vector internals are refactored, since it relies on the vector holding conflicting state (its real shape and its intended shape). This is the exact kind of complexity that the 2.x stabilization work (like a stable, user-facing .shape property in #8155) is designed to solve, but the current PR blocks that work (the shape property is most viable if the vector has a single, unambiguous shape).

Summary

This PR would significantly complicate the entire vector class, for all 2.x users, in order to accommodate a legacy edge case in a single function.

Fundamentally, this patch replaces the simpler, more robust 2.x model with the legacy 1.x model. This breaks or blocks improvements that have already been added or are actively being worked on, based on extensive discussions (including the concept of true 1D and 2D vectors, as discussed in #8118).

Proposal: Move this back to #8156 for alternatives

Since this patch appears to have a much larger blast radius than intended, I propose we continue to discuss viable options in #8156, before we merge. I think we need to find a way to patch the createVector() no-argument case without undermining the entire n-dimensional model.

My sense is that the simplest, lowest-impact solution may be to include a short note in the compatibility README, instructing users how to fix their sketches by supplying explicit 0 arguments to createVector(). But I think the wider community should have a chance to weigh in.

Thanks again for all your work on this!

@davepagurek
Copy link
Contributor

This change would make the widely-supported broadcasting policy (#8159) impossible to implement.

I think we aren't trying to reach a permanent solution in this, but just unblock sketches that are currently broken. So it's very likely that we undo whatever we do in this PR when making larger changes to broadcasting.

That said, do you think it would be reasonable to do a similar kind of padding, but only when operating on another vector for now? So like, temporarily implementing a version of broadcasting where we pad with 0s, but only when you add two vectors. So if you did:

const a = createVector(1, 2) // Dimension is 2
const b = createVector(3, 4, 5) // Dimension is 3
a.add(b) // Maybe this logs an FES message saying you've multiplied two different-sized vectors together
// A's dimension is now 3, its data is [4, 6, 5]

This would make dimension and toString() work correctly at first, and would stop NaNs from appearing in data right now. It isn't the full solution to broadcasting -- essentially it's using one form of broadcasting as a stopgap until we work out a full solution. But I think that takes some of what's currently broken and leaves it in a less broken state without introducing new breakages?

@GregStanton
Copy link
Collaborator

GregStanton commented Oct 29, 2025

Hi @davepagurek! Thank you so much for your quick reply. I love seeing all these ideas being put forth, and your new idea is really interesting.

We're totally in agreement about wanting to fix the current user-facing bugs as quickly as possible. With that in mind, I have a proposal for a different quick fix, a few concerns about the "stopgap" approach, and what I see as a path to immediately unlock quick, permanent fixes.

A truly quick fix

If our goal is to unblock users today with the lowest possible effort and zero technical debt, I think the fastest path is to add a note to the compatibility README and the 2.0 beta documentation. Something like this:

"In 1.x, createVector() was often used as a shortcut for createVector(0, 0, 0). In 2.x, createVector() with no arguments is no longer supported, as we now have true 1D/2D vectors. If your 1.x sketch breaks when upgrading to 2.x, you can fix it by explicitly using createVector(0), createVector(0, 0), or createVector(0, 0, 0), depending on the desired dimension."

This is a 10-minute, no-code change that immediately solves the user's "why is my sketch broken?" problem. Crucially, we can reinforce this with a dedicated Friendly Error System message. That way, the README and reference pages provide advance notice, and users who are still bitten by the bug will find an immediate, simple solution when and where it happens.

Risks of a custom "stopgap"

My main concern with the stopgap you proposed (padding with 0s for add()) is that it's not a partial form of standard broadcasting—it's a new, custom rule that explicitly violates the universally adopted broadcasting rule.

This rule is precisely the same in every major library for math, machine learning, and when applicable, creative-coding. For example, openFrameworks also follows the same rule.

Violating the rule means we'd have to code in warning messages that teach users special behavior that they'll have to unlearn—the permanent solution explicitly disallows this exact behavior. This feels like the "whack-a-mole" problem: we'd be solving the NaN bug by introducing a new source of user confusion.

An opportunity for quick, permanent fixes

This brings me to what I think is the most exciting and high-leverage opportunity.

The permanent solutions for this bug (and many others) are already clearly defined, the key policies like broadcasting have strong community support, and the issues have volunteers ready and waiting to implement them. The only thing preventing us from fixing these bugs quickly and permanently is that we're blocked on finalizing a few key policy decisions.

I believe the most effective use of our time is to unblock the community. If the maintainer team can reach a final decision on these three key issues, it would unleash all of that volunteer energy:

  • Broadcasting policy (#8159): Fortunately, this isn't a long-term project; implementing the full policy is a small, simple fix, based around just two features. The mult(), div(), and rem() methods already broadcast scalars. The only methods requiring an immediate update are add() and sub(); I've confirmed that the logic for those can be adapted directly from the simple loop already in mult() (changing *= to += or -=). Beyond that, the only other change is throwing Friendly Error Messages in unsupported cases. My review of 100 sketches shows zero disruption from these changes. In this case, the permanent solution is also the quick fix. Approving it is an easy win.

  • The x/y/z behavior (#8153): This is a simple bug fix that aligns x, y, and z with the correct behavior of toString(). The exact changes that need to be made have been identified, and involve removing a few characters of code. It's also backed by previous discussion of true 1D/2D vector support.

  • The dimensions naming (#8155): We've already refined the API through several rounds of feedback, identified the core problems, and proposed a standard, precedent-backed solution. The final step is just a quick cross-check against existing getter/setter patterns across the library (which I can complete by tomorrow) to ensure long-term consistency.

Once these policies are approved, the community can immediately start implementing permanent fixes for these NaN bugs, and many other issues will be unblocked (e.g. #8188, #8189, #8210, #8215, and #8218).

What do you think of this approach? It seems like a way to get the best of both worlds: a zero-debt immediate fix (the README) and a clear plan to rapidly unlock the permanent fixes.

@ksen0
Copy link
Member

ksen0 commented Oct 29, 2025

Hi @GregStanton thank you for your thoughtful review! After going through this with @davepagurek , here are my takeaways and recommendation for this PR:

  1. This PR should be updated to be more focused on only the zero-argument usage, in a way that does not introduce new partial broadcasting policy. See also this comment describing @davepagurek 's proposal of "a zero vector that still has a fixed size, like other vectors, but with the specification of that size deferred until it can be inferred." In other words, this solution would only affect zero-arg vectors, and not by affecting broadcasting, but rather by allowing the existence of a vector of unspecified size until first usage. This PR should include the documentation note that this usage is not recommended; as well as the unit tests and FES note on zero-arg use. @perminder-17 does that all sound reasonable? Thanks so much for working on this!

  2. This implementation (as was noted) has drawbacks, but on discussion and reflection of the various linked issues, I think it is sensible for two related reasons. First, it is in the spirit of p5.js to support as little friction as possible in common uses; I think there is enough usage of createVector() (including in Nature of Code) that it is worthwhile to reduce this friction. Second, as all other Vector proposals suggest (or don't contradict), zero-arg usage of createVector() should be marked for deprecation and not supported at all in the future. However, given that it is currently supported, and there was not wide consensus to deprecate it, the proposed patch for minimum backwards compatibility seems justifiable. If there are severe drawbacks I am not seeing, I am very happy to reconsider this, but I think as long as there are unit tests (to reduce developer confusion) and FES messages reminding not to use createVector() (to reduce user confusion) - it is alright.

  3. Although [2.0] Proposal: A standard policy for vector dimension mismatches #8159 is leaning toward no partial broadcasting (and it's a great discussion that I'm really glad is happening!) there is not yet clear and wide consensus (besides that issue, there are other places where there was more support for partial broadcasting). Also, as far as I understand, the standard broadcasting solution to this situation is to disallow zero-arg use (and update docs accordingly) - I agree overall with future deprecation, however, it has not been deprecated (or at minimum, there has not been - as far as I know - meaningful deliberation and consensus in the past to fully deprecate zero-arg usage). Again, if I'm missing something please let me know, I tried to catch up as best as I could.

While considering this I also referred to Dan Shiffman's comment and from what I could tell, although the code examples in that comment won't work with this patch, the teaching approach does use constructors with explicit arguments, so this supports keeping the scope of this fix separate from broadcasting fix.

Thanks all for your careful work on this!

@GregStanton
Copy link
Collaborator

GregStanton commented Oct 29, 2025

Hi @ksen0 and @davepagurek,

Thank you both for digging into this so thoroughly and proposing the size-deferred approach. I really appreciate the effort to find a solution that minimizes friction for users migrating from 1.x, especially those working from major references like Nature of Code. I absolutely share the goal of making this transition as smooth as possible.

However, after analyzing the size-deferment proposal in more detail, I'm increasingly concerned that this specific automatic fix might inadvertently introduce more friction and complexity than it eliminates, both for users and contributors. While I've tried to remain open to different automatic solutions, my analysis keeps leading back to the conclusion that the simpler approach (guiding users via README + FES message) might actually be the most user-friendly one in this specific case.

Concerns about the size-deferment approach

While extremely clever, this approach seems to introduce several significant drawbacks:

  1. It creates deep user confusion: The core issue is that this patch introduces complex, "magic" behavior (implicitly mutable dimensions, hidden states, automatic resizing) specifically for users who follow the createVector() pattern. Instead of guiding them towards the clear 2.x model, it makes their code harder to understand and debug, inviting invisible bugs. As @sidwellr pointed out, users lose a clear mental model ("what dimension is my vector?"), violating the principle of least astonishment.

  2. It is entangled with, and conflicts with, broadcasting: While the intent is to disentangle this PR from broadcasting, @sidwellr's v1.add(v2) example, where v2 is temporarily a 1D vector, perfectly illustrates the unavoidable conflict. Does the size-deferred vector v2 get "locked" by padding the vector itself with zeros as an implicit side effect, or does broadcasting repeat the x value without side effects? The two systems collide, forcing an arbitrary rule and undermining the clarity the broadcasting proposal (#8159) aims to achieve.

  3. It harms contributor accessibility: This is critical for the project's health. The size-deferment patch obfuscates the fundamental concept of dimension, making ongoing stabilization work more difficult. Adding complex, state-dependent logic (_setDimension, _matchDimensions, etc.) to potentially every vector operation creates another significant barrier for contributors. Looking forward, ensuring interoperability with future classes like Matrix is also complicated by this edge-case fix. Overall, it risks making a core class unmaintainable and complicates ongoing work on many other critical, open issues.

  4. Unaddressed edge cases & inconsistencies: Interactions with unary operations that don't imply a dimension (limit(), mag(), magSq(), normalize(), and setMag()), or methods like .setValue(), have not been specified. These entail additional special cases and new inconsistencies. For example, .setValue() currently throws an error if the user tries to set a z-value on a 1D vector, whereas .z simply does nothing in this case. This is an existing inconsistency that I'm working to resolve. Size-deferment adds a third inconsistency, whereby out-of-bounds elements can be set, and the start of a vector is padded with zeros. This adds complexity, when our overall goal is simplification.

Reconsidering the friction

The primary motivation seems to be avoiding the friction of users manually updating createVector() calls, particularly in those widespread Nature of Code examples. However, I believe the friction introduced by the size-deferment approach is ultimately much higher and more persistent:

  • The ongoing friction of debugging silent failures caused by implicit, "magic" dimension changes.
  • The ongoing friction of trying to understand and predict this complex, undocumented behavior.
  • The ongoing friction for contributors facing a more complex and brittle codebase.

In contrast, the README + FES message approach involves a simple, one-time, explicitly-guided code change. It leverages the excellent capabilities of the Friendly Error System, turning a potentially breaking error into a helpful, in-context tutorial, guiding the user directly to the simple fix. While it requires a manual update, this transparency respects users and leads to clearer code.

Crucially, since the zero-argument createVector() will likely be deprecated anyway, users will eventually need to update their code regardless. With the 2.0 stabilization period extending until August 2026, the FES message provides ample lead time for this simple, guided update. This feels like the lower-friction path, minimizing pain for both users and contributors.

Recommendation

Given the significant drawbacks, I strongly believe the size-deferment approach, while well-intentioned as a temporary bridge, is ultimately detrimental due to the persistent complexity it introduces.

Could we reconsider the simpler path?

  1. Implement the README note + FES message. This provides clear, actionable guidance with zero technical debt, making the fix easy to understand and implement, using p5's excellent FES capabilities.

  2. Finalize the core policies (#8159, #8153, #8155). This unblocks the community and allows for permanent, stable fixes using simple, well-understood code. The case for the broadcasting proposal (#8159), in particular, is now exceptionally strong. Every major math, machine-learning, and creative-coding library that has encountered this problem has come to the same conclusion. It represents a simple, low-risk implementation path, making it a quick win once approved. The implementation is also exceptionally simple.

This approach seems to offer the best balance: it addresses the immediate compatibility concern clearly and effectively, without compromising the long-term stability, simplicity, and maintainability of p5.Vector. It acknowledges the disruption of the breaking change but argues that a quick, guided fix is less harmful than introducing stubborn, hidden complexity.

What are your thoughts on this analysis? I'm eager to find the best solution together.

@sidwellr
Copy link

I think the simplest, lowest-impact solution to fix 1.x sketches that break today is to replace the body of Vector.sub() with the body of Vector.add() and change the + to -. This will fix the NaN issue (#8117), and then most users will not notice that some 3D vectors turn up in their code since they will only be using v.x and v.y to get the coordinates they need for drawing. It's basically the "3D illusion" that existed in version 1 and frankly, if that bug didn't exist I doubt if issues #8117 or #8118 (which led to #8149 and its sub-issues) would have been created.

But the issues we are discussing under #8149 are important and I'm glad we are having the discussions. This simple fix does not address the larger issue of vector dimension mismatches (#8159), so is a quick fix until that is resolved. Making Vector.add() and Vector.sub() consistent should make that effort easier. And this only addresses the last bullet in @ksen0's actionable solution; it doesn't deprecate createVector() with no arguments or create a friendly warning/suggestion when it is used. See @GregStanton's comment above under the heading A truly quick fix for how to do these.

@GregStanton
Copy link
Collaborator

GregStanton commented Oct 30, 2025

Hi @ksen0 and @davepagurek. Thanks, @sidwellr, for that insightful analysis! You've hit on a crucial insight: the NaN bug in sub() is a simple, targeted fix. This perfectly highlights the high-leverage opportunity we have right now.

The permanent fix is just as quick as the temporary fix

Fixing this the temporary way (making sub() match add()) is the same amount of work as fixing this the permanent way (making sub() match mult()).

The full, permanent solution isn't a long-term project. It's an extremely simple change:

  1. For add() and sub(), we adapt the simple for loop already in mult(), changing *= to += or -=.
  2. For all other mismatches, we add a simple else condition to throw a Friendly Error Message.

This implementation is just as fast as the temporary patch, but it has the massive benefit of also unblocking all the other stabilization work for div(), set(), etc., and it solves the problem correctly, once and for all.

The case for the permanent fix

As we've discussed in the broadcasting proposal (#8159), the non-standard pad-by-zero logic creates internal inconsistency and confusion:

  • add(2) adds 2 only to the first element (non-standard)
  • mult(2) multiplies every element by 2 (standard)

My careful review of 100 sketches (50 for add(), 50 for mult()) shows the nonstandard pad-by-zero behavior is relied on by 0% of users. In contrast, the standard broadcasting behavior in mult() is common and aligns with user expectations. The standard behavior is both useful and universal: openFrameworks uses it for addition, as does every other major library, across domains and languages.

Seizing the opportunity

Given that the permanent fix is just as fast, has 0% disruption, and aligns with a universal standard that is the only mismatch policy our users actually rely on, it seems to be the most efficient path forward.

Why spend time on a temporary patch that is no faster to implement, implements a 0%-used confusing behavior, and will need to be undone?

Could we seize this opportunity to implement the quick, permanent fix by approving #8159 and patching sub? This respects both the urgency of the bug and the long-term health of the library.

@sidwellr
Copy link

I agree with @GregStanton that making sub() match mult() will fix the NaN issue. But it is also a breaking change from version 1 and needs to be documented as such. I don't think that a sample size of 100 sketches is statistically significant to say this won't break existing sketches, but I also doubt that many users use v.add(2) to add 2 to v.x; it would be more common (and readable) to use v.x += 2.

So, I don't object to this proposal, but observe that it is not "just as quick" because it would require updating documentation as well as code, and also note it isn't a complete fix; #8159 also requires checking for mismatched dimensions. Do we have enough support for #8159 to approve and implement it?

@GregStanton
Copy link
Collaborator

GregStanton commented Oct 31, 2025

Thanks, @sidwellr, for your feedback and attention to detail!

The good news is that the simplicity of the broadcasting proposal means the fix itself is extremely simple, including the documentation, which would need to be updated in either case (it's currently incomplete, in various ways).

I'll address the excellent points you raised.

Sample-size concerns: Abundance of evidence indicates zero disruption

I totally agree that we need to be cautious about breaking changes, and I'm glad you questioned the sample size. It's a critical point, which is why I combined (1) the empirical data from the sketches with (2) strong domain knowledge.

  • Empirical data: My review of 100 sketches (50 for add(), 50 for mult()) found 0% relied on the non-standard behavior.
  • Domain Knowledge: This 0% finding is what we'd expect. The non-standard behavior is not documented by any reference examples, it has a more writable and readable alternative (v.x += 2), it has no clear use cases, and it is inconsistent with every single major library, across languages and domains—even Processing's PVector does not behave this way.
A more rigorous, Bayesian analysis (for the curious)

For those interested in statistical rigor, this is a textbook case for a beta-binomial model. Given the $0$ observed uses in our $n=50$ sample for add(), and a very generous prior belief that maybe 1 in 1,000 sketches that use add() rely on the nonstandard behavior (0.1%), we can be 97.5% confident that the true usage rate in the wild is, at most, 0.351% (or about 1 in 284 sketches that use add()). It's likely that the true proportion is significantly lower and may well be exactly zero.

This change simplifies documentation

You're also right that this requires a documentation change—thankfully, it's a simplification! The 2.x docs need a significant update anyway. For example, most of the mult() docs are missing.

Adopting standard broadcasting makes the documentation easier because the rules are simpler, they reflect actual usage, and they make the API consistent. Instead of the complicated and incomplete documentation that we have now, we can provide documentation that is so consistent, it's essentially a matter of copying and pasting:

mult():

Multiplies vectors with the same number of elements: createVector(1, 2).mult(2, 3) returns a vector with elements [2, 6]. If a vector is multiplied by a single element like 2, all its elements will be multiplied by 2.

add():

Adds vectors with the same number of elements: createVector(1, 2).add(2, 3) returns a vector with elements [3, 5]. If a vector is added with a single element like 2, all its elements will be added with 2.

And yes, we would absolutely add this to the compatibility README.

The full fix is simple, fast, and removes flawed code

The permanent fix (patching add()/sub() and adding error checks across methods) is extremely simple and more performant.

Simpler Code: The entire implementation is just adapting the simple for loop from mult() and adding an else { FES-error } clause. The error message is simple because the behavior is simple: "The number of elements provided must either be one, or the same as the number of elements in the calling vector."

Better Performance: The current add()/sub() implementations contain unnecessary checks on every single element; these erroneous checks are there because the current system is harder to reason about. Standard broadcasting allows us to delete this flawed code, simplifying the implementation and removing a small performance overhead.

So, the permanent fix is quick to implement (it's just a copy/paste), easy to document, and results in cleaner, faster-running code. This seems like a clear win-win, allowing us to fix the NaN bug permanently and correctly, without adding any significant implementation cost.

Given this, could we seize this opportunity by approving #8159? This would unblock the community to implement the permanent fix right away and seems like the most efficient path forward for everyone.

@ksen0
Copy link
Member

ksen0 commented Oct 31, 2025

Hi all! Thanks for your attention on all this and the various vector topics. Maintainers (@limzykenneth , @perminder-17 , @dave , and I) discussed this and the related threads. I hope that you can understand that we would like to keep this PR narrowly focused on a compatibility fix (not on changing broadcasting policy) to reduce friction migrating 1.x → 2.x.

We're not quite ready to support the standard broadcasting proposal in 2.1. This PR is the last code change in that milestone. We are happy to review all the discussion for standard broadcasting for 2.2 (or any next 2.1.x patches), but for this minor release, it is too last-minute. All those proposals include substantial refactoring; and to the best of my understanding, the proposed fix is not creating the backwards compatibility we're discussing.

Planned scope of this PR, which should "address" rather than "resolve" the issue (plus tests):

  • Mark zero-arg createVector() as deprecated and emit warnings (FES).
  • Add a size-deferral check that sets a vector’s dimensionality on first use and emits the deprecation message — this does not change vector operation logic or implement partial broadcasting.

I also acknowledge @sidwellr’s and @GregStanton's suggestions (adopting the behaviour of add or mult everywhere) as a reasonable targeted options, but these also address broadcasting policy, which we'd like to have more time to consider. For now, we prefer to keep any changes in this PR to address usage of zero-argument vectors only. We then can finish discussion and adopt broadcasting policy with less of a rush for a later release (2.2 or any patch before that) given the 2.1 timeline. I really hope this helps to clarify the reasoning.

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.

[2.0] Stabilize behavior of createVector() with zero arguments

5 participants