Hi,
So here is GroovyTranslator being used with Gremlin-Java to yield a
Gremlin-Groovy traversal.
@Test
public void test() throws Exception {
final GraphTraversalSource g =
TinkerFactory.createModern().traversal().withTranslator(GroovyTranslator.of("g"));
GraphTraversal.Admin<Vertex, Number> t =
g.V().hasLabel("person").out().map(x ->
"it.get().value('name').length()").sum().asAdmin();
System.out.println(t.getStrategies().getStrategy(TranslationStrategy.class).get().getTranslator().getTraversalScript());
System.out.print(t.toList());
}
With the following System.out.println():
g.V().has("~label",P.eq("person")).out().map({it.get().value('name').length()}).sum()
[24]
This is the model where you use the anonymous function infrastructure of the
host languages, but use it like a “Supplier” to generate a String
representation of the lambda for the underlying execution language.
Gremlin-Java scared me the most because of the strong type system, but even
without “sum()”, you can simply typecast your Traversal. This also is only
needed if your lambda step is the final step in the traversal.
Anywho…. seems like this model of host language lambda -> execute language
lambda will work.
*** I also tested it with PythonTranslator and it works as expected too.
Thoughts?,
Marko.
http://markorodriguez.com
> On Jun 16, 2016, at 7:50 AM, Marko Rodriguez <[email protected]> wrote:
>
> BTW: Here is GroovyTranslator for Gremlin-Python.
>
> https://gist.github.com/okram/406157b21371a540d2641f52a4208760
> <https://gist.github.com/okram/406157b21371a540d2641f52a4208760>
>
> Realize that Translator exists as a class in both Java and in Python with
> identical APIs. … and will exist as such in JavaScript, Ruby, etc.
>
> Its really not that complicated to create a Translator. The complication
> exists in XXXTraversal, XXXTraversalSource, and XXXAnonymousTraversal:
> https://gist.github.com/okram/fe6bdfe36b970af73b2bcb9e3cfc5e3d
> <https://gist.github.com/okram/fe6bdfe36b970af73b2bcb9e3cfc5e3d>
> ..but that is written once and used over and over by various translators.
> Moreover, that source code is generated automagically via introspection into
> the Gremlin-Java API.
> https://gist.github.com/okram/88f0ddbd9d0d257d1113b0740260a6b6
> <https://gist.github.com/okram/88f0ddbd9d0d257d1113b0740260a6b6>
>
> Marko.
>
> http://markorodriguez.com <http://markorodriguez.com/>
>
>
>
>> On Jun 16, 2016, at 7:35 AM, Marko Rodriguez <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> Hello,
>>
>>> I think this is generally on the right track as there aren't many other
>>> tracks to get this to work. Is it possible to leave open the option for a
>>> language that is translating into itself (e.g. javascript to javascript) to
>>> have the ability to take a non-string lambda if it is a language that is
>>> capable of inspecting itself to get the string representation of its own
>>> code?
>>
>> Yes. So with Python we can inspect the lambda. Thus, if you are in CPython
>> and want to submit a Gremlin-Python traversal to GremlinServer running
>> Jython, then the PythonTranslator would NOT just evaluate the lambda for a
>> String, but instead would do the following — inspect the lambda for a String:
>>
>> >>> from dill.source import getsource
>> >>> x = lambda a: a + 2
>> >>> x
>> <function <lambda> at 0x10bfe70c8>
>> >>> getsource(x)
>> 'x = lambda a: a + 2\n'
>> >>>
>>
>> Realize that since we have decoupled the “translator” from the “language,”
>> anyone can use Gremlin-Python and write their own translator. That
>> translator can do as they please with each step(args). Thus, CPython->Jython
>> can do as above with lambdas and introspect to get the code string during
>> translation. For Gremlin-Python with GroovyTranslator, the best I have come
>> up with is:
>>
>> >>> g.V().out().map(lambda: "it.get().value('name')")
>> g.V().out().map({it.get().value('name')})
>>
>> Now, another drawback of “the best I have come up with" is that the
>> translator’s target language is showing up in the host language. That is,
>> the traversal above is forced to use a GroovyTranslator and thus is not
>> portable to any other translator. While, if a traversal did NOT have
>> lambdas, you could easily change the translator and everything would just
>> work as expected.
>>
>> Take care,
>> Marko.
>>
>> http://markorodriguez.com <http://markorodriguez.com/>
>>
>>
>>>
>>> On Thu, Jun 16, 2016 at 2:12 AM, Daniel Kuppitz <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>> I wouldn't say that I like it, cause code as a String will always be very
>>>> error prone, but still, it's likely the only way to get lambdas working in
>>>> all language variants. Hence: "cool".
>>>>
>>>> Cheers,
>>>> Daniel
>>>>
>>>>
>>>> On Thu, Jun 16, 2016 at 12:03 AM, Marko Rodriguez <[email protected]
>>>> <mailto:[email protected]>>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> What do people think of this idea:
>>>>>
>>>>> https://gist.github.com/okram/df6a104bde51a4f4f6f0da11f46909d5
>>>>> <https://gist.github.com/okram/df6a104bde51a4f4f6f0da11f46909d5> <
>>>>> https://gist.github.com/okram/df6a104bde51a4f4f6f0da11f46909d5
>>>>> <https://gist.github.com/okram/df6a104bde51a4f4f6f0da11f46909d5>>
>>>>>
>>>>> If you pass a lambda/closure/anonymousFunction/etc. in the respective
>>>>> language (during translation), it calls it to get the string
>>>>> representation. … ?
>>>>>
>>>>> Marko.
>>>>>
>>>>> http://markorodriguez.com <http://markorodriguez.com/>
>>>>>
>>>>>
>>>>>
>>>>>> On Jun 15, 2016, at 10:50 AM, Marko Rodriguez <[email protected]
>>>>>> <mailto:[email protected]>>
>>>>> wrote:
>>>>>>
>>>>>> Hello,
>>>>>>
>>>>>> I think we should introduce an S object. It would stand for Script and
>>>>> would allow you to do:
>>>>>>
>>>>>> S.f(“{ it.length }”)
>>>>>>
>>>>>> Where does this come in handy? Language variants.
>>>>>>
>>>>>> Imagine using gremlin_python that will compile to Gremlin-Groovy for
>>>>> execution at GremlinServer.
>>>>>>
>>>>>> g.V().out(“knows”)[0:2].name.map(f(“{ it.length }”))
>>>>>>
>>>>>> Next, imagine you are in Gremlin-Java and want to submit a traversal to
>>>>> GremlinServer, but it has a lambda. No worries, just use the
>>>>> GroovyTranslator and you have:
>>>>>>
>>>>>> g.V().out(“knows”).limit(2).values(“name”).map(f(“{ it.length
>>>> }”))
>>>>>>
>>>>>> We could also have:
>>>>>>
>>>>>> S.s = supplier
>>>>>> S.c = consumer
>>>>>> S.f = function
>>>>>> S.o = operator
>>>>>>
>>>>>> This gets to the general problem of being able to translate lambdas
>>>>> between different languages as well as being able to send lambdas over
>>>> the
>>>>> wire.
>>>>>>
>>>>>> Thoughts?,
>>>>>> Marko.
>>>>>>
>>>>>> http://markorodriguez.com <http://markorodriguez.com/>
>>>>>> <http://markorodriguez.com/ <http://markorodriguez.com/>>
>