QDL is an outgrowth of some of the seminal ideas in K. Iverson's work. It is a list (aka array)
processing language.
Merits of such languages are

* loop free, recursion free
* extending operations over lists effectively embeds most common control structures
  in the data --  stems are therefore objects
* partial answer to the "von Neumann bottleneck".
* polymorphism on rank of objects.

There are a couple of different ways to approach this topic. APL had strict conformity on arrays.
J has the ability to box and unbox them, i.e. treat arrays as if they were scalars. Other languages
like Haskell also have some structures. The real issue in all of them is ragged arrays, meaning arrays
of objects that are not uniform. Some reject ragged arrays, some have a lot of work arounds. The
model in QDL is lists of lists and no further structure is assumed.

QDL uses stem variables, which allow ragged arrays, non-integer keys and employs subsetting,
that is to say, operations only apply to common keys between lists. So if a stem is
   a.f0 :='bar';
   a.f1 := 'baz';
   b.f0 := 'bar';
   a. == b.
{f0:true}

Since that is the only common key.

One common issue with APL is if there are missing entries, they may be supplied with a default of 0 or ' '.
In many cases that is reasonable, but some case it introduces errors that are hard to track down. If QDL
returns less than expected, the data was bad going in and you know that up front. Also, to only have corresponding
parts of arrays act on each other sometimes requires a lot of surgery to get the conformity right.

Another point is performance.
To enforce strict structure on arrays means that a lot of information about the arrays has to be tracked and
maintained. QDL does not do that and does not have to. If you interrogate it, it will tell what is there at
the given instant, (e.g. the size() command). Rather than have an expensive system that tracks state, QDL
has expensive interrogation commands. 