-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Description
[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
dimensionsdoes not always reflect the true dimensions of the vector. For example,createVector()(with no params) creates a 3D vector[0, 0, 0]but setsdimensionsto 2. Andp5.Vector.sub(createVector(1, 2), createVector(1, 2, 3))will return a 3D vector withdimensionsset 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 than3.
- This API is used by TensorFlow.js. The original motivation for
-
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 aNumberfor vectors and anArrayfor matrices. - This API extends naturally to matrices, tensors, and even scalars (where
.shapewould be[]and.rankwould be0).
- Using an array for
-
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
dimensionswith a.shapeof[3]and a.rankof1provides standard, unambiguous terms for these distinct concepts.
- This API eliminates the confusion around the overloaded term "dimension." A vector like
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:~~[x, y, z] |
.dimensionSize |
3 |
Number |
.dimensionSizes |
[3, 4] |
Array |
|
.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
getsyntax - Reach consensus on the rename
- Implement the rename, if accepted by the community
Edits:
- Added points from @sidwellr.
- Added table to illustrate naming scheme, and clarified its benefits.
- Added task list.
- Reorganized post to reflect community feedback.
Metadata
Metadata
Assignees
Type
Projects
Status