I think adhering to the Gremlin-Java interface is a great idea exactly for the reasons that you stated.
The main reason that I didn’t map one-to-one with the native interface is because I wasn’t too sure how to do so, I knew that there was a lot of method overloading which isn’t possible in either of the languages that I wrote this in (Python/PHP), and I figured this approach would be more flexible with regard to changes in the language (to make it TP3 all I had to do was define all of the predicates check for them when they’re passed into functions). The more that I think about it, I think that Gremlinpy’s aim was to be able to write Groovy in Python. That is the main reason why I didn’t choose just straight-up string concatenation — I needed to be able to do things like if clauses or closures or really compounded queries. (In Gizmo, my OGM, I’ve built some pretty dense queries to send to the Gremlin server). Your approach is clearly closer to to Gremlin-Java interface and we should probably use some variant of it going forward. I quickly took that interface and used Gremlinpy to handle all of the processing as seen in this gist: https://gist.github.com/emehrkay/68a9e64789826f6a59e8b5c837dd6ce4 > On Apr 19, 2016, at 10:54 PM, Marko Rodriguez <okramma...@gmail.com> wrote: > > Hi, > > Sweet -- your dev@ mail works now. > >> I think you are on to something with this code example. Gremlinpy does this, >> but a bit differently. It uses Python’s magic methods to dynamically build a >> linked list. >> >> So when you do something like >> >> g = Gremlin() >> g.function() >> >> It creates simply adds an gremlinpy.gremlin.Function object to the queue. >> That object has the parameters to send once the linked list is converted to >> a string. > > Why would you create a queue and not just concatenate a String? > >> Check out the readme for a few more examples (it can do things like add >> pre-defined statements to the chain, nesting Gremlin instances, and manually >> binding params) https://github.com/emehrkay/gremlinpy >> <https://github.com/emehrkay/gremlinpy> > > Ah, parameter bindings. Hmm… > >> I think that a very simple linked list build with a fluid interface and few >> predefined object types may be a good approach to defining a native way to >> represent a Gremlin query. >> >> What do you think? > > It would be really clean if there was GraphTraversalSource, GraphTraversal, > and __ Traversal without any "extra methods." In Gremlinpy README I see lots > of other methods off of "g" that are not Gremlin-Java methods. It would be > cool if it was a direct map of Gremlin-Java (like Gremlin-Groovy and > Gremlin-Scala). Where the only deviations are things like _in(), _as(), etc > and any nifty language tricks like g.V().name or g.V().out()[0:10]. This way, > we instill in the designers that any Gremlin language variant should be > "identical," where (within reason) the docs for Gremlin-Java are just as > useful to Gremlinpy people. Furthermore, by stressing this, we ensure that > variants don't deviate and go down their own syntax/constructs path. For > instance, I see g.v(12) instead of g.V(12). When a Gremlin language variant > wants to do something new, we should argue -- "submit a PR to Gremlin-Java w/ > your desired addition" as Apache's Gremlin-Java should be considered the > standard/idiomatic representation of Gremlin. > > Finally, it would be cool to have a tool that introspected on Gremlin-Java > and verified that Gremlinpy had all the methods implemented. Another thing to > stress to language variant designers -- make sure you are in sync with every > version so write a test case that does such introspection. > > Thoughts?, > Marko. > > http://markorodriguez.com > > > > >> >>> On Apr 19, 2016, at 10:19 PM, Marko Rodriguez <okramma...@gmail.com> wrote: >>> >>> Hello, >>> >>> Okay, so I got into a groove. Here is Python->Gremlin-Groovy(String). This >>> is pure Python -- nothing Jython going on here. >>> >>> https://gist.github.com/okram/4705fed038dde673f4c5323416899992 >>> >>> Here it is in action: >>> >>> # create a traversal source (stupid class name, I know) >>>>>> g = PythonStringGraphTraversalSource("g") >>> >>> # simple warmup >>>>>> g.V().has("name","marko") >>> g.V().has("name", "marko") >>> >>> # one has()-method, but varargs parsing is smart >>>>>> g.V().has("person","name","marko") >>> g.V().has("person", "name", "marko") >>> >>> # strings and numbers mixed >>>>>> g.V().has("person","age",32) >>> g.V().has("person", "age", 32) >>> >>> # nested anonymous traversal >>>>>> g.V().where(out("knows")) >>> g.V().where(__.out("knows")) >>> >>> # as() is reserved in Python, so _as() is used. >>>>>> g.V()._as("a").out("created")._as("b").where(_as("a").out("knows")) >>> g.V().as("a").out("created").as("b").where(__.as("a").out("knows")) >>> >>> # multi-traversal match() >>>>>> g.V().match(_as("a").out("knows")._as("b"), >>>>>> _as("b").out("knows")._as("a")) >>> g.V().match(__.as("a").out("knows").as("b"), >>> __.as("b").out("knows").as("a")) >>> >>> # P-predicates and .name-sugar (attribute access interception) >>>>>> g.V().hasLabel("person").has("age",gt(30)).out("created","knows").name >>> g.V().hasLabel("person").has("age", P.gt(30)).out("created", >>> "knows").values("name") >>> >>> # smart about boolean conversion >>>>>> g.V().valueMap(True,"name","age") >>> g.V().valueMap(true, "name", "age") >>> >>> # lambdas -- ghetto as its not a Python lambda, but a Groovy lambda string >>>>>> g.V().map('it.get().value("name")') >>> g.V().map(it.get().value("name")) >>> >>> What other constructs are there? I think thats it… Everything else from >>> here is just fat fingering in all the methods. Then, from there you use >>> David Brown's GremlinClient (https://github.com/davebshow/gremlinclient) to >>> shuffle the string across the network to GremlinServer and get back >>> results. I suppose there needs to be some sort of .submit() method ? …. >>> hmmm… wondering if .next()/hasNext() iterator methods can be used to submit >>> automagically and then it feels JUST like Gremlin-Java. >>> >>> @Mark: This is what Gremlinpy should do, no? >>> @Dylan: Can you find any Gremlin syntax hole I'm missing that isn't >>> solvable with the current espoused pattern? >>> >>> Good, right? >>> Marko. >>> >>> http://markorodriguez.com >>> >>> On Apr 19, 2016, at 4:51 PM, Marko Rodriguez <okramma...@gmail.com> wrote: >>> >>>> Hi, >>>> >>>> Done for the night. Here is PythonStringGraphTraversal. >>>> >>>> https://gist.github.com/okram/4705fed038dde673f4c5323416899992 >>>> >>>> ??? Cool? >>>> >>>> Marko. >>>> >>>> http://markorodriguez.com >>>> >>>> On Apr 19, 2016, at 4:28 PM, Marko Rodriguez <okramma...@gmail.com> wrote: >>>> >>>>> Hi, >>>>> >>>>> So I "learned" Python and am able to do a Python class wrapper around >>>>> GraphTraversal. >>>>> >>>>> https://gist.github.com/okram/1a0c5f6b65a4b70c558537e5eeaad429 >>>>> >>>>> Its crazy, it "just works" -- with __ static methods and all. >>>>> >>>>> The reason I wanted to create a wrapper is because I want to use >>>>> Python-specific language constructs and not only Gremlin-Java. What those >>>>> specific language constructs are, I don't know as I don't know Python :). >>>>> Moreover, this shell of a wrapper will be used for the JNI and String >>>>> construction models. Right? >>>>> >>>>>>>> g = PythonGraphTraversalSource(graph) >>>>>>>> g >>>>> graphtraversalsource[tinkergraph[vertices:6 edges:6], standard] >>>>>>>> g.V() >>>>> [GraphStep(vertex,[])] >>>>>>>> g.V().toList() >>>>> [v[1], v[2], v[3], v[4], v[5], v[6]] >>>>>>>> g.V().where(__.out("created")).values("name").toList() >>>>> [marko, josh, peter] >>>>>>>> >>>>> >>>>> Even valueMap() which takes var args of different types works. >>>>> >>>>>>>> g.V().valueMap() >>>>> [GraphStep(vertex,[]), PropertyMapStep(value)] >>>>>>>> g.V().valueMap().toList() >>>>> [{name=[marko], age=[29]}, {name=[vadas], age=[27]}, {name=[lop], >>>>> lang=[java]}, {name=[josh], age=[32]}, {name=[ripple], lang=[java]}, >>>>> {name=[peter], age=[35]}] >>>>>>>> g.V().valueMap("name").toList() >>>>> [{name=[marko]}, {name=[vadas]}, {name=[lop]}, {name=[josh]}, >>>>> {name=[ripple]}, {name=[peter]}] >>>>>>>> g.V().valueMap(True,"name").toList() >>>>> [{label=person, name=[marko], id=1}, {label=person, name=[vadas], id=2}, >>>>> {label=software, name=[lop], id=3}, {label=person, name=[josh], id=4}, >>>>> {label=software, name=[ripple], id=5}, {label=person, name=[peter], id=6}] >>>>>>>> >>>>> >>>>> Easy peasy lemon squeezy or is there something fundamental I'm missing? >>>>> >>>>> Marko. >>>>> >>>>> http://markorodriguez.com >>>>> >>>>> On Apr 19, 2016, at 2:58 PM, Marko Rodriguez <okramma...@gmail.com> wrote: >>>>> >>>>>> Hi, >>>>>> >>>>>> So I downloaded and installed Jython 2.7.0. >>>>>> >>>>>> This how easy it was to get Gremlin working in Jython. >>>>>> >>>>>> import sys >>>>>> sys.path.append("/Users/marko/software/tinkerpop/tinkerpop3/gremlin-console/target/apache-gremlin-console-3.2.1-SNAPSHOT-standalone/lib/commons-codec-1.9.jar") >>>>>> sys.path.append("/Users/marko/software/tinkerpop/tinkerpop3/gremlin-console/target/apache-gremlin-console-3.2.1-SNAPSHOT-standalone/lib/commons-configuration-1.10.jar") >>>>>> … lots of jars to add >>>>>> sys.path.append("/Users/marko/software/tinkerpop/tinkerpop3/gremlin-console/target/apache-gremlin-console-3.2.1-SNAPSHOT-standalone/ext/tinkergraph-gremlin/lib/tinkergraph-gremlin-3.2.1-SNAPSHOT.jar") >>>>>> >>>>>> from org.apache.tinkerpop.gremlin.tinkergraph.structure import >>>>>> TinkerFactory >>>>>> graph = TinkerFactory.createModern() >>>>>> g = graph.traversal() >>>>>> g >>>>>> g.V().hasLabel("person").out("knows").out("created") >>>>>> g.V().hasLabel("person").out("knows").out("created").toList() >>>>>> >>>>>> Then, the output looks like this: >>>>>> >>>>>>>>> from org.apache.tinkerpop.gremlin.tinkergraph.structure import >>>>>>>>> TinkerFactory >>>>>>>>> graph = TinkerFactory.createModern() >>>>>>>>> g = graph.traversal() >>>>>>>>> g >>>>>> graphtraversalsource[tinkergraph[vertices:6 edges:6], standard] >>>>>>>>> g.V().hasLabel("person").out("knows").out("created") >>>>>> [GraphStep(vertex,[]), HasStep([~label.eq(person)]), >>>>>> VertexStep(OUT,[knows],vertex), VertexStep(OUT,[created],vertex)] >>>>>>>>> g.V().hasLabel("person").out("knows").out("created").toList() >>>>>> [v[5], v[3]] >>>>>> >>>>>> Note that, of course, Jython's command line doesn't auto-iterate >>>>>> traversals. Besides that -- sheez, that was simple. >>>>>> >>>>>> The trick now is to use Jython idioms to make Gremlin-Jython be >>>>>> comfortable to Python users… >>>>>> >>>>>> Marko. >>>>>> >>>>>> http://markorodriguez.com >>>>>> >>>>>> On Apr 19, 2016, at 11:43 AM, Marko Rodriguez <okramma...@gmail.com> >>>>>> wrote: >>>>>> >>>>>>> Hi, >>>>>>> >>>>>>> So I just pushed: >>>>>>> >>>>>>> https://git1-us-west.apache.org/repos/asf?p=incubator-tinkerpop.git;a=commitdiff;h=0beae616 >>>>>>> >>>>>>> This should help provide the scaffolding for the tutorial. Given that I >>>>>>> know nothing about Python, I think my contributions start to fall off >>>>>>> significantly here. :) … Well, I can help and write more text, I just >>>>>>> don't know how to use Jython, Python idioms, Gremlinpy, etc….. >>>>>>> >>>>>>> @Mark/Dylan: If you want to build the tutorial and look at it, you >>>>>>> simple do: >>>>>>> >>>>>>> $ bin/process-docs.sh --dryRun >>>>>>> >>>>>>> And then for me, the URI to which I point my browser for the index.html >>>>>>> on my local computer is: >>>>>>> >>>>>>> >>>>>>> file:///Users/marko/software/tinkerpop/tinkerpop3/target/docs/htmlsingle/tutorials/gremlin-language-variants/index.html >>>>>>> >>>>>>> Marko. >>>>>>> >>>>>>> http://markorodriguez.com >>>>>>> >>>>>>> On Apr 19, 2016, at 9:16 AM, Marko Rodriguez <okramma...@gmail.com> >>>>>>> wrote: >>>>>>> >>>>>>>> Hello (NOTE: I dropped gremlin-users@), >>>>>>>> >>>>>>>> Thank you Stephen. Its crazy how simple that is :D. >>>>>>>> https://twitter.com/apachetinkerpop/status/722432843360546816 >>>>>>>> >>>>>>>> So Mark, now your fork's TINKERPOP-1232/ branch and >>>>>>>> https://github.com/apache/incubator-tinkerpop/tree/TINKERPOP-1232 >>>>>>>> exist and we can keep them sync'd accordingly as we develop this >>>>>>>> tutorial. When we feel that the tutorial is ready for primetime, we >>>>>>>> will issue a PR to have it merged into tp31/ (and thus, up merged to >>>>>>>> master/). >>>>>>>> >>>>>>>> Where do we go from here? I think this is a good opportunity to work >>>>>>>> both on Gremlinpy and the tutorial. Can we make Gremlinpy as true to >>>>>>>> the spirit of "host language embedding" as possible? In doing so, can >>>>>>>> we explain how we did it so other language providers can learn the >>>>>>>> best practices? >>>>>>>> >>>>>>>> In the tutorial we have 3 models we want to promote: >>>>>>>> >>>>>>>> 1. Jython >>>>>>>> 2. Python JINI >>>>>>>> 3. Python String >>>>>>>> >>>>>>>> (1) is easy to knock off. In fact, we should ask Michael Pollmeier for >>>>>>>> advice here given his work on Gremlin-Scala. (2) -- ?? do you know how >>>>>>>> do this? If so, it should be only fairly more difficult than (1). >>>>>>>> Finally, (3) is the big win and where I think most of the work both in >>>>>>>> the tutorial and in Gremlinpy will happen. >>>>>>>> >>>>>>>> How do you propose we proceed? >>>>>>>> >>>>>>>> Thank you, >>>>>>>> Marko. >>>>>>>> >>>>>>>> http://markorodriguez.com >>>>>>>> >>>>>>>> On Apr 19, 2016, at 8:24 AM, Stephen Mallette <spmalle...@gmail.com> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> ok - done: >>>>>>>>> https://github.com/apache/incubator-tinkerpop/tree/TINKERPOP-1232 >>>>>>>>> >>>>>>>>> On Tue, Apr 19, 2016 at 9:41 AM, Marko Rodriguez >>>>>>>>> <okramma...@gmail.com> wrote: >>>>>>>>> Hello, >>>>>>>>> >>>>>>>>> *** Mark, if you are not on dev@tinkerpop, I would recommend joining >>>>>>>>> that as I will drop gremlin-users@ from communication on this ticket >>>>>>>>> from here on out. *** >>>>>>>>> >>>>>>>>> @Stephen: Mark forked the TinkerPop repository to his GitHub account. >>>>>>>>> I believe he gave you access as well as me. >>>>>>>>> >>>>>>>>> Can you create a new stub tutorial for Mark+Dylan+me? (Moving >>>>>>>>> forward, I will learn how to do it from your one commit). >>>>>>>>> >>>>>>>>> gremlin-language-variants/ >>>>>>>>> >>>>>>>>> After that Mark+Dylan+me will go to town on: >>>>>>>>> https://issues.apache.org/jira/browse/TINKERPOP-1232 >>>>>>>>> >>>>>>>>> Thank you, >>>>>>>>> Marko. >>>>>>>>> >>>>>>>>> http://markorodriguez.com >>>>>>>>> >>>>>>>>> Begin forwarded message: >>>>>>>>> >>>>>>>>>> From: Mark Henderson <nore...@github.com> >>>>>>>>>> Subject: emehrkay added you to incubator-tinkerpop >>>>>>>>>> Date: April 15, 2016 10:04:54 AM MDT >>>>>>>>>> To: "Marko A. Rodriguez" <okramma...@gmail.com> >>>>>>>>>> >>>>>>>>>> You can now push to this repository. >>>>>>>>>> >>>>>>>>>> --- >>>>>>>>>> View it on GitHub: >>>>>>>>>> https://github.com/emehrkay/incubator-tinkerpop >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>> Groups "Gremlin-users" group. >>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>> send an email to gremlin-users+unsubscr...@googlegroups.com. >>>>>>>>> To view this discussion on the web visit >>>>>>>>> https://groups.google.com/d/msgid/gremlin-users/18A7D2FD-B9B1-4DC9-980B-66A6A8F9C7C8%40gmail.com. >>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>> Groups "Gremlin-users" group. >>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>> send an email to gremlin-users+unsubscr...@googlegroups.com. >>>>>>>>> To view this discussion on the web visit >>>>>>>>> https://groups.google.com/d/msgid/gremlin-users/CAA-H43990bN1xrtkL%2BWW4Z%3DKY-bhamBuunpzmYcqVxniyv3NOw%40mail.gmail.com. >>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> >