diff --git a/arr.sml b/arr.sml
index 19ddee1feadd2022ba66fe265690b7c2c0d2ec0e..61a9079ed21fb51737d0efe201399b8db7686d8d 100644
--- a/arr.sml
+++ b/arr.sml
@@ -44,12 +44,30 @@   | apply1(f,Lf(N(x))) = Lf(N(f(x)))
   | apply1(f,Nd(x,y)) = Nd(apply1(f,x),apply1(f,y));
 fun apply2(f,x,y) = raise NYI; (* TODO *)
 fun append(x,a) = Nd(x,a);
-fun index(Lf(STOP),_) = raise Index
-  | index(Lf(x),0w0) = Lf(x)
-  | index(Lf(x),_) = raise Index
-  | index(Nd(x,y),0w0) = x
-  | index(Nd(x,y),i) = index(y,i-0w1)
-  | index(Bx(s,a),i) = index((unbox a),i);
+fun index _ (Lf(STOP)) = raise Index
+  | index 0w0 (Lf(x)) = Lf(x)
+  | index _ (Lf(x)) = raise Index
+  | index 0w0 (Nd(x,y)) = x
+  | index i (Nd(x,y)) = index (i-0w1) y
+  | index i (Bx(s,a)) = index i a;
+fun take _ (Lf(STOP)) = raise Index
+  | take 0w0 a = raise Index
+  | take 0w1 (Lf(x)) = Lf(x)
+  | take 0w1 (Bx(s,a)) = raise NYI (* TODO: implement taking from first axis like dyalog? *)
+  | take 0w1 (Nd(x,y)) = x
+  | take n (Nd(x,y)) = Nd(x,(take (n-0w1) y))
+  | take n (Bx(x,y)) = raise NYI; (* TODO: see above *)
+fun drop _ (Lf(STOP)) = raise Index
+  | drop 0w0 a = a
+  | drop 0w1 (Nd(x,y)) = y
+  | drop n (Nd(x,y)) = drop (n-0w1) y
+  | drop _ (Bx(s,a)) = raise NYI; (* TODO: see notes on boxes on take above *)
+fun reverse (Lf(x)) = Lf(x)
+  | reverse (Bx(s,a)) = Bx(s,a) (* TODO: boxing behaviour might be inconsistent across functions; check/correct asap before you get too deep into it *)
+  | reverse (Nd(x,y)) = Nd((reverse y),x); (* FIXME: this won't work due to the STOP elements - they need to be removed from the implementation if possible, or this needs to be reworked *)
+fun iota 0w0 = raise Index
+  | iota 0w1 = Word(0w0)
+  | iota n = Nd(Word(n-0w1),(iota (n-0w1))); (* TODO: need to reverse at the end; this probably needs to go into a let and then reverse the output at the end *)
 (* fun addD(x,Lf(STOP)) = x (* dyadic add *)
   | addD(Lf(N(x)),Lf(N(y))) = Lf(N(x+y))
   | addD(Nd(x,xs),Lf(N(y))) = Nd(Lf(N(x+y)),add(xs,Lf(N(y)))) (* FIXME: doesn't
