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

colegreer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/master by this push:
     new d9ab91229d Make range() and related steps parameterizable (#2981)
d9ab91229d is described below

commit d9ab91229d56b9a09e910c41d70566422ee15d6b
Author: Cole Greer <[email protected]>
AuthorDate: Thu Jan 16 16:11:46 2025 -0800

    Make range() and related steps parameterizable (#2981)
    
    Extends GValue Parameterization to range(), limit(), skip(), and tail() 
steps.
---
 docs/src/reference/the-traversal.asciidoc          |   4 +
 .../gremlin/language/grammar/ArgumentVisitor.java  |  28 +++++
 .../language/grammar/TraversalMethodVisitor.java   |  84 +++++++++++---
 .../traversal/dsl/graph/GraphTraversal.java        | 125 +++++++++++++++++++++
 .../gremlin/process/traversal/dsl/graph/__.java    |  56 +++++++++
 .../traversal/step/filter/RangeGlobalStep.java     |  35 +++---
 .../traversal/step/filter/TailGlobalStep.java      |  21 ++--
 .../process/traversal/step/map/RangeLocalStep.java |  21 ++--
 .../process/traversal/step/map/TailLocalStep.java  |  13 ++-
 .../language/grammar/ArgumentVisitorTest.java      |  17 +++
 .../gremlin-javascript/test/cucumber/gremlin.js    |   8 ++
 gremlin-language/src/main/antlr4/Gremlin.g4        |  16 +--
 gremlin-python/src/main/python/radish/gremlin.py   |   8 ++
 .../gremlin/test/features/filter/Range.feature     |  86 ++++++++++++++
 .../gremlin/test/features/filter/Tail.feature      |  26 +++++
 15 files changed, 491 insertions(+), 57 deletions(-)

diff --git a/docs/src/reference/the-traversal.asciidoc 
b/docs/src/reference/the-traversal.asciidoc
index cae5e05960..eeafb56e9c 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -5210,6 +5210,7 @@ a comparatively slow script compilation, which makes 
parameterization essential
 |<<vertex-steps,in()>> | String...edgeLabels
 |<<vertex-steps,inE()>> | String...edgeLabels
 |<<intersect-step,intersect()>> | Object values
+|<<limit-step,limit()>> | Long limit
 |<<merge-step,merge()>> | Object values
 |<<mergeedge-step,mergeE()>> | Map searchCreate
 |<<mergevertex-step,mergeV()>> | Map searchCreate
@@ -5217,6 +5218,9 @@ a comparatively slow script compilation, which makes 
parameterization essential
 |<<vertex-steps,out()>> | String...edgeLabels
 |<<vertex-steps,outE()>> | String...edgeLabels
 |<<product-step,product()>> | Object values
+|<<range-step,range()>> | Long low, Long high
+|<<skip-step,skip()>> | Long limit
+|<<tail-step,tail()>> | Long limit
 |<<to-step,to()>> | String... edgeLabels, Vertex toVertex
 |<<vertex-steps,toE()>> | String...edgeLabels
 |===
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitor.java
index e9eec826f4..519563451e 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitor.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.language.grammar;
 
+import 
org.apache.tinkerpop.gremlin.process.traversal.GremlinTypeErrorException;
 import org.apache.tinkerpop.gremlin.process.traversal.step.GType;
 import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -100,6 +101,33 @@ public class ArgumentVisitor extends 
DefaultGremlinBaseVisitor<Object> {
         }
     }
 
+    /**
+     * Equivalent to {@link 
ArgumentVisitor#visitIntegerArgument(GremlinParser.IntegerArgumentContext)} 
except this
+     * method promotes output types to either Long or GValue<Long>. 
(visitIntegerArgument() may produce byte, short,
+     * int, or long depending on the input script)
+     */
+    public Object parseLong(final GremlinParser.IntegerArgumentContext ctx) {
+        if (ctx.integerLiteral() != null) {
+            return 
antlr.genericVisitor.parseIntegral(ctx.integerLiteral()).longValue();
+        } else {
+            Object var = visitVariable(ctx.variable());
+            if (var instanceof Number) {
+                return ((Number) var).longValue();
+            }
+            if (GValue.valueInstanceOf(var, GType.LONG)) {
+                return var;
+            } else if (GValue.valueInstanceOf(var, GType.INTEGER)) {
+                return GValue.ofLong(((GValue<Integer>) var).getName(), 
((GValue<Integer>) var).get().longValue());
+            } else if (GValue.valueInstanceOf(var, GType.SHORT)) {
+                return GValue.ofLong(((GValue<Short>) var).getName(), 
((GValue<Short>) var).get().longValue());
+            } else if (GValue.valueInstanceOf(var, GType.BYTE)) {
+                return GValue.ofLong(((GValue<Byte>) var).getName(), 
((GValue<Byte>) var).get().longValue());
+            } else {
+                throw new GremlinParserException(String.format("Expected 
variable [%s] to resolve to an integer type, instead found: %s", 
ctx.variable().Identifier().getSymbol(), var.getClass().getName()));
+            }
+        }
+    }
+
     @Override
     public Object visitBooleanArgument(final 
GremlinParser.BooleanArgumentContext ctx) {
         if (ctx.booleanLiteral() != null) {
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
index 066b550b67..f7389aa82f 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
@@ -1022,8 +1022,14 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
      */
     @Override
     public GraphTraversal visitTraversalMethod_limit_Scope_long(final 
GremlinParser.TraversalMethod_limit_Scope_longContext ctx) {
-        return 
graphTraversal.limit(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
-                
antlr.genericVisitor.parseIntegral(ctx.integerLiteral()).longValue());
+        final Object literalOrVar = 
antlr.argumentVisitor.parseLong(ctx.integerArgument());
+        if (GValue.valueInstanceOf(literalOrVar, GType.LONG)) {
+            return 
graphTraversal.limit(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
+                    (GValue<Long>) literalOrVar);
+        } else {
+            return 
graphTraversal.limit(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
+                    (Long) literalOrVar);
+        }
     }
 
     /**
@@ -1031,7 +1037,12 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
      */
     @Override
     public GraphTraversal visitTraversalMethod_limit_long(final 
GremlinParser.TraversalMethod_limit_longContext ctx) {
-        return 
graphTraversal.limit(antlr.genericVisitor.parseIntegral(ctx.integerLiteral()).longValue());
+        final Object literalOrVar = 
antlr.argumentVisitor.parseLong(ctx.integerArgument());
+        if (GValue.valueInstanceOf(literalOrVar, GType.LONG)) {
+            return graphTraversal.limit((GValue<Long>) literalOrVar);
+        } else {
+            return graphTraversal.limit((Long) literalOrVar);
+        }
     }
 
     /**
@@ -1469,9 +1480,21 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
      */
     @Override
     public GraphTraversal visitTraversalMethod_range_Scope_long_long(final 
GremlinParser.TraversalMethod_range_Scope_long_longContext ctx) {
-        return 
graphTraversal.range(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
-                
antlr.genericVisitor.parseIntegral(ctx.integerLiteral(0)).longValue(),
-                
antlr.genericVisitor.parseIntegral(ctx.integerLiteral(1)).longValue());
+        Object low = antlr.argumentVisitor.parseLong(ctx.integerArgument(0));
+        Object high = antlr.argumentVisitor.parseLong(ctx.integerArgument(1));
+        if (GValue.valueInstanceOf(low, GType.LONG) || 
GValue.valueInstanceOf(high, GType.LONG)) {
+            if (!GValue.valueInstanceOf(low, GType.LONG)) {
+                low = GValue.ofLong(null, (Long) low);
+            }
+            if (!GValue.valueInstanceOf(high, GType.LONG)) {
+                high = GValue.ofLong(null, (Long) high);
+            }
+            return 
graphTraversal.range(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
+                    (GValue<Long>) low, (GValue<Long>) high);
+        } else {
+            return 
graphTraversal.range(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
+                    (Long) low, (Long) high);
+        }
     }
 
     /**
@@ -1479,8 +1502,19 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
      */
     @Override
     public GraphTraversal visitTraversalMethod_range_long_long(final 
GremlinParser.TraversalMethod_range_long_longContext ctx) {
-        return 
graphTraversal.range(antlr.genericVisitor.parseIntegral(ctx.integerLiteral(0)).longValue(),
-               
antlr.genericVisitor.parseIntegral(ctx.integerLiteral(1)).longValue());
+        Object low = antlr.argumentVisitor.parseLong(ctx.integerArgument(0));
+        Object high = antlr.argumentVisitor.parseLong(ctx.integerArgument(1));
+        if (GValue.valueInstanceOf(low, GType.LONG) || 
GValue.valueInstanceOf(high, GType.LONG)) {
+            if (!GValue.valueInstanceOf(low, GType.LONG)) {
+                low = GValue.ofLong(null, (Long) low);
+            }
+            if (!GValue.valueInstanceOf(high, GType.LONG)) {
+                high = GValue.ofLong(null, (Long) high);
+            }
+            return graphTraversal.range((GValue<Long>) low, (GValue<Long>) 
high);
+        } else {
+            return graphTraversal.range((Long) low, (Long) high);
+        }
     }
 
     /**
@@ -1594,8 +1628,14 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
      */
     @Override
     public GraphTraversal visitTraversalMethod_skip_Scope_long(final 
GremlinParser.TraversalMethod_skip_Scope_longContext ctx) {
-        return 
graphTraversal.skip(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
-                
antlr.genericVisitor.parseIntegral(ctx.integerLiteral()).longValue());
+        final Object literalOrVar = 
antlr.argumentVisitor.parseLong(ctx.integerArgument());
+        if (GValue.valueInstanceOf(literalOrVar, GType.LONG)) {
+            return 
graphTraversal.skip(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
+                    (GValue<Long>) literalOrVar);
+        } else {
+            return 
graphTraversal.skip(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
+                    (Long) literalOrVar);
+        }
     }
 
     /**
@@ -1603,7 +1643,12 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
      */
     @Override
     public GraphTraversal visitTraversalMethod_skip_long(final 
GremlinParser.TraversalMethod_skip_longContext ctx) {
-        return 
graphTraversal.skip(antlr.genericVisitor.parseIntegral(ctx.integerLiteral()).longValue());
+        final Object literalOrVar = 
antlr.argumentVisitor.parseLong(ctx.integerArgument());
+        if (GValue.valueInstanceOf(literalOrVar, GType.LONG)) {
+            return graphTraversal.skip((GValue<Long>) literalOrVar);
+        } else {
+            return graphTraversal.skip((Long) literalOrVar);
+        }
     }
 
     /**
@@ -1659,8 +1704,14 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
      */
     @Override
     public GraphTraversal visitTraversalMethod_tail_Scope_long(final 
GremlinParser.TraversalMethod_tail_Scope_longContext ctx) {
-        return 
graphTraversal.tail(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
-                
antlr.genericVisitor.parseIntegral(ctx.integerLiteral()).longValue());
+        final Object literalOrVar = 
antlr.argumentVisitor.parseLong(ctx.integerArgument());
+        if (GValue.valueInstanceOf(literalOrVar, GType.LONG)) {
+            return 
graphTraversal.tail(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
+                    (GValue<Long>) literalOrVar);
+        } else {
+            return 
graphTraversal.tail(TraversalEnumParser.parseTraversalEnumFromContext(Scope.class,
 ctx.traversalScope()),
+                    (Long) literalOrVar);
+        }
     }
 
     /**
@@ -1668,7 +1719,12 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
      */
     @Override
     public GraphTraversal visitTraversalMethod_tail_long(final 
GremlinParser.TraversalMethod_tail_longContext ctx) {
-        return 
graphTraversal.tail(antlr.genericVisitor.parseIntegral(ctx.integerLiteral()).longValue());
+        final Object literalOrVar = 
antlr.argumentVisitor.parseLong(ctx.integerArgument());
+        if (GValue.valueInstanceOf(literalOrVar, GType.LONG)) {
+            return graphTraversal.tail((GValue<Long>) literalOrVar);
+        } else {
+            return graphTraversal.tail((Long) literalOrVar);
+        }
     }
 
     /**
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index a876193578..c93b150002 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -3112,6 +3112,21 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
         return this.asAdmin().addStep(new RangeGlobalStep<>(this.asAdmin(), 
low, high));
     }
 
+    /**
+     * Filter the objects in the traversal by the number of them to pass 
through the stream. Those before the value
+     * of {@code low} do not pass through and those that exceed the value of 
{@code high} will end the iteration.
+     *
+     * @param low  the number at which to start allowing objects through the 
stream
+     * @param high the number at which to end the stream - use {@code -1} to 
emit all remaining objects
+     * @return the traversal with an appended {@link RangeGlobalStep}
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#range-step";
 target="_blank">Reference Documentation - Range Step</a>
+     * @since 4.0.0
+     */
+    public default GraphTraversal<S, E> range(final GValue<Long> low, final 
GValue<Long> high) {
+        this.asAdmin().getGremlinLang().addStep(Symbols.range, low, high);
+        return this.asAdmin().addStep(new RangeGlobalStep<>(this.asAdmin(), 
low, high));
+    }
+
     /**
      * Filter the objects in the traversal by the number of them to pass 
through the stream as constrained by the
      * {@link Scope}. Those before the value of {@code low} do not pass 
through and those that exceed the value of
@@ -3131,6 +3146,25 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
                 : new RangeLocalStep<>(this.asAdmin(), low, high));
     }
 
+    /**
+     * Filter the objects in the traversal by the number of them to pass 
through the stream as constrained by the
+     * {@link Scope}. Those before the value of {@code low} do not pass 
through and those that exceed the value of
+     * {@code high} will end the iteration.
+     *
+     * @param scope the scope of how to apply the {@code range}
+     * @param low   the number at which to start allowing objects through the 
stream
+     * @param high  the number at which to end the stream - use {@code -1} to 
emit all remaining objects
+     * @return the traversal with an appended {@link RangeGlobalStep} or 
{@link RangeLocalStep} depending on {@code scope}
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#range-step";
 target="_blank">Reference Documentation - Range Step</a>
+     * @since 4.0.0
+     */
+    public default <E2> GraphTraversal<S, E2> range(final Scope scope, final 
GValue<Long> low, final GValue<Long> high) {
+        this.asAdmin().getGremlinLang().addStep(Symbols.range, scope, low, 
high);
+        return this.asAdmin().addStep(scope.equals(Scope.global)
+                ? new RangeGlobalStep<>(this.asAdmin(), low, high)
+                : new RangeLocalStep<>(this.asAdmin(), low, high));
+    }
+
     /**
      * Filter the objects in the traversal by the number of them to pass 
through the stream, where only the first
      * {@code n} objects are allowed as defined by the {@code limit} argument.
@@ -3145,6 +3179,20 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
         return this.asAdmin().addStep(new RangeGlobalStep<>(this.asAdmin(), 0, 
limit));
     }
 
+    /**
+     * Filter the objects in the traversal by the number of them to pass 
through the stream, where only the first
+     * {@code n} objects are allowed as defined by the {@code limit} argument.
+     *
+     * @param limit the number at which to end the stream
+     * @return the traversal with an appended {@link RangeGlobalStep}
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#limit-step";
 target="_blank">Reference Documentation - Limit Step</a>
+     * @since 4.0.0
+     */
+    public default GraphTraversal<S, E> limit(final GValue<Long> limit) {
+        this.asAdmin().getGremlinLang().addStep(Symbols.limit, limit);
+        return this.asAdmin().addStep(new RangeGlobalStep<>(this.asAdmin(), 
GValue.ofLong(null, 0L), limit));
+    }
+
     /**
      * Filter the objects in the traversal by the number of them to pass 
through the stream given the {@link Scope},
      * where only the first {@code n} objects are allowed as defined by the 
{@code limit} argument.
@@ -3162,6 +3210,23 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
                 : new RangeLocalStep<>(this.asAdmin(), 0, limit));
     }
 
+    /**
+     * Filter the objects in the traversal by the number of them to pass 
through the stream given the {@link Scope},
+     * where only the first {@code n} objects are allowed as defined by the 
{@code limit} argument.
+     *
+     * @param scope the scope of how to apply the {@code limit}
+     * @param limit the number at which to end the stream
+     * @return the traversal with an appended {@link RangeGlobalStep} or 
{@link RangeLocalStep} depending on {@code scope}
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#limit-step";
 target="_blank">Reference Documentation - Limit Step</a>
+     * @since 4.0.0
+     */
+    public default <E2> GraphTraversal<S, E2> limit(final Scope scope, final 
GValue<Long> limit) {
+        this.asAdmin().getGremlinLang().addStep(Symbols.limit, scope, limit);
+        return this.asAdmin().addStep(scope.equals(Scope.global)
+                ? new RangeGlobalStep<>(this.asAdmin(), GValue.ofLong(null, 
0L), limit)
+                : new RangeLocalStep<>(this.asAdmin(), GValue.ofLong(null, 
0L), limit));
+    }
+
     /**
      * Filters the objects in the traversal emitted as being last objects in 
the stream. In this case, only the last
      * object will be returned.
@@ -3189,6 +3254,20 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
         return this.asAdmin().addStep(new TailGlobalStep<>(this.asAdmin(), 
limit));
     }
 
+    /**
+     * Filters the objects in the traversal emitted as being last objects in 
the stream. In this case, only the last
+     * {@code n} objects will be returned as defined by the {@code limit}.
+     *
+     * @param limit the number at which to end the stream
+     * @return the traversal with an appended {@link TailGlobalStep}
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#tail-step"; 
target="_blank">Reference Documentation - Tail Step</a>
+     * @since 4.0.0
+     */
+    public default GraphTraversal<S, E> tail(final GValue<Long> limit) {
+        this.asAdmin().getGremlinLang().addStep(Symbols.tail, limit);
+        return this.asAdmin().addStep(new TailGlobalStep<>(this.asAdmin(), 
limit));
+    }
+
     /**
      * Filters the objects in the traversal emitted as being last objects in 
the stream given the {@link Scope}. In
      * this case, only the last object in the stream will be returned.
@@ -3222,6 +3301,23 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
                 : new TailLocalStep<>(this.asAdmin(), limit));
     }
 
+    /**
+     * Filters the objects in the traversal emitted as being last objects in 
the stream given the {@link Scope}. In
+     * this case, only the last {@code n} objects will be returned as defined 
by the {@code limit}.
+     *
+     * @param scope the scope of how to apply the {@code tail}
+     * @param limit the number at which to end the stream
+     * @return the traversal with an appended {@link TailGlobalStep} or {@link 
TailLocalStep} depending on {@code scope}
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#tail-step"; 
target="_blank">Reference Documentation - Tail Step</a>
+     * @since 4.0.0
+     */
+    public default <E2> GraphTraversal<S, E2> tail(final Scope scope, final 
GValue<Long> limit) {
+        this.asAdmin().getGremlinLang().addStep(Symbols.tail, scope, limit);
+        return this.asAdmin().addStep(scope.equals(Scope.global)
+                ? new TailGlobalStep<>(this.asAdmin(), limit)
+                : new TailLocalStep<>(this.asAdmin(), limit));
+    }
+
     /**
      * Filters out the first {@code n} objects in the traversal.
      *
@@ -3235,6 +3331,19 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
         return this.asAdmin().addStep(new RangeGlobalStep<>(this.asAdmin(), 
skip, -1));
     }
 
+    /**
+     * Filters out the first {@code n} objects in the traversal.
+     *
+     * @param skip the number of objects to skip
+     * @return the traversal with an appended {@link RangeGlobalStep}
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#skip-step"; 
target="_blank">Reference Documentation - Skip Step</a>
+     * @since 4.0.0
+     */
+    public default GraphTraversal<S, E> skip(final GValue<Long> skip) {
+        this.asAdmin().getGremlinLang().addStep(Symbols.skip, skip);
+        return this.asAdmin().addStep(new RangeGlobalStep<>(this.asAdmin(), 
skip, GValue.ofLong(null, -1L)));
+    }
+
     /**
      * Filters out the first {@code n} objects in the traversal.
      *
@@ -3251,6 +3360,22 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
                 : new RangeLocalStep<>(this.asAdmin(), skip, -1));
     }
 
+    /**
+     * Filters out the first {@code n} objects in the traversal.
+     *
+     * @param scope the scope of how to apply the {@code tail}
+     * @param skip  the number of objects to skip
+     * @return the traversal with an appended {@link RangeGlobalStep} or 
{@link RangeLocalStep} depending on {@code scope}
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#skip-step"; 
target="_blank">Reference Documentation - Skip Step</a>
+     * @since 4.0.0
+     */
+    public default <E2> GraphTraversal<S, E2> skip(final Scope scope, final 
GValue<Long> skip) {
+        this.asAdmin().getGremlinLang().addStep(Symbols.skip, scope, skip);
+        return this.asAdmin().addStep(scope.equals(Scope.global)
+                ? new RangeGlobalStep<>(this.asAdmin(), skip, 
GValue.ofLong(null, -1L))
+                : new RangeLocalStep<>(this.asAdmin(), skip, 
GValue.ofLong(null, -1L)));
+    }
+
     /**
      * Once the first {@link Traverser} hits this step, a count down is 
started. Once the time limit is up, all remaining traversers are filtered out.
      *
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
index ac882fe31a..b2285f087e 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
@@ -1306,6 +1306,13 @@ public class __ {
         return __.<A>start().range(low, high);
     }
 
+    /**
+     * @see GraphTraversal#range(GValue, GValue)
+     */
+    public static <A> GraphTraversal<A, A> range(final GValue<Long> low, final 
GValue<Long> high) {
+        return __.<A>start().range(low, high);
+    }
+
     /**
      * @see GraphTraversal#range(Scope, long, long)
      */
@@ -1313,6 +1320,13 @@ public class __ {
         return __.<A>start().range(scope, low, high);
     }
 
+    /**
+     * @see GraphTraversal#range(Scope, GValue, GValue)
+     */
+    public static <A> GraphTraversal<A, A> range(final Scope scope, final 
GValue<Long> low, final GValue<Long> high) {
+        return __.<A>start().range(scope, low, high);
+    }
+
     /**
      * @see GraphTraversal#limit(long)
      */
@@ -1320,6 +1334,13 @@ public class __ {
         return __.<A>start().limit(limit);
     }
 
+    /**
+     * @see GraphTraversal#limit(GValue)
+     */
+    public static <A> GraphTraversal<A, A> limit(final GValue<Long> limit) {
+        return __.<A>start().limit(limit);
+    }
+
     /**
      * @see GraphTraversal#limit(Scope, long)
      */
@@ -1327,6 +1348,13 @@ public class __ {
         return __.<A>start().limit(scope, limit);
     }
 
+    /**
+     * @see GraphTraversal#limit(Scope, GValue)
+     */
+    public static <A> GraphTraversal<A, A> limit(final Scope scope, final 
GValue<Long> limit) {
+        return __.<A>start().limit(scope, limit);
+    }
+
     /**
      * @see GraphTraversal#skip(long)
      */
@@ -1334,6 +1362,13 @@ public class __ {
         return __.<A>start().skip(skip);
     }
 
+    /**
+     * @see GraphTraversal#skip(GValue)
+     */
+    public static <A> GraphTraversal<A, A> skip(final GValue<Long> skip) {
+        return __.<A>start().skip(skip);
+    }
+
     /**
      * @see GraphTraversal#skip(Scope, long)
      */
@@ -1341,6 +1376,13 @@ public class __ {
         return __.<A>start().skip(scope, skip);
     }
 
+    /**
+     * @see GraphTraversal#skip(Scope, GValue)
+     */
+    public static <A> GraphTraversal<A, A> skip(final Scope scope, final 
GValue<Long> skip) {
+        return __.<A>start().skip(scope, skip);
+    }
+
     /**
      * @see GraphTraversal#tail()
      */
@@ -1355,6 +1397,13 @@ public class __ {
         return __.<A>start().tail(limit);
     }
 
+    /**
+     * @see GraphTraversal#tail(GValue)
+     */
+    public static <A> GraphTraversal<A, A> tail(final GValue<Long> limit) {
+        return __.<A>start().tail(limit);
+    }
+
     /**
      * @see GraphTraversal#tail(Scope)
      */
@@ -1369,6 +1418,13 @@ public class __ {
         return __.<A>start().tail(scope, limit);
     }
 
+    /**
+     * @see GraphTraversal#tail(Scope, GValue)
+     */
+    public static <A> GraphTraversal<A, A> tail(final Scope scope, final 
GValue<Long> limit) {
+        return __.<A>start().tail(scope, limit);
+    }
+
     /**
      * @see GraphTraversal#simplePath()
      */
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 9824332785..7b6fc721ab 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -23,6 +23,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Bypassing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Ranging;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
@@ -44,14 +45,18 @@ import java.util.function.BinaryOperator;
  */
 public final class RangeGlobalStep<S> extends FilterStep<S> implements 
Ranging, Bypassing, Barrier<TraverserSet<S>> {
 
-    private long low;
-    private final long high;
+    private GValue<Long> low;
+    private final GValue<Long> high;
     private AtomicLong counter = new AtomicLong(0l);
     private boolean bypass;
 
     public RangeGlobalStep(final Traversal.Admin traversal, final long low, 
final long high) {
+        this(traversal, GValue.ofLong(null, low), GValue.ofLong(null, high));
+    }
+
+    public RangeGlobalStep(final Traversal.Admin traversal, final GValue<Long> 
low, final GValue<Long> high) {
         super(traversal);
-        if (low != -1 && high != -1 && low > high) {
+        if (low.get() != -1 && high.get() != -1 && low.get() > high.get()) {
             throw new IllegalArgumentException("Not a legal range: [" + low + 
", " + high + ']');
         }
         this.low = low;
@@ -62,12 +67,12 @@ public final class RangeGlobalStep<S> extends FilterStep<S> 
implements Ranging,
     protected boolean filter(final Traverser.Admin<S> traverser) {
         if (this.bypass) return true;
 
-        if (this.high != -1 && this.counter.get() >= this.high) {
+        if (this.high.get() != -1 && this.counter.get() >= this.high.get()) {
             throw FastNoSuchElementException.instance();
         }
 
         long avail = traverser.bulk();
-        if (this.counter.get() + avail <= this.low) {
+        if (this.counter.get() + avail <= this.low.get()) {
             // Will not surpass the low w/ this traverser. Skip and filter the 
whole thing.
             this.counter.getAndAdd(avail);
             return false;
@@ -76,13 +81,13 @@ public final class RangeGlobalStep<S> extends FilterStep<S> 
implements Ranging,
         // Skip for the low and trim for the high. Both can happen at once.
 
         long toSkip = 0;
-        if (this.counter.get() < this.low) {
-            toSkip = this.low - this.counter.get();
+        if (this.counter.get() < this.low.get()) {
+            toSkip = this.low.get() - this.counter.get();
         }
 
         long toTrim = 0;
-        if (this.high != -1 && this.counter.get() + avail >= this.high) {
-            toTrim = this.counter.get() + avail - this.high;
+        if (this.high.get() != -1 && this.counter.get() + avail >= 
this.high.get()) {
+            toTrim = this.counter.get() + avail - this.high.get();
         }
 
         long toEmit = avail - toSkip - toTrim;
@@ -100,17 +105,17 @@ public final class RangeGlobalStep<S> extends 
FilterStep<S> implements Ranging,
 
     @Override
     public String toString() {
-        return StringFactory.stepString(this, this.low, this.high);
+        return StringFactory.stepString(this, this.low.get(), this.high.get());
     }
 
     @Override
     public long getLowRange() {
-        return this.low;
+        return this.low.get();
     }
 
     @Override
     public long getHighRange() {
-        return this.high;
+        return this.high.get();
     }
 
     @Override
@@ -122,14 +127,14 @@ public final class RangeGlobalStep<S> extends 
FilterStep<S> implements Ranging,
 
     @Override
     public int hashCode() {
-        return super.hashCode() ^ Long.hashCode(this.low) ^ 
Long.hashCode(this.high);
+        return super.hashCode() ^ Long.hashCode(this.low.get()) ^ 
Long.hashCode(this.high.get());
     }
 
     @Override
     public boolean equals(final Object other) {
         if (super.equals(other)) {
             final RangeGlobalStep typedOther = (RangeGlobalStep) other;
-            return typedOther.low == this.low && typedOther.high == this.high;
+            return typedOther.low.get() == this.low.get() && 
typedOther.high.get() == this.high.get();
         }
         return false;
     }
@@ -142,7 +147,7 @@ public final class RangeGlobalStep<S> extends FilterStep<S> 
implements Ranging,
 
     @Override
     public MemoryComputeKey<TraverserSet<S>> getMemoryComputeKey() {
-        return MemoryComputeKey.of(this.getId(), new 
RangeBiOperator<>(this.high), false, true);
+        return MemoryComputeKey.of(this.getId(), new 
RangeBiOperator<>(this.high.get()), false, true);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailGlobalStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailGlobalStep.java
index cc746c8bb3..293eba24de 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailGlobalStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailGlobalStep.java
@@ -23,6 +23,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Bypassing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
@@ -41,15 +42,19 @@ import java.util.Set;
  */
 public final class TailGlobalStep<S> extends AbstractStep<S, S> implements 
Bypassing, Barrier<TraverserSet<S>> {
 
-    private final long limit;
+    private final GValue<Long> limit;
     private Deque<Traverser.Admin<S>> tail;
     private long tailBulk = 0L;
     private boolean bypass = false;
 
     public TailGlobalStep(final Traversal.Admin traversal, final long limit) {
+        this(traversal, GValue.ofLong(null, limit));
+    }
+
+    public TailGlobalStep(final Traversal.Admin traversal, final GValue<Long> 
limit) {
         super(traversal);
         this.limit = limit;
-        this.tail = new ArrayDeque<>((int) limit);
+        this.tail = new ArrayDeque<>(limit.get().intValue());
     }
 
     public void setBypass(final boolean bypass) {
@@ -69,7 +74,7 @@ public final class TailGlobalStep<S> extends AbstractStep<S, 
S> implements Bypas
             // Pull the oldest traverser from the tail buffer.
             final Traverser.Admin<S> oldest = this.tail.pop();
             // Trim any excess from the oldest traverser.
-            final long excess = this.tailBulk - this.limit;
+            final long excess = this.tailBulk - this.limit.get();
             if (excess > 0) {
                 oldest.setBulk(oldest.bulk() - excess);
                 // Account for the loss of excess in the tail buffer
@@ -90,20 +95,20 @@ public final class TailGlobalStep<S> extends 
AbstractStep<S, S> implements Bypas
 
     @Override
     public String toString() {
-        return StringFactory.stepString(this, this.limit);
+        return StringFactory.stepString(this, this.limit.get());
     }
 
     @Override
     public TailGlobalStep<S> clone() {
         final TailGlobalStep<S> clone = (TailGlobalStep<S>) super.clone();
-        clone.tail = new ArrayDeque<>((int) this.limit);
+        clone.tail = new ArrayDeque<>(this.limit.get().intValue());
         clone.tailBulk = 0L;
         return clone;
     }
 
     @Override
     public int hashCode() {
-        return super.hashCode() ^ Long.hashCode(this.limit);
+        return super.hashCode() ^ Long.hashCode(this.limit.get());
     }
 
     @Override
@@ -118,7 +123,7 @@ public final class TailGlobalStep<S> extends 
AbstractStep<S, S> implements Bypas
         while (!this.tail.isEmpty()) {
             final Traverser.Admin<S> oldest = this.tail.getFirst();
             final long bulk = oldest.bulk();
-            if (this.tailBulk - bulk < limit)
+            if (this.tailBulk - bulk < limit.get())
                 break;
             this.tail.pop();
             this.tailBulk -= bulk;
@@ -129,7 +134,7 @@ public final class TailGlobalStep<S> extends 
AbstractStep<S, S> implements Bypas
 
     @Override
     public MemoryComputeKey<TraverserSet<S>> getMemoryComputeKey() {
-        return MemoryComputeKey.of(this.getId(), new 
RangeGlobalStep.RangeBiOperator<>(this.limit), false, true);
+        return MemoryComputeKey.of(this.getId(), new 
RangeGlobalStep.RangeBiOperator<>(this.limit.get()), false, true);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
index 19b26af911..a1052be995 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
@@ -21,6 +21,7 @@ package 
org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import 
org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
@@ -39,12 +40,16 @@ import java.util.Set;
  */
 public final class RangeLocalStep<S> extends ScalarMapStep<S, S> {
 
-    private final long low;
-    private final long high;
+    private final GValue<Long> low;
+    private final GValue<Long> high;
 
     public RangeLocalStep(final Traversal.Admin traversal, final long low, 
final long high) {
+        this(traversal, GValue.ofLong(null, low), GValue.ofLong(null, high));
+    }
+
+    public RangeLocalStep(final Traversal.Admin traversal, final GValue<Long> 
low, final GValue<Long> high) {
         super(traversal);
-        if (low != -1 && high != -1 && low > high) {
+        if (low.get() != -1 && high.get() != -1 && low.get() > high.get()) {
             throw new IllegalArgumentException("Not a legal range: [" + low + 
", " + high + ']');
         }
         this.low = low;
@@ -52,18 +57,18 @@ public final class RangeLocalStep<S> extends 
ScalarMapStep<S, S> {
     }
 
     public long getLowRange() {
-        return this.low;
+        return this.low.get();
     }
  
     public long getHighRange() {
-        return this.high;
+        return this.high.get();
     } 
  
 
     @Override
     protected S map(final Traverser.Admin<S> traverser) {
         final S start = traverser.get();
-        return applyRange(start, this.low, this.high);
+        return applyRange(start, this.low.get(), this.high.get());
     }
 
     /**
@@ -146,12 +151,12 @@ public final class RangeLocalStep<S> extends 
ScalarMapStep<S, S> {
 
     @Override
     public String toString() {
-        return StringFactory.stepString(this, this.low, this.high);
+        return StringFactory.stepString(this, this.low.get(), this.high.get());
     }
 
     @Override
     public int hashCode() {
-        return super.hashCode() ^ Long.hashCode(this.high) ^ 
Long.hashCode(this.low);
+        return super.hashCode() ^ Long.hashCode(this.high.get()) ^ 
Long.hashCode(this.low.get());
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java
index 9f9770644f..2dbe084db8 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java
@@ -22,6 +22,7 @@ package 
org.apache.tinkerpop.gremlin.process.traversal.step.map;
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -36,9 +37,13 @@ import java.util.Set;
  */
 public final class TailLocalStep<S> extends ScalarMapStep<S, S> {
 
-    private final long limit;
+    private final GValue<Long> limit;
 
     public TailLocalStep(final Traversal.Admin traversal, final long limit) {
+        this(traversal, GValue.ofLong(null, limit));
+    }
+
+    public TailLocalStep(final Traversal.Admin traversal, final GValue<Long> 
limit) {
         super(traversal);
         this.limit = limit;
     }
@@ -55,19 +60,19 @@ public final class TailLocalStep<S> extends 
ScalarMapStep<S, S> {
                                 start instanceof Path ? ((Path) start).size() :
                                         start instanceof Iterable ? 
IteratorUtils.count((Iterable) start) :
                                                 
IteratorUtils.count(IteratorUtils.asIterator(start));
-        final long low = high - this.limit;
+        final long low = high - this.limit.get();
         final S result = RangeLocalStep.applyRange(start, low, high);
         return result;
     }
 
     @Override
     public String toString() {
-        return StringFactory.stepString(this, this.limit);
+        return StringFactory.stepString(this, this.limit.get());
     }
 
     @Override
     public int hashCode() {
-        return super.hashCode() ^ Long.hashCode(this.limit);
+        return super.hashCode() ^ Long.hashCode(this.limit.get());
     }
 
     @Override
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitorTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitorTest.java
index ab5fbdcecb..003039560b 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitorTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/ArgumentVisitorTest.java
@@ -97,6 +97,18 @@ public class ArgumentVisitorTest {
                 {Integer.class, "x", GValue.of("x", 0L), createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", 0L)))},
                 {Integer.class, "x", 0, createAntlr(new 
VariableResolver.DirectVariableResolver(ElementHelper.asMap("x", 0)))},
                 {Integer.class, "x", 0L, createAntlr(new 
VariableResolver.DirectVariableResolver(ElementHelper.asMap("x", 0L)))},
+                {Long.class, "x", new VariableResolverException("x"), 
createAntlr(VariableResolver.NoVariableResolver.instance())},
+                {Long.class, "0", 0L, createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", 100)))},
+                {Long.class, "0i", 0L, createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", 100)))},
+                {Long.class, "0L", 0L, createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", 100)))},
+                {Long.class, "x", GValue.ofLong("x", 0L), createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", (byte) 0)))},
+                {Long.class, "x", GValue.ofLong("x", 0L), createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", (short) 0)))},
+                {Long.class, "x", GValue.ofLong("x", 0L), createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", 0)))},
+                {Long.class, "x", GValue.ofLong("x", 0L), createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", 0L)))},
+                {Long.class, "x", 0L, createAntlr(new 
VariableResolver.DirectVariableResolver(ElementHelper.asMap("x", (byte) 0)))},
+                {Long.class, "x", 0L, createAntlr(new 
VariableResolver.DirectVariableResolver(ElementHelper.asMap("x", (short) 0)))},
+                {Long.class, "x", 0L, createAntlr(new 
VariableResolver.DirectVariableResolver(ElementHelper.asMap("x", 0)))},
+                {Long.class, "x", 0L, createAntlr(new 
VariableResolver.DirectVariableResolver(ElementHelper.asMap("x", 0L)))},
                 {Float.class, "x", new VariableResolverException("x"), 
createAntlr(VariableResolver.NoVariableResolver.instance())},
                 {Float.class, "0.0d", 0.0, createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", 1000.0)))},
                 {Float.class, "0d", 0.0, createAntlr(new 
VariableResolver.DefaultVariableResolver(ElementHelper.asMap("x", 1000.0)))},
@@ -163,6 +175,11 @@ public class ArgumentVisitorTest {
                 final GremlinParser.IntegerArgumentContext ctx = 
parser.integerArgument();
                 return 
antlrToLanguage.argumentVisitor.visitIntegerArgument(ctx);
             });
+        } else if (clazz.equals(Long.class)) {
+            assertParsing(() -> {
+                final GremlinParser.IntegerArgumentContext ctx = 
parser.integerArgument();
+                return antlrToLanguage.argumentVisitor.parseLong(ctx);
+            });
         } else if (clazz.equals(Float.class)) {
             assertParsing(() -> {
                 final GremlinParser.FloatArgumentContext ctx = 
parser.floatArgument();
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index ac6b67bd2f..006ffd72a4 100644
--- 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -340,19 +340,25 @@ const gremlins = {
     g_V_orXoutEXknowsX__hasXlabel_softwareX_or_hasXage_gte_35XX_name: 
[function({g}) { return g.V().or(__.outE("knows"), __.has(T.label, 
"software").or().has("age", P.gte(35))).values("name") }], 
     g_V_asXaX_orXselectXaX_selectXaXX: [function({g}) { return 
g.V().as("a").or(__.select("a"), __.select("a")) }], 
     g_VX1X_out_limitX2X: [function({g, vid1}) { return 
g.V(vid1).out().limit(2) }], 
+    g_VX1X_out_limitX2varX: [function({g, xx1, vid1}) { return 
g.V(vid1).out().limit(xx1) }], 
     g_V_localXoutE_limitX1X_inVX_limitX3X: [function({g}) { return 
g.V().local(__.outE().limit(1)).inV().limit(3) }], 
     g_VX1X_outXknowsX_outEXcreatedX_rangeX0_1X_inV: [function({g, vid1}) { 
return g.V(vid1).out("knows").outE("created").range(0, 1).inV() }], 
     g_VX1X_outXknowsX_outXcreatedX_rangeX0_1X: [function({g, vid1}) { return 
g.V(vid1).out("knows").out("created").range(0, 1) }], 
     g_VX1X_outXcreatedX_inXcreatedX_rangeX1_3X: [function({g, vid1}) { return 
g.V(vid1).out("created").in_("created").range(1, 3) }], 
+    g_VX1X_outXcreatedX_inXcreatedX_rangeX1var_3varX: [function({g, xx1, xx2, 
vid1}) { return g.V(vid1).out("created").in_("created").range(xx1, xx2) }], 
     g_VX1X_outXcreatedX_inEXcreatedX_rangeX1_3X_outV: [function({g, vid1}) { 
return g.V(vid1).out("created").inE("created").range(1, 3).outV() }], 
     g_V_repeatXbothX_timesX3X_rangeX5_11X: [function({g}) { return 
g.V().repeat(__.both()).times(3).range(5, 11) }], 
     g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_2X: 
[function({g}) { return g.V().as("a").in_().as("b").in_().as("c").select("a", 
"b", "c").by("name").limit(Scope.local, 2) }], 
+    g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_2varX: 
[function({g, xx1}) { return 
g.V().as("a").in_().as("b").in_().as("c").select("a", "b", 
"c").by("name").limit(Scope.local, xx1) }], 
     g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_1X: 
[function({g}) { return g.V().as("a").in_().as("b").in_().as("c").select("a", 
"b", "c").by("name").limit(Scope.local, 1) }], 
     g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_rangeXlocal_1_3X: 
[function({g}) { return g.V().as("a").out().as("b").out().as("c").select("a", 
"b", "c").by("name").range(Scope.local, 1, 3) }], 
+    
g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_rangeXlocal_1var_3varX: 
[function({g, xx1, xx2}) { return 
g.V().as("a").out().as("b").out().as("c").select("a", "b", 
"c").by("name").range(Scope.local, xx1, xx2) }], 
     g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_rangeXlocal_1_2X: 
[function({g}) { return g.V().as("a").out().as("b").out().as("c").select("a", 
"b", "c").by("name").range(Scope.local, 1, 2) }], 
     g_V_hasLabelXpersonX_order_byXageX_skipX1X_valuesXnameX: [function({g}) { 
return g.V().hasLabel("person").order().by("age").skip(1).values("name") }], 
+    g_V_hasLabelXpersonX_order_byXageX_skipX1varX_valuesXnameX: [function({g, 
xx1}) { return 
g.V().hasLabel("person").order().by("age").skip(xx1).values("name") }], 
     g_V_foldX_rangeXlocal_6_7X: [function({g}) { return 
g.V().fold().range(Scope.local, 6, 7) }], 
     g_V_outE_valuesXweightX_fold_orderXlocalX_skipXlocal_2X: [function({g}) { 
return 
g.V().outE().values("weight").fold().order(Scope.local).skip(Scope.local, 2) 
}], 
+    g_V_outE_valuesXweightX_fold_orderXlocalX_skipXlocal_2varX: [function({g, 
xx1}) { return 
g.V().outE().values("weight").fold().order(Scope.local).skip(Scope.local, xx1) 
}], 
     g_V_hasLabelXpersonX_order_byXageX_valuesXnameX_skipX1X: [function({g}) { 
return g.V().hasLabel("person").order().by("age").values("name").skip(1) }], 
     g_VX1X_valuesXageX_rangeXlocal_20_30X: [function({g, vid1}) { return 
g.V(vid1).values("age").range(Scope.local, 20, 30) }], 
     g_V_mapXin_hasIdX1XX_limitX2X_valuesXnameX: [function({g, vid1}) { return 
g.V().map(__.in_().hasId(vid1)).limit(2).values("name") }], 
@@ -370,6 +376,7 @@ const gremlins = {
     g_V_both_asXaX_both_asXbX_simplePath_path_byXageX__fromXaX_toXbX: 
[function({g}) { return 
g.V().both().as("a").both().as("b").simplePath().path().by("age").from_("a").to("b")
 }], 
     g_V_valuesXnameX_order_tailXglobal_2X: [function({g}) { return 
g.V().values("name").order().tail(Scope.global, 2) }], 
     g_V_valuesXnameX_order_tailX2X: [function({g}) { return 
g.V().values("name").order().tail(2) }], 
+    g_V_valuesXnameX_order_tailX2varX: [function({g, xx1}) { return 
g.V().values("name").order().tail(xx1) }], 
     g_V_valuesXnameX_order_tail: [function({g}) { return 
g.V().values("name").order().tail() }], 
     g_V_valuesXnameX_order_tailX7X: [function({g}) { return 
g.V().values("name").order().tail(7) }], 
     g_V_repeatXbothX_timesX3X_tailX7X: [function({g}) { return 
g.V().repeat(__.both()).times(3).tail(7) }], 
@@ -377,6 +384,7 @@ const gremlins = {
     
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local,
 1) }], 
     
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local)
 }], 
     g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2X: 
[function({g}) { return g.V().as("a").out().as("b").out().as("c").select("a", 
"b", "c").by("name").tail(Scope.local, 2) }], 
+    g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2varX: 
[function({g, xx1}) { return 
g.V().as("a").out().as("b").out().as("c").select("a", "b", 
"c").by("name").tail(Scope.local, xx1) }], 
     g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_1X: 
[function({g}) { return g.V().as("a").out().as("b").out().as("c").select("a", 
"b", "c").by("name").tail(Scope.local, 1) }], 
     
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local, 1) }], 
     
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local) }], 
diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 
b/gremlin-language/src/main/antlr4/Gremlin.g4
index 8133e751ad..422166578e 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -588,8 +588,8 @@ traversalMethod_label
     ;
 
 traversalMethod_limit
-    : 'limit' LPAREN traversalScope COMMA integerLiteral RPAREN 
#traversalMethod_limit_Scope_long
-    | 'limit' LPAREN integerLiteral RPAREN #traversalMethod_limit_long
+    : 'limit' LPAREN traversalScope COMMA integerArgument RPAREN 
#traversalMethod_limit_Scope_long
+    | 'limit' LPAREN integerArgument RPAREN #traversalMethod_limit_long
     ;
 
 traversalMethod_local
@@ -720,8 +720,8 @@ traversalMethod_propertyMap
     ;
 
 traversalMethod_range
-    : 'range' LPAREN traversalScope COMMA integerLiteral COMMA integerLiteral 
RPAREN #traversalMethod_range_Scope_long_long
-    | 'range' LPAREN integerLiteral COMMA integerLiteral RPAREN 
#traversalMethod_range_long_long
+    : 'range' LPAREN traversalScope COMMA integerArgument COMMA 
integerArgument RPAREN #traversalMethod_range_Scope_long_long
+    | 'range' LPAREN integerArgument COMMA integerArgument RPAREN 
#traversalMethod_range_long_long
     ;
 
 traversalMethod_read
@@ -770,8 +770,8 @@ traversalMethod_simplePath
     ;
 
 traversalMethod_skip
-    : 'skip' LPAREN traversalScope COMMA integerLiteral RPAREN 
#traversalMethod_skip_Scope_long
-    | 'skip' LPAREN integerLiteral RPAREN #traversalMethod_skip_long
+    : 'skip' LPAREN traversalScope COMMA integerArgument RPAREN 
#traversalMethod_skip_Scope_long
+    | 'skip' LPAREN integerArgument RPAREN #traversalMethod_skip_long
     ;
 
 traversalMethod_store
@@ -790,8 +790,8 @@ traversalMethod_sum
 traversalMethod_tail
     : 'tail' LPAREN RPAREN #traversalMethod_tail_Empty
     | 'tail' LPAREN traversalScope RPAREN #traversalMethod_tail_Scope
-    | 'tail' LPAREN traversalScope COMMA integerLiteral RPAREN 
#traversalMethod_tail_Scope_long
-    | 'tail' LPAREN integerLiteral RPAREN #traversalMethod_tail_long
+    | 'tail' LPAREN traversalScope COMMA integerArgument RPAREN 
#traversalMethod_tail_Scope_long
+    | 'tail' LPAREN integerArgument RPAREN #traversalMethod_tail_long
     ;
 
 traversalMethod_fail
diff --git a/gremlin-python/src/main/python/radish/gremlin.py 
b/gremlin-python/src/main/python/radish/gremlin.py
index 247f98b86f..eb81fb997c 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -322,19 +322,25 @@ world.gremlins = {
     'g_V_orXoutEXknowsX__hasXlabel_softwareX_or_hasXage_gte_35XX_name': 
[(lambda g:g.V().or_(__.out_e('knows'), __.has(T.label, 
'software').or_().has('age', P.gte(35))).values('name'))], 
     'g_V_asXaX_orXselectXaX_selectXaXX': [(lambda 
g:g.V().as_('a').or_(__.select('a'), __.select('a')))], 
     'g_VX1X_out_limitX2X': [(lambda g, vid1=None:g.V(vid1).out().limit(2))], 
+    'g_VX1X_out_limitX2varX': [(lambda g, 
xx1=None,vid1=None:g.V(vid1).out().limit(xx1))], 
     'g_V_localXoutE_limitX1X_inVX_limitX3X': [(lambda 
g:g.V().local(__.out_e().limit(1)).in_v().limit(3))], 
     'g_VX1X_outXknowsX_outEXcreatedX_rangeX0_1X_inV': [(lambda g, 
vid1=None:g.V(vid1).out('knows').out_e('created').range_(0, 1).in_v())], 
     'g_VX1X_outXknowsX_outXcreatedX_rangeX0_1X': [(lambda g, 
vid1=None:g.V(vid1).out('knows').out('created').range_(0, 1))], 
     'g_VX1X_outXcreatedX_inXcreatedX_rangeX1_3X': [(lambda g, 
vid1=None:g.V(vid1).out('created').in_('created').range_(1, 3))], 
+    'g_VX1X_outXcreatedX_inXcreatedX_rangeX1var_3varX': [(lambda g, 
xx1=None,xx2=None,vid1=None:g.V(vid1).out('created').in_('created').range_(xx1, 
xx2))], 
     'g_VX1X_outXcreatedX_inEXcreatedX_rangeX1_3X_outV': [(lambda g, 
vid1=None:g.V(vid1).out('created').in_e('created').range_(1, 3).out_v())], 
     'g_V_repeatXbothX_timesX3X_rangeX5_11X': [(lambda 
g:g.V().repeat(__.both()).times(3).range_(5, 11))], 
     'g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_2X': 
[(lambda g:g.V().as_('a').in_().as_('b').in_().as_('c').select('a', 'b', 
'c').by('name').limit(Scope.local, 2))], 
+    'g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_2varX': 
[(lambda g, xx1=None:g.V().as_('a').in_().as_('b').in_().as_('c').select('a', 
'b', 'c').by('name').limit(Scope.local, xx1))], 
     'g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_1X': 
[(lambda g:g.V().as_('a').in_().as_('b').in_().as_('c').select('a', 'b', 
'c').by('name').limit(Scope.local, 1))], 
     'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_rangeXlocal_1_3X': 
[(lambda g:g.V().as_('a').out().as_('b').out().as_('c').select('a', 'b', 
'c').by('name').range_(Scope.local, 1, 3))], 
+    
'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_rangeXlocal_1var_3varX': 
[(lambda g, 
xx1=None,xx2=None:g.V().as_('a').out().as_('b').out().as_('c').select('a', 'b', 
'c').by('name').range_(Scope.local, xx1, xx2))], 
     'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_rangeXlocal_1_2X': 
[(lambda g:g.V().as_('a').out().as_('b').out().as_('c').select('a', 'b', 
'c').by('name').range_(Scope.local, 1, 2))], 
     'g_V_hasLabelXpersonX_order_byXageX_skipX1X_valuesXnameX': [(lambda 
g:g.V().has_label('person').order().by('age').skip(1).values('name'))], 
+    'g_V_hasLabelXpersonX_order_byXageX_skipX1varX_valuesXnameX': [(lambda g, 
xx1=None:g.V().has_label('person').order().by('age').skip(xx1).values('name'))],
 
     'g_V_foldX_rangeXlocal_6_7X': [(lambda g:g.V().fold().range_(Scope.local, 
6, 7))], 
     'g_V_outE_valuesXweightX_fold_orderXlocalX_skipXlocal_2X': [(lambda 
g:g.V().out_e().values('weight').fold().order(Scope.local).skip(Scope.local, 
2))], 
+    'g_V_outE_valuesXweightX_fold_orderXlocalX_skipXlocal_2varX': [(lambda g, 
xx1=None:g.V().out_e().values('weight').fold().order(Scope.local).skip(Scope.local,
 xx1))], 
     'g_V_hasLabelXpersonX_order_byXageX_valuesXnameX_skipX1X': [(lambda 
g:g.V().has_label('person').order().by('age').values('name').skip(1))], 
     'g_VX1X_valuesXageX_rangeXlocal_20_30X': [(lambda g, 
vid1=None:g.V(vid1).values('age').range_(Scope.local, 20, 30))], 
     'g_V_mapXin_hasIdX1XX_limitX2X_valuesXnameX': [(lambda g, 
vid1=None:g.V().map(__.in_().has_id(vid1)).limit(2).values('name'))], 
@@ -352,6 +358,7 @@ world.gremlins = {
     'g_V_both_asXaX_both_asXbX_simplePath_path_byXageX__fromXaX_toXbX': 
[(lambda 
g:g.V().both().as_('a').both().as_('b').simple_path().path().by('age').from_('a').to('b'))],
 
     'g_V_valuesXnameX_order_tailXglobal_2X': [(lambda 
g:g.V().values('name').order().tail(Scope.global_, 2))], 
     'g_V_valuesXnameX_order_tailX2X': [(lambda 
g:g.V().values('name').order().tail(2))], 
+    'g_V_valuesXnameX_order_tailX2varX': [(lambda g, 
xx1=None:g.V().values('name').order().tail(xx1))], 
     'g_V_valuesXnameX_order_tail': [(lambda 
g:g.V().values('name').order().tail())], 
     'g_V_valuesXnameX_order_tailX7X': [(lambda 
g:g.V().values('name').order().tail(7))], 
     'g_V_repeatXbothX_timesX3X_tailX7X': [(lambda 
g:g.V().repeat(__.both()).times(3).tail(7))], 
@@ -359,6 +366,7 @@ world.gremlins = {
     
'g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X':
 [(lambda 
g:g.V().as_('a').out().as_('a').out().as_('a').select('a').by(__.unfold().values('name').fold()).tail(Scope.local,
 1))], 
     
'g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX':
 [(lambda 
g:g.V().as_('a').out().as_('a').out().as_('a').select('a').by(__.unfold().values('name').fold()).tail(Scope.local))],
 
     'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2X': 
[(lambda g:g.V().as_('a').out().as_('b').out().as_('c').select('a', 'b', 
'c').by('name').tail(Scope.local, 2))], 
+    'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2varX': 
[(lambda g, xx1=None:g.V().as_('a').out().as_('b').out().as_('c').select('a', 
'b', 'c').by('name').tail(Scope.local, xx1))], 
     'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_1X': 
[(lambda g:g.V().as_('a').out().as_('b').out().as_('c').select('a', 'b', 
'c').by('name').tail(Scope.local, 1))], 
     
'g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X':
 [(lambda g:g.V().as_('a').out().as_('a').out().as_('a').select(Pop.mixed, 
'a').by(__.unfold().values('name').fold()).tail(Scope.local, 1))], 
     
'g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX':
 [(lambda g:g.V().as_('a').out().as_('a').out().as_('a').select(Pop.mixed, 
'a').by(__.unfold().values('name').fold()).tail(Scope.local))], 
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
index d185d47f8e..cae49f7594 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
@@ -33,6 +33,22 @@ Feature: Step - range()
       | v[lop] |
     And the result should have a count of 2
 
+  Scenario: g_VX1X_out_limitX2varX
+    Given the modern graph
+    And using the parameter vid1 defined as "v[marko].id"
+    And using the parameter xx1 defined as "d[2].i"
+    And the traversal of
+      """
+      g.V(vid1).out().limit(xx1)
+      """
+    When iterated to list
+    Then the result should be of
+      | result |
+      | v[josh] |
+      | v[vadas] |
+      | v[lop] |
+    And the result should have a count of 2
+
   Scenario: g_V_localXoutE_limitX1X_inVX_limitX3X
     Given the modern graph
     And the traversal of
@@ -91,6 +107,23 @@ Feature: Step - range()
       | v[peter] |
     And the result should have a count of 2
 
+  Scenario: g_VX1X_outXcreatedX_inXcreatedX_rangeX1var_3varX
+    Given the modern graph
+    And using the parameter vid1 defined as "v[marko].id"
+    And using the parameter xx1 defined as "d[1].i"
+    And using the parameter xx2 defined as "d[3].i"
+    And the traversal of
+      """
+      g.V(vid1).out("created").in("created").range(xx1, xx2)
+      """
+    When iterated to list
+    Then the result should be of
+      | result |
+      | v[marko] |
+      | v[josh] |
+      | v[peter] |
+    And the result should have a count of 2
+
   Scenario: g_VX1X_outXcreatedX_inEXcreatedX_rangeX1_3X_outV
     Given the modern graph
     And using the parameter vid1 defined as "v[marko].id"
@@ -135,6 +168,19 @@ Feature: Step - range()
       | m[{"a":"lop","b":"josh"}] |
       | m[{"a":"ripple","b":"josh"}] |
 
+  Scenario: 
g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_2varX
+    Given the modern graph
+    And using the parameter xx1 defined as "d[2].i"
+    And the traversal of
+      """
+      
g.V().as("a").in().as("b").in().as("c").select("a","b","c").by("name").limit(Scope.local,
 xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"a":"lop","b":"josh"}] |
+      | m[{"a":"ripple","b":"josh"}] |
+
   Scenario: g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_1X
     Given the modern graph
     And the traversal of
@@ -159,6 +205,20 @@ Feature: Step - range()
       | m[{"b":"josh","c":"lop"}] |
       | m[{"b":"josh","c":"ripple"}] |
 
+  Scenario: 
g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_rangeXlocal_1var_3varX
+    Given the modern graph
+    And using the parameter xx1 defined as "d[1].i"
+    And using the parameter xx2 defined as "d[3].i"
+    And the traversal of
+      """
+      
g.V().as("a").out().as("b").out().as("c").select("a","b","c").by("name").range(Scope.local,
 xx1, xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"b":"josh","c":"lop"}] |
+      | m[{"b":"josh","c":"ripple"}] |
+
   Scenario: 
g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_rangeXlocal_1_2X
     Given the modern graph
     And the traversal of
@@ -184,6 +244,20 @@ Feature: Step - range()
       | josh |
       | peter |
 
+  Scenario: g_V_hasLabelXpersonX_order_byXageX_skipX1varX_valuesXnameX
+    Given the modern graph
+    And using the parameter xx1 defined as "d[1].i"
+    And the traversal of
+      """
+      g.V().hasLabel("person").order().by("age").skip(xx1).values("name")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | marko |
+      | josh |
+      | peter |
+
   @GraphComputerVerificationReferenceOnly
   Scenario: g_V_foldX_rangeXlocal_6_7X
     Given the modern graph
@@ -205,6 +279,18 @@ Feature: Step - range()
       | result |
       | l[d[0.4].d,d[0.5].d,d[1.0].d,d[1.0].d] |
 
+  Scenario: g_V_outE_valuesXweightX_fold_orderXlocalX_skipXlocal_2varX
+    Given the modern graph
+    And using the parameter xx1 defined as "d[2].i"
+    And the traversal of
+      """
+      
g.V().outE().values("weight").fold().order(Scope.local).skip(Scope.local, xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[0.4].d,d[0.5].d,d[1.0].d,d[1.0].d] |
+
   Scenario: g_V_hasLabelXpersonX_order_byXageX_valuesXnameX_skipX1X
     Given the modern graph
     And the traversal of
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Tail.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Tail.feature
index e8a2284c77..1fb3d215bd 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Tail.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Tail.feature
@@ -42,6 +42,19 @@ Feature: Step - tail()
       | ripple |
       | vadas |
 
+  Scenario: g_V_valuesXnameX_order_tailX2varX
+    Given the modern graph
+    And using the parameter xx1 defined as "d[2].i"
+    And the traversal of
+      """
+      g.V().values("name").order().tail(xx1)
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | ripple |
+      | vadas |
+
   Scenario: g_V_valuesXnameX_order_tail
     Given the modern graph
     And the traversal of
@@ -127,6 +140,19 @@ Feature: Step - tail()
       | m[{"b":"josh","c":"ripple"}] |
       | m[{"b":"josh","c":"lop"}] |
 
+  Scenario: 
g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2varX
+    Given the modern graph
+    And using the parameter xx1 defined as "d[2].i"
+    And the traversal of
+      """
+      
g.V().as("a").out().as("b").out().as("c").select("a","b","c").by("name").tail(Scope.local,
 xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"b":"josh","c":"ripple"}] |
+      | m[{"b":"josh","c":"lop"}] |
+
   Scenario: g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_1X
     Given the modern graph
     And the traversal of

Reply via email to