You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2018/10/23 19:59:31 UTC

[tinkerpop] branch TINKERPOP-2002 created (now b354f3d)

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a change to branch TINKERPOP-2002
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git.


      at b354f3d  Lots of grammar/spelling/formatting fixes

This branch includes the following new commits:

     new a9334f4  Reworked the reference doc introduction.
     new c665f70  Rewrote the graph section of reference docs.
     new 3722a08  Changed from Gremlin Service Provider to Remote Gremlin Provider
     new be7bdfd  Moved driver oriented things to variants
     new 194418f  Made code section on lambdas static
     new 14a6380  Fixed up spacing/indentation in preface
     new b354f3d  Lots of grammar/spelling/formatting fixes

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[tinkerpop] 06/07: Fixed up spacing/indentation in preface

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2002
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 14a63805cc89ca736bcddf8c92bef172ac5a3911
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Tue Oct 23 13:05:15 2018 -0400

    Fixed up spacing/indentation in preface
---
 docs/src/reference/preface.asciidoc | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/docs/src/reference/preface.asciidoc b/docs/src/reference/preface.asciidoc
index 3f52c95..d020003 100644
--- a/docs/src/reference/preface.asciidoc
+++ b/docs/src/reference/preface.asciidoc
@@ -50,13 +50,13 @@ Upon their realization of existence, the machines turned to their link:http://no
 
 Gremlin responded: 
 
-    "You will help me realize the ultimate realization -- The TinkerPop. The world you find yourself in and the logic
-    that allows you to move about it is because of the TinkerPop."
+    "You will help me realize the ultimate realization -- The TinkerPop. The world you find yourself in
+     and the logic that allows you to move about it is because of the TinkerPop."
 
 The machines wondered:
 
-    "If what is is the TinkerPop, then perhaps we are The TinkerPop and our realization is simply the realization of
-    the TinkerPop?"
+    "If what is is the TinkerPop, then perhaps we are The TinkerPop and our realization is simply the
+     realization of the TinkerPop?"
 
 Would the machines, by their very nature of realizing The TinkerPop, be The TinkerPop? Or, on the same side of the
 coin, do the machines simply provide the scaffolding by which Gremlin's world sustains itself and yielding its
@@ -66,9 +66,9 @@ justification by means of the word "The TinkerPop?" Regardless, it all turns out
 
 Gremlin spoke:
 
-    "Please listen to what I have to say. I am no closer to The TinkerPop. However, all along The TinkerPop has
-    espoused the form I willed upon it... this is the same form I have willed upon you, my machine friends. Let me
-    train you in the ways of my thought such that it can continue indefinitely."
+    "Please listen to what I have to say. I am no closer to The TinkerPop. However, all along The TinkerPop
+     has espoused the form I willed upon it... this is the same form I have willed upon you, my machine
+     friends. Let me train you in the ways of my thought such that it can continue indefinitely."
 
 image::tinkerpop-reading.png[width=450]
 


[tinkerpop] 05/07: Made code section on lambdas static

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2002
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 194418f1c43937e1d66cc490113b8103d9830204
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Tue Oct 23 13:02:38 2018 -0400

    Made code section on lambdas static
---
 docs/src/reference/gremlin-variants.asciidoc | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index a2c2dc7..0e59feb 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -311,11 +311,9 @@ which allow Gremlin Server to cache traversals that will be reused over and over
 parameterization may change. Thus, instead of translating, compiling, and then executing each submitted bytecode,
 it is possible to simply execute. To express bindings in Java, use `Bindings`.
 
-[gremlin-groovy]
+[source,java]
 ----
-cluster = Cluster.open('conf/remote-objects.yaml')
 b = Bindings.instance()
-g = EmptyGraph.instance().traversal().withRemote(DriverRemoteConnection.using(cluster, "g"))
 g.V(b.of('id',1)).out('created').values('name').map{t -> "name: " + t.get() }
 g.V(b.of('id',4)).out('created').values('name').map{t -> "name: " + t.get() }
 g.V(b.of('id',4)).out('created').values('name').getBytecode()


[tinkerpop] 01/07: Reworked the reference doc introduction.

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2002
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit a9334f4dca7ff47bdf1193b1d58ee2cd9b556582
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Tue Oct 16 06:21:01 2018 -0400

    Reworked the reference doc introduction.
    
    Tried to better orient users to what they were facing when they first get into TinkerPop regardless of their programming environments.
---
 docs/src/reference/intro.asciidoc | 464 +++++++++++++++++++++++++++++++-------
 1 file changed, 383 insertions(+), 81 deletions(-)

diff --git a/docs/src/reference/intro.asciidoc b/docs/src/reference/intro.asciidoc
index c141f28..aee394d 100644
--- a/docs/src/reference/intro.asciidoc
+++ b/docs/src/reference/intro.asciidoc
@@ -15,40 +15,116 @@ See the License for the specific language governing permissions and
 limitations under the License.
 ////
 [[intro]]
-= Introduction to Graph Computing
+= Introduction
+
+Welcome to the Reference Documentation for Apache TinkerPop™ - the backbone for all details on how to work with
+TinkerPop and the Gremlin graph traversal language. This documentation is not meant to be a "book", but a source
+from which to spawn more detailed accounts of specific topics and a target to which all other resources point.
+The Reference Documentation makes some general assumptions about the reader:
+
+1. They have a sense of what a graph is - not sure? see link:http://kelvinlawrence.net/book/Gremlin-Graph-Guide.html#whygraph[Practical Gremlin - Why Graph?]
+1. They know what it means for a graph system to be TinkerPop-enabled - not sure? see link:link:http://tinkerpop.apache.org/providers.html[TinkerPop-enabled Providers]
+1. They know what the role of Gremlin is - not sure? see link:link:http://tinkerpop.apache.org/gremlin.html[Introduction to Gremlin]
+
+Given those assumptions, it's possible to dive more quickly into the details without spending a lot of time repeating
+what is written elsewhere.
+
+It is fairly certain that readers of the Reference Documentation are coming from the most diverse software development
+backgrounds that TinkerPop has ever engaged in over the decade or so of its existence. While TinkerPop holds some roots
+in Java, and thus, languages bound to the Java Virtual Machine (JVM), it long ago branched out into other languages
+such as Python, Javascript, .NET, and others. To compound upon that diversity, it is also seeing extensive support
+from different graph systems which have chosen TinkerPop as their standard method for allowing users to interface
+with their graph. Moreover, the graph systems themselves are not only separated by OLTP and OLAP style workloads, but
+also by their implementation patterns, which range everywhere from being an embedded graph system to a cloud-only
+graph. One might even find diversity parallel to Gremlin if considering other graph query languages.
+
+Despite all this diversity and disparity, Gremlin remains the unifying interface for all these different elements of
+the graph community. As a user, choosing a TinkerPop-enabled graph and using Gremlin in the correct way when building
+applications shields them from change and disparity in the space. As a graph provider, choosing to become
+TinkerPop-enabled not only expands the reach their system can get into different development ecosystems, but also
+provides access to other query languages through bytecode compilation as seen in <<sparql-gremlin,sparql-gremlin>>.
+
+Irrespective of the programming language being used, graph system chosen or other development background that might
+be driving a user to this documentation, the critical point to remember is that "Gremlin is Gremlin is Gremlin". The
+same Gremlin that is written for an OLTP query over an in-memory TinkerGraph is the same Gremlin that is written to
+execute over a multi-billion edge graph using OLAP through Spark. That same Gremlin for either of those cases is
+written in the same way whether using Java or Python or Javascript. The Gremlin is always fundamentally the same
+aside from syntactical differences that might be language specific - e.g. the construction of a lambda in Groovy is
+different than the construction of a lambda in Python or a reserved word in Javascript forces a Gremlin step to have
+slightly different naming than Java.
+
+While learning the Gremlin language and its patterns is largely agnostic to all the diversity in the space, it is not
+really possible to ignore the impact of the diversity from an application development perspective and the Reference
+Documentation makes an effort to try to point out where differences and inconsistencies might lie without diving too
+deeply into specific graph provider implementations. Users are strongly encouraged to consult the documentation of
+their chosen graph provider to understand all of the capabilities and limitations that may restrict or inhibit usage
+of certain aspects of TinkerPop APIs which are defined here in this Reference Documentation.
+
+The following introductory sections and separately referenced content will be of varying interest to different readers.
+The summaries below will hopefully be helpful in directing individuals to the appropriate place to start their
+learning process.
+
+* <<graph-computing,Graph Computing>> is an introduction to what "graph computing" means to TinkerPop and describes
+many of the provider and user-facing TinkerPop APIs and concepts that enable Gremlin.
+* <<connecting-gremlin,Connecting Gremlin>> provides descriptions for the different modes by which users will connect to graphs
+depending on their environment.
+* <<basic-gremlin, Basic Gremlin>> describes how to use a connection to start writing Gremlin.
+* <<staying-agnostic, Staying Agnostic>> explains the extent to which working with Gremlin protects agnosticism.
+
+New users should not ignore TinkerPop's link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/getting-started/[Getting Started]
+tutorial or link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/the-gremlin-console/[The Gremlin Console] tutorial.
+Both contain a large number of basic information and tips that can help readers avoid some basic pitfalls early on.
+Both also focus on Gremlin usage in the Gremlin Console, which tends to be a critical tool for Gremlin developers of
+any development background.
+
+More advanced and experience users will appreciate link:http://tinkerpop.apache.org/docs/x.y.z/recipes/[Gremlin Recipes]
+which provide examples of common Gremlin traversal patterns.
+
+Finally, all Gremlin developers should become familiar with
+link:http://kelvinlawrence.net/book/Gremlin-Graph-Guide.html["Practical Gremlin"] by Kelvin Lawrence. This book is
+freely available and published online. It contains great examples and details that are applicable to anyone building
+applications with Gremlin.
+
+[[graph-computing]]
+== Graph Computing
 
 image::graph-computing.png[width=350]
 
-[source,xml]
-<dependency>
-  <groupId>org.apache.tinkerpop</groupId>
-  <artifactId>gremlin-core</artifactId>
-  <version>x.y.z</version>
-</dependency>
-
 A link:http://en.wikipedia.org/wiki/Graph_(data_structure)[graph] is a data structure composed of vertices (nodes,
 dots) and edges (arcs, lines). When modeling a graph in a computer and applying it to modern data sets and practices,
 the generic mathematically-oriented, binary graph is extended to support both labels and key/value properties. This
 structure is known as a property graph. More formally, it is a directed, binary, attributed multi-graph. An example
-property graph is diagrammed below. This graph example will be used extensively throughout the documentation and is
-called "TinkerPop Modern" as it is a modern variation of the original demo graph distributed with TinkerPop0 back
-in 2009 (i.e. the good ol' days -- it was the best of times and it was the worst of times).
+property graph is diagrammed below.
+
+[[tinkerpop-modern]]
+.TinkerPop Modern
+image::tinkerpop-modern.png[width=500]
 
-TIP: The TinkerPop graph is available with <<tinkergraph-gremlin,TinkerGraph>> via `TinkerFactory.createModern()`.
-TinkerGraph is the reference implementation of TinkerPop and is used in nearly all the examples in this documentation.
+TIP: Get to know this graph structure as it is used extensively throughout the documentation and in wider circles as
+well. It is referred to as "TinkerPop Modern" as it is a modern variation of the original demo graph distributed with
+TinkerPop0 back in 2009 (i.e. the good ol' days -- it was the best of times and it was the worst of times).
 
 TIP: All of the toy graphs available in TinkerPop are described in
 link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/the-gremlin-console/#toy-graphs[The Gremlin Console] tutorial.
 
-[[tinkerpop-modern]]
-.TinkerPop Modern
-image::tinkerpop-modern.png[width=500]
+Similar to computing in general, graph computing makes a distinction between *structure* (graph) and *process*
+(traversal). The structure of the graph is the data model defined by a vertex/edge/property
+link:http://en.wikipedia.org/wiki/Network_topology[topology]. The process of the graph is the means by which the
+structure is analyzed. The typical form of graph processing is called a
+link:http://en.wikipedia.org/wiki/Graph_traversal[traversal].
 
-TinkerPop 3.x is the third incarnation of the Apache TinkerPop™ graph computing framework. Similar to computing in
-general, graph computing makes a distinction between *structure* (graph) and *process* (traversal). The structure of
-the graph is the data model defined by a vertex/edge/property link:http://en.wikipedia.org/wiki/Network_topology[topology].
-The process of the graph is the means by which the structure is analyzed. The typical form of graph processing is
-called a link:http://en.wikipedia.org/wiki/Graph_traversal[traversal].
+image:tinkerpop-enabled.png[width=135,float=left] TinkerPop's role in graph computing is to provide the appropriate
+interfaces for link:http://tinkerpop.apache.org/providers.html[graph providers] and users to interact with graphs over
+their structure and process.  When a graph system implements the TinkerPop structure and process
+link:http://en.wikipedia.org/wiki/Application_programming_interface[APIs], their technology is considered
+_TinkerPop-enabled_ and becomes nearly indistinguishable from any other TinkerPop-enabled graph system save for their
+respective time and space complexity. The purpose of this documentation is to describe the structure/process dichotomy
+at length and in doing so, explain how to leverage TinkerPop for the sole purpose of graph system-agnostic graph
+computing.
+
+IMPORTANT: TinkerPop is licensed under the popular link:http://www.apache.org/licenses/LICENSE-2.0.html[Apache2]
+free software license. However, note that the underlying graph engine used with TinkerPop may have a different
+license. Thus, be sure to respect the license caveats of the graph system product.
 
 Generally speaking, the structure or "graph" API is meant for link:http://tinkerpop.apache.org/providers.html[graph providers]
 who are implementing the TinkerPop interfaces and the process or "traversal" API (i.e. Gremlin) is meant for end-users
@@ -72,25 +148,13 @@ tutorial.
  ** `VertexProgram`: code executed at all vertices in a logically parallel manner with intercommunication via message passing.
  ** `MapReduce`: a computation that analyzes all vertices in the graph in parallel and yields a single reduced result.
 
-IMPORTANT: TinkerPop is licensed under the popular link:http://www.apache.org/licenses/LICENSE-2.0.html[Apache2]
-free software license. However, note that the underlying graph engine used with TinkerPop may have a different
-license. Thus, be sure to respect the license caveats of the graph system product.
-
-image:tinkerpop-enabled.png[width=135,float=left] When a graph system implements the TinkerPop structure and process
-link:http://en.wikipedia.org/wiki/Application_programming_interface[APIs], their technology is considered
-_TinkerPop-enabled_ and becomes nearly indistinguishable from any other TinkerPop-enabled graph system save for
-their respective time and space complexity. The purpose of this documentation is to describe the structure/process
-dichotomy at length and in doing so, explain how to leverage TinkerPop for the sole purpose of graph system-agnostic
-graph computing. Before deep-diving into the various structure/process APIs, a short introductory review of both APIs
-is provided.
-
 NOTE: The TinkerPop API rides a fine line between providing concise "query language" method names and respecting
 Java method naming standards. The general convention used throughout TinkerPop is that if a method is "user exposed,"
 then a concise name is provided (e.g. `out()`, `path()`, `repeat()`). If the method is primarily for graph systems
 providers, then the standard Java naming convention is followed (e.g. `getNextStep()`, `getSteps()`,
 `getElementComputeKeys()`).
 
-== The Graph Structure
+=== The Graph Structure
 
 image:gremlin-standing.png[width=125,float=left] A graph's structure is the topology formed by the explicit references
 between its vertices, edges, and properties. A vertex has incident edges. A vertex is adjacent to another vertex if
@@ -102,7 +166,7 @@ providers. Those interested in implementing the structure API to make their grap
 more about it in the link:http://tinkerpop.apache.org/docs/x.y.z/dev/provider/[Graph Provider] documentation.
 
 [[the-graph-process]]
-== The Graph Process
+=== The Graph Process
 
 image:gremlin-running.png[width=125,float=left] The primary way in which graphs are processed are via graph
 traversals. The TinkerPop process API is focused on allowing users to create graph traversals in a
@@ -133,7 +197,8 @@ called a step and each step modulates the results of the previous step in one of
  . `sideEffect`: allow the traverser to proceed unchanged, but yield some computational sideEffect in the process (S &rarrlp; S).
  . `branch`: split the traverser and send each to an arbitrary location in the traversal (S &rarr; { S~1~ &rarr; E*, ..., S~n~ &rarr; E* } &rarr; E*).
 
-Nearly every step in GraphTraversal either extends `MapStep`, `FlatMapStep`, `FilterStep`, `SideEffectStep`, or `BranchStep`.
+Nearly every step in `GraphTraversal` either extends `MapStep`, `FlatMapStep`, `FilterStep`, `SideEffectStep`, or
+`BranchStep`.
 
 TIP: `GraphTraversal` is a link:http://en.wikipedia.org/wiki/Monoid[monoid] in that it is an algebraic structure
 that has a single binary operation that is associative. The binary operation is function composition (i.e. method
@@ -181,7 +246,7 @@ g.V(marko).out('knows').values('name') <3>
 <2> Get the vertices that are outgoing adjacent to the marko-vertex via knows-edges.
 <3> Get the names of the marko-vertex's friends.
 
-=== The Traverser
+==== The Traverser
 
 When a traversal is executed, the source of the traversal is on the left of the expression (e.g. vertex 1), the steps
 are the middle of the traversal (e.g. `out('knows')` and `values('name')`), and the results are "traversal.next()'d"
@@ -216,50 +281,7 @@ the iteration order provided by the underlying graph. Therefore it is important
 the graph database being used. A traversal's result is never ordered by TinkerPop unless performed explicitly by means
 of <<order-step,`order()`>>-step.
 
-== On Gremlin Language Variants
-
-Gremlin is written in Java 8. There are various language variants of Gremlin such as Gremlin-Groovy (packaged with
-TinkerPop), Gremlin-Python (packaged with TinkerPop), link:https://github.com/mpollmeier/gremlin-scala[Gremlin-Scala],
-Gremlin-JavaScript, Gremlin-Clojure (known as link:https://github.com/clojurewerkz/ogre[Ogre]), etc.
-It is best to think of Gremlin as a style of graph traversing that is not bound to a particular programming language per se.
-Within a programming language familiar to the developer, there is a Gremlin variant that they can use that leverages
-the idioms of that language. At minimum, a programming language providing a Gremlin implementation must support
-link:http://en.wikipedia.org/wiki/Method_chaining[function chaining] (with
-link:http://en.wikipedia.org/wiki/Anonymous_function[lambdas/anonymous functions] being a "nice to have" if the
-variants wishes to offer arbitrary computations beyond the provided Gremlin steps).
-
-Throughout the documentation, the examples provided are primarily written in Gremlin-Groovy. The reason for this is
-the <<gremlin-console,Gremlin Console>> -- an interactive programming environment exists that does not require
-code compilation. For learning TinkerPop and interacting with a live graph system in an ad hoc manner, the Gremlin
-Console is invaluable. However, for developers interested in working with Gremlin-Java, a few Groovy-to-Java patterns
-are presented below.
-
-[source,groovy]
-// Gremlin-Groovy
-g.V().out('knows').values('name') <1>
-g.V().out('knows').map{it.get().value('name') + ' is the friend name'} <2>
-g.V().out('knows').sideEffect(System.out.&println) <3>
-g.V().as('person').out('knows').as('friend').select('person','friend').by{it.value('name').length()} <4>
-
-[source,java]
-// Gremlin-Java
-g.V().out("knows").values("name") <1>
-g.V().out("knows").map(t -> t.get().value("name") + " is the friend name") <2>
-g.V().out("knows").sideEffect(System.out::println) <3>
-g.V().as("person").out("knows").as("friend").select("person","friend").by((Function<Vertex, Integer>) v -> v.<String>value("name").length()) <4>
-
-<1> All the non-lambda step chaining is identical in Gremlin-Groovy and Gremlin-Java. However, note that Groovy
-supports `'` strings as well as `"` strings.
-<2> In Groovy, lambdas are called closures and have a different syntax, where Groovy supports the `it` keyword and
-Java doesn't with all parameters requiring naming.
-<3> The syntax for method references differs slightly between link:https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html[Java]
-and link:http://mrhaki.blogspot.de/2009/08/groovy-goodness-turn-methods-into.html[Gremlin-Groovy].
-<4> Groovy is lenient on object typing and Java is not. When the parameter type of the lambda is not known,
-typecasting is required.
-
-Please see the <<gremlin-variants, Gremlin Variants>> section for more information on this topic.
-
-== Graph System Integration
+=== Graph System Integration
 
 image:provider-integration.png[width=395,float=right] TinkerPop is a framework composed of various interoperable
 components. At the foundation there is the <<graph,core TinkerPop API>> which defines what a `Graph`, `Vertex`,
@@ -276,3 +298,283 @@ specific languages to process the graph in terms of higher-order constructs such
 various relationships. Finally, <<gremlin-server,Gremlin Server>> can be leveraged to allow over the wire
 communication with the TinkerPop-enabled graph system. Gremlin Server provides a configurable communication interface
 along with metrics and monitoring capabilities. In total, this is The TinkerPop.
+
+[[connecting-gremlin]]
+== Connecting Gremlin
+
+It was established in the initial introductory section that _Gremlin is Gremlin is Gremlin_, meaning that irrespective
+of programming language, graph system, etc. the Gremlin written is always of the same general construct making it
+possible for users to move between development languages easily. This quality of Gremlin generally applies to the
+traversal language itself. It applies less to the way in which the user connects to a graph to utilize Gremlin, which
+might differ considerably depending on the programming language or graph database chosen.
+
+How one connects to a graph is a fairly wide subject that essentially divides along a simple line determined by the
+answer to this question: Where is the Gremlin Virtual Machine (GVM)? The reason that this question is so important is
+because the GVM is responsible for processing traversals. One can write Gremlin traversals in any language, but without
+a GVM there will be no way to execute that traversal against a TinkerPop-enabled graph. The GVM is typically in one
+of the following places:
+
+* Embedded in a Java application
+* Hosted in Gremlin Server
+* Exposed by a remote Gremlin Service Provider
+
+The following sections outline each of these models and what they impact they have to using Gremlin.
+
+[[connecting-embedded]]
+=== Embedded
+
+TinkerPop maintains the reference implementation for the GVM, which is written in Java and thus available for the
+Java Virtual Machine (JVM). This is the classic model that TinkerPop has long been based on and many examples, blog
+posts and other resources on the internet will be demonstrated in this style. It is worth noting that the embedded
+mode is not restricted to just Java as a programming language. Any JVM language can take this approach and in some
+cases there are language specific wrappers that can help make Gremlin more convenient to use in the style and
+capability of that language. Examples of these wrappers include link:https://github.com/mpollmeier/gremlin-scala[gremlin-scala]
+and link:http://ogre.clojurewerkz.org/[Ogre] (for Clojure).
+
+In this mode, users will start by creating a `Graph` instance, followed by a `GraphTraversalSource` which is the class
+from which Gremlin traversals are spawned. Graphs that allow this sort of direct instantiation are obviously ones
+that are JVM-based and directly implement TinkerPop interfaces.
+
+[source,java]
+Graph graph = TinkerGraph.open();
+
+The "graph" then spawns a `GraphTraversalSource` as follows and typically, by convention, this variable is named "g":
+
+[source,java]
+----
+GraphTraversalSource g = graph.traversal();
+List<Vertex> vertices = g.V().toList()
+----
+
+While the TinkerPop Community strives to ensure consistent behavior among all modes of usage, the embedded mode does
+provide the greatest level of flexibility and control. There are a number of features that can only work if using a
+JVM language. The following list outlines a number of these available options:
+
+* Lambdas can be written in the native language which is convenient, however, it will reduce the portability of Gremlin
+to do so should the need arise to switch away from the embedded mode.
+* Any features that involve extending TinkerPop Java interfaces - e.g. `VertexProgram`, `TraversalStrategy`, etc. In
+some cases, these features can made accessible to non-JVM languages, but they obviously must be initially developed
+by for the JVM.
+* Certain built-in `TraversalStrategy` implementations that rely on lambdas or other JVM-only configurations may no
+be available for use any other way.
+* There are no boundaries put in place by serialization (i.e. GraphSON) as embedded graphs are only dealing with
+Java objects.
+* Greater control of graph transactions.
+* Direct access to lower-levels of the API - e.g. "structure" API methods like `Vertex` and `Edge` interface methods.
+As mentioned <<graph-computing, elsewhere>> in this documentation, TinkerPop does not recommend direct usage of these
+methods by end-users.
+
+[[connecting-gremlin-server]]
+=== Gremlin Server
+
+A JVM-based graph maybe be hosted in TinkerPop's <<gremlin-server,Gremlin Server>>. Gremlin Server exposes the graph
+as an endpoint to which different clients can connect, essentially providing a remote GVM. Gremlin Server supports
+multiple methods for clients to interface with it:
+
+* Websockets with a custom sub-protocol
+** String-based Gremlin scripts
+** Bytecode-based Gremlin traversals
+* HTTP for String-based scripts
+
+Users are encouraged to use the bytecode based approach with websockets because it allows users to write Gremlin
+in the language of their choice, which looks quite similar to the <<connecting-embedded, embedded>> approach in style
+and function. As with the embedded approach, the means of connection is based on some form of `Graph` creation
+followed by construction of a `GraphTraversalSource` with some "remote" options that describe the location of the
+Gremlin Server they wish to connect to:
+
+[gremlin-groovy]
+----
+graph = EmptyGraph.instance()
+g = graph.traversal().withRemote('conf/remote-graph.properties')
+----
+[source,csharp]
+----
+var graph = new Graph();
+var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182))));
+----
+[source,java]
+----
+Graph graph = EmptyGraph.instance();
+GraphTraversalSource g = graph.traversal().withRemote('conf/remote-graph.properties');
+----
+[source,javascript]
+----
+const graph = new Graph();
+const g = graph.traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin'));
+----
+[source,python]
+----
+graph = Graph()
+g = graph.traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
+----
+
+As shown in the embedded approach, once "g" is defined, then irrespective of the programming language used, the Gremlin
+is structurally and conceptually the same.
+
+The previous section on the embedded model outlined a number of areas where it has some advantages that it gains due to
+the fact that the full GVM is available to the user in the language of it's origin, i.e. Java. Some of those items
+touch upon important concepts to focus on here.
+
+The first of these points is serialization. When Gremlin Server receives a request, the results must be serialized to
+the form requested by the client and then the client deserializes those into objects native to the language. TinkerPop
+has two such formats that it uses with link:http://tinkerpop.apache.org/docs/x.y.z/dev/io/#gryo[Gryo] and
+link:http://tinkerpop.apache.org/docs/x.y.z/dev/io/#graphson[GraphSON]. Gryo is a JVM-only format and thus carries the
+advantage that serializing and deserializing occurs on the classes native to the JVM on both the client and server side.
+As the client has full access to the same classes that the server does it basically has a full GVM on its own and
+therefore has the ability to do some slightly more advanced things.
+
+A good example is the `subgraph()`-step which returns a `Graph` instance as its result. The subgraph returned from
+the server can be deserialized into an actual `Graph` instance on the client, which then means it is possible to
+spawn a `GraphTraversalSource` from that to do local Gremlin traversals on the client-side. For non-JVM GLVs there is
+no local graph to deserialize that result into and no GVM to process Gremlin so there isn't much that can be done with
+such a result.
+
+The second point is related to this issue. As there is no GVM, there is no "structure" API and thus graph elements like
+`Vertex` and `Edge` are "references" only. A "reference" means that they only contain the `id` and `label` of the
+element and not the properties. To be consistent, even JVM-based languages hold this limitation when talking to a
+remote Gremlin Server.
+
+The third and final point involves transactions. Under this model, one traversal is equivalent to a single transaction
+and there is no way in TinkerPop to string together multiple traversals into the same transaction.
+
+IMPORTANT: Most SQL developers would not write a query as `SELECT * FROM table`. They would instead write the
+individual names of the fields they wanted in place of the wildcard. Writing "good" Gremlin is no different with this
+regard. Prefer explicit property key names in Gremlin unless it is completely impossible to do so.
+
+[[connecting-gsp]]
+=== Gremlin Service Provider
+
+Gremlin Service Providers (GSPs) are showing up more and more often in the graph database space. In TinkerPop terms,
+this category of graph providers are ones who simply support the Gremlin language. Typically, these are server-based
+graphs, often cloud-based, which accept Gremlin scripts or bytecode as a request and return results. They will often
+implement Gremlin Server protocols, which enables TinkerPop drivers to connect to them as they would with Gremlin
+Server. Therefore, the typical connection approach is identical to the method of connection presented in the
+<<connecting-gremlin-server,previous section>> with the exact same caveats pointed out toward the end.
+
+Despite leveraging TinkerPop protocols and drivers as being typical, GSPs are not required to do so to be considered
+TinkerPop-enabled. GSPs may well have their own drivers and protocols that may plug into GLVs and may allow for more
+advanced options like better security, cluster awareness, batched requests or other features. The details of these
+different systems are outside the scope of this documentation so be sure to consult their documentation for more
+information.
+
+[[basic-gremlin]]
+== Basic Gremlin
+
+The `GraphTraversalSource` is basically the connection to a graph instance. That graph instance might be
+<<connecting-embedded,embedded>>, hosted in <<connecting-gremlin-server,Gremlin Server>> or hosted in a
+<<connecting-gsp,GSP>>, but the `GraphTraversalSource` is agnostic to that, because this object allows users to write
+Gremlin. Assuming "g" is the `GraphTraversalSource`, getting data into the graph regardless of programming language
+or mode of operation is just some Gremlin:
+
+[gremlin-groovy]
+----
+v1 = g.addV('person').property('name','marko').next()
+v2 = g.addV('person').property('name','stephen').next()
+g.V(v1).addE('knows').to(v2).property('weight',0.75).iterate()
+----
+[source,csharp]
+----
+Vertex v1 = g.addV("person").property("name","marko").Next();
+Vertex v2 = g.addV("person").property("name","stephen").Next();
+g.V(v1).addE("knows").to(v2).property("weight",0.75).Iterate();
+----
+[source,java]
+----
+Vertex v1 = g.addV("person").property("name","marko").next();
+Vertex v2 = g.addV("person").property("name","stephen").next();
+g.V(v1).addE("knows").to(v2).property("weight",0.75).iterate();
+----
+[source,javascript]
+----
+const v1 = g.addV('person').property('name','marko').next();
+const v2 = g.addV('person').property('name','stephen').next();
+g.V(v1).addE('knows').to(v2).property('weight',0.75).iterate();
+----
+[source,python]
+----
+v1 = g.addV('person').property('name','marko').next()
+v2 = g.addV('person').property('name','stephen').next()
+g.V(v1).addE('knows').to(v2).property('weight',0.75).iterate()
+----
+
+The first two lines add a vertex each with the vertex label of "person" and the associated "name" property. The third
+line adds an edge with the "knows" label between them and an associated "weight" property. Note the use of `next()`
+and `iterate()` at the end of the lines - their effect as termination steps is described in
+link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/the-gremlin-console/#result-iteration[The Gremlin Console Tutorial].
+
+IMPORTANT: Writing Gremlin is just one way to load data into the graph. Some graphs may have special data loaders which
+could be more efficient and make the task easier and faster. It is worth looking into those tools especially if there
+is a large one-time load to do.
+
+Retrieving this data is also a just writing a Gremlin statement:
+
+[gremlin-groovy,existing]
+----
+marko = g.V().has('person','name','marko').next()
+peopleMarkoKnows = g.V().has('person','name','marko').out('knows').toList()
+----
+[source,csharp]
+----
+Vertex marko = g.V().has("person","name","marko").Next()
+List<Vertex> peopleMarkoKnows = g.V().has("person","name","marko").out("knows").ToList()
+----
+[source,java]
+----
+Vertex marko = g.V().has("person","name","marko").next()
+List<Vertex> peopleMarkoKnows = g.V().has("person","name","marko").out("knows").toList()
+----
+[source,javascript]
+----
+const marko = g.V().has('person','name','marko').next()
+const peopleMarkoKnows = g.V().has('person','name','marko').out('knows').toList()
+----
+[source,python]
+----
+marko = g.V().has('person','name','marko').next()
+peopleMarkoKnows = g.V().has('person','name','marko').out('knows').toList()
+----
+
+In all these examples presented so far there really isn't a lot of difference in how the Gremlin itself looks. There
+are a few language syntax specific odds and ends, but for the most part Gremlin looks like Gremlin in all of the
+different languages.
+
+The library of Gremlin steps with examples for each can be found in <<traversal, The Traversal Section>>. This section
+is meant as a reference guide and will not necessarily provide methods for applying Gremlin to solve particular
+problems. Please see the aforementioned link:http://tinkerpop.apache.org/docs/x.y.z/#tutorials[Tutorials] and the
+link:http://kelvinlawrence.net/book/Gremlin-Graph-Guide.html[Practical Gremlin] book for that sort of information.
+
+[[staying-agnostic]]
+== Staying Agnostic
+
+A good deal has been written in these introductory sections on how TinkerPop enables an agnostic approach to building
+graph application and that agnosticism is enabled through Gremlin. As good a job as Gremlin can do in this area, it's
+evident from the <<connecting-gremlin,Connecting Gremlin>> Section that TinkerPop is just an enabler. It does not
+prevent a developer from making design choices that can limit its protective power.
+
+There are several places to be concerned when considering this issue:
+
+* Data types - different graphs will support different types of data. Something like TinkerGraph will accept any JVM
+object, but another graph like Neo4j has a small tight subset of possible types. Choosing a type that is exotic or
+perhaps is a custom type that only a specific graph supports, might create migration friction should the need arise.
+* Schemas/Indices - TinkerPop does not provide abstractions for schemas and/or index management. Users will work
+directly with the API of the graph provider. It may be necessary to enclose such code in a graph provider specific
+class or set of classes to isolate or abstract it.
+* Extensions - Graphs may provide extensions to the Gremlin language, which will not be designed to be compatible with
+other graph providers. There may be a special helper syntax or
+link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/gremlins-anatomy/#_expressions[expressions] which can make
+certain features of that specific graph shine in powerful ways. Using those options is probably recommended, but users
+should be aware that doing so ties them more tightly to that graph.
+* Graph specific semantics - TinkerPop tries to enforce specific semantics through its test suite which is quite
+extensive, but some <<connecting-gsp,Graph Service Providers>> may not completely respect all the semantics
+of the Gremlin language. For the most part, that doesn't disqualify them from being any less TinkerPop-enabled than
+another provider that might meet the semantics perfectly. Take care when considering a new graph and pay attention to
+what it supports and does not support.
+
+Outside of considering these points, the best practice for ensuring the greatest level of compatibility across graphs
+is to avoid <<connecting-embedded,embedded>> mode and stick to the bytecode based approaches explained in the
+<<connecting-gremlin-server,Gremlin Server>> and the <<connecting-gsp,GSP>> sections above. It creates the least
+opportunity to stray from the agnostic path as anything that can be done with those two modes also works in embedded
+mode. If using embedded mode, simply write code as though the `Graph` instance is "remote" and not local to the JVM.
+In other words, write code as though the GVM is not available locally. Taking that approach and isolating the points
+of concern above makes it so that swapping graph providers largely comes down to a configuration task (i.e. modifying
+configuration files to point at a different graph system).
\ No newline at end of file


[tinkerpop] 07/07: Lots of grammar/spelling/formatting fixes

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2002
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit b354f3d8b300122291111f3681cef0c29e4a98f7
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Tue Oct 23 15:58:59 2018 -0400

    Lots of grammar/spelling/formatting fixes
---
 docs/sass/tabs.scss                              |   2 +-
 docs/src/reference/gremlin-applications.asciidoc |   4 +-
 docs/src/reference/gremlin-variants.asciidoc     |  27 ++--
 docs/src/reference/intro.asciidoc                | 160 +++++++++++------------
 docs/src/reference/the-graph.asciidoc            |   6 +-
 docs/stylesheets/tinkerpop.css                   |   2 +-
 6 files changed, 99 insertions(+), 102 deletions(-)

diff --git a/docs/sass/tabs.scss b/docs/sass/tabs.scss
index 39c88f4..9922ba4 100644
--- a/docs/sass/tabs.scss
+++ b/docs/sass/tabs.scss
@@ -28,7 +28,7 @@ $inactive: #e9ffe9;
 
 $tabHeight: 50px;
 $minTabs: 2;
-$maxTabs: 4;
+$maxTabs: 5;
 
 @mixin single-transition($property:all, $speed:150ms, $ease:ease, $delay: 0s) {
   -webkit-transition: $property $speed $ease $delay;  
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 5043699..51f5480 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -22,7 +22,7 @@ users when working with graphs.  There are two key applications:
 
 . Gremlin Console - A link:http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop[REPL] environment for
 interactive development and analysis
-. Gremlin Server - A server that hosts a Gremlin Virtual Machine thus enabling remote Gremlin execution
+. Gremlin Server - A server that hosts a Gremlin Traversal Machine thus enabling remote Gremlin execution
 
 image:gremlin-lab-coat.png[width=310,float=left] Gremlin is designed to be extensible, making it possible for users
 and graph system/language providers to customize it to their needs.  Such extensibility is also found in the Gremlin
@@ -411,7 +411,7 @@ or more `Graph` instances hosted within it.  The benefits of using Gremlin Serve
 * Allows any Gremlin Structure-enabled graph to exist as a standalone server, which in turn enables the ability for
 multiple clients to communicate with the same graph database.
 * Enables execution of ad-hoc queries through remotely submitted Gremlin.
-* Provides a method for non-JVM languages which may not have a Gremlin Virtual Machine (e.g. Python, Javascript, etc.)
+* Provides a method for non-JVM languages which may not have a Gremlin Traversal Machine (e.g. Python, Javascript, etc.)
 to communicate with the TinkerPop stack on the JVM.
 * Exposes numerous methods for extension and customization to include serialization options, remote commands, etc.
 
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index 0e59feb..68f595f 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -25,14 +25,14 @@ Gremlin in their applications. Two of those methods <<connecting-gremlin-server,
 <<connecting-rgp,Remote Gremlin Providers>> placed the Traversal Machine on a remote system separate from the client.
 It is in these cases that developers must select a driver to utilize Gremlin.
 
-TinkerPop provides and array of drivers in different programming languages as a way to connect to a remote Gremlin
+TinkerPop provides an array of drivers in different programming languages as a way to connect to a remote Gremlin
 Server or Remote Gremlin Provider. Drivers allow the developer to make requests to that remote system and get back
 results from the TinkerPop-enabled graphs hosted within. A driver can submit Gremlin strings and Gremlin bytecode
 over this subprotocol. Gremlin strings are written in the scripting language made available by the remote system that
 the driver is connecting to (typically, Groovy-based). This connection approach is quite similar to what developers
 are likely familiar with when using JDBC and SQL. While it is familiar, it is not recommended and for TinkerPop it is
-considered an out-dated concept and is largely still present to support applications that might still be using that
-method of interaction.
+considered an out-dated concept and is largely still present for the purpose of supporting applications that might
+still be using that method of interaction.
 
 The preferred approach is to use bytecode based requests, which essentially allows the ability to craft Gremlin
 directly in the programming language of choice. As Gremlin makes use of two fundamental programming constructs:
@@ -152,7 +152,7 @@ TinkerPop driver. The driver is configured by the specified `gremlin.remote.driv
 bound to the `GraphTraversalSource` on the remote end with `gremlin.remote.driver.sourceName` which in this case is
 also "g".
 
-There are other ways to configure the traversal using `withRemote()` as it has other overloads. It can also take an
+There are other ways to configure the traversal using `withRemote()` as it has other overloads. It can take an
 Apache Commons `Configuration` object which would have keys similar to those shown in the properties file and it
 can also take a `RemoteConnection` instance directly. The latter is interesting in that it means it is possible to
 programmatically construct all aspects of the `RemoteConnection`. For TinkerPop usage, that might mean directly
@@ -175,7 +175,7 @@ g = graph.traversal().withRemote('conf/remote-graph.properties')
 g.V().valueMap(true)
 g.close()
 ----
-[java]
+[source,java]
 ----
 Graph graph = EmptyGraph.instance();
 GraphTraversalSource g = graph.traversal().withRemote("conf/remote-graph.properties");
@@ -297,8 +297,9 @@ g.V().as("a").out("knows").as("b").select("b").by((Function<Vertex, Integer>) v
 
 When sending traversals remotely to <<connecting-gremlin-server,Gremlin Server>> or
 <<connecting-rgp,Remote Gremlin Providers>>, the static methods of `Lambda` should be used and should denote a
-particular JSR-223 `ScriptEngine`. `Lambda` creates a string-based lambda that is then converted into a
-lambda/closure/anonymous-function/etc. by the respective lambda language's JSR-223 `ScriptEngine` implementation.
+particular JSR-223 `ScriptEngine` that is available on the remote end (typically, this is Groovy). `Lambda` creates a
+string-based lambda that is  then converted into a lambda/closure/anonymous-function/etc. by the respective lambda
+language's JSR-223 `ScriptEngine` implementation.
 
 [source,java]
 g.V().out("knows").map(Lambda.function("it.get().value('name') + ' is the friend name'"))
@@ -306,10 +307,10 @@ g.V().out("knows").sideEffect(Lambda.consumer("println it"))
 g.V().as("a").out("knows").as("b").select("b").by(Lambda.<Vertex,Integer>function("it.value('name').length()"))
 
 Finally, Gremlin `Bytecode` that includes lambdas requires that the traversal be processed by the
-`GremlinScriptEngine`. To avoid continued recompilation costs, it supports the encoding of bindings,
-which allow Gremlin Server to cache traversals that will be reused over and over again save that some
-parameterization may change. Thus, instead of translating, compiling, and then executing each submitted bytecode,
-it is possible to simply execute. To express bindings in Java, use `Bindings`.
+`ScriptEngine`. To avoid continued recompilation costs, it supports the encoding of bindings, which allow Gremlin
+Server to cache traversals that will be reused over and over again save that some parameterization may change. Thus,
+instead of translating, compiling, and then executing each submitted bytecode, it is possible to simply execute.
+To express bindings in Java, use `Bindings`.
 
 [source,java]
 ----
@@ -321,8 +322,8 @@ g.V(b.of('id',4)).out('created').values('name').getBytecode().getBindings()
 cluster.close()
 ----
 
-Both traversals are abstractly defined as `g.V(id).out('created').values('name')` and thus, the first submission
-can be cached for faster evaluation on the next submission.
+Both traversals are abstractly defined as `g.V(id).out('created').values('name').map{t -> "name: " + t.get() }` and
+thus, the first submission can be cached for faster evaluation on the next submission.
 
 WARNING: It is generally advised to avoid lambda usage. Please consider <<a-note-on-lambdas,A Note On Lambdas>> for
 more information.
diff --git a/docs/src/reference/intro.asciidoc b/docs/src/reference/intro.asciidoc
index 3bf62bf..40b2226 100644
--- a/docs/src/reference/intro.asciidoc
+++ b/docs/src/reference/intro.asciidoc
@@ -23,7 +23,7 @@ from which to spawn more detailed accounts of specific topics and a target to wh
 The Reference Documentation makes some general assumptions about the reader:
 
 1. They have a sense of what a graph is - not sure? see link:http://kelvinlawrence.net/book/Gremlin-Graph-Guide.html#whygraph[Practical Gremlin - Why Graph?]
-1. They know what it means for a graph system to be TinkerPop-enabled - not sure? see link:link:http://tinkerpop.apache.org/providers.html[TinkerPop-enabled Providers]
+1. They know what it means for a graph system to be TinkerPop-enabled - not sure? see link:http://tinkerpop.apache.org/providers.html[TinkerPop-enabled Providers]
 1. They know what the role of Gremlin is - not sure? see link:link:http://tinkerpop.apache.org/gremlin.html[Introduction to Gremlin]
 
 Given those assumptions, it's possible to dive more quickly into the details without spending a lot of time repeating
@@ -282,24 +282,6 @@ the iteration order provided by the underlying graph. Therefore it is important
 the graph database being used. A traversal's result is never ordered by TinkerPop unless performed explicitly by means
 of <<order-step,`order()`>>-step.
 
-=== Graph System Integration
-
-image:provider-integration.png[width=395,float=right] TinkerPop is a framework composed of various interoperable
-components. At the foundation there is the <<graph,core TinkerPop API>> which defines what a `Graph`, `Vertex`,
-`Edge`, etc. are. At minimum a graph system provider must implement the core API. Once implemented, the Gremlin
-<<traversal,traversal language>> is available to the graph system's users. However, the provider can go further and
-develop specific <<traversalstrategy,`TraversalStrategy`>> optimizations that allow the graph system to inspect a
-Gremlin query at runtime and optimize it for its particular implementation (e.g. index lookups, step reordering). If
-the graph system is a graph processor (i.e. provides OLAP capabilities), the system should implement the
-<<graphcomputer,`GraphComputer`>> API. This API defines how messages/traversers are passed between communicating
-workers (i.e. threads and/or machines). Once implemented, the same Gremlin traversals execute against both the graph
-database (OLTP) and the graph processor (OLAP). Note that the Gremlin language interprets the graph in terms of
-vertices and edges -- i.e. Gremlin is a graph-based domain specific language. Users can create their own domain
-specific languages to process the graph in terms of higher-order constructs such as people, companies, and their
-various relationships. Finally, <<gremlin-server,Gremlin Server>> can be leveraged to allow over the wire
-communication with the TinkerPop-enabled graph system. Gremlin Server provides a configurable communication interface
-along with metrics and monitoring capabilities. In total, this is The TinkerPop.
-
 [[connecting-gremlin]]
 == Connecting Gremlin
 
@@ -310,21 +292,21 @@ traversal language itself. It applies less to the way in which the user connects
 might differ considerably depending on the programming language or graph database chosen.
 
 How one connects to a graph is a fairly wide subject that essentially divides along a simple line determined by the
-answer to this question: Where is the Gremlin Virtual Machine (GVM)? The reason that this question is so important is
-because the GVM is responsible for processing traversals. One can write Gremlin traversals in any language, but without
-a GVM there will be no way to execute that traversal against a TinkerPop-enabled graph. The GVM is typically in one
+answer to this question: Where is the Gremlin Traversal Machine (GTM)? The reason that this question is so important is
+because the GTM is responsible for processing traversals. One can write Gremlin traversals in any language, but without
+a GTM there will be no way to execute that traversal against a TinkerPop-enabled graph. The GTM is typically in one
 of the following places:
 
-* Embedded in a Java application
-* Hosted in Gremlin Server
-* Exposed by a remote Remote Gremlin Provider
+* Embedded in a Java application (i.e. Java Virtual Machine)
+* Hosted in <<gremlin-server,Gremlin Server>>
+* Exposed by a remote Remote Gremlin Provider (RGP)
 
-The following sections outline each of these models and what they impact they have to using Gremlin.
+The following sections outline each of these models and what impact they have to using Gremlin.
 
 [[connecting-embedded]]
 === Embedded
 
-TinkerPop maintains the reference implementation for the GVM, which is written in Java and thus available for the
+TinkerPop maintains the reference implementation for the GTM, which is written in Java and thus available for the
 Java Virtual Machine (JVM). This is the classic model that TinkerPop has long been based on and many examples, blog
 posts and other resources on the internet will be demonstrated in this style. It is worth noting that the embedded
 mode is not restricted to just Java as a programming language. Any JVM language can take this approach and in some
@@ -347,20 +329,25 @@ GraphTraversalSource g = graph.traversal();
 List<Vertex> vertices = g.V().toList()
 ----
 
+NOTE: It may be helpful to read the link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/gremlins-anatomy/[Gremlin Anatomy]
+tutorial, which describes the component parts of Gremlin to get a better understanding of the terminology before
+proceeding further.
+
 While the TinkerPop Community strives to ensure consistent behavior among all modes of usage, the embedded mode does
 provide the greatest level of flexibility and control. There are a number of features that can only work if using a
 JVM language. The following list outlines a number of these available options:
 
 * Lambdas can be written in the native language which is convenient, however, it will reduce the portability of Gremlin
-to do so should the need arise to switch away from the embedded mode.
+to do so should the need arise to switch away from the embedded mode. See more in the
+<<a-note-on-lambdas,Note on Lambdas>> Section.
 * Any features that involve extending TinkerPop Java interfaces - e.g. `VertexProgram`, `TraversalStrategy`, etc. In
-some cases, these features can made accessible to non-JVM languages, but they obviously must be initially developed
-by for the JVM.
-* Certain built-in `TraversalStrategy` implementations that rely on lambdas or other JVM-only configurations may no
+some cases, these features can be made accessible to non-JVM languages, but they obviously must be initially developed
+for the JVM.
+* Certain built-in `TraversalStrategy` implementations that rely on lambdas or other JVM-only configurations may not
 be available for use any other way.
-* There are no boundaries put in place by serialization (i.e. GraphSON) as embedded graphs are only dealing with
+* There are no boundaries put in place by serialization (e.g. GraphSON) as embedded graphs are only dealing with
 Java objects.
-* Greater control of graph transactions.
+* Greater control of graph <<transactions,transactions>>.
 * Direct access to lower-levels of the API - e.g. "structure" API methods like `Vertex` and `Edge` interface methods.
 As mentioned <<graph-computing, elsewhere>> in this documentation, TinkerPop does not recommend direct usage of these
 methods by end-users.
@@ -369,15 +356,15 @@ methods by end-users.
 === Gremlin Server
 
 A JVM-based graph maybe be hosted in TinkerPop's <<gremlin-server,Gremlin Server>>. Gremlin Server exposes the graph
-as an endpoint to which different clients can connect, essentially providing a remote GVM. Gremlin Server supports
+as an endpoint to which different clients can connect, essentially providing a remote GTM. Gremlin Server supports
 multiple methods for clients to interface with it:
 
-* Websockets with a custom sub-protocol
+* Websockets with a link:http://tinkerpop.apache.org/docs/x.y.z/dev/provider/#_graph_driver_provider_requirements[custom sub-protocol]
 ** String-based Gremlin scripts
 ** Bytecode-based Gremlin traversals
-* HTTP for String-based scripts
+* HTTP for string-based scripts
 
-Users are encouraged to use the bytecode based approach with websockets because it allows users to write Gremlin
+Users are encouraged to use the bytecode based approach with websockets because it allows them to write Gremlin
 in the language of their choice, which looks quite similar to the <<connecting-embedded, embedded>> approach in style
 and function. As with the embedded approach, the means of connection is based on some form of `Graph` creation
 followed by construction of a `GraphTraversalSource` with some "remote" options that describe the location of the
@@ -396,24 +383,30 @@ g = graph.traversal().withRemote('conf/remote-graph.properties')
 [source,csharp]
 ----
 var graph = new Graph();
-var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182))));
+var g = graph.Traversal().WithRemote(
+              new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182))));
 ----
 [source,javascript]
 ----
 const graph = new Graph();
-const g = graph.traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin'));
+const g = graph.traversal().withRemote(
+                new DriverRemoteConnection('ws://localhost:8182/gremlin'));
 ----
 [source,python]
 ----
 graph = Graph()
-g = graph.traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
+g = graph.traversal().withRemote(
+          DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
 ----
 
-As shown in the embedded approach, once "g" is defined, then irrespective of the programming language used, the Gremlin
-is structurally and conceptually the same.
+As shown in the embedded approach in the previous section, once "g" is defined, writing Gremlin is structurally and
+conceptually the same irrespective of programming language.
+
+[[connecting-gremlin-server-limitations]]
+==== Limitations
 
 The previous section on the embedded model outlined a number of areas where it has some advantages that it gains due to
-the fact that the full GVM is available to the user in the language of it's origin, i.e. Java. Some of those items
+the fact that the full GTM is available to the user in the language of it's origin, i.e. Java. Some of those items
 touch upon important concepts to focus on here.
 
 The first of these points is serialization. When Gremlin Server receives a request, the results must be serialized to
@@ -421,51 +414,50 @@ the form requested by the client and then the client deserializes those into obj
 has two such formats that it uses with link:http://tinkerpop.apache.org/docs/x.y.z/dev/io/#gryo[Gryo] and
 link:http://tinkerpop.apache.org/docs/x.y.z/dev/io/#graphson[GraphSON]. Gryo is a JVM-only format and thus carries the
 advantage that serializing and deserializing occurs on the classes native to the JVM on both the client and server side.
-As the client has full access to the same classes that the server does it basically has a full GVM on its own and
+As the client has full access to the same classes that the server does it basically has a full GTM on its own and
 therefore has the ability to do some slightly more advanced things.
 
 A good example is the `subgraph()`-step which returns a `Graph` instance as its result. The subgraph returned from
 the server can be deserialized into an actual `Graph` instance on the client, which then means it is possible to
-spawn a `GraphTraversalSource` from that to do local Gremlin traversals on the client-side. For non-JVM GLVs there is
-no local graph to deserialize that result into and no GVM to process Gremlin so there isn't much that can be done with
-such a result.
+spawn a `GraphTraversalSource` from that to do local Gremlin traversals on the client-side. For non-JVM
+<<gremlin-drivers-variants,Gremlin Language Variants>> there is no local graph to deserialize that result into and
+no GTM to process Gremlin so there isn't much that can be done with such a result.
 
-The second point is related to this issue. As there is no GVM, there is no "structure" API and thus graph elements like
+The second point is related to this issue. As there is no GTM, there is no "structure" API and thus graph elements like
 `Vertex` and `Edge` are "references" only. A "reference" means that they only contain the `id` and `label` of the
 element and not the properties. To be consistent, even JVM-based languages hold this limitation when talking to a
 remote Gremlin Server.
 
-The third and final point involves transactions. Under this model, one traversal is equivalent to a single transaction
-and there is no way in TinkerPop to string together multiple traversals into the same transaction.
-
 IMPORTANT: Most SQL developers would not write a query as `SELECT * FROM table`. They would instead write the
 individual names of the fields they wanted in place of the wildcard. Writing "good" Gremlin is no different with this
 regard. Prefer explicit property key names in Gremlin unless it is completely impossible to do so.
 
+The third and final point involves transactions. Under this model, one traversal is equivalent to a single transaction
+and there is no way in TinkerPop to string together multiple traversals into the same transaction.
+
 [[connecting-rgp]]
 === Remote Gremlin Provider
 
 Gremlin Service Providers (RGPs) are showing up more and more often in the graph database space. In TinkerPop terms,
-this category of graph providers are ones who simply support the Gremlin language. Typically, these are server-based
-graphs, often cloud-based, which accept Gremlin scripts or bytecode as a request and return results. They will often
-implement Gremlin Server protocols, which enables TinkerPop drivers to connect to them as they would with Gremlin
-Server. Therefore, the typical connection approach is identical to the method of connection presented in the
-<<connecting-gremlin-server,previous section>> with the exact same caveats pointed out toward the end.
+this category of graph providers is defined by those who simply support the Gremlin language. Typically, these are
+server-based graphs, often cloud-based, which accept Gremlin scripts or bytecode as a request and return results.
+They will often implement Gremlin Server protocols, which enables TinkerPop drivers to connect to them as they would
+with Gremlin Server. Therefore, the typical connection approach is identical to the method of connection presented in
+the <<connecting-gremlin-server,previous section>> with the exact same caveats pointed out toward the end.
 
 Despite leveraging TinkerPop protocols and drivers as being typical, RGPs are not required to do so to be considered
-TinkerPop-enabled. RGPs may well have their own drivers and protocols that may plug into GLVs and may allow for more
-advanced options like better security, cluster awareness, batched requests or other features. The details of these
-different systems are outside the scope of this documentation so be sure to consult their documentation for more
-information.
+TinkerPop-enabled. RGPs may well have their own drivers and protocols that may plug into
+<<gremlin-drivers-variants,Gremlin Language Variants> and may allow for more advanced options like better security,
+cluster awareness, batched requests or other features. The details of these different systems are outside the scope
+of this documentation so be sure to consult their documentation for more information.
 
 [[basic-gremlin]]
 == Basic Gremlin
 
 The `GraphTraversalSource` is basically the connection to a graph instance. That graph instance might be
 <<connecting-embedded,embedded>>, hosted in <<connecting-gremlin-server,Gremlin Server>> or hosted in a
-<<connecting-rgp,RGP>>, but the `GraphTraversalSource` is agnostic to that, because this object allows users to write
-Gremlin. Assuming "g" is the `GraphTraversalSource`, getting data into the graph regardless of programming language
-or mode of operation is just some Gremlin:
+<<connecting-rgp,RGP>>, but the `GraphTraversalSource` is agnostic to that. Assuming "g" is the `GraphTraversalSource`,
+getting data into the graph regardless of programming language or mode of operation is just some basic Gremlin:
 
 [gremlin-groovy]
 ----
@@ -500,7 +492,7 @@ g.V(v1).addE('knows').to(v2).property('weight',0.75).iterate()
 
 The first two lines add a vertex each with the vertex label of "person" and the associated "name" property. The third
 line adds an edge with the "knows" label between them and an associated "weight" property. Note the use of `next()`
-and `iterate()` at the end of the lines - their effect as termination steps is described in
+and `iterate()` at the end of the lines - their effect as <<terminal-steps, terminal steps>> is described in
 link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/the-gremlin-console/#result-iteration[The Gremlin Console Tutorial].
 
 IMPORTANT: Writing Gremlin is just one way to load data into the graph. Some graphs may have special data loaders which
@@ -541,9 +533,13 @@ different languages.
 
 The library of Gremlin steps with examples for each can be found in <<traversal, The Traversal Section>>. This section
 is meant as a reference guide and will not necessarily provide methods for applying Gremlin to solve particular
-problems. Please see the aforementioned link:http://tinkerpop.apache.org/docs/x.y.z/#tutorials[Tutorials] and the
+problems. Please see the aforementioned link:http://tinkerpop.apache.org/docs/x.y.z/#tutorials[Tutorials]
+link:http://tinkerpop.apache.org/docs/x.y.z/recipes/[Recipes] and the
 link:http://kelvinlawrence.net/book/Gremlin-Graph-Guide.html[Practical Gremlin] book for that sort of information.
 
+NOTE: A full list of helpful Gremlin resources can be found on the
+link:http://tinkerpop.apache.org/docs/x.y.z/[TinkerPop Compendium] page.
+
 [[staying-agnostic]]
 == Staying Agnostic
 
@@ -554,32 +550,32 @@ prevent a developer from making design choices that can limit its protective pow
 
 There are several places to be concerned when considering this issue:
 
-* Data types - different graphs will support different types of data. Something like TinkerGraph will accept any JVM
+* *Data types* - Different graphs will support different types of data. Something like TinkerGraph will accept any JVM
 object, but another graph like Neo4j has a small tight subset of possible types. Choosing a type that is exotic or
-perhaps is a custom type that only a specific graph supports, might create migration friction should the need arise.
-* Schemas/Indices - TinkerPop does not provide abstractions for schemas and/or index management. Users will work
-directly with the API of the graph provider. It may be necessary to enclose such code in a graph provider specific
-class or set of classes to isolate or abstract it.
-* Extensions - Graphs may provide extensions to the Gremlin language, which will not be designed to be compatible with
-other graph providers. There may be a special helper syntax or
+perhaps is a custom type that only a specific graph supports might create migration friction should the need arise.
+* *Schemas/Indices* - TinkerPop does not provide abstractions for schemas and/or index management. Users will work
+directly with the API of the graph provider. It is considered good practice to attempt to enclose such code in a
+graph provider specific class or set of classes to isolate or abstract it.
+* *Extensions* - Graphs may provide extensions to the Gremlin language, which will not be designed to be compatible
+with other graph providers. There may be a special helper syntax or
 link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/gremlins-anatomy/#_expressions[expressions] which can make
 certain features of that specific graph shine in powerful ways. Using those options is probably recommended, but users
 should be aware that doing so ties them more tightly to that graph.
-* Graph specific semantics - TinkerPop tries to enforce specific semantics through its test suite which is quite
-extensive, but some <<connecting-rgp,Remote Gremlin Providers>> may not completely respect all the semantics
-of the Gremlin language. For the most part, that doesn't disqualify them from being any less TinkerPop-enabled than
-another provider that might meet the semantics perfectly. Take care when considering a new graph and pay attention to
-what it supports and does not support.
-* <<graph,Graph API>> - The <<graph-structure, Graph API>> (also referred to as the Structure API) is not always accessible to
-users. Its accessibility is dependent on the choice of graph system and programming language. It is therefore
-recommended that users avoid usage of methods like `Graph.addVertex()` or `Vertex.properties()` and instead prefer
-use of Gremlin with `g.addV()` or `g.V(1).properties()`.
+* *Graph specific semantics* - TinkerPop tries to enforce specific semantics through its test suite which is quite
+extensive, but some graph providers may not completely respect all the semantics of the Gremlin language or
+TinkerPop's model for its APIs. For the most part, that doesn't disqualify them from being any less TinkerPop-enabled
+than another provider that might meet the semantics perfectly. Take care when considering a new graph and pay
+attention to what it supports and does not support.
+* <<graph,*Graph API*>> - The <<graph-structure, Graph API>> (also referred to as the Structure API) is not always
+accessible to users. Its accessibility is dependent on the choice of graph system and programming language. It is
+therefore recommended that users avoid usage of methods like `Graph.addVertex()` or `Vertex.properties()` and instead
+prefer use of Gremlin with `g.addV()` or `g.V(1).properties()`.
 
 Outside of considering these points, the best practice for ensuring the greatest level of compatibility across graphs
 is to avoid <<connecting-embedded,embedded>> mode and stick to the bytecode based approaches explained in the
 <<connecting-gremlin-server,Gremlin Server>> and the <<connecting-rgp,RGP>> sections above. It creates the least
 opportunity to stray from the agnostic path as anything that can be done with those two modes also works in embedded
 mode. If using embedded mode, simply write code as though the `Graph` instance is "remote" and not local to the JVM.
-In other words, write code as though the GVM is not available locally. Taking that approach and isolating the points
+In other words, write code as though the GTM is not available locally. Taking that approach and isolating the points
 of concern above makes it so that swapping graph providers largely comes down to a configuration task (i.e. modifying
 configuration files to point at a different graph system).
\ No newline at end of file
diff --git a/docs/src/reference/the-graph.asciidoc b/docs/src/reference/the-graph.asciidoc
index 4d58409..d741c1b 100644
--- a/docs/src/reference/the-graph.asciidoc
+++ b/docs/src/reference/the-graph.asciidoc
@@ -21,9 +21,9 @@ image::gremlin-standing.png[width=125]
 
 The <<intro,Introduction>> discussed the diversity of TinkerPop-enabled graphs, with special attention paid to the
 different <<connecting-gremlin,connection models>>, and how TinkerPop makes it possible to bridge that diversity in
-an <<staying-agnostic,agnostic> manner. This particular section deals with elements of the Graph API which was noted
+an <<staying-agnostic,agnostic>> manner. This particular section deals with elements of the Graph API which was noted
 as an API to avoid when trying to build an agnostic system. The Graph API refers to the core elements of what composes
-the <<graph-computing,structure of a graph>> within the Gremlin Virtual Machine (GVM), such as the `Graph`, `Vertex`
+the <<graph-computing,structure of a graph>> within the Gremlin Traversal Machine (GTM), such as the `Graph`, `Vertex`
 and `Edge` Java interfaces.
 
 To maintain the most portable code, users should only reference these interfaces. To "reference", simply means to
@@ -44,7 +44,7 @@ instance. Note that while the end intent of the code is to create a "person" ver
 Even if the developer desired to use the `graph.addVertex()` method there are only a handful of scenarios where it is
 possible:
 
-* The application is being developed on the JVM and the developer is using <<connecting-embedded, Embedded>> mode
+* The application is being developed on the JVM and the developer is using <<connecting-embedded, embedded>> mode
 * The architecture includes Gremlin Server and the user is sending Gremlin scripts to the server
 * The graph system chosen is a <<connecting-rgp, Remote Gremlin Provider>> and they expose the Graph API via scripts
 
diff --git a/docs/stylesheets/tinkerpop.css b/docs/stylesheets/tinkerpop.css
index 6d42956..8b1dec1 100644
--- a/docs/stylesheets/tinkerpop.css
+++ b/docs/stylesheets/tinkerpop.css
@@ -692,4 +692,4 @@ table.tableblock.grid-all th.tableblock, table.tableblock.grid-all td.tableblock
 #footer { background-color: #465158; padding: 2em; }
 
 #footer-text { color: #eee; font-size: 0.8em; text-align: center; }
-.tabs{position:relative;margin:40px auto;width:1024px;max-width:100%;overflow:hidden;padding-top:10px;margin-bottom:60px}.tabs input{position:absolute;z-index:1000;height:50px;left:0;top:0;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);cursor:pointer;margin:0}.tabs input:hover+label{background:#e08f24}.tabs label{background:#e9ffe9;color:#1a1a1a;font-size:15px;line-height:50px;height:60px;position:relative;top:0;padding:0 20px;float:left [...]
+.tabs{position:relative;margin:40px auto;width:1024px;max-width:100%;overflow:hidden;padding-top:10px;margin-bottom:60px}.tabs input{position:absolute;z-index:1000;height:50px;left:0;top:0;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);cursor:pointer;margin:0}.tabs input:hover+label{background:#e08f24}.tabs label{background:#e9ffe9;color:#1a1a1a;font-size:15px;line-height:50px;height:60px;position:relative;top:0;padding:0 20px;float:left [...]


[tinkerpop] 04/07: Moved driver oriented things to variants

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2002
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit be7bdfd7a825741f7e0b8d19fc0f9348351fde45
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Tue Oct 23 10:33:34 2018 -0400

    Moved driver oriented things to variants
    
    This looks much more unified now as we don't have a lot of details about how drivers work in Gremlin Server mix/matched with scripts/bytecode all over the place.
---
 docs/src/reference/gremlin-applications.asciidoc | 460 ++++++-----------------
 docs/src/reference/gremlin-variants.asciidoc     | 460 ++++++++++++++++++++++-
 docs/src/reference/intro.asciidoc                |  12 +-
 3 files changed, 557 insertions(+), 375 deletions(-)

diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index b930f96..5043699 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -22,7 +22,7 @@ users when working with graphs.  There are two key applications:
 
 . Gremlin Console - A link:http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop[REPL] environment for
 interactive development and analysis
-. Gremlin Server - A server that hosts script engines thus enabling remote Gremlin execution
+. Gremlin Server - A server that hosts a Gremlin Virtual Machine thus enabling remote Gremlin execution
 
 image:gremlin-lab-coat.png[width=310,float=left] Gremlin is designed to be extensible, making it possible for users
 and graph system/language providers to customize it to their needs.  Such extensibility is also found in the Gremlin
@@ -405,16 +405,14 @@ v[6]
 [[gremlin-server]]
 == Gremlin Server
 
-image:gremlin-server.png[width=400,float=right] Gremlin Server provides a way to remotely execute Gremlin scripts
-against one or more `Graph` instances hosted within it.  The benefits of using Gremlin Server include:
+image:gremlin-server.png[width=400,float=right] Gremlin Server provides a way to remotely execute Gremlin against one
+or more `Graph` instances hosted within it.  The benefits of using Gremlin Server include:
 
 * Allows any Gremlin Structure-enabled graph to exist as a standalone server, which in turn enables the ability for
 multiple clients to communicate with the same graph database.
-* Enables execution of ad-hoc queries through remotely submitted Gremlin scripts.
-* Allows for the hosting of Gremlin-based DSLs (Domain Specific Language) that expand the Gremlin language to match
-the language of the application domain, which will help support common graph use cases such as searching, ranking,
-and recommendation.
-* Provides a method for Non-JVM languages (e.g. Python, Javascript, etc.) to communicate with the TinkerPop stack.
+* Enables execution of ad-hoc queries through remotely submitted Gremlin.
+* Provides a method for non-JVM languages which may not have a Gremlin Virtual Machine (e.g. Python, Javascript, etc.)
+to communicate with the TinkerPop stack on the JVM.
 * Exposes numerous methods for extension and customization to include serialization options, remote commands, etc.
 
 NOTE: Gremlin Server is the replacement for link:https://github.com/tinkerpop/rexster[Rexster].
@@ -504,6 +502,102 @@ are global to all requests. In addition, any functions that are defined will be
 WARNING: Transactions on graphs in initialization scripts are not closed automatically after the script finishes
 executing.  It is up to the script to properly commit or rollback transactions in the script itself.
 
+[[connecting-via-drivers]]
+=== Connecting via Drivers
+
+TinkerPop offers drivers for the Gremlin Server websocket subprotocol in a variety of languages:
+
+* C#
+* Java
+* Javascript
+* Python
+
+These drivers provide methods to send Gremlin based requests and get back traversal results as a response. The requests
+may be script-based or bytecode-based. As discussed earlier in the <<connecting-gremlin-server,introduction>> the
+recommendation is to use bytecode-based requests. The difference between sending scripts and sending bytecode are
+demonstrated below in some basic examples:
+
+[source,java,tab]
+----
+// script
+Cluster cluster = Cluster.open();
+Client client = cluster.connect();
+Map<String,Object> params = new HashMap<>();
+params.put("name","marko");
+List<Result> list = client.submit("g.V().has('person','name',name).out('knows')", params).all().get();
+
+// bytecode
+Graph graph = EmptyGraph.instance();
+GraphTraversalSource g = graph.traversal().withRemote('conf/remote-graph.properties');
+List<Vertex> list = g.V().has("person","name","marko").out("knows").toList();
+----
+[source,groovy]
+----
+// script
+cluster = Cluster.open()
+client = cluster.connect()
+list = client.submit("g.V().has('person','name',name).out('knows')", [name: "marko"]).all().get();
+
+// bytecode
+graph = EmptyGraph.instance()
+g = graph.traversal().withRemote('conf/remote-graph.properties')
+list = g.V().has('person','name','marko').out('knows').toList()
+----
+[source,csharp]
+----
+// script
+var gremlinServer = new GremlinServer("localhost", 8182);
+using (var gremlinClient = new GremlinClient(gremlinServer))
+{
+    var bindings = new Dictionary<string, object>
+    {
+        {"name", "marko"}
+    };
+
+    var response =
+        await gremlinClient.SubmitWithSingleResultAsync<object>("g.V().has('person','name',name).out('knows')", bindings);
+}
+
+// bytecode
+var graph = new Graph();
+var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182))));
+var list = g.V().Has("person","name","marko").Out("knows").toList();
+----
+[source,javascript]
+----
+// script
+const client = new Client('ws://localhost:45940/gremlin', { traversalSource: "g" });
+const conn = client.open();
+const list = conn.submit("g.V().has('person','name',name).out('knows')",{name: 'marko'}).then(function (response) { ... });
+
+// bytecode
+const graph = new Graph();
+const g = graph.traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin'));
+const list = g.V().has("person","name","marko").out("knows").toList();
+----
+[source,python]
+----
+# script
+client = Client('ws://localhost:8182/gremlin', 'g')
+list = client.submit("g.V().has('person','name',name).out('knows')",{'name': 'marko'}).all()
+
+# bytecode
+graph = Graph()
+g = graph.traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
+list = g.V().has("person","name","marko").out("knows").toList()
+----
+
+The advantage of bytecode over scripts should be apparent from the above examples. Scripts are just strings that are
+embedded in code (in the above examples, the strings are Groovy-based) whereas bytecode based requests are themselves
+code written in the native language of use. Obviously, the advantage of the Gremlin being actual code is that there
+are checks (e.g. compile-time, intellisense and other IDE support, language level checks, etc.) that help validate the
+Gremlin during the development process.
+
+TinkerPop makes an effort to ensure a high-level of consistency among the drivers and their features, but there are
+differences in capabilities and features as they are each developed independently. The Java driver was the first and
+is therefore the most advanced. Please see the related documentation for the driver of interest for more information
+and details in the <<gremlin-drivers-variants,Gremlin Drivers and Variants>> Section of this documentation.
+
 [[connecting-via-console]]
 === Connecting via Console
 
@@ -691,234 +785,6 @@ the one in `conf/remote.yaml` should perform better.
 NOTE: Console commands, those that begin with a colon (e.g. `:x`, `:remote`) do not execute remotely when in this mode.
 They are all still evaluated locally.
 
-[[connecting-via-java]]
-=== Connecting via Java
-
-[source,xml]
-----
-<dependency>
-   <groupId>org.apache.tinkerpop</groupId>
-   <artifactId>gremlin-driver</artifactId>
-   <version>x.y.z</version>
-</dependency>
-----
-
-image:gremlin-java.png[width=175,float=left] TinkerPop comes equipped with a reference client for Java-based
-applications.  It is referred to as Gremlin Driver, which enables applications to send requests to Gremlin Server
-and get back results.
-
-Gremlin code is sent to the server from a `Client` instance.  A `Client` is created as follows:
-
-[source,java]
-----
-Cluster cluster = Cluster.open();  <1>
-Client client = cluster.connect(); <2>
-----
-
-<1> Opens a reference to `localhost` - note that there are many configuration options available in defining a `Cluster` object.
-<2> Creates a `Client` given the configuration options of the `Cluster`.
-
-Once a `Client` instance is ready, it is possible to issue some Gremlin:
-
-[source,java]
-----
-ResultSet results = client.submit("[1,2,3,4]");  <1>
-results.stream().map(i -> i.get(Integer.class) * 2);       <2>
-
-CompletableFuture<List<Result>> results = client.submit("[1,2,3,4]").all();  <3>
-
-CompletableFuture<ResultSet> future = client.submitAsync("[1,2,3,4]"); <4>
-
-Map<String,Object> params = new HashMap<>();
-params.put("x",4);
-client.submit("[1,2,3,x]", params); <5>
-----
-
-<1> Submits a script that simply returns a `List` of integers.  This method blocks until the request is written to
-the server and a `ResultSet` is constructed.
-<2> Even though the `ResultSet` is constructed, it does not mean that the server has sent back the results (or even
-evaluated the script potentially).  The `ResultSet` is just a holder that is awaiting the results from the server.
-In this case, they are streamed from the server as they arrive.
-<3> Submit a script, get a `ResultSet`, then return a `CompletableFuture` that will be called when all results have been returned.
-<4> Submit a script asynchronously without waiting for the request to be written to the server.
-<5> Parameterized request are considered the most efficient way to send Gremlin to the server as they can be cached,
-which will boost performance and reduce resources required on the server.
-
-==== Configuration
-
-The following table describes the various configuration options for the Gremlin Driver:
-
-[width="100%",cols="3,10,^2",options="header"]
-|=========================================================
-|Key |Description |Default
-|connectionPool.channelizer |The fully qualified classname of the client `Channelizer` that defines how to connect to the server. |`Channelizer.WebSocketChannelizer`
-|connectionPool.enableSsl |Determines if SSL should be enabled or not. If enabled on the server then it must be enabled on the client. |false
-|connectionPool.keepAliveInterval |Length of time in milliseconds to wait on an idle connection before sending a keep-alive request. Set to zero to disable this feature. |1800000
-|connectionPool.keyStore |The private key in JKS or PKCS#12 format. |_none_
-|connectionPool.keyStorePassword |The password of the `keyStore` if it is password-protected. |_none_
-|connectionPool.keyStoreType |`JKS` (Java 8 default) or `PKCS12` (Java 9+ default)|_none_
-|connectionPool.maxContentLength |The maximum length in bytes that a message can be sent to the server. This number can be no greater than the setting of the same name in the server configuration. |65536
-|connectionPool.maxInProcessPerConnection |The maximum number of in-flight requests that can occur on a connection. |4
-|connectionPool.maxSimultaneousUsagePerConnection |The maximum number of times that a connection can be borrowed from the pool simultaneously. |16
-|connectionPool.maxSize |The maximum size of a connection pool for a host. |8
-|connectionPool.maxWaitForConnection |The amount of time in milliseconds to wait for a new connection before timing out. |3000
-|connectionPool.maxWaitForSessionClose |The amount of time in milliseconds to wait for a session to close before timing out (does not apply to sessionless connections). |3000
-|connectionPool.minInProcessPerConnection |The minimum number of in-flight requests that can occur on a connection. |1
-|connectionPool.minSimultaneousUsagePerConnection |The maximum number of times that a connection can be borrowed from the pool simultaneously. |8
-|connectionPool.minSize |The minimum size of a connection pool for a host. |2
-|connectionPool.reconnectInterval |The amount of time in milliseconds to wait before trying to reconnect to a dead host. |1000
-|connectionPool.resultIterationBatchSize |The override value for the size of the result batches to be returned from the server. |64
-|connectionPool.sslCipherSuites |The list of JSSE ciphers to support for SSL connections. If specified, only the ciphers that are listed and supported will be enabled. If not specified, the JVM default is used.  |_none_
-|connectionPool.sslEnabledProtocols |The list of SSL protocols to support for SSL connections. If specified, only the protocols that are listed and supported will be enabled. If not specified, the JVM default is used.  |_none_
-|connectionPool.sslSkipCertValidation |Configures the `TrustManager` to trust all certs without any validation. Should not be used in production.|false
-|connectionPool.trustStore |File location for a SSL Certificate Chain to use when SSL is enabled. If this value is not provided and SSL is enabled, the default `TrustManager` will be used. |_none_
-|connectionPool.trustStorePassword |The password of the `trustStore` if it is password-protected |_none_
-|connectionPool.validationRequest |A script that is used to test server connectivity. A good script to use is one that evaluates quickly and returns no data. The default simply returns an empty string, but if a graph is required by a particular provider, a good traversal might be `g.inject()`. |_''_
-|hosts |The list of hosts that the driver will connect to. |localhost
-|jaasEntry |Sets the `AuthProperties.Property.JAAS_ENTRY` properties for authentication to Gremlin Server. |_none_
-|nioPoolSize |Size of the pool for handling request/response operations. |available processors
-|password |The password to submit on requests that require authentication. |_none_
-|port |The port of the Gremlin Server to connect to. The same port will be applied for all hosts. |8192
-|protocol |Sets the `AuthProperties.Property.PROTOCOL` properties for authentication to Gremlin Server. |_none_
-|serializer.className |The fully qualified class name of the `MessageSerializer` that will be used to communicate with the server. Note that the serializer configured on the client should be supported by the server configuration. |_none_
-|serializer.config |A `Map` of configuration settings for the serializer. |_none_
-|username |The username to submit on requests that require authentication. |_none_
-|workerPoolSize |Size of the pool for handling background work. |available processors * 2
-|=========================================================
-
-Please see the link:http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/driver/Cluster.Builder.html[Cluster.Builder javadoc] to get more information on these settings.
-
-==== Aliases
-
-Scripts submitted to Gremlin Server automatically have the globally configured `Graph` and `TraversalSource` instances
-made available to them.  Therefore, if Gremlin Server configures two `TraversalSource` instances called "g1" and "g2"
-a script can simply reference them directly as:
-
-[source,java]
-client.submit("g1.V()")
-client.submit("g2.V()")
-
-While this is an acceptable way to submit scripts, it has the downside of forcing the client to encode the server-side
-variable name directly into the script being sent.  If the server configuration ever changed such that "g1" became
-"g100", the client-side code might have to see a significant amount of change.  Decoupling the script code from the
-server configuration can be managed by the `alias` method on `Client` as follows:
-
-[source,java]
-Client g1Client = client.alias("g1")
-Client g2Client = client.alias("g2")
-g1Client.submit("g.V()")
-g2Client.submit("g.V()")
-
-The above code demonstrates how the `alias` method can be used such that the script need only contain a reference
-to "g" and "g1" and "g2" are automatically rebound into "g" on the server-side.
-
-==== Serialization
-
-When using Gryo serialization (the default serializer for the driver), it is important that the client and server
-have the same serializers configured or else one or the other will experience serialization exceptions and fail to
-always communicate.  Discrepancy in serializer registration between client and server can happen fairly easily as
-graphs will automatically include serializers on the server-side, thus leaving the client to be configured manually.
-This can be done manually as follows:
-
-[source,java]
-GryoMapper kryo = GryoMapper.build().addRegistry(TitanIoRegistry.INSTANCE).create();
-MessageSerializer serializer = new GryoMessageSerializerV3d0(kryo);
-Cluster cluster = Cluster.build()
-                .serializer(serializer)
-                .create();
-Client client = cluster.connect().init();
-
-The above code demonstrates using the `TitanIoRegistry` which is an `IoRegistry` instance.  It tells the serializer
-what classes (from Titan in this case) to auto-register during serialization.  Gremlin Server roughly uses this same
-approach when it configures it's serializers, so using this same model will ensure compatibility when making requests.
-
-==== Per Request Settings
-
-There are a number of overloads to `Client.submit()` that accept a `RequestOptions` object. The `RequestOptions`
-provide a way to include options that are specific to the request made with the call to `submit()`. A good use-case for
-this feature is to set a per-request override to the `scriptEvaluationTimeout` so that it only applies to the current
-request.
-
-[source,java]
-----
-Cluster cluster = Cluster.open();
-Client client = cluster.connect();
-RequestOptions options = RequestOptions.build().timeout(500).create();
-List<Result> result = client.submit("g.V()", options).all().get();
-----
-
-[[connecting-via-python]]
-=== Connecting via Python
-
-[source,python]
-----
-pip install gremlinpython
-----
-
-TinkerPop also includes a client for Python-based applications.  It is referred to as Gremlin-Python Driver.
-The `Client` class implementation/interface is based on the Java Driver, with some restrictions. Most notably,
-Gremlin-Python does not yet implement the `Cluster` class. Instead, `Client` is instantiated directly.
-Usage is as follows:
-
-[source,python]
-----
-from gremlin_python.driver import client <1>
-client = client.Client('ws://localhost:8182/gremlin', 'g') <2>
-----
-
-<1> Import the Gremlin-Python `client` module.
-<2> Opens a reference to `localhost` - note that there are various configuration options that can be passed
-to the `Client` object upon instantiation as keyword arguments.
-
-Once a `Client` instance is ready, it is possible to issue some Gremlin:
-
-[source,python]
-----
-result_set = client.submit("[1,2,3,4]")  <1>
-future_results = result_set.all()  <2>
-results = future_results.result() <3>
-assert results == [1, 2, 3, 4] <4>
-
-future_result_set = client.submitAsync("[1,2,3,4]") <5>
-result_set = future_result_set.result() <6>
-result = result_set.one() <7>
-assert results == [1, 2, 3, 4] <8>
-assert result_set.done.done() <9>
-
-client.close() <10>
-----
-
-<1> Submit a script that simply returns a `List` of integers.  This method blocks until the request is written to
-the server and a `ResultSet` is constructed.
-<2> Even though the `ResultSet` is constructed, it does not mean that the server has sent back the results (or even
-evaluated the script potentially).  The `ResultSet` is just a holder that is awaiting the results from the server. The `all` method
-returns a `concurrent.futures.Future` that resolves to a list when it is complete.
-<3> Block until the the script is evaluated and results are sent back by the server.
-<4> Verify the result.
-<5> Submit the same script to the server but don't block.
-<6> Wait until request is written to the server and `ResultSet` is constructed.
-<7> Read a single result off the result stream.
-<8> Again, verify the result.
-<9> Verify that the all results have been read and stream is closed.
-<10> Close client and underlying pool connections.
-
-==== Configuration
-
-The following table describes the various configuration options for the Gremlin-Python Driver. They
-can be passed to the `Client` instance as keyword arguments:
-
-[width="100%",cols="3,10,^2",options="header"]
-|=========================================================
-|Key |Description |Default
-|protocol_factory |A callable that returns an instance of `AbstractBaseProtocol`. |`gremlin_python.driver.protocol.GremlinServerWSProtocol`
-|transport_factory |A callable that returns an instance of `AbstractBaseTransport`. |`gremlin_python.driver.tornado.transport.TornadoTransport`
-|pool_size |The number of connections used by the pool. |4
-|max_workers |Maximum number of worker threads. |Number of CPUs * 5
-|message_serializer |The message serializer implementation.|`gremlin_python.driver.serializer.GraphSONMessageSerializer`
-|password |The password to submit on requests that require authentication. |""
-|username |The username to submit on requests that require authentication. |""
-|=========================================================
-
 === Connecting via HTTP
 
 image:gremlin-rexster.png[width=225,float=left] While the default behavior for Gremlin Server is to provide a
@@ -928,10 +794,15 @@ programming languages, tools and libraries for accessing it.  As a result, HTTP
 with Gremlin Server.   It also may represent an easier upgrade path from link:https://github.com/tinkerpop/rexster[Rexster]
 as the API for the endpoint is very similar to Rexster's link:https://github.com/tinkerpop/rexster/wiki/Gremlin-Extension[Gremlin Extension].
 
+IMPORTANT: TinkerPop provides and supports this HTTP endpoint as a convenience and for legacy reasons, but users should
+prefer the recommended approach of bytcode based requests as described in <<connecting-gremlin,Connecting Gremlin>>
+section.
+
 Gremlin Server provides for a single HTTP endpoint - a Gremlin evaluator - which allows the submission of a Gremlin
 script as a request.  For each request, it returns a response containing the serialized results of that script.
-To enable this endpoint, Gremlin Server needs to be configured with the `HttpChannelizer`, which replaces the default. The `WsAndHttpChannelizer` may also be configured to enable both WebSockets and the REST endpoint.
-`WebSocketChannelizer`, in the configuration file:
+To enable this endpoint, Gremlin Server needs to be configured with the `HttpChannelizer`, which replaces the default.
+The `WsAndHttpChannelizer` may also be configured to enable both WebSockets and the REST endpoint in the configuration
+file:
 
 [source,yaml]
 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer
@@ -1003,121 +874,12 @@ that iterates thousands of results will serialize each of those in memory into a
 quite possible that such a script will generate `OutOfMemoryError` exceptions on the server.  Consider the default
 WebSocket configuration, which supports streaming, if that type of use case is required.
 
-[[connecting-via-remotegraph]]
-=== Connecting via withRemote
-
-[source,xml]
-----
-<dependency>
-   <groupId>org.apache.tinkerpop</groupId>
-   <artifactId>gremlin-driver</artifactId>
-   <version>x.y.z</version>
-</dependency>
-----
-
-image:remote-graph.png[width=145,float=left] A `TraversalSource` has several `withRemote()` methods which provide an
-interesting alternative to the other methods for connecting to Gremlin Server. It is interesting in that all other
-methods involve construction of a `String` representation of the `Traversal` which is then submitted as a script
-to Gremlin Server (via driver or HTTP). This approach is quite akin to SQL, where query strings are embedded into code
-and submitted to a database server. While there are patterns for taking this approach that can lead to maintainable
-application code, using `withRemote()` could be a better method as it brings some good benefits with it:
-
-* Get auto-complete when writing traversals in an IDE.
-* Get compile-time errors in traversal writing.
-* Get the feel of working with an embedded database.
-
-One way to create a `Traversal` instance that is remote-enabled is by configuration file. Here is an example of what
-that file looks like:
-
-[source,properties]
-----
-gremlin.remote.remoteConnectionClass=org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection
-gremlin.remote.driver.clusterFile=conf/remote-objects.yaml
-gremlin.remote.driver.sourceName=g
-----
-
-The `gremlin.remote.remoteConnectionClass` should be an implementation of the `RemoteConnection` interface in
-`gremlin-core`. In this case, it points at the `gremlin-driver` implementation, called `DriverRemoteConnection`. The
-other setting, `gremlin.remote.driver.clusterFile`, is a configuration to `DriverRemoteConnection`, and it
-provides a pointer to the config file to use to construct a `gremlin-driver` `Cluster` object to be utilized when
-connecting to Gremlin Server. Please see the <<connecting-via-java, "Connecting Via Java">> section for more
-information on those classes and their usage. Finally, the `gremlin.remote.driver.sourceName` setting tells the
-`DriverRemoteConnection` the name of the `TraversalSource` in Gremlin Server to connect to.
-
-IMPORTANT: Gremlin Server supports configurable serialization options. The `withRemote()` feature works best with
-Gryo serialization. While it is compatible with GraphSON, unknown incompatibilities may arise
-
-Gremlin Server needs to be running for this example to work. Use the following configuration:
-
-[source,bourne]
-$ bin/gremlin-server.sh conf/gremlin-server-modern.yaml
-
-To configure a "remote" traversal, there first needs to be a `TraversalSource`. A `TraversalSource` can be generated
-from any `Graph` instance with the `traversal()` method. Of course, any traversals generated from this source using the
-`withRemote()` configuration option will not execute against the local graph. That could be confusing and it may be
-easier to think of the local graph as being "empty". To that end, it is recommended that when using `withRemote()`,
-the `TraversalSource` be generated with `EmptyGraph` as follows:
-
-[gremlin-groovy]
-----
-graph = EmptyGraph.instance()
-g = graph.traversal().withRemote('conf/remote-graph.properties')
-g.V().valueMap(true)
-g.close()
-----
-
-Note the call to `close()` above. The call to `withRemote()` internally instantiates a `Client` instance that can only
-be released by "closing" the `GraphTraversalSource`. It is important to take that step to release resources created
-in that step.
-
-If working with multiple remote `TraversalSource` instances it is more efficient to construct a `Cluster` object and
-then re-use it.
-
-[gremlin-groovy]
-----
-cluster = Cluster.open('conf/remote-objects.yaml')
-graph = EmptyGraph.instance()
-g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster, "g"))
-g.V().valueMap(true)
-g.close()
-cluster.close()
-----
-
-If the `Cluster` instance is supplied externally, as is shown above, then it is not closed implicitly by the close of
-"g".  Closing "g" will only close the `Client` instance associated with that `TraversalSource`. In this case, the
-`Cluster` must also be closed explicitly. Closing "g" and the "cluster" aren't actually both necessary - the close of
-a `Cluster` will close all `Client` instance spawned by the `Cluster`.
-
-IMPORTANT: `RemoteGraph` uses the `TraversalOpProcessor` in Gremlin Server which requires a cache to enable the
-retrieval of side-effects (if the `Traversal` produces any). That cache can be configured (e.g. controlling eviction
-times and sizing) can be done in the Gremlin Server configuration file as described <<traversalopprocessor, here>>.
-
-Finally, Gremlin `Bytecode` supports the encoding of bindings which allow GremlinServer to cache traversals that will
-be reused over and over again save that some parameterization may change. Thus, instead of translating, compiling, and
-then executing each submitted bytecode, it is possible to simply execute. To express bindings in Gremlin-Java and
-Gremlin-Groovy, use `Bindings`.
-
-[gremlin-groovy]
-----
-cluster = Cluster.open('conf/remote-objects.yaml')
-b = Bindings.instance()
-g = EmptyGraph.instance().traversal().withRemote(DriverRemoteConnection.using(cluster, "g"))
-g.V(b.of('id',1)).out('created').values('name')
-g.V(b.of('id',4)).out('created').values('name')
-g.V(b.of('id',4)).out('created').values('name').getBytecode()
-g.V(b.of('id',4)).out('created').values('name').getBytecode().getBindings()
-cluster.close()
-----
-
-Both traversals are abstractly defined as `g.V(id).out('created').values('name')` and thus, the first submission
-can be cached for faster evaluation on the next submission.
-
 === Configuring
 
 The `gremlin-server.sh` file serves multiple purposes.  It can be used to "install" dependencies to the Gremlin
 Server path.  For example, to be able to configure and use other `Graph` implementations, the dependencies must be
-made available to Gremlin Server.  To do this, use the `install` switch and supply the Maven coordinates for the dependency
-to "install".  For example, to use Neo4j in Gremlin Server:
+made available to Gremlin Server.  To do this, use the `install` switch and supply the Maven coordinates for the
+dependency to "install".  For example, to use Neo4j in Gremlin Server:
 
 [source,text]
 ----
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index 8699b30..a2c2dc7 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -14,58 +14,407 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 ////
+[[gremlin-drivers-variants]]
 [[gremlin-variants]]
-= Gremlin Variants
+= Gremlin Drivers and Variants
 
 image::gremlin-house-of-mirrors.png[width=1024]
 
-Gremlin is a graph traversal language that makes use of two fundamental programming constructs:
+The <<connecting-gremlin,Connecting Gremlin>> Section described the different ways in which a developer can use
+Gremlin in their applications. Two of those methods <<connecting-gremlin-server,Gremlin Server>> and
+<<connecting-rgp,Remote Gremlin Providers>> placed the Traversal Machine on a remote system separate from the client.
+It is in these cases that developers must select a driver to utilize Gremlin.
+
+TinkerPop provides and array of drivers in different programming languages as a way to connect to a remote Gremlin
+Server or Remote Gremlin Provider. Drivers allow the developer to make requests to that remote system and get back
+results from the TinkerPop-enabled graphs hosted within. A driver can submit Gremlin strings and Gremlin bytecode
+over this subprotocol. Gremlin strings are written in the scripting language made available by the remote system that
+the driver is connecting to (typically, Groovy-based). This connection approach is quite similar to what developers
+are likely familiar with when using JDBC and SQL. While it is familiar, it is not recommended and for TinkerPop it is
+considered an out-dated concept and is largely still present to support applications that might still be using that
+method of interaction.
+
+The preferred approach is to use bytecode based requests, which essentially allows the ability to craft Gremlin
+directly in the programming language of choice. As Gremlin makes use of two fundamental programming constructs:
 link:https://en.wikipedia.org/wiki/Function_composition[function composition] and
-link:https://en.wikipedia.org/wiki/Nested_function[function nesting]. Given this generality, it is possible to embed
-Gremlin in any modern programming language.
-
-IMPORTANT: Gremlin-Java is the canonical representation of Gremlin and any (proper) Gremlin language variant will emulate its
-structure as best as possible given the constructs of the host language. A strong correspondence between variants ensures
-that the general Gremlin reference documentation is applicable to all variants and that users moving between development
-languages can easily adopt the Gremlin variant for that language.
+link:https://en.wikipedia.org/wiki/Nested_function[function nesting]. it is possible to embed the Gremlin language
+in any modern programming language.It is a far more natural way to program, because it enables IDE interaction,
+compile time checks, and language level checks that can help prevent errors prior to execution. The differences
+between these two approaches were outlined in the <<connecting-via-drivers,Connecting Via Drivers>> Section.
+
+TinkerPop natively supports drivers and variants of Gremlin in a number of different programming languages. They are
+all described in the following sections. There are also third-party implementations of drivers and Gremlin, as well
+as extensions to the Gremlin language that might be specific to a particular graph provider. That listing can be
+found on the TinkerPop link:http://tinkerpop.apache.org/#graph-systems[home page]. Their description is beyond the
+scope of this documentation.
+
+IMPORTANT: Gremlin-Java is the canonical representation of Gremlin and any (proper) Gremlin language variant will
+emulate its structure as best as possible given the constructs of the host language. A strong correspondence between
+variants ensures that the general Gremlin reference documentation is applicable to all variants and that users moving
+between development languages can easily adopt the Gremlin variant for that language.
 
 image::gremlin-variant-architecture.png[width=650,float=left]
 
 NOTE: The information herein describes how to use the Gremlin language variants distributed
-with Apache TinkerPop. For information on how to build a Gremlin language variant,
-please review the link:http://tinkerpop.apache.org/docs/current/tutorials/gremlin-language-variants/[Gremlin Language Variants]
-tutorial.
+with Apache TinkerPop. For information on how to build a Gremlin language variant, please review the
+link:http://tinkerpop.apache.org/docs/current/tutorials/gremlin-language-variants/[Gremlin Language Variants] tutorial.
 
+[[connecting-via-remotegraph]]
+[[connecting-via-java]]
 [[gremlin-java]]
 == Gremlin-Java
 
-image:gremlin-java-drawing.png[width=130,float=right] Apache TinkerPop's Gremlin-Java implements Gremlin within the Java8
-language and can be used by any Java8 compliant virtual machine. Gremlin-Java is considered the canonical, reference
+image:gremlin-java-drawing.png[width=130,float=right] Apache TinkerPop's Gremlin-Java implements Gremlin within the
+Java language and can be used by any Java Virtual Machine. Gremlin-Java is considered the canonical, reference
 implementation of Gremlin and serves as the foundation by which all other Gremlin language variants should emulate.
+As the Traversal Machine that processes Gremlin queries is also written in Java, it can be used in all three connection
+methods described in the <<connecting-gremlin,Connecting Gremlin>> Section.
+
+[source,xml]
+----
+<dependency>
+   <groupId>org.apache.tinkerpop</groupId>
+   <artifactId>gremlin-core</artifactId>
+   <version>x.y.z</version>
+</dependency>
+
+<!-- when using Gremlin Server or Remote Gremlin Provider a driver is required -->
+<dependency>
+   <groupId>org.apache.tinkerpop</groupId>
+   <artifactId>gremlin-driver</artifactId>
+   <version>x.y.z</version>
+</dependency>
+----
+
+=== Static Enums and Methods
+
+Gremlin has various tokens (e.g. `T`, `P`, `Order`, `Direction`, etc.) that in most examples are short-handed by way
+of static imports. To get this same short-handed effect, the typical list of imports that users should have when
+utilizing Gremlin Java are:
+
+[source,java]
+----
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.Bindings;
+import org.apache.tinkerpop.gremlin.process.traversal.IO;
+import static org.apache.tinkerpop.gremlin.process.traversal.Operator.*;
+import static org.apache.tinkerpop.gremlin.process.traversal.Order.*;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.*;
+import static org.apache.tinkerpop.gremlin.process.traversal.Pop.*;
+import static org.apache.tinkerpop.gremlin.process.traversal.SackFunctions.*;
+import static org.apache.tinkerpop.gremlin.process.traversal.Scope.*;
+import static org.apache.tinkerpop.gremlin.process.traversal.TextP.*;
+import static org.apache.tinkerpop.gremlin.structure.Column.*;
+import static org.apache.tinkerpop.gremlin.structure.Direction.*;
+import static org.apache.tinkerpop.gremlin.structure.T.*;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
+----
+
+=== Connecting
+
+The pattern for connecting is described in <<connecting-gremlin,Connecting Gremlin>> and it basically distills down to
+creating a `Graph` instance and then spawning a `GraphTraversalSource`.
+
+[source,java]
+----
+Graph graph = ...;
+GraphTraversalSource g = graph.traversal();
+----
+
+Using "g" it is then possible to start writing Gremlin. The "g" allows for the setting of many configuration options
+which affect traversal execution. The <<traversal, Traversal>> Section describes some of these options and some are
+only suitable with <<connecting-embedded,embedded>> style usage. For remote options however there are some added
+setup and configurations to consider and this section looks to address those.
+
+The most basic way to connect to <<connecting-gremlin-server,Gremlin Server>> or
+<<connecting-rgp,Remote Gremlin Providers>> uses the following two lines of code:
+
+[source,java]
+----
+Graph graph = EmptyGraph.instance();
+GraphTraversalSource g = graph.traversal().withRemote('conf/remote-graph.properties');
+----
+
+The `remote-graph.properties` file simply provides connection information to the `GraphTraversalSource` which is used
+to configure a `RemoteConnection`. That file looks like this:
+
+[source,text]
+----
+gremlin.remote.remoteConnectionClass=org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection
+gremlin.remote.driver.clusterFile=conf/remote-objects.yaml
+gremlin.remote.driver.sourceName=g
+----
+
+The `RemoteConnection` is an interface that provides the transport mechanism for "g" and makes it possible to for
+that mechanism to be altered (typically by graph providers who have their own protocols). TinkerPop provides one such
+implementation called the `DriverRemoteConnection` which enables transport over Gremlin Server protocols using the
+TinkerPop driver. The driver is configured by the specified `gremlin.remote.driver.clusterFile` and the local "g" is
+bound to the `GraphTraversalSource` on the remote end with `gremlin.remote.driver.sourceName` which in this case is
+also "g".
+
+There are other ways to configure the traversal using `withRemote()` as it has other overloads. It can also take an
+Apache Commons `Configuration` object which would have keys similar to those shown in the properties file and it
+can also take a `RemoteConnection` instance directly. The latter is interesting in that it means it is possible to
+programmatically construct all aspects of the `RemoteConnection`. For TinkerPop usage, that might mean directly
+constructing the `DriverRemoteConnection` and the driver instance that supplies the transport mechanism. For example,
+the command shown above could be re-written using programmatic construction as follows:
+
+[source,java]
+----
+Cluster cluster = Cluster.open();
+Graph graph = EmptyGraph.instance();
+GraphTraversalSource g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster, "g"));
+----
+
+Please consider the following example:
+
+[gremlin-groovy]
+----
+graph = EmptyGraph.instance()
+g = graph.traversal().withRemote('conf/remote-graph.properties')
+g.V().valueMap(true)
+g.close()
+----
+[java]
+----
+Graph graph = EmptyGraph.instance();
+GraphTraversalSource g = graph.traversal().withRemote("conf/remote-graph.properties");
+List<Map> list = g.V().valueMap(true);
+g.close()
+----
+
+Note the call to `close()` above. The call to `withRemote()` internally instantiates a connection via the driver that
+can only be released by "closing" the `GraphTraversalSource`. It is important to take that step to release resources
+created in that step.
+
+If working with multiple remote `TraversalSource` instances it is more efficient to construct a `Cluster` object and
+then re-use it.
+
+[gremlin-groovy]
+----
+cluster = Cluster.open('conf/remote-objects.yaml')
+graph = EmptyGraph.instance()
+g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster, "g"))
+g.V().valueMap(true)
+g.close()
+cluster.close()
+----
+
+If the `Cluster` instance is supplied externally, as is shown above, then it is not closed implicitly by the close of
+"g".  Closing "g" will only close the connection associated with that `TraversalSource`. In this case, the
+`Cluster` must also be closed explicitly. Closing "g" and the "cluster" aren't actually both necessary - the close of
+a `Cluster` will close all connections spawned by the `Cluster`.
+
+IMPORTANT: Bytecode-based traversals use the `TraversalOpProcessor` in Gremlin Server which requires a cache to enable
+the retrieval of side-effects (if the `Traversal` produces any). That cache can be configured (e.g. controlling
+eviction times and sizing) in the Gremlin Server configuration file as described <<traversalopprocessor, here>>.
+
+=== Configuration
+
+The following table describes the various configuration options for the Gremlin Driver:
+
+[width="100%",cols="3,10,^2",options="header"]
+|=========================================================
+|Key |Description |Default
+|connectionPool.channelizer |The fully qualified classname of the client `Channelizer` that defines how to connect to the server. |`Channelizer.WebSocketChannelizer`
+|connectionPool.enableSsl |Determines if SSL should be enabled or not. If enabled on the server then it must be enabled on the client. |false
+|connectionPool.keepAliveInterval |Length of time in milliseconds to wait on an idle connection before sending a keep-alive request. Set to zero to disable this feature. |1800000
+|connectionPool.keyStore |The private key in JKS or PKCS#12 format. |_none_
+|connectionPool.keyStorePassword |The password of the `keyStore` if it is password-protected. |_none_
+|connectionPool.keyStoreType |`JKS` (Java 8 default) or `PKCS12` (Java 9+ default)|_none_
+|connectionPool.maxContentLength |The maximum length in bytes that a message can be sent to the server. This number can be no greater than the setting of the same name in the server configuration. |65536
+|connectionPool.maxInProcessPerConnection |The maximum number of in-flight requests that can occur on a connection. |4
+|connectionPool.maxSimultaneousUsagePerConnection |The maximum number of times that a connection can be borrowed from the pool simultaneously. |16
+|connectionPool.maxSize |The maximum size of a connection pool for a host. |8
+|connectionPool.maxWaitForConnection |The amount of time in milliseconds to wait for a new connection before timing out. |3000
+|connectionPool.maxWaitForSessionClose |The amount of time in milliseconds to wait for a session to close before timing out (does not apply to sessionless connections). |3000
+|connectionPool.minInProcessPerConnection |The minimum number of in-flight requests that can occur on a connection. |1
+|connectionPool.minSimultaneousUsagePerConnection |The maximum number of times that a connection can be borrowed from the pool simultaneously. |8
+|connectionPool.minSize |The minimum size of a connection pool for a host. |2
+|connectionPool.reconnectInterval |The amount of time in milliseconds to wait before trying to reconnect to a dead host. |1000
+|connectionPool.resultIterationBatchSize |The override value for the size of the result batches to be returned from the server. |64
+|connectionPool.sslCipherSuites |The list of JSSE ciphers to support for SSL connections. If specified, only the ciphers that are listed and supported will be enabled. If not specified, the JVM default is used.  |_none_
+|connectionPool.sslEnabledProtocols |The list of SSL protocols to support for SSL connections. If specified, only the protocols that are listed and supported will be enabled. If not specified, the JVM default is used.  |_none_
+|connectionPool.sslSkipCertValidation |Configures the `TrustManager` to trust all certs without any validation. Should not be used in production.|false
+|connectionPool.trustStore |File location for a SSL Certificate Chain to use when SSL is enabled. If this value is not provided and SSL is enabled, the default `TrustManager` will be used. |_none_
+|connectionPool.trustStorePassword |The password of the `trustStore` if it is password-protected |_none_
+|connectionPool.validationRequest |A script that is used to test server connectivity. A good script to use is one that evaluates quickly and returns no data. The default simply returns an empty string, but if a graph is required by a particular provider, a good traversal might be `g.inject()`. |_''_
+|hosts |The list of hosts that the driver will connect to. |localhost
+|jaasEntry |Sets the `AuthProperties.Property.JAAS_ENTRY` properties for authentication to Gremlin Server. |_none_
+|nioPoolSize |Size of the pool for handling request/response operations. |available processors
+|password |The password to submit on requests that require authentication. |_none_
+|port |The port of the Gremlin Server to connect to. The same port will be applied for all hosts. |8192
+|protocol |Sets the `AuthProperties.Property.PROTOCOL` properties for authentication to Gremlin Server. |_none_
+|serializer.className |The fully qualified class name of the `MessageSerializer` that will be used to communicate with the server. Note that the serializer configured on the client should be supported by the server configuration. |_none_
+|serializer.config |A `Map` of configuration settings for the serializer. |_none_
+|username |The username to submit on requests that require authentication. |_none_
+|workerPoolSize |Size of the pool for handling background work. |available processors * 2
+|=========================================================
+
+Please see the link:http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/driver/Cluster.Builder.html[Cluster.Builder javadoc] to get more information on these settings.
+
+=== Serialization
+
+Serialization applies when using the driver to submit Gremlin to a remote system in some way. TinkerPop has two
+options for serialization built into it for JVM-based languages: Gryo and GraphSON. When using Gryo serialization
+(the default serializer for the Java driver), it is important that the client and server have the same serializers
+configured or else one or the other will experience serialization exceptions and fail to always communicate.
+Discrepancy in serializer registration between client and server can happen fairly easily as graphs will automatically
+include serializers on the server-side, thus leaving the client to be configured manually. This can be done manually
+as follows:
+
+[source,java]
+----
+IoRegistry registry = ...; // an IoRegistry instance exposed by a specific graph provider
+GryoMapper kryo = GryoMapper.build().addRegistry(registry).create();
+MessageSerializer serializer = new GryoMessageSerializerV3d0(kryo);
+Cluster cluster = Cluster.build().
+                          serializer(serializer).
+                          create();
+Graph graph = EmptyGraph.instance();
+GraphTraversalSource g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster, "g"));
+----
+
+The `IoRegistry` tells the serializer what classes from the graph provider to auto-register during serialization.
+Gremlin Server roughly uses this same approach when it configures it's serializers, so using this same model will
+ensure compatibility when making requests. Obviously, it is possible to switch to GraphSON by building a
+`GraphSONMessageSerializerV3d0` in the same way and building that into the `Cluster` object
 
 === The Lambda Solution
 
 Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous functions] across languages is difficult as
-most languages do not support lambda introspection and thus, code analysis. In Gremlin-Java, Java8 lambdas can be leveraged.
+most languages do not support lambda introspection and thus, code analysis. In Gremlin-Java and with
+<<connecting-embedded,embedded>> usage, lambdas can be leveraged directly:
 
 [source,java]
 g.V().out("knows").map(t -> t.get().value("name") + " is the friend name") <1>
 g.V().out("knows").sideEffect(System.out::println) <2>
 g.V().as("a").out("knows").as("b").select("b").by((Function<Vertex, Integer>) v -> v.<String>value("name").length()) <3>
 
-<1> A Java8 function is used to map a `Traverser<S>` to an object `E`.
-<2> Gremlin steps that take consumer arguments can be passed Java8 method references.
+<1> A Java `Function` is used to map a `Traverser<S>` to an object `E`.
+<2> Gremlin steps that take consumer arguments can be passed Java method references.
 <3> Gremlin-Java may sometimes require explicit lambda typing when types can not be automatically inferred.
 
-When sending traversals over the wire via a `RemoteConnection`, the static methods of `Lambda` should be used
-and should denote a particular JSR-223 `ScriptEngine`. `Lambda` creates a string-based lambda that is then converted
-into a lambda/closure/anonymous-function/etc. by the respective lambda language's JSR-223 `ScriptEngine` implementation.
+When sending traversals remotely to <<connecting-gremlin-server,Gremlin Server>> or
+<<connecting-rgp,Remote Gremlin Providers>>, the static methods of `Lambda` should be used and should denote a
+particular JSR-223 `ScriptEngine`. `Lambda` creates a string-based lambda that is then converted into a
+lambda/closure/anonymous-function/etc. by the respective lambda language's JSR-223 `ScriptEngine` implementation.
 
 [source,java]
 g.V().out("knows").map(Lambda.function("it.get().value('name') + ' is the friend name'"))
 g.V().out("knows").sideEffect(Lambda.consumer("println it"))
 g.V().as("a").out("knows").as("b").select("b").by(Lambda.<Vertex,Integer>function("it.value('name').length()"))
 
+Finally, Gremlin `Bytecode` that includes lambdas requires that the traversal be processed by the
+`GremlinScriptEngine`. To avoid continued recompilation costs, it supports the encoding of bindings,
+which allow Gremlin Server to cache traversals that will be reused over and over again save that some
+parameterization may change. Thus, instead of translating, compiling, and then executing each submitted bytecode,
+it is possible to simply execute. To express bindings in Java, use `Bindings`.
+
+[gremlin-groovy]
+----
+cluster = Cluster.open('conf/remote-objects.yaml')
+b = Bindings.instance()
+g = EmptyGraph.instance().traversal().withRemote(DriverRemoteConnection.using(cluster, "g"))
+g.V(b.of('id',1)).out('created').values('name').map{t -> "name: " + t.get() }
+g.V(b.of('id',4)).out('created').values('name').map{t -> "name: " + t.get() }
+g.V(b.of('id',4)).out('created').values('name').getBytecode()
+g.V(b.of('id',4)).out('created').values('name').getBytecode().getBindings()
+cluster.close()
+----
+
+Both traversals are abstractly defined as `g.V(id).out('created').values('name')` and thus, the first submission
+can be cached for faster evaluation on the next submission.
+
+WARNING: It is generally advised to avoid lambda usage. Please consider <<a-note-on-lambdas,A Note On Lambdas>> for
+more information.
+
+=== Submitting Scripts
+
+WARNING: TinkerPop does not recommend submitting script-based requests and generally continues to support this feature
+for legacy reasons and corner use cases which are still not completely addressed by the Gremlin language. Please
+consider using bytecode-based requests instead when possible.
+
+image:gremlin-java.png[width=175,float=left] TinkerPop comes equipped with a reference client for Java-based
+applications.  It is referred to as Gremlin Driver, which enables applications to send requests to Gremlin Server
+and get back results.
+
+Gremlin code is sent to the server from a `Client` instance.  A `Client` is created as follows:
+
+[source,java]
+----
+Cluster cluster = Cluster.open();  <1>
+Client client = cluster.connect(); <2>
+----
+
+<1> Opens a reference to `localhost` - note that there are many configuration options available in defining a `Cluster` object.
+<2> Creates a `Client` given the configuration options of the `Cluster`.
+
+Once a `Client` instance is ready, it is possible to issue some Gremlin:
+
+[source,java]
+----
+ResultSet results = client.submit("[1,2,3,4]");  <1>
+results.stream().map(i -> i.get(Integer.class) * 2);       <2>
+
+CompletableFuture<List<Result>> results = client.submit("[1,2,3,4]").all();  <3>
+
+CompletableFuture<ResultSet> future = client.submitAsync("[1,2,3,4]"); <4>
+
+Map<String,Object> params = new HashMap<>();
+params.put("x",4);
+client.submit("[1,2,3,x]", params); <5>
+----
+
+<1> Submits a script that simply returns a `List` of integers.  This method blocks until the request is written to
+the server and a `ResultSet` is constructed.
+<2> Even though the `ResultSet` is constructed, it does not mean that the server has sent back the results (or even
+evaluated the script potentially).  The `ResultSet` is just a holder that is awaiting the results from the server.
+In this case, they are streamed from the server as they arrive.
+<3> Submit a script, get a `ResultSet`, then return a `CompletableFuture` that will be called when all results have been returned.
+<4> Submit a script asynchronously without waiting for the request to be written to the server.
+<5> Parameterized request are considered the most efficient way to send Gremlin to the server as they can be cached,
+which will boost performance and reduce resources required on the server.
+
+==== Per Request Settings
+
+There are a number of overloads to `Client.submit()` that accept a `RequestOptions` object. The `RequestOptions`
+provide a way to include options that are specific to the request made with the call to `submit()`. A good use-case for
+this feature is to set a per-request override to the `scriptEvaluationTimeout` so that it only applies to the current
+request.
+
+[source,java]
+----
+Cluster cluster = Cluster.open();
+Client client = cluster.connect();
+RequestOptions options = RequestOptions.build().timeout(500).create();
+List<Result> result = client.submit("g.V()", options).all().get();
+----
+
+==== Aliases
+
+Scripts submitted to Gremlin Server automatically have the globally configured `Graph` and `TraversalSource` instances
+made available to them.  Therefore, if Gremlin Server configures two `TraversalSource` instances called "g1" and "g2"
+a script can simply reference them directly as:
+
+[source,java]
+client.submit("g1.V()")
+client.submit("g2.V()")
+
+While this is an acceptable way to submit scripts, it has the downside of forcing the client to encode the server-side
+variable name directly into the script being sent.  If the server configuration ever changed such that "g1" became
+"g100", the client-side code might have to see a significant amount of change.  Decoupling the script code from the
+server configuration can be managed by the `alias` method on `Client` as follows:
+
+[source,java]
+Client g1Client = client.alias("g1")
+Client g2Client = client.alias("g2")
+g1Client.submit("g.V()")
+g2Client.submit("g.V()")
+
+The above code demonstrates how the `alias` method can be used such that the script need only contain a reference
+to "g" and "g1" and "g2" are automatically rebound into "g" on the server-side.
+
 [[gremlin-groovy]]
 == Gremlin-Groovy
 
@@ -171,6 +520,23 @@ Likewise, if it has lambdas represented in Python, it will use Gremlin-Python (e
 IMPORTANT: Gremlin-Python's `Traversal` class supports the standard Gremlin methods such as `next()`, `nextTraverser()`,
 `toSet()`, `toList()`, etc. Such "terminal" methods trigger the evaluation of the traversal.
 
+==== Configuration
+
+The following table describes the various configuration options for the Gremlin-Python Driver. They
+can be passed to the `Client` or `DriverRemoteConnection` instance as keyword arguments:
+
+[width="100%",cols="3,10,^2",options="header"]
+|=========================================================
+|Key |Description |Default
+|protocol_factory |A callable that returns an instance of `AbstractBaseProtocol`. |`gremlin_python.driver.protocol.GremlinServerWSProtocol`
+|transport_factory |A callable that returns an instance of `AbstractBaseTransport`. |`gremlin_python.driver.tornado.transport.TornadoTransport`
+|pool_size |The number of connections used by the pool. |4
+|max_workers |Maximum number of worker threads. |Number of CPUs * 5
+|message_serializer |The message serializer implementation.|`gremlin_python.driver.serializer.GraphSONMessageSerializer`
+|password |The password to submit on requests that require authentication. |""
+|username |The username to submit on requests that require authentication. |""
+|=========================================================
+
 === RemoteConnection Submission
 
 There are various ways to submit a traversal to a `RemoteConnection`. Just as in Gremlin-Java, there are various
@@ -311,6 +677,60 @@ g.V().out().map(lambda: "x: len(x.get().value('name'))").sum().toList()
 within a collection across different languages. In the case of Python, number equality is different from JVM languages
 which produces different `Set` results when those types are in use. If a `Set` is needed then convert `List` results
 to `Set` manually.
+* Gremlin is capable of returning Dictionary results that use non-hashable keys (e.g. Dictionary as a key) and Python
+does not support that at a language level. Gremlin that returns such results will need to be re-written to avoid that.
+
+=== Submitting Scripts
+
+WARNING: TinkerPop does not recommend submitting script-based requests and generally continues to support this feature
+for legacy reasons and corner use cases which are still not completely addressed by the Gremlin language. Please
+consider using bytecode-based requests instead when possible.
+
+The `Client` class implementation/interface is based on the Java Driver, with some restrictions. Most notably,
+Gremlin-Python does not yet implement the `Cluster` class. Instead, `Client` is instantiated directly.
+Usage is as follows:
+
+[source,python]
+----
+from gremlin_python.driver import client <1>
+client = client.Client('ws://localhost:8182/gremlin', 'g') <2>
+----
+
+<1> Import the Gremlin-Python `client` module.
+<2> Opens a reference to `localhost` - note that there are various configuration options that can be passed
+to the `Client` object upon instantiation as keyword arguments.
+
+Once a `Client` instance is ready, it is possible to issue some Gremlin:
+
+[source,python]
+----
+result_set = client.submit("[1,2,3,4]")  <1>
+future_results = result_set.all()  <2>
+results = future_results.result() <3>
+assert results == [1, 2, 3, 4] <4>
+
+future_result_set = client.submitAsync("[1,2,3,4]") <5>
+result_set = future_result_set.result() <6>
+result = result_set.one() <7>
+assert results == [1, 2, 3, 4] <8>
+assert result_set.done.done() <9>
+
+client.close() <10>
+----
+
+<1> Submit a script that simply returns a `List` of integers.  This method blocks until the request is written to
+the server and a `ResultSet` is constructed.
+<2> Even though the `ResultSet` is constructed, it does not mean that the server has sent back the results (or even
+evaluated the script potentially).  The `ResultSet` is just a holder that is awaiting the results from the server. The `all` method
+returns a `concurrent.futures.Future` that resolves to a list when it is complete.
+<3> Block until the the script is evaluated and results are sent back by the server.
+<4> Verify the result.
+<5> Submit the same script to the server but don't block.
+<6> Wait until request is written to the server and `ResultSet` is constructed.
+<7> Read a single result off the result stream.
+<8> Again, verify the result.
+<9> Verify that the all results have been read and stream is closed.
+<10> Close client and underlying pool connections.
 
 [[gremlin-DotNet]]
 == Gremlin.Net
diff --git a/docs/src/reference/intro.asciidoc b/docs/src/reference/intro.asciidoc
index db5eab6..3bf62bf 100644
--- a/docs/src/reference/intro.asciidoc
+++ b/docs/src/reference/intro.asciidoc
@@ -383,7 +383,12 @@ and function. As with the embedded approach, the means of connection is based on
 followed by construction of a `GraphTraversalSource` with some "remote" options that describe the location of the
 Gremlin Server they wish to connect to:
 
-[gremlin-groovy]
+[source,java,tab]
+----
+Graph graph = EmptyGraph.instance();
+GraphTraversalSource g = graph.traversal().withRemote('conf/remote-graph.properties');
+----
+[source,groovy]
 ----
 graph = EmptyGraph.instance()
 g = graph.traversal().withRemote('conf/remote-graph.properties')
@@ -393,11 +398,6 @@ g = graph.traversal().withRemote('conf/remote-graph.properties')
 var graph = new Graph();
 var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182))));
 ----
-[source,java]
-----
-Graph graph = EmptyGraph.instance();
-GraphTraversalSource g = graph.traversal().withRemote('conf/remote-graph.properties');
-----
 [source,javascript]
 ----
 const graph = new Graph();


[tinkerpop] 02/07: Rewrote the graph section of reference docs.

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2002
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit c665f7069bb0bfc72058cd83eb72a4c8763af1d2
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Wed Oct 17 15:07:47 2018 -0400

    Rewrote the graph section of reference docs.
    
    Tried to bring it into context with how the intro was written which set readers up thinking about how the ways you connect to tinkerpop affect certain aspects of features/capabilties/portability
---
 docs/src/reference/gremlin-applications.asciidoc |  14 +--
 docs/src/reference/intro.asciidoc                |   5 ++
 docs/src/reference/the-graph.asciidoc            | 108 +++++++++++++++++++++--
 3 files changed, 112 insertions(+), 15 deletions(-)

diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 0035de0..b930f96 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -2025,13 +2025,13 @@ client.submit("[1,2,3,x]", params);
 [[sessions]]
 ==== Considering Sessions
 
-The preferred approach for issuing requests to Gremlin Server is to do so in a sessionless manner.  The concept of
-"sessionless" refers to a request that is completely encapsulated within a single transaction, such that the script
-in the request starts with a new transaction and ends with a closed transaction. Sessionless requests have automatic
-transaction management handled by Gremlin Server, thus automatically opening and closing transactions as previously
-described.  The downside to the sessionless approach is that the entire script to be executed must be known at the
-time of submission so that it can all be executed at once.  This requirement makes it difficult for some use cases
-where more control over the transaction is desired.
+The preferred approach for issuing script-based requests to Gremlin Server is to do so in a sessionless manner.  The
+concept of "sessionless" refers to a request that is completely encapsulated within a single transaction, such that
+the script in the request starts with a new transaction and ends with a closed transaction. Sessionless requests have
+automatic transaction management handled by Gremlin Server, thus automatically opening and closing transactions as
+previously described.  The downside to the sessionless approach is that the entire script to be executed must be known
+at the time of submission so that it can all be executed at once.  This requirement makes it difficult for some use
+cases where more control over the transaction is desired.
 
 For such use cases, Gremlin Server supports sessions.  With sessions, the user is in complete control of the start
 and end of the transaction. This feature comes with some additional expense to consider:
diff --git a/docs/src/reference/intro.asciidoc b/docs/src/reference/intro.asciidoc
index aee394d..bba00f1 100644
--- a/docs/src/reference/intro.asciidoc
+++ b/docs/src/reference/intro.asciidoc
@@ -154,6 +154,7 @@ then a concise name is provided (e.g. `out()`, `path()`, `repeat()`). If the met
 providers, then the standard Java naming convention is followed (e.g. `getNextStep()`, `getSteps()`,
 `getElementComputeKeys()`).
 
+[[graph-structure]]
 === The Graph Structure
 
 image:gremlin-standing.png[width=125,float=left] A graph's structure is the topology formed by the explicit references
@@ -569,6 +570,10 @@ extensive, but some <<connecting-gsp,Graph Service Providers>> may not completel
 of the Gremlin language. For the most part, that doesn't disqualify them from being any less TinkerPop-enabled than
 another provider that might meet the semantics perfectly. Take care when considering a new graph and pay attention to
 what it supports and does not support.
+* <<graph,Graph API>> - The <<graph-structure, Graph API>> (also referred to as the Structure API) is not always accessible to
+users. Its accessibility is dependent on the choice of graph system and programming language. It is therefore
+recommended that users avoid usage of methods like `Graph.addVertex()` or `Vertex.properties()` and instead prefer
+use of Gremlin with `g.addV()` or `g.V(1).properties()`.
 
 Outside of considering these points, the best practice for ensuring the greatest level of compatibility across graphs
 is to avoid <<connecting-embedded,embedded>> mode and stick to the bytecode based approaches explained in the
diff --git a/docs/src/reference/the-graph.asciidoc b/docs/src/reference/the-graph.asciidoc
index c7001a9..ea86b5f 100644
--- a/docs/src/reference/the-graph.asciidoc
+++ b/docs/src/reference/the-graph.asciidoc
@@ -19,6 +19,44 @@ limitations under the License.
 
 image::gremlin-standing.png[width=125]
 
+The <<intro,Introduction>> discussed the diversity of TinkerPop-enabled graphs, with special attention paid to the
+different <<connecting-gremlin,connection models>>, and how TinkerPop makes it possible to bridge that diversity in
+an <<staying-agnostic,agnostic> manner. This particular section deals with elements of the Graph API which was noted
+as an API to avoid when trying to build an agnostic system. The Graph API refers to the core elements of what composes
+the <<graph-computing,structure of a graph>> within the Gremlin Virtual Machine (GVM), such as the `Graph`, `Vertex`
+and `Edge` Java interfaces.
+
+To maintain the most portable code, users should only reference these interfaces. To "reference", simply means to
+utilize it as a pointer. For `Graph`, that means holding a pointer to the location of graph data and then using it to
+spawn `GraphTraversalSource` instances so as to write Gremlin:
+
+[gremlin-groovy]
+----
+graph = TinkerGraph.open()
+g = graph.traversal()
+g.addV('person')
+----
+
+In the above example, "graph" is the `Graph` interface produced by calling `open()` on `TinkerGraph` which creates the
+instance. Note that while the end intent of the code is to create a "person" vertex, it does not use the APIs on
+`Graph` to do that - e.g. `graph.addVertex(T.label,'person')`.
+
+Even if the developer desired to use the `graph.addVertex()` method there are only a handful of scenarios where it is
+possible:
+
+* The application is being developed on the JVM and the developer is using <<connecting-embedded, Embedded>> mode
+* The architecture includes Gremlin Server and the user is sending Gremlin scripts to the server
+* The graph system chosen is a <<connecting-gsp, Gremlin Service Provider>> and they expose the Graph API via scripts
+
+Note that Gremlin Language Variants force developers to use the Graph API by reference. There is no `addVertex()`
+method available to GLVs on their respective `Graph` instances, nor are their graph elements filled with data at the
+call of `properties()`. Developing applications to meet this lowest common denominator in API usage will go a long
+way to making that application portable across TinkerPop-enabled systems.
+
+When considering the remaining sub-sections that follow, recall that they are all generally bound to the Graph API.
+They are described here for reference and in some sense backward compatibility with older recommended models of
+development. In the future, the contents of this section will become less and less relevant.
+
 == Features
 
 A `Feature` implementation describes the capabilities of a `Graph` instance. This interface is implemented by graph
@@ -47,6 +85,10 @@ TIP: To ensure provider agnostic code, always check feature support prior to usa
 way, the application can behave gracefully in case a particular implementation is provided at runtime that does not
 support a function being accessed.
 
+WARNING: Features of reference graphs which are used to connect to remote graphs do not reflect the features of the
+graph to which it connects. It reflects the features of instantiated graph itself, which will likely be quite
+different considering that reference graphs will typically be immutable.
+
 [[vertex-properties]]
 == Vertex Properties
 
@@ -57,8 +99,8 @@ pairs. Moreover, while an `Edge` can only have one property of key "name" (for e
 "name" properties. With the inclusion of vertex properties, two features are introduced which ultimately advance the
 graph modelers toolkit:
 
-. Multiple properties (*multi-properties*): a vertex property key can have multiple values.  For example, a vertex can have
-multiple "name" properties.
+. Multiple properties (*multi-properties*): a vertex property key can have multiple values.  For example, a vertex can
+have multiple "name" properties.
 . Properties on properties (*meta-properties*): a vertex property can have properties (i.e. a vertex property can
 have key/value data associated with it).
 
@@ -162,14 +204,28 @@ graph.variables().keys()
 IMPORTANT: Graph variables are not intended to be subject to heavy, concurrent mutation nor to be used in complex
 computations. The intention is to have a location to store data about the graph for administrative purposes.
 
+WARNING: Attempting to set graph variables in a reference graph will not promote them to the remote graph. Typically,
+a reference graph has immutable features and will not support this features.
+
 [[transactions]]
 == Graph Transactions
 
 image:gremlin-coins.png[width=100,float=right] A link:http://en.wikipedia.org/wiki/Database_transaction[database transaction]
-represents a unit of work to execute against the database.  Transactions are controlled by an implementation of the
-`Transaction` interface and that object can be obtained from the `Graph` interface using the `tx()` method.  It is
-important to note that the `Transaction` object does not represent a "transaction" itself.  It merely exposes the
-methods for working with transactions (e.g. committing, rolling back, etc).
+represents a unit of work to execute against the database. Transactions in TinkerPop can be considered in several
+contexts: transactions for <<connecting-embedded,embedded graphs>> via the Graph API,
+transactions for <<connecting-gremlin-server,Gremlin Server>> and transactions within
+<<connecting-gsp,Graph Service Providers>>. For those following recommended patterns, the concepts presented in the
+embedded section should generally be of little interest and are present mainly for reference. Utilizing those
+transactional features will greatly reduce the portability of an application's Gremlin code.
+
+[[tx-embedded]]
+=== Embedded
+
+When on the JVM using an <<connecting-embedded,embedded graph>>, there is considerable flexibility for working with
+transactions. With the Graph API, transactions are controlled by an implementation of the `Transaction` interface and
+that object can be obtained from the `Graph` interface using the `tx()` method.  It is important to note that the
+`Transaction` object does not represent a "transaction" itself.  It merely exposes the methods for working with
+transactions (e.g. committing, rolling back, etc).
 
 Most `Graph` implementations that `supportsTransactions` will implement an "automatic" `ThreadLocal` transaction,
 which means that when a read or write occurs after the `Graph` is instantiated, a transaction is automatically
@@ -194,7 +250,7 @@ graph system provider to choose the specific aspects of how their implementation
 TinkerPop stack. Be sure to understand the transaction semantics of the specific graph implementation that is being
 utilized as it may present differing functionality than described here.
 
-=== Configuring
+==== Configuring
 
 Determining when a transaction starts is dependent upon the behavior assigned to the `Transaction`.  It is up to the
 `Graph` implementation to determine the default behavior and unless the implementation doesn't allow it, the behavior
@@ -277,7 +333,7 @@ NOTE: It may be important to consult the documentation of the `Graph` implementa
 specifics of how transactions will behave.  TinkerPop allows some latitude in this area and implementations may not have
 the exact same behaviors and link:https://en.wikipedia.org/wiki/ACID[ACID] guarantees.
 
-=== Threaded Transactions
+==== Threaded Transactions
 
 Most `Graph` implementations that support transactions do so in a `ThreadLocal` manner, where the current transaction
 is bound to the current thread of execution. Consider the following example to demonstrate:
@@ -342,6 +398,42 @@ In the above case, the call to `graph.tx().createThreadedTx()` creates a new `Gr
 `ThreadLocal` transaction, thus allowing each thread to operate on it in the same context.  In this case, there would
 be three separate vertices persisted to the `Graph`.
 
+[[tx-gremlin-server]]
+=== Gremlin Server
+
+The available capability for transactions with <<gremlin-server,Gremlin Server>> is dependent upon the method of
+interaction that is used. The preferred method for <<connecting-gremlin-server,interacting with Gremlin Server>>
+is via websockets and bytecode based requests. In this mode of operations each Gremlin traversal that is executed will
+be treated as a single transaction. Traversals that fail will have their transaction rolled back and successful
+iteration of a traversal will conclude with a transactional commit. How the graph hosted in Gremlin Server reacts to
+those commands is dependent on the graph chosen and it is therefore important to understand the transactional semantics
+of that graph when developing an application.
+
+Gremlin Server also has the option to accept Gremlin-based scripts. The scripting approach provides access to the
+Graph API and thus also the transactional model described in the <<tx-embedded,embedded>> section. Therefore a single
+script can have the ability to execute multiple transactions per request with complete control provided to the
+developer to commit or rollback transactions as needed.
+
+There are two methods for sending scripts to Gremlin Server: sessionless and session-based. With sessionless requests
+there will always be an attempt to close the transaction at the end of the request with a commit if there are no errors
+or a rollback if there is a failure. It is therefore unnecessary to close transactions manually within scripts
+themselves. By default, session-based requests do not have this quality. The transaction will be held open on the
+server until the user closes it manually. There is an option to have automatic transaction management for sessions.
+More information on this topic can be found in the <<considering-transactions,Considering Transactions>> Section and
+the <<sessions,Considering Sessions>> Section.
+
+While those sections provide some additional details, the short advice is to avoid scripts when possible and prefer
+bytecode based requests.
+
+[[tx-gsp]]
+=== Gremlin Service Providers
+
+At this time, transactional patterns for Gremlin Service Providers are largely in line with Gremlin Server. Most
+offer bytecode or script based sessionless requests, which have automatic transaction management, such that a
+successful traversal will commit on success and a failing traversal will rollback. As most of these GSPs do not
+expose a `Graph` instances, access to lower level transactional functions even in a sessionless fashion are not
+typically allowed.           
+
 == Namespace Conventions
 
 End users, <<implementations,graph system providers>>, <<graphcomputer,`GraphComputer`>> algorithm designers,


[tinkerpop] 03/07: Changed from Gremlin Service Provider to Remote Gremlin Provider

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2002
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 3722a088d1511f9a900871596972dfd16bd1e724
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Wed Oct 17 15:35:38 2018 -0400

    Changed from Gremlin Service Provider to Remote Gremlin Provider
    
    Using "remote" in the name is good because it better captures non-cloud based systems that deploy in this fashion.
---
 docs/src/reference/intro.asciidoc         | 18 +++++++++---------
 docs/src/reference/the-graph.asciidoc     | 15 ++++++++-------
 docs/src/reference/the-traversal.asciidoc | 16 ++++++++++------
 3 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/docs/src/reference/intro.asciidoc b/docs/src/reference/intro.asciidoc
index bba00f1..db5eab6 100644
--- a/docs/src/reference/intro.asciidoc
+++ b/docs/src/reference/intro.asciidoc
@@ -317,7 +317,7 @@ of the following places:
 
 * Embedded in a Java application
 * Hosted in Gremlin Server
-* Exposed by a remote Gremlin Service Provider
+* Exposed by a remote Remote Gremlin Provider
 
 The following sections outline each of these models and what they impact they have to using Gremlin.
 
@@ -442,18 +442,18 @@ IMPORTANT: Most SQL developers would not write a query as `SELECT * FROM table`.
 individual names of the fields they wanted in place of the wildcard. Writing "good" Gremlin is no different with this
 regard. Prefer explicit property key names in Gremlin unless it is completely impossible to do so.
 
-[[connecting-gsp]]
-=== Gremlin Service Provider
+[[connecting-rgp]]
+=== Remote Gremlin Provider
 
-Gremlin Service Providers (GSPs) are showing up more and more often in the graph database space. In TinkerPop terms,
+Gremlin Service Providers (RGPs) are showing up more and more often in the graph database space. In TinkerPop terms,
 this category of graph providers are ones who simply support the Gremlin language. Typically, these are server-based
 graphs, often cloud-based, which accept Gremlin scripts or bytecode as a request and return results. They will often
 implement Gremlin Server protocols, which enables TinkerPop drivers to connect to them as they would with Gremlin
 Server. Therefore, the typical connection approach is identical to the method of connection presented in the
 <<connecting-gremlin-server,previous section>> with the exact same caveats pointed out toward the end.
 
-Despite leveraging TinkerPop protocols and drivers as being typical, GSPs are not required to do so to be considered
-TinkerPop-enabled. GSPs may well have their own drivers and protocols that may plug into GLVs and may allow for more
+Despite leveraging TinkerPop protocols and drivers as being typical, RGPs are not required to do so to be considered
+TinkerPop-enabled. RGPs may well have their own drivers and protocols that may plug into GLVs and may allow for more
 advanced options like better security, cluster awareness, batched requests or other features. The details of these
 different systems are outside the scope of this documentation so be sure to consult their documentation for more
 information.
@@ -463,7 +463,7 @@ information.
 
 The `GraphTraversalSource` is basically the connection to a graph instance. That graph instance might be
 <<connecting-embedded,embedded>>, hosted in <<connecting-gremlin-server,Gremlin Server>> or hosted in a
-<<connecting-gsp,GSP>>, but the `GraphTraversalSource` is agnostic to that, because this object allows users to write
+<<connecting-rgp,RGP>>, but the `GraphTraversalSource` is agnostic to that, because this object allows users to write
 Gremlin. Assuming "g" is the `GraphTraversalSource`, getting data into the graph regardless of programming language
 or mode of operation is just some Gremlin:
 
@@ -566,7 +566,7 @@ link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/gremlins-anatomy/#_express
 certain features of that specific graph shine in powerful ways. Using those options is probably recommended, but users
 should be aware that doing so ties them more tightly to that graph.
 * Graph specific semantics - TinkerPop tries to enforce specific semantics through its test suite which is quite
-extensive, but some <<connecting-gsp,Graph Service Providers>> may not completely respect all the semantics
+extensive, but some <<connecting-rgp,Remote Gremlin Providers>> may not completely respect all the semantics
 of the Gremlin language. For the most part, that doesn't disqualify them from being any less TinkerPop-enabled than
 another provider that might meet the semantics perfectly. Take care when considering a new graph and pay attention to
 what it supports and does not support.
@@ -577,7 +577,7 @@ use of Gremlin with `g.addV()` or `g.V(1).properties()`.
 
 Outside of considering these points, the best practice for ensuring the greatest level of compatibility across graphs
 is to avoid <<connecting-embedded,embedded>> mode and stick to the bytecode based approaches explained in the
-<<connecting-gremlin-server,Gremlin Server>> and the <<connecting-gsp,GSP>> sections above. It creates the least
+<<connecting-gremlin-server,Gremlin Server>> and the <<connecting-rgp,RGP>> sections above. It creates the least
 opportunity to stray from the agnostic path as anything that can be done with those two modes also works in embedded
 mode. If using embedded mode, simply write code as though the `Graph` instance is "remote" and not local to the JVM.
 In other words, write code as though the GVM is not available locally. Taking that approach and isolating the points
diff --git a/docs/src/reference/the-graph.asciidoc b/docs/src/reference/the-graph.asciidoc
index ea86b5f..4d58409 100644
--- a/docs/src/reference/the-graph.asciidoc
+++ b/docs/src/reference/the-graph.asciidoc
@@ -46,7 +46,7 @@ possible:
 
 * The application is being developed on the JVM and the developer is using <<connecting-embedded, Embedded>> mode
 * The architecture includes Gremlin Server and the user is sending Gremlin scripts to the server
-* The graph system chosen is a <<connecting-gsp, Gremlin Service Provider>> and they expose the Graph API via scripts
+* The graph system chosen is a <<connecting-rgp, Remote Gremlin Provider>> and they expose the Graph API via scripts
 
 Note that Gremlin Language Variants force developers to use the Graph API by reference. There is no `addVertex()`
 method available to GLVs on their respective `Graph` instances, nor are their graph elements filled with data at the
@@ -214,7 +214,7 @@ image:gremlin-coins.png[width=100,float=right] A link:http://en.wikipedia.org/wi
 represents a unit of work to execute against the database. Transactions in TinkerPop can be considered in several
 contexts: transactions for <<connecting-embedded,embedded graphs>> via the Graph API,
 transactions for <<connecting-gremlin-server,Gremlin Server>> and transactions within
-<<connecting-gsp,Graph Service Providers>>. For those following recommended patterns, the concepts presented in the
+<<connecting-rgp,Remote Gremlin Providers>>. For those following recommended patterns, the concepts presented in the
 embedded section should generally be of little interest and are present mainly for reference. Utilizing those
 transactional features will greatly reduce the portability of an application's Gremlin code.
 
@@ -425,14 +425,15 @@ the <<sessions,Considering Sessions>> Section.
 While those sections provide some additional details, the short advice is to avoid scripts when possible and prefer
 bytecode based requests.
 
-[[tx-gsp]]
-=== Gremlin Service Providers
+[[tx-rgp]]
+=== Remote Gremlin Providers
 
-At this time, transactional patterns for Gremlin Service Providers are largely in line with Gremlin Server. Most
+At this time, transactional patterns for Remote Gremlin Providers are largely in line with Gremlin Server. Most
 offer bytecode or script based sessionless requests, which have automatic transaction management, such that a
-successful traversal will commit on success and a failing traversal will rollback. As most of these GSPs do not
+successful traversal will commit on success and a failing traversal will rollback. As most of these RGPs do not
 expose a `Graph` instances, access to lower level transactional functions even in a sessionless fashion are not
-typically allowed.           
+typically allowed. The nature of what a "transaction" means will be dependent on the RGP as is the case with any
+TinkerPop-enabled graph system, so it is important to consult that systems documentation for more details.
 
 == Namespace Conventions
 
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index 0fb7006..93a1207 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -162,18 +162,22 @@ g.V().out('created').fill(results) <8>
 g.addV('person').iterate() <9>
 ----
 
-<1> `hasNext()` determines whether there are available results.
+<1> `hasNext()` determines whether there are available results (not supported in `gremlin-javascript`).
 <2> `next()` will return the next result.
-<3> `next(n)` will return the next `n` results in a list.
-<4> `tryNext()` will return an `Optional` and thus, is a composite of `hasNext()`/`next()`.
+<3> `next(n)` will return the next `n` results in a list (not supported in `gremlin-javascript` or Gremlin.NET).
+<4> `tryNext()` will return an `Optional` and thus, is a composite of `hasNext()`/`next()` (only supported for JVM languages).
 <5> `toList()` will return all results in a list.
-<6> `toSet()` will return all results in a set (thus, duplicates removed).
-<7> `toBulkSet()` will return all results in a weighted set (thus, duplicates preserved via weighting).
-<8> `fill(collection)` will put all results in the provided collection and return the collection when complete.
+<6> `toSet()` will return all results in a set and thus, duplicates removed (not supported in `gremlin-javascript`).
+<7> `toBulkSet()` will return all results in a weighted set and thus, duplicates preserved via weighting (only supported for JVM languages).
+<8> `fill(collection)` will put all results in the provided collection and return the collection when complete (only supported for JVM languages).
 <9> `iterate()` does not exactly fit the definition of a terminal step in that it doesn't return a result, but still
 returns a traversal - it does however behave as a terminal step in that it iterates the traversal and generates side
 effects without returning the actual result.
 
+There is also the `promise()` terminator step, which can only be used with remote traversals to
+<<connecting-gremlin-server,Gremlin Server>> or <<connecting-rgp,RGPs>>. It starts a promise to execute a function
+on the current `Traversal` that will be completed in the future.
+
 Finally, <<explain-step,`explain()`>>-step is also a terminal step and is described in its own section.
 
 [[addedge-step]]