Types and constants
How jaala reads a constant against the type of the argument it stands in, and how numbers and text compare and sort.
Every value in jaala is a number or text (or absent, which the host-facing pages cover). A relation’s arguments can have types, and when they do, jaala reads a constant as the type of the argument it stands in.
Declared types ¶
A rule head can declare an argument’s type with ?n: number. That turns a constant written in the query into a value of that type, so "800" in a number argument means the number 800:
And a constant that can’t be read that way is refused, rather than answering nothing:
size(?p, ?n: number) :- loc(?p, ?n);
size(?p, "big") => ?pquery: size's "n" argument cannot be "big" (it holds a number)
deps datasetThe difference matters most when a question comes from a person or a form, where "big" is a mistake you’d want reported. Without the declaration, jaala has no type to check against, and the same question matches no rows without saying why:
size(?p, ?n) :- loc(?p, ?n);
size(?p, "big") => ?pNo rows.
deps datasetA host can declare types on the relations it serves too, which mostly saves you writing them in rules, and a rule’s undeclared arguments pick up types from what its body reads. The facts on this site declare none, which is why the rule here has to.
Numbers and text ¶
Numbers compare by value and text compares as text, which is the usual order for strings:
A number never equals text, so "1" and 1 are different values, and quotes are what make a constant text (#162). That only bites in a column with no declared type. In a typed one, jaala reads both sides as the column’s type: the query’s constants before evaluating, and the source’s facts as it reads them, so a pin a source stored as the number 3 reads as "3" in a pin column, and a count stored as the text "0010" reads as 10 in a number column. Keeping kinds apart is what makes equality consistent: if two values both equal a third, they equal each other, whichever order a join meets them in.
A number and a piece of text have no order between them, so a comparison of one with the other never holds, whichever way round it’s written:
loc(?p, ?n), ?n < "a" => ?pNo rows.
deps datasetWhen a column holds both, the answer still has to come back in one order, so jaala puts every number before every piece of text, numbers by value and text as text:
value(?x) :- loc(_, ?x);
value(?x) :- owner(_, ?x);
value(?x) => ?x| ?x |
|---|
| 100 |
| 150 |
| 200 |
| 250 |
| 300 |
| 400 |
| 800 |
| 900 |
| 1200 |
| 1500 |
| data |
| platform |
| security |
| web |
deps datasetThat order is the same every time, for the same facts and the same query, which is what lets a host compare two answers line by line. The ordering page has the rest of it.
An answer writes a plain number one way, the way Go’s %g would, however the query or the source spelled it. So 1.50 comes back as 1.5, 01 as 1, and 1.0 and 1 are the same row (#148):
limit(?team, 1.50) :- owner(_, ?team);
limit(?team, ?l) => ?team, ?l| ?team | ?l |
|---|---|
| data | 1.5 |
| platform | 1.5 |
| security | 1.5 |
| web | 1.5 |
deps datasetText that says more than the number is kept as the source wrote it. A host storing a voltage as 3.3V with the number 3.3 gets 3.3V back, and so does a query that asked about 3.3, since where two spellings of one number meet, the one saying more wins. A value the host bound with Bind comes back exactly as bound.