That's a nice article on Jython. I can confirm that the same can be accomplished with PHP. I actually like the script to generate the traversal. It's more effort but is more IDE friendly than using magic methods.
To bounce off of the Python->Gremlin-Groovy(String). How would that work with bindings? For instance how would one write the following groovy script: a = "person";b = "name";c = "marko"; g.V().has(a, b, c); (I think it's important to support multiline queries as the gremlin-server communication overhead is pretty significant) On Wed, Apr 20, 2016 at 12:09 PM, Marko Rodriguez <okramma...@gmail.com> wrote: > Hi, > > Here is a published SNAPSHOT DRAFT of what I have so far for the tutorial. > > http://tinkerpop.apache.org/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/ > > I've asked Ketrina to do a new graphic for this. It will be CrAzY. > > The gremlin-jython.py link is broken as I didn't do a full doc build. Its > here to look at if you are interested: > > https://github.com/apache/incubator-tinkerpop/blob/TINKERPOP-1232/docs/static/resources/gremlin-jython.py > > Marko. > > http://markorodriguez.com > > On Apr 19, 2016, at 10:08 PM, 8trk <mark.hender...@8trk.com> wrote: > > > Ha. That is very cool. You can easily just rewrite that for PHP and > probably Ruby too and have working native interfaces. > > > > I updated my Gist to work with your examples. I had to update Gremlinpy > because I didn’t define __ correctly (thanks! this was a fun challenge). > > > > https://gist.github.com/emehrkay/68a9e64789826f6a59e8b5c837dd6ce4 < > https://gist.github.com/emehrkay/68a9e64789826f6a59e8b5c837dd6ce4> > > > > > >> On Apr 19, 2016, at 11:55 PM, Marko Rodriguez <okramma...@gmail.com> > wrote: > >> > >> Hi, > >> > >>> 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). > >> > >> Check this out. Here is a Groovy script the generates the Python > traversal class. > >> > >> https://gist.github.com/okram/940adc02834a97a7187d3da57cbf3227 > >> - super simple. > >> > >> Thus, no need to fat finger anything in and you know you have every > method implemented. Moreover, every release, just generate the Python class > by running this script in the Gremlin Console. And it just works: > >> > >>>>> g.V().has("name","marko") > >> g.V().has("name", "marko") > >>>>> g.V().has("person","name","marko") > >> g.V().has("person", "name", "marko") > >>>>> g.V().where(out("knows")) > >> g.V().where(__.out("knows")) > >>>>> 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")) > >>>>> 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")) > >>>>> > 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") > >> > >> > >>> 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). > >> > >> Yea, the closures are the hard part. I saw that in Python you can walk > the syntax tree of a closure :) … nasty. > >> > >>> 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 > >> > >> Interesting. See how it does with my auto-code generator. Also, I want > to steal your P, T constructs as I think you do that better in Gremlinpy. > >> > >> Marko. > >> > >> http://markorodriguez.com > >> > >>> > >>> > >>>> 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. > >>>>>>>>>>> > >>>>>>>>>> > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>>> > >>> > >> > > > >