Index: libcfa/src/containers/array.hfa
===================================================================
--- libcfa/src/containers/array.hfa	(revision 63a4b92a1b215265addfc287907ae92a2316f258)
+++ libcfa/src/containers/array.hfa	(revision b9dae14c8dda6106bfff9679df8e3614bfe25d02)
@@ -5,8 +5,5 @@
 
 // the inverse of Z(-)
-#define z(Zn) sizeof(Zn)
-
-// if you're expecting a Z(n), say so, by asking for a ztype, instead of dtype or otype
-#define ztype(Zn) Zn & | sized(Zn)
+#define z(N) sizeof(N)
 
 forall( T & ) struct tag {};
@@ -19,32 +16,32 @@
 //
 
-forall( ztype(Zn), ztype(S), Timmed &, Tbase & ) {
+forall( [N], [S], Timmed &, Tbase & ) {
     struct arpk {
-        S strides[z(Zn)];
+        S strides[z(N)];
     };
 
-    Timmed & ?[?]( arpk(Zn, S, Timmed, Tbase) & a, ptrdiff_t i ) {
+    Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, ptrdiff_t i ) {
         return (Timmed &) a.strides[i];
     }
 
-    Timmed & ?[?]( arpk(Zn, S, Timmed, Tbase) & a, int i ) {
+    Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, int i ) {
         return (Timmed &) a.strides[i];
     }
 
-    Timmed & ?[?]( arpk(Zn, S, Timmed, Tbase) & a, size_t i ) {
+    Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, size_t i ) {
         return (Timmed &) a.strides[i];
     }
 
-    size_t ?`len( arpk(Zn, S, Timmed, Tbase) & a ) {
-        return z(Zn);
+    size_t ?`len( arpk(N, S, Timmed, Tbase) & a ) {
+        return z(N);
     }
 
     // workaround #226 (and array relevance thereof demonstrated in mike102/otype-slow-ndims.cfa)
-    void ?{}( arpk(Zn, S, Timmed, Tbase) & this ) {
-        void ?{}( S (&inner)[z(Zn)] ) {}
+    void ?{}( arpk(N, S, Timmed, Tbase) & this ) {
+        void ?{}( S (&inner)[z(N)] ) {}
         ?{}(this.strides);
     }
-    void ^?{}( arpk(Zn, S, Timmed, Tbase) & this ) {
-        void ^?{}( S (&inner)[z(Zn)] ) {}
+    void ^?{}( arpk(N, S, Timmed, Tbase) & this ) {
+        void ^?{}( S (&inner)[z(N)] ) {}
         ^?{}(this.strides);
     }
@@ -58,6 +55,6 @@
 Te mkar_( tag(Te) ) {}
 
-forall( ztype(Zn), ZTags ... , Trslt &, Tatom & | { Trslt mkar_( tag(Tatom), ZTags ); } )
-arpk(Zn, Trslt, Trslt, Tatom) mkar_( tag(Tatom), tag(Zn), ZTags ) {}
+forall( [N], ZTags ... , Trslt &, Tatom & | { Trslt mkar_( tag(Tatom), ZTags ); } )
+arpk(N, Trslt, Trslt, Tatom) mkar_( tag(Tatom), tag(N), ZTags ) {}
 
 // based on https://stackoverflow.com/questions/1872220/is-it-possible-to-iterate-over-arguments-in-variadic-macros
@@ -123,15 +120,15 @@
 
 // Base
-forall( ztype(Zq), ztype(Sq), Tbase & )
-tag(arpk(Zq, Sq, Tbase, Tbase)) enq_( tag(Tbase), tag(Zq), tag(Sq), tag(Tbase) ) {}
+forall( [Nq], [Sq], Tbase & )
+tag(arpk(Nq, Sq, Tbase, Tbase)) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(Tbase) ) {}
 
 // Rec
-forall( ztype(Zq), ztype(Sq), ztype(Z), ztype(S), recq &, recr &, Tbase & | { tag(recr) enq_( tag(Tbase), tag(Zq), tag(Sq), tag(recq) ); } )
-tag(arpk(Z, S, recr, Tbase)) enq_( tag(Tbase), tag(Zq), tag(Sq), tag(arpk(Z, S, recq, Tbase)) ) {}
+forall( [Nq], [Sq], [N], [S], recq &, recr &, Tbase & | { tag(recr) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(recq) ); } )
+tag(arpk(N, S, recr, Tbase)) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(arpk(N, S, recq, Tbase)) ) {}
 
 // Wrapper
 struct all_t {} all;
-forall( ztype(Z), ztype(S), Te &, result &, Tbase & | { tag(result) enq_( tag(Tbase), tag(Z), tag(S), tag(Te) ); } )
-result & ?[?]( arpk(Z, S, Te, Tbase) & this, all_t ) {
+forall( [N], [S], Te &, result &, Tbase & | { tag(result) enq_( tag(Tbase), tag(N), tag(S), tag(Te) ); } )
+result & ?[?]( arpk(N, S, Te, Tbase) & this, all_t ) {
     return (result&) this;
 }
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 63a4b92a1b215265addfc287907ae92a2316f258)
+++ src/Parser/DeclarationNode.cc	(revision b9dae14c8dda6106bfff9679df8e3614bfe25d02)
@@ -1076,8 +1076,8 @@
 	if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
 		// otype is internally converted to dtype + otype parameters
-		static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::DStype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::ALtype };
+		static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::DStype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dtype };
 		static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
 		assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
-		TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype, variable.initializer ? variable.initializer->buildType() : nullptr );
+		TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::ALtype, variable.initializer ? variable.initializer->buildType() : nullptr );
 		buildList( variable.assertions, ret->get_assertions() );
 		return ret;
Index: tests/array-container/array-basic.cfa
===================================================================
--- tests/array-container/array-basic.cfa	(revision 63a4b92a1b215265addfc287907ae92a2316f258)
+++ tests/array-container/array-basic.cfa	(revision b9dae14c8dda6106bfff9679df8e3614bfe25d02)
@@ -5,5 +5,5 @@
 //
 
-forall( ztype(Nx), ztype(Ny), ztype(Nz) )
+forall( [Nx], [Ny], [Nz] )
 void typesTest( tag(Nx), tag(Ny), tag(Nz) ) {
 
@@ -59,5 +59,5 @@
 }
 
-forall( ztype(Nw), ztype(Nx), ztype(Ny), ztype(Nz) )
+forall( [Nw], [Nx], [Ny], [Nz] )
 void fillHelloData( array( float, Nw, Nx, Ny, Nz ) & wxyz ) {
     for (w; z(Nw))
@@ -68,5 +68,5 @@
 }
 
-forall( ztype(Zn)
+forall( [Zn]
       , S & | sized(S)
       )
@@ -86,5 +86,5 @@
 }
 
-forall( ztype(Nw), ztype(Nx), ztype(Ny), ztype(Nz) )
+forall( [Nw], [Nx], [Ny], [Nz] )
 void runtimeTest( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
 
Index: tests/array-container/array-md-sbscr-cases.cfa
===================================================================
--- tests/array-container/array-md-sbscr-cases.cfa	(revision 63a4b92a1b215265addfc287907ae92a2316f258)
+++ tests/array-container/array-md-sbscr-cases.cfa	(revision b9dae14c8dda6106bfff9679df8e3614bfe25d02)
@@ -18,5 +18,5 @@
 }
 
-forall( ztype(Nw), ztype(Nx), ztype(Ny), ztype(Nz) )
+forall( [Nw], [Nx], [Ny], [Nz] )
 void fillHelloData( array( float, Nw, Nx, Ny, Nz ) & wxyz ) {
     for (w; z(Nw))
@@ -27,24 +27,6 @@
 }
 
-forall( ztype(Zn)
-      , S & | sized(S)
-      )
-float total1d_low( arpk(Zn, S, float, float ) & a ) {
-    float total = 0.0f;
-    for (i; z(Zn))
-        total += a[i];
-    return total;
-}
-
-forall( A & | ar(A, float) )
-float total1d_hi( A & a ) {
-    float total = 0.0f;
-    for (i; a`len)
-        total += a[i];
-    return total;
-}
-
 // Tests all the ways to split dimensions into CFA-supported chunks, by the only order that C supports: coarsest to finest stride.
-forall( ztype(Nw), ztype(Nx), ztype(Ny), ztype(Nz) )
+forall( [Nw], [Nx], [Ny], [Nz] )
 void test_inOrderSplits( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
 
@@ -96,5 +78,5 @@
 
 // All orders that skip a single dimension, each in its most natural split.
-forall( ztype(Nw), ztype(Nx), ztype(Ny), ztype(Nz) )
+forall( [Nw], [Nx], [Ny], [Nz] )
 void test_skipSingle( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
 
@@ -137,5 +119,5 @@
 // Natural split means the arity of every -[[-,...]] tuple equals the dimensionality of its "this" operand, then that the fewest "all" subscripts are given.
 // The commented-out test code shows cases that don't work.  We wish all the comment-coverd cases worked.
-forall( ztype(Nw), ztype(Nx), ztype(Ny), ztype(Nz) )
+forall( [Nw], [Nx], [Ny], [Nz] )
 void test_latticeCoverage( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
 
@@ -235,5 +217,5 @@
 }
 
-forall( ztype(Nw), ztype(Nx), ztype(Ny), ztype(Nz) )
+forall( [Nw], [Nx], [Ny], [Nz] )
 void test_numSubscrTypeCompatibility( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
 
@@ -282,4 +264,5 @@
     test_skipSingle     ( ztag(KW), ztag(KX), ztag(KY), ztag(KZ) );
     test_latticeCoverage( ztag(KW), ztag(KX), ztag(KY), ztag(KZ) );
+    test_numSubscrTypeCompatibility( ztag(KW), ztag(KX), ztag(KY), ztag(KZ) );
     printf("done\n");
 }
