-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP - Add variable relations #37
Conversation
@dkubb Can you give me a short summary why materialized relations need to be mutable? I know this was heavily discussed in channel but I think a summary is more helpful for me. |
@mbj the reason is that most of the datastore based relations work like this: relation.insert([new_tuple])
# the new tuple is available from the same relation
relation.include?(new_tuple) # => true Yet the in-memory relations work like this: relation.insert([new_tuple])
# the new tuple is not available
relation.include?(new_tuple) # => false
# however...
new_relation = relation.insert([new_tuple])
new_relation.include?(new_tuple) # => true This change is an attempt to resolve the inconsistency and make the in-memory materialized relations work the same as the datastore backed relations. |
@solnic does my example above summarize the issue succinctly? |
@dkubb yes this is perfect |
@dkubb Thx for summary. I fully agree now. |
I've been experimenting with a few approaches to handling this and I've settled on making an If anyone is interested I can go into more detail on why I did this rather than simply mutating a materialized relation. Atm I don't have much time to go into it, but I wanted to drop an update on this. |
@dkubb I suspect it's because that's the simplest thing that can possibly work since it's an addition instead of a change, anyhow, worksforme™ |
@dkubb while this surely looks fine for me, i'd love it if you could explain the rationale behind this a bit more in depth. Relation variables are a known concept in RA, and i'd like to hear about the reasoning behind this and how the concept is inline with the implementation. |
@snusnu ok yeah, I'll try to explain it but I haven't yet tried to describe it to anyone out loud so bear with me. And feel free to ask questions if I'm unclear on anything. So to explain this I need to give a bit of backstory first (more than I did above), and then describe the problem I ran into, and then describe why I think this is a good solution. BackstoryLast week I finished up a working version of However, in the I'm so glad @solnic called me out on it, because after thinking about it I don't actually know how it would even be possible to have datastore backed relations work like the memory adapter at all. I don't think it would be possible without doing something crazy and scoping relations by created_at dates or something.. and aside from being brittle, there's no guarantee every relation is going to have that kind of field. Plus that doesn't deal with deletes at all. The most important thing for axiom is that the relations behave the same regardless of what the underlying datastore is. We cannot have relations from axom-memory-adapter having a different interface than axiom-do-adapter relations. Sure, there will be performance differences between each adapter for specific operations, but the interface should not vary. If the interface varies, then we're only slightly better off than if we had custom, optimized interfaces for each datastore. Plus it makes it impossible to build tools to work with axiom, or on top of it, because you could not code to the interface. This made my approach a no-go. Mutable RelationsOne of my first thoughts when faced with this problem is if I made it so mutable materialized relations could be writable. This means when I do With a normal materialized relation, this should work great. I could just make it so the underlying tuples are written to. The tuples are a The problem comes with the second kind of relation we have called More commonly it is the result of passing a relation through other.join(relation - relation) The inner relation statement will always be empty, regardless of what it contains, and joining against an empty relation also cannot return anything so the whole expression can be replaced with an The actual problem comes when you consider how you write to this instance. Doing something like Variable relationsAfter thinking about this problem this afternoon, while cleaning up axiom-optimizer, I thought that maybe delegation might be an elegant answer. I can have something that delegates all the methods to a relation, and uses the return value of Interestingly enough this was basically the first solution I offered to @solnic in IRC. I thought it was more of a quick-fix or a hack, but now I realize it was probably the simplest and most elegant solution to the problem. It's funny how the first thing that came to mind (probably) ended up being what we needed. Final thoughtsAside from attempting to make materialized relations mutable I haven't actually attempted to implement the variable relations idea. I've only thought about this so I could end up being wrong. I have a few strategies to attempt to make this work and I'll report back either way with my findings, even if it doesn't work out so well. |
* This branch will change materialized relations to be mutable
Since I'm adding variable relations, and no longer making materialized relations themselves mutable, and you can't change the branch name of a PR, I'm going to close this PR and open a new one. I'll make sure to link to this discussion for reference. |
This branch will change materialized relations to be mutable
* [ ] AddAxiom::Relation::Variable
proxy* [ ] Ready for review