Problem
NDArray accepts an ImmutableMemoryView<T> in its constructor and immediately casts it to MemoryView<T>:
// multik-core/src/commonMain/kotlin/.../data/NDArray.kt:50
public override val data: MemoryView<T> = data as MemoryView<T>
This breaks the MultiArray (read-only) → MutableMultiArray → NDArray hierarchy: any code holding a MultiArray reference can observe mutations through shared backing data. The ImmutableMemoryView parameter type promises immutability that the implementation doesn't honor — analogous to casting List<T> to MutableList<T> internally.
Suggested approach
Either:
- Accept
MemoryView<T> directly in the constructor (the cast already assumes it), making the contract honest; or
- Drop the
MultiArray / MutableMultiArray split and expose an explicit readOnly() wrapper (akin to Collections.unmodifiableList()).
Defensive copies are likely too expensive given Multik's view-based slicing semantics.
Problem
NDArrayaccepts anImmutableMemoryView<T>in its constructor and immediately casts it toMemoryView<T>:This breaks the
MultiArray(read-only) →MutableMultiArray→NDArrayhierarchy: any code holding aMultiArrayreference can observe mutations through shared backing data. TheImmutableMemoryViewparameter type promises immutability that the implementation doesn't honor — analogous to castingList<T>toMutableList<T>internally.Suggested approach
Either:
MemoryView<T>directly in the constructor (the cast already assumes it), making the contract honest; orMultiArray/MutableMultiArraysplit and expose an explicitreadOnly()wrapper (akin toCollections.unmodifiableList()).Defensive copies are likely too expensive given Multik's view-based slicing semantics.