aboutsummaryrefslogtreecommitdiffstats
path: root/docs/evaluators.org
blob: 1e0d7ccbb1e1fcd63064be83a0556a25c340d63a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#+TITLE: Evaluators

* Position
RNT should supply objects, storage, transactions, and execution
lifecycle, but not directly a sublanguage. That duty is then on the
clients to implement one and register it, using the kernel's
capabilities.

In this context, an evaluator is an RNT object, registered and
selected through the object interface, with a special "evaluator"
protocol. Unlike SQL where the boundaries between execution contexts
of the language is confusing and sometmes non-trivial, a sublanguage
=A= may serve retrieval, =B= may serve DML and DDL while =C= may serve
DML alongside =B=. Nothing arbitrates between B and C; making the
client free to opt for one.

The FOL evaluator is therefore, one of such evaluators that is shipped
alongside RNT for specifically Data Retrieval.

* Capability tags
An evaluator object declares a set of opaque labels — =drl=, =dml=,
=ddl=, =vcs=, or anything a client invents. The registry stores and
indexes them so a client can ask which evaluators declare =dml= and
get back B and C.

* Protocols
Three object components, following the existing =implementation= /
=make= / =from= pattern.

=Protocols.Evaluator= admits programs in string format. Admission
validates a program in the evaluator's own representation (as in:
parses, type checks and does all it requires to validate it) and
yields a handle.

#+begin_src ocaml
  class type implementation = object
    method capabilities : string BatSet.t
    method admit : string -> (Handle.t, condition) result
  end
#+end_src

=Protocols.Program= exposes entry points and an invocation, making a
program reusable, since each invocation carries independent state
based atop of a database view of the world (hash dependent and
isolated).

#+begin_src ocaml
class type implementation = object
  method entry_points : string list
  method invoke :
    entry:string -> bindings:Concepts.Tuple.t -> Runtime.Context.t ->
    (Handle.t, condition) result
end
#+end_src

The returned handle carries a result protocol with =Protocols.Cursor=,
giving it incremental consumption. A successor state and a command
completion are further result protocols, added for DML and DDL
later. It's important to notice that the kernel enumerates result
protocols; it thererfore does not enumerate sublanguages. That is not
to say however that we cannot have a builtin catalog relation
installed and configured by the client that enumerates them (that's a
concern for the future).

* Context
=Runtime.Context.t= supplies the selected database state, handles
(which assume authorization, since we are a capability based system),
cancellation, and resource usage. Evaluators reach kernel resources
*only* through it.

A nested invocation shares state, transaction, cancellation, and
budget, and may be given less authority than its caller. Reads keep
the selected state so that nesting does not need to resolve a branch
tip again, and a successful evaluation and cursor exhaustion never
commit. Commit should be an explicit host operation.

* Composition
Evaluators compose through invocation and result protocols alone. A
DML program written in B may invoke a retrieval program written in A,
consume its cursor, and build a successor state from the tuples. A
retrieval program in A may invoke a procedural relation implemented by
C. Neither evaluator however knows the other's representation. The
caller must establish that the callee's contract meets its needs,
obviously.

* Registration
Registration is made by the client, and in the case of builtins, 
automatically at initialization, just as =Relation= and =Schematics=, 
for example. A foreign registration path is a later concern and is not
designed for here.

Only =Protocols.Cursor= exists as a result protocol (at least for now), 
so a successor state, completion, plan persistence, and cross-evaluator 
optimizations are absent by design.