[ 
https://issues.apache.org/jira/browse/TINKERPOP3-788?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14717458#comment-14717458
 ] 

Matt Frantz commented on TINKERPOP3-788:
----------------------------------------

I understand pushing things to a DSL, but what is the primitive in which I 
would insert my UDT?  Are we saying that {{Function}} arguments are in play for 
implementing a DSL?

The extensions to {{curry}} which I outlined today in TINKERPOP3-761 include 
cases where the first argument is a {{Function}} in the form of the proposed 
{{Operator}} enum.

https://issues.apache.org/jira/browse/TINKERPOP3-761?focusedCommentId=14715813&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14715813

The use of {{Foo.class}} is sugar for invoking a constructor.  It stands for a 
{{Function}} that accepts arguments that include the traverser value plus any 
positional arguments, and returns an instance of type {{Foo}}.

In a sense, a {{Function}} is sugar for a barrier {{Traversal}} that accepts a 
sequence of traversers (as function arguments) and produces a single traverser.

Here's more about currying:

https://web.archive.org/web/20140714014530/http://hughfdjackson.com/javascript/why-curry-helps

It's a step toward having traversers contain {{Functions}} and even 
{{Traversals}}.  This could be another way to defer execution.  For example, 
suppose there is a {{Function}} class {{Foo}} that accepts three parameters, x, 
y, and z.  You could invoke it all at once like so:

{noformat}
g.V()...as('x')...as('y')...as('z')...select('x').curry(Foo, select('y'), 
select('z'))
{noformat}

Or, you could compose and evaluate it incrementally:

{noformat}
g.V()...as('x').curry(Foo).as('withX')
...as('y').curry(select('withX')).as('withXY')
...as('z').curry(select('withXY'))
{noformat}

Since the traverser could contain the {{Function}} which is incrementally bound 
each time {{curry}} is invoked, you end up with a powerful way to write 
reusable traversals that can be dynamically assembled.

Most generally, the "root" of the {{curry}} call need not be a {{Function}}.  
Instead, it could be a {{Traversal}} to which you feed parameters.  Perhaps 
this is how parameterized traversals are exploited.  {{Function}} would be a 
special case of a {{Traversal}}.  It would mean "code as data" in a sense, 
allowing Gremlin to eat its tail.


> Curry step
> ----------
>
>                 Key: TINKERPOP3-788
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP3-788
>             Project: TinkerPop 3
>          Issue Type: Improvement
>          Components: process
>    Affects Versions: 3.0.0-incubating
>            Reporter: Matt Frantz
>            Assignee: Marko A. Rodriguez
>
> The {{curry}} step would be a way to introduce user-defined types without 
> lambdas.
> {noformat}
> <E2> GraphTraversal<S, E2> curry(Class<? extends E2> c);
> {noformat}
> It would be the equivalent of a {{map}} step that instantiates the class with 
> a single constructor argument provided by the traverser.
> {noformat}
> g.V().curry(MyType.class)
> g.V().<MyType>map{it -> new MyType(it.get())}
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to