shadow skill said:
One suggestion I find worthy of ridicule however is the idea that OO class hierarchies make it easier to describe real world data. Such a suggestion makes little sense given the fact that tables in a relational model are equivalent to a class in an OO language except they do not have mutators and only group data. It is trivial to describe hierarchies with either method, it is however easier to perform dictionary lookup type operations using the relational model conceptually speaking.
Hmm, i wouldn't fully agree with that. IMO, current programming languages as well as databases both make it difficult to work with tree-like hierachies. And that is because the syntax for addressing things is not designed for this. To explain it with something that everyone here knows:
You cannot just anywhere do ".." to go one "directory" up. Same for many other tasks that span multiple nodes. In a programming language, you need to hold it's hand, and tell it where to go, one node at a time. That's because programming languages conceptually do not assume that such trees exist - the way they treat things is more like this:
Code:
Object
-> Pointer1
-> Pointer2
-> Pointer3
This is related to something very fundamental in programming languages: The call syntax. The call syntax is designed, to at any time call a neighbour (pointer) of your current object. Oh sure, we could kludge stuff together, like a linked list, by making the neighbours point to more neighbours, and then pretend, that this created tree-style addressing. It didn't. Sure, it created a tree-like structure.... but calling/addressing conventions did not adapt to this. Perhaps the most convincing sign of this, is that there is no direction: Where's the super? Where the sub? There are no builtin ways to define some pointers as "sub-pointers" and others as "super-pointers" - if you do it, then its pure convention (the GC will thank you for it... not).
And what about this call-thingie? We need to CALL something just to navigate to the next node?????? What on.... we don't need to execute anything, and don't need a return... we just need to follow a ref! A dozen context-switches just to emulate tree-style navigation? Imagine this in a filesystem. Imagine you need to execute a chain of files just to switch to some other directory - what the hell?
Perhaps the closest one can come to intuitive tree-navigation, is via cascaded hashes. That is: linked STRINGS:
Code:
currObject = ["foo"]["bar"]["baz"]
# notice that there's still no way back after executing this
See what we did here? We circumvented the modus operandi of the language, to get what we want. Actually, we circumvented the purpose of the language so much, that now we have *lazy evaluation* in a language that isn't meant to be lazy-evaluated - the compiler will just surrender when seeing this. There is no way he can optimize for such lookups - the language isn't meant to do navigation this way all the time (only exception: lua).
And databases? What are we gonna do there? Create views for everything, resulting in "a-dozen-tables"-joins? Chain queries together, akin to the call-chains in programming languages?
Databases certainly are much better at querying single tables - basically like a hash that has like 5 tokens that can be used as key or value (which can be very useful - damnit, i stopped counting how often i wanted a "super" and "sub" key in hashes). But they - just like programming languages - aren't meant to navigate trees.
Phrased differently (big ontological revelation): Databases consist of table-entities and cell-entities... and cells always are the sub of tables, while tables always are at the root-level. In other words:
That is how much hierachical depth databases support out of the box natively. Two levels. Doesn't that someway seem familiar to something we saw earlier?
We have things, that point "somewhere" to other things. And we have no fucking idea "where in space we are".
How it could be different you ask? What else to do? Well, umm, how about there isn't even a difference between "tables" and "cells"? That is, a cell again is a table that can contain cells? And then imagine being able to navigate by giving complete routes.... so, instead of "enter foo; enter bar; enter baz;" we can just say "foo/bar/baz".
---
Imagine mentally walking the tree for the word "fear." You would have to walk the tree starting from the individual letters of the alphabet until you got to the word emotion which is a superordinate (superclass) of fear and finally get to the definition. Takes too goddamn long to mentally construct the tree, a much simpler operation would be to do a dictionary lookup where the word is the key and the definition is the value. A query language facilitates this naturally when the execution path is not known well ahead of time. When working with a machine.
The funny thing is that - lazy evaluation ignored - this IS how precompiled programming languages internally work anyways. It's called the symbol-table. The only thing standing in the way of lazy-evaluation, is that the original keys are not kept - only the "hashes" (well, in this case just incrementing integers) are kept.
---
That a programmer considers it an advantage to not use a query language shows that he or she doesn't understand the point of such a language which is to allow non programmers to apply their own mental dictionary lookup operation to the machine without having to have knowledge of the implicit tree structure of the information they wish to view.
Agreed. I basically said the same thing earlier when i wrote:
Here, we have "dead" and persistent databases that are good (though, not very flexible) at filtering and addressing information (programming languages don't have this - there ain't no such thing as an sql query for cascaded hashes - and that is a really low bar... they can't even do that). Programming languages know crap about patternmatching - by now, the modern ones are expected to do it with strings - but patternmatching datastructures? You kidding? "Thats what DBs are for"
---
These sorts of suggestions on the part of OODBMS advocates remind me of the suggestion by Python programmers that syntactic indentation is a good thing because it makes programs more readable. This is laughable when you realize that giving a character that is invisible to the human eye meaning is one of the dumbest things a person can do. The human brain doesn't care about white space the subconscious discards white space because our brain is interested in deriving meaning from context more so than structure.
Using whitespace to impart meaning only creates a more error prone language system. It doesn't help the human being who has to write the software become more efficient. It is even worse than the syntactic case sensitivity common to many programming languages.
Heh, ask cib about that. He's currently writing a preproc to "undo" this, along with adding support for "END". There are a lot of good things about python. The support (including docs) is awesome. It is consistent. It has no killer-flaws. But all this comes at the price of a mentality, that is so theoretical and idealistic, that one may almost call it dictatorial.
If ruby were the hippie-camp of folks who are all about fun and flexibility, but as a result getting a chaotic mess and inconsistencies patched by black magic..... then python would be the rightwing camp that is all about consistency and cleanliness, but as a result ending up with something cold, unflexible and ignorant of individual needs. As usual, sanity is strangely absent from the lineup
The other problem people have had with OODBMS' is that referential integrity is difficult to maintain because the unique id of any class object is a generated pointer. Apparently since the object ID is a memory address and not a part of the schema delete operations can break things if other objects still reference the old address. (Hello concurrency hell with pointers!)
I'd be so bold as to claim that this is only fixable cleanly by full-on lazy evaluation. See, CPU-manufacturers and OS-vendors gave us this nice thing called "virtual memory", but they forgot that what we actually need, is not virtual memory-addresses, but instead virtual object identifiers, precisely so that memoryaddresses do no longer matter. Unfortunatelly, x86 being all about backward-compatibility, this is not gonna change - we'll have to do it ourself "on-top" - again.