 M: matrix4 new-sequence 2drop matrix4 (struct) ; inline
 
 <PRIVATE
+
+: rows ( a -- a1 a2 a3 a4 )
+    rows>> first4 ; inline
+
+:: set-rows ( c1 c2 c3 c4 c -- c )
+    c rows>> :> rows
+    c1 rows set-first
+    c2 rows set-second
+    c3 rows set-third
+    c4 rows set-fourth
+    c ; inline
+
 :: 2map-rows ( a b quot -- c )
     matrix4 (struct) :> c
 
-    a rows>> first  :> a1
-    a rows>> second :> a2
-    a rows>> third  :> a3
-    a rows>> fourth :> a4
-    b rows>> first  :> b1
-    b rows>> second :> b2
-    b rows>> third  :> b3
-    b rows>> fourth :> b4
+    a rows :> a4 :> a3 :> a2 :> a1
+    b rows :> b4 :> b3 :> b2 :> b1
 
-    a1 b1 quot call :> c1
-    a2 b2 quot call :> c2
-    a3 b3 quot call :> c3
-    a4 b4 quot call :> c4
+    a1 b1 quot call
+    a2 b2 quot call
+    a3 b3 quot call
+    a4 b4 quot call
 
-    c1 c rows>> set-first
-    c2 c rows>> set-second
-    c3 c rows>> set-third
-    c4 c rows>> set-fourth
-
-    c ; inline
+    c set-rows ; inline
 
 :: map-rows ( a quot -- c )
     matrix4 (struct) :> c
 
-    a rows>> first  :> a1
-    a rows>> second :> a2
-    a rows>> third  :> a3
-    a rows>> fourth :> a4
+    a rows :> a4 :> a3 :> a2 :> a1
 
-    a1 quot call :> c1
-    a2 quot call :> c2
-    a3 quot call :> c3
-    a4 quot call :> c4
+    a1 quot call
+    a2 quot call
+    a3 quot call
+    a4 quot call
 
-    c1 c rows>> set-first
-    c2 c rows>> set-second
-    c3 c rows>> set-third
-    c4 c rows>> set-fourth
-
-    c ; inline
+    c set-rows ; inline
     
 PRIVATE>
 

    matrix4 (struct) :> c

    factors { t t t f } vmask :> factors'
    factors' { 0 3 3 3 } vshuffle :> c1
    factors' { 3 1 3 3 } vshuffle :> c2
    factors' { 3 3 2 3 } vshuffle :> c3
    float-4{ 0.0 0.0 0.0 1.0 } :> c4

    c1 c rows>> set-first
    c2 c rows>> set-second
    c3 c rows>> set-third
    c4 c rows>> set-fourth

    c ;

: ortho-matrix4 ( factors -- matrix )
    float-4{ 1.0 1.0 1.0 1.0 } swap v/ scale-matrix4 ; inline


    float-4{ 0.0 0.0 0.0 1.0 } :> c4
    { t t t f } offset c4 v? :> offset'

    offset' { 3 3 3 0 } vshuffle { t f f t } vmask
    offset' { 3 3 3 1 } vshuffle { f t f t } vmask
    offset' { 3 3 3 2 } vshuffle { f f t t } vmask
    c4

    c set-rows ;

TYPED:: rotation-matrix4 ( axis: float-4 theta: float -- matrix: matrix4 )
    !   x*x + c*(1.0 - x*x)   x*y*(1.0 - c) - s*z   x*z*(1.0 - c) + s*y   0
