Skip to content

[2.0] Stabilize the undocumented dimensions field of p5.Vector #8155

@GregStanton

Description

@GregStanton

[2.0] Stabilize the undocumented dimensions field of p5.Vector

This issue involves two parts: a bug fix and a new API. I plan to cleanly separate these parts into actionable sub-issues.

Sub-issue 1: Bug fix

Problem

The dimensions field isn't currently documented, but it appears to users when they use the command console.log(myVector), and it may sometimes have inaccurate values, as observed here and here. Thanks to @sidwellr for the following summary:

The gist of the comments linked above is that dimensions does not always reflect the true dimensions of the vector. For example, createVector() (with no params) creates a 3D vector [0, 0, 0] but sets dimensions to 2. And p5.Vector.sub(createVector(1, 2), createVector(1, 2, 3)) will return a 3D vector with dimensions set to 2.

Solution

These bugs should be readily fixable by implementing the property with the JS get syntax, and having the getter retrieve the current, correct value whenever a user accesses it.

Sub-issue 2: A strong API, refined through community discussion

The original API proposal has been withdrawn and can be viewed in the details section further below, for continuity. It's been replaced with a stronger proposal that incorporates community feedback. The new .shape/.rank API would replace dimensions, and would work as follows:

Data structure Proposed read-only property Example value Data type
Vector [x, y, z] .shape [3] Array
Vector [x, y, z] .rank 1 Number
Matrix (3 rows, 4 cols) .shape [3, 4] Array
Matrix (3 rows, 4 cols) .rank 2 Number

Benefits

  • Predictability: Enjoys strong precedents in both math and creative coding
    • This API is used by TensorFlow.js. The original motivation for $n$-dimensional vectors was to provide an onramp to exactly this kind of library.
    • Using an array for the shape of a vector also enjoys a strong precedent in creative coding: babylon.js, a major peer library backed by Microsoft. It uses [3] for the shape of a vector [x, y, z], rather than 3.
  • Consistency and extensibility: Offers type consistency and extends to other classes
    • Using an array for .shape (e.g., [3] for a vector) ensures the property always returns the same data type (Array), unlike a property that might return a Number for vectors and an Array for matrices.
    • This API extends naturally to matrices, tensors, and even scalars (where .shape would be [] and .rank would be 0).
  • Readability: Replace ambiguity with clarity
    • This API eliminates the confusion around the overloaded term "dimension." A vector like [2, 3, 5] might be called "3-dimensional," but as a data structure, it's 1-dimensional (like a list), while a matrix is 2-dimensional.
    • Replacing dimensions with a .shape of [3] and a .rank of 1 provides standard, unambiguous terms for these distinct concepts.
Original, withdrawn renaming proposal for `dimensions` ~~This would likely be a useful feature, with precedent in other libraries, e.g. [babylon.js has `dimension`](https://doc.babylonjs.com/typedoc/interfaces/BABYLON.Tensor#dimension). But, prior to release, it may be renamed to `dimensionSize`, which works better in the context of p5. This name would be clearer, and it'd allow a consistent interface across vectors, matrices, and potentially tensors:~~
Data structure Proposed property Example value Data type
Vector [x, y, z] .dimensionSize 3 Number
Matrix (3 rows, 4 cols) .dimensionSizes [3, 4] Array
Matrix (3 rows, 4 cols) .dimensionCount 2 Number

This naming scheme prevents users from falling into type traps and ambiguity traps, as described in this comment.

Previous note regarding settable properties (this point has been settled)

Writability:
Also, there would need to be discussion about whether to (a) protect this field from modification or (b) support modification, e.g. by padding a vector with zeros or truncating it if needed. Right now, as @sidwellr noted, "users can currently set dimensions to any value, including nonsensical ones like 2.5 and 'frog'."

Update: The shape and rank are derived properties, based on the underlying data. Directly modifying the shape doesn't allow users to specify their intent (e.g. if the new shape is bigger, how should it be filled?). For vectors and matrices, the rank is a property of the class as a whole, so it's not something that should be modified. The standard, user-friendly approach is to provide explicit methods for reshaping and resizing that allow users to clearly specify their intent. The newly proposed .shape/.rank API adheres to this pattern by making these read-only properties.

Tasks

  • Fix bugs with the JS get syntax
  • Reach consensus on the rename
  • Implement the rename, if accepted by the community

Edits:

  1. Added points from @sidwellr.
  2. Added table to illustrate naming scheme, and clarified its benefits.
  3. Added task list.
  4. Reorganized post to reflect community feedback.

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions