The basic philosophies are:
* Small is beautiful
* Aim at probabilities (what you are likely to do) not possibilities (edge cases)
* Simple things should be simple
QDL originated as a very high-level, language independent description of algorithms. Eventually it acquired an implementation to help with development. It's first great application was as a server-side scripting tool for Open Authorization servers. There, the protocols are fixed and dictate various information flows, but can be messy to implement. On top of this there any number of special cases are requirements in how the protocol is used. So either
that can be invoked at regular intervals in processing to handle the special cases.
int n = 1000; double[] values = new double[n]; for(int i = 0; i < n; i++){ // Note the trick: You have indices that don't match up to values, so you must // compute them. On top of this, if you divide an integer by and integer in Java, you get // an integer, hence you must divide by 500.0 and on top of it, you want to ensure that it is // a double, so you must append a "d" to force the issue values[i] = Math.acos(Math.sin(i/500.0d -1)); }
values. := acos(sin([-1;1;1/500]));
Yes indeed. That's it. This tells QDL to start at -1 and increment by 1/500 (the expression in the brackets is called a slice). You could even use an alternate slice operator and just specify the number of elements you want.
values. := acos(sin([|-1;1;1000|]));
which tells QDL to make 1000 elements evenly distributed between -1 and 1 inclusive. And what if you needed to do this with higher precision, say to 25 decimal places? In Java you need to switch all of your variables over to BigDecimals and find some libraries that support them. In QDL you just set the precision:
numeric_digits(25)
and re-run the command.
There are many high-level languages that could have been used, such as Java, Python, Ruby etc. Here are the major reasons for using QDL:
On an OAuth server, there are many -- possibly thousands -- of clients. Under OA4MP, which handles identity management and single sign-on, each of these may have imposing institutional uses, restrictions and requirements. So, allowing clients to upload their Java code (OA4MP is written in Java) to the server is a non-starter. QDL behaves very nicely as a security policy langugage.
Unlike SAML, it is a language, because it may require quite specific decision making -- to use SAML would require some way of creating valid SAML on the fly which means eventually creating some other language just for that. Work is a conserved quantity.
As such, most server-side code is quite terse (very good for an administrator to look at and vet before accepting it) and quite easy to write. Most QDL on a server is a couple of lines and implicit looping plus aggregate operations allow a lot to be done by more or less making qualitative statements about the data.
Aggregates, aka stem variables. These are written with a trailing period, hence in QDL, my_variable. is a stem. Basic operations follow the "freshman algebra" paradigm that every operator is linear, i.e. functions are applied to each element. So to take the square root of every element in the above stem, you would just write something like
my_variable. := sqrt(my_variable.);
Once you get the knack of it though, it is very easy to work with data and mostly you tell QDL what you want to happen to your data and it does it. This can immensely streamline what would be large chunks of code in other languages.
A good comparison is in the reference manual with Armstrong numbers. Just search for Armstrong there.
a. := [;10]; // 10 elements, 0,1,...,9 b. := [;4]*2; // 4 elements, values are 0,2,4,6 a.^b.; // raise each element of a. to corresponding power in b. [1,1,16,729]
In this case, since there are only 4 elements, in b., only 4 elements get returned.
The reason for this is quite practical. We could do something like supply missing default values (actually, most languages do), but that would mean that the system is, in essence, generating data. That is a big no-no. If you do an operation on some stems and the result is smaller than you suspect, that tells you straight off the bat your inputs were off.