# WTF is this name geg use Iter IntoIter(*), Iter(*) head, drop, map, reduce, zip use Str (Str(*)) use Error (or-fail) use Hashable (Hashable(*)) # COLUMN MAJOR Vector ^e a backing Array e a inst ListLike Vector from-listlike (arr): Vector { backing: arr& } inst Indexable Vector elem-get (self, idx): Array.get(&self.backing, idx) Matrix ^col ^row a backing Array col (Array row a) fn transpose (m Matrix c r a) -> Matrix r c a return Error.todo() fn mult (m Matrix n o a, m' Matrix o p a) -> Matrix n p a return Error.todo() inst ListLike Matrix from-listlike (arr): Matrix { backing: arr& } # make a MatrixIndexer class for Indexable, so I can use both [0][2] and [(0, 2)]? just an idea. # Why have an Iter instance for Vector, but not for Array? # Intent. Most vectors will probably have a size of 3, which is small enough to be passed by value, while Arrays are more used as buffers and can be big (IntoIter takes full values bruv). # Unless we change into-iter to take in pointers, we have to do it like this bruv. VectorIter ^count a backin' Vector count a cur I32 # to match the type of ^count bruh inst IntoIter Vector into-iter (self): VectorIter { backin': self, cur: 0 } inst IntoIter VectorIter into-iter (self): self inst Iter VectorIter next (self Ptr (VectorIter count a)) if self&.cur >= count return None e = (&self&.backin'.backing) Array.get(Mem.i32-size(self&.cur)) self <&.cur= self&.cur + 1 return Just(e) inst Str Vector print-str (self): self Str.print-as-list() chars (self): Error.todo() fn distance-to (v Vector a F64, v' Vector a F64): v zip (v') map(fn Tuple2(l, r): l - r) map(fn x: x * x) reduce(0., fn (v, s): v + s) Math.sqrt() fn map-vector (v Vector a b, fun b -> c) -> Vector a c: { backing: v.backing Array.map-array(fun) } inst Eq Vector eq (l, r): l zip (r) Iter.all(fn ((l, r)): l == r) inst Hashable Vector hash (self): self map(hash) Iter.sum()