Hey,
> OK. I see the "referent" concept is broader than I had thought. They are > not just pointers, but (paraphrasing) expressions awaiting evaluation. The > "referent pattern" is more or less the type of the expression, i.e. the > type of whatever the expression evaluates to. Yes. As I see it. Reference = Referent Pattern + Instruction Patterns + Referents * Referent Pattern = The most specific description possible of the structure of the referents of the reference. * Instruction Patterns = The result of streaming the referents through the instruction. * Referents = The objects pointed to be the reference. Accessing them is a dereference (a manifestation). Why are references more than just pointers to referents? Kuppitz and I are realizing that ?all? database optimization can be understood as techniques to avoid dereferencing. If the reference can tell the VM what to expect from a dereference, then certain instructions can avoid dereferencing the reference. Page 17 of the mm-ADT spec has a summary table of the subsequent subsections that show how foreign keys, schemas, indices, denormalizations, views, pipelines, and aggregations are all just variations on this theme. Now, what I realized today what that there are two types of “referent patterns." * The reference’s referent pattern describes what to expect (locally). // read-oriented * The database’s type pattern describes what is legal (globally). // write-oriented I didn’t have the second and I need it. Enter a type system. We need a way to extend the mm-ADT’s type system. Enter you. > For example, in Haskell > notation: > > sum [1,2,3] :: Int > > Here, "sum [1,2,3]" is the reference. The referent is something which has > yet to be determined (the number 6). We know that the referent's type is > Int, and we can type-check the expression to be verify that it will produce > an Int. Another example: > > fmap (\n -> "number " ++ show n) $ filter (> 1) [1,2,3] :: [String] > > Here, "fmap ... [1,2,3]" is the reference, and the referent is a list of > strings: ["number 2","number 3”]. Bingo. So there are three types of “right hand sides” to an instruction pattern. [instruction pattern]->result pattern (a description of what too expect) [instruction pattern]->result object (the actual result to expect — memoization-style) [instruction pattern]->bytecode (a different computation that should be executed) …where the first is the second given a specific enough pattern ;). That is, so the pattern is so specific that its an explicit object. And the last is something new that I realized this weekend with respects to writing, that might not be necessary…. > Instruction patterns seem like additional "referents" to me, with the > difference that they are applied to objects, and that they are composed of > concrete instructions. Yes. Though not “concrete” instructions, but instruction patterns. For instance, what is a database hash-index over the name-attribute? *person{name:@string, age:@int / // referent pattern [has,name,eq,$x.@string]->*person{name:x, age:@int} } // instruction pattern The concrete instruction [has,name,eq,marko] will match the above instruction pattern and will return a reference to person objects whose name is now known and whose age is still just some integer. > Instruction patterns seem like additional "referents" to me I would argue that referent patterns are actually just instruction patterns as: [value,name]->@string // instruction pattern is the same thing as {name:@string} // referent pattern …I don’t have an ultra-confident reason why references aren’t just instruction patterns, but its related to behavioral differences in reading/writing. More exploration is required. > If a referent is nullary (has some type "a"), an > instruction pattern seems unary (has some type "a->b", consuming an "a" and > producing a "b"). But I need to grok more. Sorta. The semantics of X->Y are: “Given a matching X-instruction executed on the reference’s referents, the result is Y." If Y is sufficient to solve the computation, the VM avoided dereferencing… and this is database optimization in a nutshell. Marko. http://rredux.com > > > On Sun, May 26, 2019 at 6:51 PM Marko Rodriguez <okramma...@gmail.com> > wrote: > >> Hello, >> >>>> [db][get,’people’] // *{name:@string, age:!gt(20)&!lt(33)} >>>> >>>> We have lost information about the “schema.” This is not good as >>>> compile-time write validation is not possible. >>>> >>> >>> So far, I am thinking: yeah, dealing with schema changes can be tricky. >> >> This is not a “schema change” but a greater specification of what the >> referents are. Again, a reference is defined by its referent pattern (and >> instruction patterns). The referent pattern is a description of the current >> instances (referents) while the “schema” is a description of what is legal >> for all instances (referents). Without “schema,” I lose compile-time >> validation. >> >>> I then create a people-key on the db map that maintains a >> person-reference. >>>> >>> >>> OK. I think by people-key you mean the primary key for the person type, >>> i.e. the vertex id. Correct me if I am wrong. >> >> No. db.get(‘people’) is the "people table.” RDBMSs are modeled as a map >> with the keys being the table names and the values being *{:} references to >> maps (i.e. rows). >> >>> I see this as a type plus a constraint. And... you won't be surprised to >>> hear me say this... you express it with a select statement: >>> >>> youngishPeople := σ_{age <= 20 ∧ age >= 33}(people) >> >> Well, type definitions like this won’t happen at runtime. The VM will just >> be able to tell you if the range has been restricted. It won’t create new >> types. But yea, referent patterns are (now) a type plus a constraint. >> Before, they were just constraints and that is why I lost schema >> information at runtime. >> >> Take care, >> Marko. >> >> http://rredux.com >> >>