Hi,

*** This email is primarily for Kuppitz (and Stephen might appreciate the 
general idea — especially the last part). ***

We have 3 types of containers in mm-ADT.

        1. map        -> [:]
        2. list       -> [ ]
        3. ?sequence? -> .*

This #3 thing doesn’t have a name, but its what is iterated by a reference — 
its “the referents.” However, we have been using this “thing” extensively as it 
is how we model the following database structures:

Graph: [db][values,V]      => &vertex*
RDBMS: [db][values,people] => &person*
RDF:   [db][triples]       => &statement*

I’ve been banging my head against the wall all day trying to figure out how to 
write to these #3 things! That is, how will we do:

Graph: add/update/delete vertex
RDBMS: add/update/delete row
RDF:   add/delete statement
...

While I was gardening this afternoon, it struck me! 

        &person* is exactly what it says it is — a reference to zero or more 
person objects.

This isn’t the table! No, its a cursor to the head of a 
sequence/stream/iterator. Its not a “container” — its transient!  A result set.

So then what is the people-table? Its a list! 

Here is the full bytecode to create an mm-ADT RDBMS.

[define,row,map,[(@string,@object)*]]
[define,table,list,[@row*]]
[define,db,map,[(@string:@table)*]]

1. a row extends map with the constraint that all keys must be strings.
2. a table extends list with the constraint that all elements must be rows.
3. a db extends map with the constraint that all keys are strings (table name) 
with values that are tables.

So that is the meta-model. What about a particular instance of an RDBMS? In 
bytecode, here is how you define the people-table and the person-object. 

[define,person,row,[name:@string,age:@int]]
[define,people,table,[@person*]]

Thus, people-table is a list of zero or more person-rows. Now lets CREATE TABLE 
and put me in it: 

[db][insert,[create,people,[[[create,person,[name:marko,age:29]]]]]]

##############################################

Okay. So here is where the fun beings… What is the output signature of the 
following bytecode?

[db][value,people]

Its:

@people

"Whoa! Chill out there cowboy?! So are you saying that when you access the 
people-table, you get back the entire list representation of the table? That 
could be an insane amount of data!?”

To that I say — "yes, you are right, the above bytecode will do that. Its a 
very dangerous piece of bytecode." However, the bytecode below does something 
different…and this is what is going to open a vast new territory for the mm-ADT 
spec:

[db][&value,people] => &people

[&value] is a “get by reference” where [value] is a “get by value”. Why is this 
cool? Well, according to the mm-ADT specification, operations on a reference 
MUST be semantically equivalent to operations on the object itself. Thus, we 
can now read/write/delete the table like any old list!

[db][&value,people][insert,[create,person,[name:josh,age:32]]]

Tada! Appending to the reference will push the append to the database with the 
only data transfer being the &people reference (cheap) fetched and the 
peson-object pushed (basically INSERT INTO people (josh,32)).

#### @stephen: this is where you will get excited. ####

[db][&value,people][has,name,eq,marko]
        => person[name:marko,age:29]

As expected. I got the person-row with name:marko. All this ‘by value’.

Now, let me formally define this new [&value] instruction:

opcode   : &value
arguments: @object,@pattern? 

The optional pattern says: “what aspects of the referents do you want by 
value?” In other words, want do you want to know for certain in the referent 
pattern (it all connects!).

[db][&value,people,@person[age:@int]][has,name,eq,marko]
        => person[name:&string,age:29]

And there you have it. A half populated object. With the @person[age:@int] 
pattern, we are saying, I only want the age-property of the person object by 
value. Everything else, by reference. Thus, if we actually want the name, well, 
we have the reference to go and get it (which is a database call), but if our 
bytecode optimizer is good and we never use the name, well, we only grab the 
data we need! 

You may be thinking, but don’t we need the name for the next instruction: 
[has,NAME,eq,marko]?!  To that I say: “You poor fool. Realize that we have a 
&people and if there is an index on the people table, well 
[has,name,@cop,@string] is an instruction pattern and thus, we are in the 
reference graph! And if we don’t have an index on the people-table, then YES, 
we will need to pull the name by value cause we will be filtering in the 
processor, not the storage system. Its all so self-consistent I can barely 
contain my bowels.

Three problems solved with [&value]

        1. ?sequences? are no longer these weird anonymous data structures. 
They are cursors in the classic database sense.
        2. The same instructions we use for manipulating containers can 
manipulate ‘remote’ containers. (referenced containers)
        3. We can selectively populate only portions of an object with all the 
remaining portions maintaining references.

Its almost too perfect.

Take care,
Marko.

http://rredux.com <http://rredux.com/>




Reply via email to