Implement joins for queries
One possibility for a join implementation could work as follows:
First a precondition has to be considered: You are only allowed to join objects that have a relation to each other.
I.e. a person may have several e-mail-adresses. A possible join could now be, to load a person from the repository and directly load (join) all e-mail-adresses with the tld ".de" this person has onto the person object. The technical effect would be that the person is not loaded with all her e-mail-adresses but only with the joined ones.
Of course this is conceptually not correct, because the person in fact might have other addresses that would not be there by executing this join query. There are two solutions for this:
1. If you write a join query, you have to be aware that the result is only a part of the truth, meaning there could be more objects in the aggregate you didn't get by your query.
2. All objects you didn't get directly (didn't match the join condition) are lazy loaded if you want to access them at a later point. This would need a lazy loading mechanism that can lazy load collections (array, SplObjectStorage) on a per element basis.
To conclude the whole story. Joins in the object world can be used to reduce the objects that have to be loaded at a time. Meaning they are more like a optimization than a conceptual query construct.