HI,

For fun, I created a play "toString()” that emits a JSON representation of 
ByteCode.

        
g.V().as("a").out().repeat(both("created")).times(10).as("b").values("name”).range(0,2).select("a",
 "b").by("name”)

becomes —>

[["withComputer",[]],["V",[]],["as",["a"]],["out",[]],["repeat",[[["both",["created"]]]]],["times",[10]],["as",["b"]],["values",["name"]],["range",[0,2]],["select",["a","b"]],["by",["name"]]]

which in “pretty print” JSON is:

[
    [
        "withComputer",
        []
    ],
    [
        "V",
        []
    ],
    [
        "as",
        [
            "a"
        ]
    ],
    [
        "out",
        []
    ],
    [
        "repeat",
        [
            [
                [
                    "both",
                    [
                        "created"
                    ]
                ]
            ]
        ]
    ],
    [
        "times",
        [
            10
        ]
    ],
    [
        "as",
        [
            "b"
        ]
    ],
    [
        "values",
        [
            "name"
        ]
    ],
    [
        "dedup",
        []
    ],
    [
        "select",
        [
            "a",
            "b"
        ]
    ],
    [
        "by",
        [
            "name"
        ]
    ]
]

Which then via gets translated into Python via PythonTranslator as:

g.V().as('a').out().repeat(both('created')).times(10).as('b').name[0,2].select('a','b').by('name’)

Pretty simple…. once we get a standard ?JSON? serialization format for 
ByteCode, then we can simply have one Translator for each Gremlin variant — 
ByteCode -> Gremlin-XXX. What we need to do proper is typing — long, String, 
double, float, P, Order, Lambda, etc. Once that is square we should be good.

Take care,
Marko.

http://markorodriguez.com



On Jul 2, 2016, at 8:04 AM, Marko Rodriguez <[email protected]> wrote:
> 
> Hello,
> 
> So TINKERPOP-1278 (aka “Gremlin-Python”) has introduced the notion of 
> Traversal ByteCode. 
> 
>       
> https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/ByteCode.java
>  
> <https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/ByteCode.java>
> 
> In essence, ByteCode is the construction history of a traversal and is of the 
> form:
> 
>       [string, object*]* // a list of (operator, arguments[])
> 
> The traversal 
> 
> g.V(1).outE(‘created’).inV().
>   repeat(out(‘created’).in(‘created’)).times(5).
>   valueMap(’name’,’age’) 
> 
> has a ByteCode representation as below:
> 
> 
> [
>       [V, 1]
>       [outE, ‘created’]
>       [inV]
>       [repeat, [
>               [out, ‘created’]
>               [in, ‘created’]
>       ]
>       [times, 5]
>       [valueMap, name, age]
> ]
> 
> Again, Gremlin is a simple language based on function concatenation and 
> nesting. Thats all there is to it. Thus, it forms a tree and trees are easy 
> to encode, distribute, serialize, decode, prune/optimize, search, etc. 
> Moreover, every programming language supports function composition and 
> nesting and thus, Gremlin is able to be hosted in any programming language. 
> [http://tinkerpop.apache.org/gremlin.html 
> <http://tinkerpop.apache.org/gremlin.html>]
> 
> The benefit of ByteCode as it applies to TINKERPOP-1278 is that a Translator 
> is able to access the ByteCode of the traversal and then use that 
> linear-nested structure (wide-tree) to generate a traversal representation in 
> another language — e.g. Gremlin-Python, Gremlin-Ruby, Gremlin-JavaScript, 
> etc. 
> 
> Here is the Gremlin-Python translator that will turn ByteCode into 
> Gremlin-Python:
>       
> https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslator.java
>  
> <https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslator.java>
> Here is the Gremlin-Groovy translator that will turn ByteCode into 
> Gremlin-Groovy:
>       
> https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/java/translator/GroovyTranslator.java
>  
> <https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/java/translator/GroovyTranslator.java>
> 
> Pretty simple, eh? So, why would you want Gremlin-Java to translate to 
> Gremlin-Groovy? Well, so you can code in Gremlin-Java and then have it 
> execute on GremlinServer via the GremlinGroovy JSR223 ScriptEngine. However, 
> one can imagine a Gremlin-Java->Gremlin-Java translator! What is that?! Well, 
> it would use reflection (or some more efficient mechanism) to reconstruct the 
> Gremlin-Java traversal from ByteCode generated from Gremlin-Java and thus, 
> the entire cluster/sever infrastructure is simply migrating ByteCode around 
> as opposed to worrying about language specific representation — e.g. it has 
> nothing to do with the JVM! Also, assume a Python-based graph database exists 
> that implements the GreminVM — Gremlin-Java can easily talk to it via 
> ByteCode.
> 
> To ensure ByteCode generation is not costly, here are the runtimes for 
> construction and compilation of a “fairly complex” traversal in both master/ 
> and TINKERPOP-1278/
> 
>       master/
> 
> gremlin> 
> clock(5000){g.V().repeat(out()).times(2).as("a").union(both(),out()).dedup().as("b").select("a","b").identity()
>  }
> ==>0.004184923
> gremlin> 
> clock(5000){g.V().repeat(out()).times(2).as("a").union(both(),out()).dedup().as("b").select("a","b").identity().applyStrategies()
>  }
> ==>0.0264354126
> 
>       TINKERPOP-1278/
> 
> gremlin> 
> clock(5000){g.V().repeat(out()).times(2).as("a").union(both(),out()).dedup().as("b").select("a","b").identity()
>  }
> ==>0.0048526357999999995
> gremlin> 
> clock(5000){g.V().repeat(out()).times(2).as("a").union(both(),out()).dedup().as("b").select("a","b").identity().applyStrategies()
>  }
> ==>0.0245924514
> 
> Finally, there are various entailments that come from this ByteCode 
> representation that have started to surface in my mind:
> 
>       1. We can now optimize at the ByteCode level and not at the step level 
> — ByteCodeStrategies could be a new TraversalStrategy class that comes before 
> DecorationStrategies.
>       2. Gremlin-Java can support bindings so that its Gremlin-Groovy (e.g.) 
> compiled form uses bindings. How? By simply rewriting the ByteCode prior to 
> compilation and replacing values with variables!
>       3. GraphSON can now easily support Traversal serialization — ByteCode 
> in JSON is natural. Gremlin-GraphSON anyone? (get it?)
>               [g, V : [1], outE : [created], inV : repeat : [out : [created], 
> in : [created]], times : 5], valueMap : [name, age]]
> 
> This is what makes Gremlin so powerful — its syntax is crazy simple as its 
> just functions and thus, it can naturally exist in any language — even XML! … 
> ByteCode is what is going to free Gremlin from the JVM…as we are already now 
> on the CPython VM with relative ease:
> 
>       PythonGraphTraversal
>               
> https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-python/src/main/jython/gremlin_python/graph_traversal.py
>  
> <https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-python/src/main/jython/gremlin_python/graph_traversal.py>
>  
>       JythonTranslator (Gremlin-Python to Gremlin-Jython)
>               
> https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-python/src/main/jython/gremlin_python/jython_translator.py
>  
> <https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-python/src/main/jython/gremlin_python/jython_translator.py>
>       GroovyTranslator (Gremlin-Python to Gremlin-Groovy)
>               
> https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-python/src/main/jython/gremlin_python/groovy_translator.py
>  
> <https://github.com/apache/tinkerpop/blob/c34fe9fc2cee8bf231c7d4a2d52e746053273129/gremlin-python/src/main/jython/gremlin_python/groovy_translator.py>
> 
> *** NOTE: I have yet to introduce the ByteCode concepts to gremlin-python/ 
> package so use your imagination when seeing how PythonGraphTraversal will 
> construct ByteCode and the respective translators will translate it. Finally, 
> realize that people can now compile Python ByteCode into Python-based steps 
> and thus, Gremlin can live and execute on the Python VM against Python-based 
> graph systems. Its really that easy (though, lots of work to implement the 30 
> some standard steps in Python). What this means though is that, in the 
> future, Gremlin can just move between languages/VMs … between Python, JVM, 
> Ruby, JavaScript, C, etc.-based graph processing systems. One language, 
> tailored to its host, and agnostic to the underlying virtual machine.
> 
> Enjoy,
> Marko.
> 
> http://markorodriguez.com <http://markorodriguez.com/>
> 
> 
> 

Reply via email to