You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tinkerpop.apache.org by "Christopher Smith (Jira)" <ji...@apache.org> on 2021/01/19 04:12:00 UTC

[jira] [Comment Edited] (TINKERPOP-2502) Consistent start API for anonymous and regular traversals

    [ https://issues.apache.org/jira/browse/TINKERPOP-2502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17267638#comment-17267638 ] 

Christopher Smith edited comment on TINKERPOP-2502 at 1/19/21, 4:11 AM:
------------------------------------------------------------------------

I'm writing what's essentially a mini-OGM for Groovy, to be eventually implemented as a set of compile-time AST transformations to generate the repetitive part of mapping traversals. This is an extension method (in Java) that allows writing {{gts.addV(newPerson, PERSON_WRITER)}} (the logic might look familiar):

{code:java}
@SuppressWarnings("unchecked") // both traversal paths end in a Vertex
public static <V extends HasLabelAndId> GraphTraversal<Vertex, Vertex> addV(GraphTraversalSource self, V entity, VertexWriter<V> writer) {
    // https://stackoverflow.com/a/46053115/1189885
    return self
            .V(entity.getLabelAndId().getId()).fold()
            .coalesce(
                    whenExists(true, unfold()),
                    whenExists(false, writer.createVertex(start(), entity))
            )
            .filter(select("existed").is(false))
            .select("element");
}

private static <A> GraphTraversal<A, Map<String, Object>> whenExists(boolean exists, GraphTraversal<A, ?> gt) {
    return gt.project("element", "existed").by(identity()).by(constant(exists));
}
{code}

However, this method can _only_ be called as {{gts.addV}}; it _cannot_ be called as {{__.addV}}, because there is no common supertype. Furthermore, while in the anonymous case (say, creating multiple vertices with edges between them) I could call {{__.start()}} to get a traversal to feed to the pipeline above, as I do to pass to {{createVertex}}, if I already have a {{GraphTraversalSource}} there's no way to turn it into a {{GraphTraversal}} except through {{V}}, {{E}}, {{addV}}, {{addE}}, or {{inject}} (potentially problematic with some implementations).

Instead, if I had a method such as {{GraphTraversalSource#start()}} with the obvious semantics, I could modify the above method to accept a {{GraphTraversal}}, consume it for both anonymous and regular traversals, and provide sugar to adapt those cases onto it. If I understand the semantics correctly, it would be as simple as cloning the other entry-point methods and dropping the {{addStep}} call.


was (Author: chrylis):
I'm writing what's essentially a mini-OGM for Groovy, to be eventually implemented as a set of compile-time AST transformations to generate the repetitive part of mapping traversals. This is an extension method (in Java) that allows writing {{gts.addV(newPerson, PERSON_WRITER)}} (the logic might look familiar):

{code:java}
@SuppressWarnings("unchecked") // both traversal paths end in a Vertex
public static <V extends HasLabelAndId> GraphTraversal<Vertex, Vertex> addV(GraphTraversalSource self, V entity, VertexWriter<V> writer) {
    // https://stackoverflow.com/a/46053115/1189885
    return self
            .V(entity.getLabelAndId().getId()).fold()
            .coalesce(
                    whenExists(true, unfold()),
                    whenExists(false, writer.createVertex(start(), entity))
            )
            .filter(select("existed").is(false))
            .select("element");
}

private static <A> GraphTraversal<A, Map<String, Object>> whenExists(boolean exists, GraphTraversal<A, ?> gt) {
    return gt.project("element", "existed").by(identity()).by(constant(exists));
}
{code}

However, this method can _only_ be called as {{gts.addV}}; it _cannot_ be called as {{__.addV}}, because there is no common supertype. Furthermore, while in the anonymous case (say, creating multiple vertices with edges between them) I could call {{__.start()}} to get a traversal to feed to the pipeline above, as I do to pass to {{createVertex}}, if I already have a {{GraphTraversalSource}} there's no way to turn it into a {{GraphTraversal}} except through {{V}}, {{E}}, {{addV}}, {{addE}}, or {{inject}} (potentially problematic with some implementations).

Instead, if I had a method such as {{GraphTraversalSource#start()}} with the obvious semantics, I could modify the above method to accept a {{GraphTraversal}}, consume it for both anonymous and regular traversals, and provide sugar to adapt those cases onto it.

> Consistent start API for anonymous and regular traversals
> ---------------------------------------------------------
>
>                 Key: TINKERPOP-2502
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2502
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: process
>    Affects Versions: 3.4.9
>            Reporter: Christopher Smith
>            Priority: Minor
>
> I am writing a graph-based application and am taking advantage of the method-based nature of Gremlin to librarify some of my common usage patterns. However, I'm encountering a frustrating problem where I frequently need to be able to attach the same traversal steps to either a real {{GraphTraversalSource}} or an anonymous traversal (usually for some nested reason like a coalesced conditional insert).
> The methods on {{__}} are mostly static, but I can call {{__.start()}} to obtain a live {{GraphTraversal}} object and then proceed from there (invoking {{GraphTraversal#addV}}, for example). {{GraphTraversalSource}}, however, requires me to invoke the method {{GraphTraversalSource#addV}} to get started, and there's no common base type. I think I could theoretically use something like {{inject()}}, but that seems particularly odd.
> It would be helpful to either have both {{GraphTraversal}} and {{GraphTraversalSource}} implement a common interface holding the "start opcodes" or to have a {{GraphTraversalSource#start()}} method that could be used to obtain a "blank" traversal.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)