1. What does QDL mean?
  2. Philosophy
  3. In a nutshell, how does it work?
  4. Where did QDL come from?
  5. Can you give an example showing QDL vs. another language?
  6. What is the workspace model?
  7. What's the deal with stems? What makes them different from an array?
  8. Why use QDL for server side scripting?
  9. What is the hardest conceptual hurdle in using QDL?
  10. What is subsetting?
What does QDL mean?
It refers to navigational bearings (taken in a regular and precise way and are essential for proper aviation.) It is so easy to code quickly and easily that it also is humorously referred to as "quick and dirty language".



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


In a nutshell, how does it work?
QDL is a functional programming language that works on aggregates. It is a fairly direct outgrowth of Church's λ-calculus and also satisfies the Böhm-Jacopini Theorem, viz., it has the correct control structures to allow structured programming as well, hence is also doubly Turing-complete. Why do that? It can be a pain in the neck in practice to have precisely one way to do everything. (Remember that the promise and curse of Java is that everything is an object?) Therefore, QDL has standard procedural statements (such as for looping, switches, etc.) and such.


Where did QDL come from?

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

  • one is constantly tweaking the server code or
  • one fixes it to run the bare-bone protocol and has a scripting language

that can be invoked at regular intervals in processing to handle the special cases.


Can you give an example showing QDL vs. another language?
An easy one is to fill an array of doubles with acos(sin(x)) for 1,000 values in the range -1 up to, but not including 1. In Java:
                    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));
We can contrast this with QDL:
                    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:


and re-run the command.


What is the workspace model?
The workspace (aka WS) is a basic unit of work organization. It is an interactive shell that allows for managing QDL development. In short, it is QDL's IDE. Workspaces can be saved with their current state as a snapshot, then reloaded. They are also portable, so you can share them with others. This allows you to create a workspace per project and keep everything available. In cases where you may have large gaps in activity (a very common case), you can simply load the workspace for that project and instantly resume what you were doing.


What's the deal with stems? What makes them different from an array?
Stems are generally referred to as an "associative array" whose keys may be strings or integers. If strings only, this is effectively a map. If integers, it is a list. Probably the most interesting thing is that operations are done on aggregates, which renders much of a program’s control structure implicit. You mostly have operators that describe what you want to happen to the data and it just occurs. On top of that, there are functions like query() which let you use JSON Path to interrogate the contents of a stem and the extraction operator, \, which lets you dissect one. A common happenstance is getting some enormous JSON blob and having to dissect it for useful information. QDL makes this quite easy.


Why use QDL for server side scripting?

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.


What is the hardest conceptual hurdle in using QDL?

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.


What is subsetting?
Since operations happen on stems element-wise, operations are only done on corresponding elements with the same index. This means you always will get a (possibly improper) subset of the indices. E.g.
                    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.

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.