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

Reply via email to