Yes - that's the position from the other thread - i started a new one to catch people's attention and not distract from the cool stuff here on gremlin and python. Anyway, I think that your position to not be concerned with JVM languages makes sense. Those languages can also directly work with RemoteGraph so the need there is lessened.
On Thu, Apr 21, 2016 at 12:59 PM, Marko Rodriguez <okramma...@gmail.com> wrote: > Hi, > > Sorry, I'm getting all confused. I just read the other thread on language > variants! :) "TinkerPop mantained Gremlin Language Variants" > > So I now understand what you are talking about. I think the keyword in > your other email is "base language variant." Apache TinkerPop finds a > simple repeatable/testable pattern for "knocking out" simple language > variants in all the major programming language and we maintain those. > People can then, as you say, extend those with other niceties like how > Gremlin-Scala does operator overloading for its ASCII-art mutation system, > etc. Moreover, I think we can just NOT do this for all the JVM languages > given that these languages can talk to GraphTraversal directly -- thus, the > "base implementation" is just the JVM language itself talking to > GraphTraversal. Thus, I think a good list of languages to target that > outside the JVM are: > > Gremlin-Ruby > Gremlin-Python > Gremlin-PHP > Gremlin-R > > I have competence in Python (as of 48 hours ago) and R. Dylan is good with > PHP. I'm sure someone knows Ruby. > > Too many threads. > > ?, > Marko. > > http://markorodriguez.com > > On Apr 21, 2016, at 10:25 AM, Marko Rodriguez <okramma...@gmail.com> > wrote: > > > Have I ever been serious? … ah, yea, but people already have their own > variants with those names, like, for example, Gremlin-Scala! :D And I don't > think (or maybe I'm wrong) that we want to take in, for example, > Gremlin-Scala into TinkerPop? -- and all the others? ………. gets back to the > TinkerPop2 days when MongoGraph was in our repo. > > > > Marko. > > > > http://markorodriguez.com > > > > On Apr 21, 2016, at 9:55 AM, Stephen Mallette <spmalle...@gmail.com> > wrote: > > > >> ha - i can't tell how serious you are being but i get what you're > saying. > >> it's not really something we can impose anyway. i guess i was thinking > >> ahead a bit and more about any TinkerPop maintained GLVs (getting tired > of > >> typing Gremlin Language Variants) and their naming pattern. > >> > >> On Thu, Apr 21, 2016 at 11:13 AM, Marko Rodriguez <okramma...@gmail.com > > > >> wrote: > >> > >>> Hi, > >>> > >>> One of the problem is, what if someone HATES (like literally is > DISGUSTED > >>> by) Michael's Gremlin-Scala implementation and decides to make their > own? > >>> Should it be called Gremlin-Scala-Cause-I-Hate-Gremlin-Scala? > >>> > >>> Marko. > >>> > >>> http://markorodriguez.com > >>> > >>> On Apr 21, 2016, at 9:10 AM, Stephen Mallette <spmalle...@gmail.com> > >>> wrote: > >>> > >>>> it would be nice if we had some consistency in the community around > >>> naming > >>>> of these things. I think that > >>>> > >>>> gremlin-php > >>>> gremlin-scala > >>>> gremlin-go > >>>> gremlin-python > >>>> gremlin-whatever > >>>> > >>>> should be the official Gremlin Language Variant naming patterns. > That''s > >>>> especially true if the other parallel thread to this has community > >>>> consensus that these things should become TinkerPop maintained > projects. > >>>> > >>>> > >>>> > >>>> On Thu, Apr 21, 2016 at 10:59 AM, Dylan Millikin < > >>> dylan.milli...@gmail.com> > >>>> wrote: > >>>> > >>>>> Hey, gremlin-php being the driver do you mean making some sort of > >>>>> gremlin-php-language library that would then leverage the driver? > >>>>> Any suggestion with naming more than welcome here. > natural-gremlin-php? > >>>>> > >>>>> On Thu, Apr 21, 2016 at 10:52 AM, Marko Rodriguez < > okramma...@gmail.com > >>>> > >>>>> wrote: > >>>>> > >>>>>> Hello, > >>>>>> > >>>>>> So, I had to move the tutorial to 3.2.x+ branch because it uses the > new > >>>>>> TraversalSource API. Thus, the new URL for the DRAFT tutorial is > here: > >>>>>> > >>>>>> > >>>>>> > >>>>> > >>> > http://tinkerpop.apache.org/docs/3.2.1-SNAPSHOT/tutorials/gremlin-language-variants/ > >>>>>> > >>>>>> I think this is near complete. Here are some things I would like to > add > >>>>>> before calling it quits: > >>>>>> > >>>>>> 1. I would like to make a head-nod at least to JINI. I didn't > >>>>> feel > >>>>>> that it was worth going into that model in the tutorial. Most people > >>>>> won't > >>>>>> do that. > >>>>>> 2. I would like to work with Mark to make Gremlinpy > "compliant" > >>>>>> and then promote Gremlinpy at the end. > >>>>>> 3. I would like to work with Dylan to make Gremlin-PHP > >>>>> "compliant" > >>>>>> and then promote Gremlin-PHP at the end. > >>>>>> 4. Any recommendations you may have… ? > >>>>>> > >>>>>> Thank you, > >>>>>> Marko. > >>>>>> > >>>>>> http://markorodriguez.com > >>>>>> > >>>>>> On Apr 20, 2016, at 5:36 PM, Marko Rodriguez <okramma...@gmail.com> > >>>>> wrote: > >>>>>> > >>>>>>> Hello, > >>>>>>> > >>>>>>> I have pure Python talking to GremlinServer now via David Brown's > >>>>>> gremlin-python WebSocket driver. > >>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>> > http://tinkerpop.apache.org/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/#using-python-and-gremlin-server > >>>>>>> > >>>>>>> I haven't updated the text, but you can see the Groovy script that > >>>>>> generates the code. Slicky. > >>>>>>> > >>>>>>> Here it is in action: > >>>>>>> > >>>>>>>>>> execfile("/Users/marko/Desktop/gremlin-python.py") > >>>>>>>>>> g = PythonGraphTraversalSource("g") > >>>>>>>>>> > >>>>> g.V().hasLabel("person").repeat(__.out()).times(2).name[0:2].toList() > >>>>>>> [u'ripple', u'lop'] > >>>>>>>>>> m = > >>>>>> > g.V().hasLabel("person").repeat(__.out()).times(2).name[0:2].toList() > >>>>>>>>>> type(m) > >>>>>>> <type 'list'> > >>>>>>>>>> g.V().out("created").count().toList() > >>>>>>> [4] > >>>>>>>>>> g.V().out("created").groupCount().by("name").toList() > >>>>>>> [{u'ripple': 1, u'lop': 3}] > >>>>>>>>>> > >>>>>>> > >>>>>>> Criznazy, > >>>>>>> Marko. > >>>>>>> > >>>>>>> http://markorodriguez.com > >>>>>>> > >>>>>>> On Apr 20, 2016, at 2:25 PM, Marko Rodriguez <okramma...@gmail.com > > > >>>>>> wrote: > >>>>>>> > >>>>>>>> Hi, > >>>>>>>> > >>>>>>>> I added the pure Python model: > >>>>>>>> > >>>>>>>> > >>>>>> > >>>>> > >>> > http://tinkerpop.apache.org/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/#using-python-and-gremlin-server > >>>>>>>> > >>>>>>>> So this section just ends with a generated String. It would be > neat > >>> to > >>>>>> show David Brown's python driver library submitted that string and > >>>>> getting > >>>>>> back a result set. Anyone have the patience to set up GremlinServer > and > >>>>>> import python driver module and "do the do" ? > >>>>>>>> > >>>>>>>> Also note the section on "Language Drivers vs. Language Variants." > >>>>>>>> > >>>>>> > >>>>> > >>> > http://tinkerpop.apache.org/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/ > >>>>>> (forgot to a href anchor it -- scroll down) > >>>>>>>> > >>>>>>>> Finally, here is the generate gremlin-python.py file. > >>>>>>>> > >>>>>> > >>>>> > >>> > https://github.com/apache/incubator-tinkerpop/blob/TINKERPOP-1232/docs/static/resources/gremlin-python.py > >>>>>>>> > >>>>>>>> Take care, > >>>>>>>> Marko. > >>>>>>>> > >>>>>>>> http://markorodriguez.com > >>>>>>>> > >>>>>>>> On Apr 20, 2016, at 1:20 PM, Marko Rodriguez < > okramma...@gmail.com> > >>>>>> wrote: > >>>>>>>> > >>>>>>>>> Hi Dylan, > >>>>>>>>> > >>>>>>>>>> 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. > >>>>>>>>> > >>>>>>>>> Great. Its still DRAFT so please provide ideas/directions. > >>>>>>>>> > >>>>>>>>>> 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) > >>>>>>>>> > >>>>>>>>> I don't know yet. Perhaps, in Python, you write: > >>>>>>>>> > >>>>>>>>> g.V().has("#a") to denote that you want the #a-string to be a > >>>>> variable > >>>>>> and thus, the compilation is g.V().has(a). Then its up to the > language > >>>>>> driver to determine how bindings are declared. > >>>>>>>>> > >>>>>>>>> Thoughts?, > >>>>>>>>> Marko. > >>>>>>>>> > >>>>>>>>> http://markorodriguez.com > >>>>>>>>> > >>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> 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. > >>>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>> > >>>>>> > >>>>> > >>> > >>> > > > >