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. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> >