Sorry about the Groovy tests. My development environment requires that I boot a Linux VM to run those tests. In this case, because they were already failing in the tinkergraph tests, I didn't follow through on running the hadoop tests. Thanks for fixing them.
On Tue, Jun 23, 2015 at 7:51 AM, Marko Rodriguez <[email protected]> wrote: > Hello Matt, > > I merged your pull request. First, great PR -- thank you for the test > cases. Next, the failures your tests identified are a function of the > non-existent labels in Scope.local situations. What happens is that the > ScopingStrategy says "well, judging from the an analysis of the as() > labels, it looks like this Scoping step doesn't access path information, > but instead, map information." > > > https://github.com/apache/incubator-tinkerpop/blob/master/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java#L51-L54 > > However, if there are no map objects flowing into the Scope step, then a > ClassCastException occurs. The remedy to this is simple. ScopingStrategy > stays the same --- if there aren't path labels, then its okay to think you > are in Scope.local (mainly because its the most efficient state to be in as > path calculations are turned off). However, if the object that the Scoping > step pulls in is NOT a Map, it shouldn't get upset and throw a > ClassCastException. Instead, it should simply assume Collections.emptyMap(). > > > https://github.com/apache/incubator-tinkerpop/blob/master/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java#L70-L74 > > Collections.emptyMap() is the analogous structure to EmptyPath. > > https://github.com/apache/incubator-tinkerpop/blob/master/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/EmptyPath.java > > Now missing labels in a Scoping step behave the same in both Scope.local > and Scope.global. > > Thanks again for your help, > Marko. > > http://markorodriguez.com > > P.S. I notice a lot that your GroovyXXXTest need "fixing up" before > merging to master/. Do you build the code on your local machine? Note the > diff with GroovySelectTest. > > https://github.com/apache/incubator-tinkerpop/commit/161250061a1230ad293915b1d5d19a647d202aae > > > > > > On Jun 22, 2015, at 8:58 PM, Marko Rodriguez <[email protected]> wrote: > > > Hello, > > > > This is what I'm doing first thing tomorrow morning. > > > > Marko. > > > > http://markorodriguez.com > > > > On Jun 22, 2015, at 7:53 PM, Matt Frantz <[email protected]> > wrote: > > > >> Marko, have you had a chance to look at this PR? Do these use cases > make > >> sense? Any idea why they are failing? Should we reopen #619 as a > reminder > >> to keep looking at this PR? It would be nice to settle this for GA. > >> > >> On Sat, Jun 20, 2015 at 9:27 AM, Matt Frantz < > [email protected]> > >> wrote: > >> > >>> Since this was really about creating regressions for TINKERPOP3-619, I > >>> created a PR with those regressions. > >>> > >>> https://github.com/apache/incubator-tinkerpop/pull/86 > >>> > >>> As stated in the PR, a few of these cases now fail, so take a look and > let > >>> me know if I can help. > >>> > >>> On Fri, Jun 19, 2015 at 7:34 PM, Marko Rodriguez <[email protected] > > > >>> wrote: > >>> > >>>> Hey Matt, > >>>> > >>>> Can you make a "formal" ticket about the problem you are seeing, > please? > >>>> > >>>> Thanks, > >>>> Marko. > >>>> > >>>> http://markorodriguez.com > >>>> > >>>> On Jun 19, 2015, at 7:09 PM, Matt Frantz <[email protected]> > >>>> wrote: > >>>> > >>>>> Cool. Can't wait to get my hands on GA! > >>>>> > >>>>> I just read through SelectStep/SelectOneStep (again), and I'm pretty > >>>> sure > >>>>> that if you do a select of a nonexistent label, it will stop the > >>>> traversal > >>>>> rather than raise "step with provided label does not exist" > exception, > >>>> like > >>>>> in olden times. That is because Scoping.getOptionalScopeValueByKey > >>>> checks > >>>>> Path.hasLabel. That makes the Path.get exception case unreachable > from > >>>>> select, which is what we want. Not sure what to do about that, if > >>>>> anything, but I am unsure about regression test coverage. This > >>>> requirement > >>>>> came from TINKERPOP3-619 (select should not throw). > >>>>> > >>>>> g.V().select('a') [should produce nothing] > >>>>> g.V().valueMap().select('a') [should produce nothing] > >>>>> > >>>>> > >>>>> On Fri, Jun 19, 2015 at 12:24 PM, Marko Rodriguez < > [email protected] > >>>>> > >>>>> wrote: > >>>>> > >>>>>> Hi Matt, > >>>>>> > >>>>>> Okay, we now have: > >>>>>> > >>>>>> Pop.first > >>>>>> Pop.last > >>>>>> Pop.all > >>>>>> > >>>>>> And there are two "get" methods: > >>>>>> > >>>>>> A get(label) // could be a singleton, list, or exception > >>>>>> A get(pop,label) // single (or exception if doesn't exist) or > >>>> list > >>>>>> (empty list if does not exist) > >>>>>> > >>>>>> Everything looks the same except: > >>>>>> > >>>>>> path.<List>get(Pop.all, "a").size() > >>>>>> > >>>>>> Good stuff man. Appreciate your patience on the matter --- that was > >>>> like a > >>>>>> 2 month ticket. > >>>>>> > >>>>>> Marko. > >>>>>> > >>>>>> http://markorodriguez.com > >>>>>> > >>>>>> On Jun 16, 2015, at 1:53 PM, Matt Frantz < > [email protected]> > >>>>>> wrote: > >>>>>> > >>>>>>> In contrast to the current "Path.get" (which aligns with the > current > >>>>>>> "select"), specifying Pop.all would ensure that you get a List > even if > >>>>>>> there is only one element. Thus, one could choose between the > >>>>>> "containers > >>>>>>> only when necessary" API and the "predictable type" API. > >>>>>>> > >>>>>>> For context, my application contains loops (repeat-until) that > contain > >>>>>>> labeled steps. Ahead of time, you don't know how many iterations > you > >>>>>> will > >>>>>>> get. Thus, with the current "select" behavior, you don't know > whether > >>>> you > >>>>>>> will get a single element (one iteration) or a List (more than one > >>>>>>> iteration), so there has to be a check and a conversion into > List. I > >>>>>> would > >>>>>>> almost always prefer a predictable type, so I would use Pop.all > when I > >>>>>> want > >>>>>>> a List. (Of course, I sometimes want Pop.last, but that problem is > >>>> now > >>>>>>> solved.) > >>>>>>> > >>>>>>> If you change Path.get(label) to call Path.get(Pop.all, label), > then > >>>>>> select > >>>>>>> would have to be modified, provided you want to preserve the > >>>> "containers > >>>>>>> only when necessary" API. > >>>>>>> > >>>>>>> On Tue, Jun 16, 2015 at 5:13 AM, Marko Rodriguez < > >>>> [email protected]> > >>>>>>> wrote: > >>>>>>> > >>>>>>>> Hi Matt, > >>>>>>>> > >>>>>>>> So I did Pop.first ("return collection[0]") and Pop.last (i.e. > >>>> "return > >>>>>>>> collection[collection.size() - 1]"). Pushed. > >>>>>>>> > >>>>>>>> Next, so by Pop.all you mean "return collection" ? Can you explain > >>>> the > >>>>>>>> context in which this enum would be used? Are you assuming that > >>>>>>>> Path.getSingle() goes away and we have Path.get(Pop, label) with > >>>>>>>> Path.get(label) defaulting to Pop.all? > >>>>>>>> > >>>>>>>> Thanks for your help with this, > >>>>>>>> Marko. > >>>>>>>> > >>>>>>>> http://markorodriguez.com > >>>>>>>> > >>>>>>>> On Jun 15, 2015, at 10:56 AM, Matt Frantz < > >>>> [email protected]> > >>>>>>>> wrote: > >>>>>>>> > >>>>>>>>> How about a third choice that always returns a List? Pop.all? > This > >>>>>>>> would > >>>>>>>>> provide the Java Generic type safety that fills our hearts with > >>>> light. > >>>>>>>>> > >>>>>>>>> On Mon, Jun 15, 2015 at 9:49 AM, Matt Frantz < > >>>>>> [email protected] > >>>>>>>>> > >>>>>>>>> wrote: > >>>>>>>>> > >>>>>>>>>> That works for me. > >>>>>>>>>> > >>>>>>>>>> On Mon, Jun 15, 2015 at 8:55 AM, Marko Rodriguez < > >>>>>> [email protected]> > >>>>>>>>>> wrote: > >>>>>>>>>> > >>>>>>>>>>> Ah. The plot thickens. > >>>>>>>>>>> > >>>>>>>>>>> I prefer to keep limit() and tail(). > >>>>>>>>>>> > >>>>>>>>>>> What if we do: > >>>>>>>>>>> > >>>>>>>>>>> Pop.first (was Pop.tail) > >>>>>>>>>>> Pop.last (was Pop.head) > >>>>>>>>>>> > >>>>>>>>>>> Is then everything else consistent? > >>>>>>>>>>> > >>>>>>>>>>> Marko. > >>>>>>>>>>> > >>>>>>>>>>> http://markorodriguez.com > >>>>>>>>>>> > >>>>>>>>>>> On Jun 15, 2015, at 9:15 AM, Matt Frantz < > >>>> [email protected] > >>>>>>> > >>>>>>>>>>> wrote: > >>>>>>>>>>> > >>>>>>>>>>>> In addition to unfold().tail(), there is tail(local), which is > >>>>>>>>>>> consistent > >>>>>>>>>>>> with unfold().tail() in that it grabs the "end" of the List > (or > >>>>>> Map). > >>>>>>>>>>>> > >>>>>>>>>>>> By "consistent throughout", I guess you mean "select's use of > >>>>>>>> head/tail > >>>>>>>>>>>> terminology should be consistent with established terminology > in > >>>>>> graph > >>>>>>>>>>>> theory." You also say that List.iterator() emits values > >>>>>> left-to-right > >>>>>>>>>>>> (tail to head). However, the terminology that I am accustomed > >>>> to is > >>>>>>>>>>>> described on the wiki for a Linked list: "The 'head' of a > list is > >>>>>> its > >>>>>>>>>>> first > >>>>>>>>>>>> node. The 'tail' of a list may refer either to the rest of the > >>>> list > >>>>>>>>>>> after > >>>>>>>>>>>> the head, or to the last node in the list." > >>>>>>>>>>>> > >>>>>>>>>>>> This terminology resonates in a cursory search ("stream head > >>>> tail") > >>>>>> to > >>>>>>>>>>>> describe streams, i.e. "head" means the first thing that comes > >>>> out > >>>>>> of > >>>>>>>> a > >>>>>>>>>>>> stream, while "tail" means "everything except the head." > With an > >>>>>>>>>>> integer > >>>>>>>>>>>> argument, "head(n)" resembles Gremlin's "limit(n)", if you > think > >>>> of > >>>>>> a > >>>>>>>>>>>> Gremlin traversal as a stream that produces traversers. > >>>>>>>>>>>> > >>>>>>>>>>>> The use of "head" and "tail" as Unix utilities is currently > >>>>>> consistent > >>>>>>>>>>> with > >>>>>>>>>>>> the tail step's usage, in that they refer, respectively, to > the > >>>>>> first > >>>>>>>>>>> and > >>>>>>>>>>>> last objects in the stream. > >>>>>>>>>>>> > >>>>>>>>>>>> I feel that the two uses of "tail" should be consistent with > each > >>>>>>>> other > >>>>>>>>>>>> within Gremlin, but I can see that they are currently drawn > from > >>>>>>>>>>> different > >>>>>>>>>>>> disciplines of computer science. My preference would be to > >>>> replace > >>>>>>>>>>>> "limit/tail" with "first/last" to avoid such ambiguity. > Then, we > >>>>>> can > >>>>>>>>>>> swap > >>>>>>>>>>>> Pop head/tail as it was in the beginning. > >>>>>>>>>>>> > >>>>>>>>>>>> The idea of making "limit" and "tail" more obviously symmetric > >>>>>> belies > >>>>>>>>>>> the > >>>>>>>>>>>> origin of "limit" as a terminology ported from RDBMS (I > >>>> presume). I > >>>>>>>> am > >>>>>>>>>>> not > >>>>>>>>>>>> opposed to synonyms/aliases, although the Gremlin language > may be > >>>>>> rich > >>>>>>>>>>>> enough without them. > >>>>>>>>>>>> > >>>>>>>>>>>> I'd be happy to help with whatever solution is agreeable to > the > >>>>>>>>>>> community. > >>>>>>>>>>>> I'll have some TP3 budget in a couple of days. > >>>>>>>>>>>> > >>>>>>>>>>>> My two cents. > >>>>>>>>>>>> > >>>>>>>>>>>> On Mon, Jun 15, 2015 at 6:55 AM, Marko Rodriguez < > >>>>>>>> [email protected]> > >>>>>>>>>>>> wrote: > >>>>>>>>>>>> > >>>>>>>>>>>>> Hi, > >>>>>>>>>>>>> > >>>>>>>>>>>>> So the way the select() puts things into a List (i.e. > >>>> Path.get()), > >>>>>>>>>>>>> currently, is good: > >>>>>>>>>>>>> > >>>>>>>>>>>>> gremlin> g.V().as('a').out('created').as('a').select('a') > >>>>>>>>>>>>> ==>[v[1], v[3]] > >>>>>>>>>>>>> ==>[v[4], v[5]] > >>>>>>>>>>>>> ==>[v[4], v[3]] > >>>>>>>>>>>>> ==>[v[6], v[3]] > >>>>>>>>>>>>> > >>>>>>>>>>>>> In the first result, the "tail/start/initial" is v[1] and the > >>>>>>>>>>>>> "head/end/terminal" is v[3]. That lines up with the tail/head > >>>>>>>>>>> terminology > >>>>>>>>>>>>> in graph theory. However, what is off is that Pop.head/tail > is > >>>>>> wrong: > >>>>>>>>>>>>> > >>>>>>>>>>>>> gremlin> > g.V().as('a').out('created').as('a').select(head,'a') > >>>>>>>>>>>>> ==>v[1] > >>>>>>>>>>>>> ==>v[4] > >>>>>>>>>>>>> ==>v[4] > >>>>>>>>>>>>> ==>v[6] > >>>>>>>>>>>>> > >>>>>>>>>>>>> Pop.head should return v[3] (for the first result). This is a > >>>>>> simple > >>>>>>>>>>> fix > >>>>>>>>>>>>> of just reversing the meaning of Pop.head/tail (2 line fix). > >>>>>>>>>>>>> > >>>>>>>>>>>>> However, the reason you flipped Pop.head/tail to begin with > is > >>>>>>>> because > >>>>>>>>>>> you > >>>>>>>>>>>>> wanted it to align with unfold().tail(). So lets look at > >>>> unfold(). > >>>>>>>>>>>>> > >>>>>>>>>>>>> gremlin> > >>>>>>>>>>> > g.V().as('a').out('created').as('a').select('a').limit(1).unfold() > >>>>>>>>>>>>> ==>v[1] > >>>>>>>>>>>>> ==>v[3] > >>>>>>>>>>>>> gremlin> > >>>>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>> > >>>>>> > >>>> > g.V().as('a').out('created').as('a').select('a').limit(1).unfold().tail(1) > >>>>>>>>>>>>> ==>v[3] > >>>>>>>>>>>>> > >>>>>>>>>>>>> This should emit v[1]. Bumskies! However, this is about how > the > >>>>>>>>>>> "unfolded" > >>>>>>>>>>>>> Iterable is iterated. > >>>>>>>>>>>>> > >>>>>>>>>>>>> gremlin> [1,2,3,4].iterator() > >>>>>>>>>>>>> ==>1 > >>>>>>>>>>>>> ==>2 > >>>>>>>>>>>>> ==>3 > >>>>>>>>>>>>> ==>4 > >>>>>>>>>>>>> > >>>>>>>>>>>>> Unfortunately, when you do List.iterator(), it emits values > >>>>>>>>>>> left-to-right > >>>>>>>>>>>>> (tail to head). Not right-to-left (head to tail). So, we can > >>>> make > >>>>>>>>>>> unfold() > >>>>>>>>>>>>> behave differently by: > >>>>>>>>>>>>> > >>>>>>>>>>>>> gremlin> [1,2,3,4].reverse().iterator() > >>>>>>>>>>>>> ==>4 > >>>>>>>>>>>>> ==>3 > >>>>>>>>>>>>> ==>2 > >>>>>>>>>>>>> ==>1 > >>>>>>>>>>>>> > >>>>>>>>>>>>> …but that is no bueno from a memory conservation standpoint. > I > >>>>>> would > >>>>>>>>>>> argue > >>>>>>>>>>>>> that unfold() has nothing to do with path-semantics, but > >>>> instead, > >>>>>>>> list > >>>>>>>>>>>>> semantics. Therefore, we can argue (in debate) that > >>>>>> "unfold().tail()" > >>>>>>>>>>> is > >>>>>>>>>>>>> not an anomaly of tail(), but one of unfold(). > >>>>>>>>>>>>> > >>>>>>>>>>>>> Thus, to be consistent throughout, all we need to do is flip > >>>>>> Pop.head > >>>>>>>>>>> to > >>>>>>>>>>>>> Pop.tail and vice versa (i.e. as it was originally). > >>>>>>>>>>>>> > >>>>>>>>>>>>> Thoughts?, > >>>>>>>>>>>>> Marko. > >>>>>>>>>>>>> > >>>>>>>>>>>>> http://markorodriguez.com > >>>>>>>>>>>>> > >>>>>>>>>>>>> On Jun 12, 2015, at 12:56 PM, Matt Frantz < > >>>>>>>> [email protected]> > >>>>>>>>>>>>> wrote: > >>>>>>>>>>>>> > >>>>>>>>>>>>>> We could do any of the following: > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> - Rename the "tail" step (e.g. "last") so that we can flip > Pop > >>>>>> back > >>>>>>>>>>> to > >>>>>>>>>>>>>> the way graph theorists presumably expect it to work. > >>>>>>>>>>>>>> - Reverse the way "select" puts things in a List, and flip > Pop > >>>>>> back. > >>>>>>>>>>>>>> - Rename Pop head/tail to oldest/newest (or first/last) > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> On Fri, Jun 12, 2015 at 5:14 AM, Marko Rodriguez < > >>>>>>>>>>> [email protected]> > >>>>>>>>>>>>>> wrote: > >>>>>>>>>>>>>> > >>>>>>>>>>>>>>> Hm… I see what you are saying. The problem is that in graph > >>>>>> theory, > >>>>>>>>>>>>>>> head/tail terms are reversed in Path. > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> Marko. > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> http://markorodriguez.com > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> On Jun 11, 2015, at 3:39 PM, Matt Frantz < > >>>>>>>> [email protected] > >>>>>>>>>>>> > >>>>>>>>>>>>>>> wrote: > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> Another symmetry I was aiming for: > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> ...select(tail, 'a') > >>>>>>>>>>>>>>>> ...select('a').by(unfold.tail(1)) > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> On Thu, Jun 11, 2015 at 2:16 PM, Matt Frantz < > >>>>>>>>>>>>> [email protected] > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> wrote: > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> I was trying to reconcile the way that the > range/limit/tail > >>>>>> steps > >>>>>>>>>>>>>>> operate > >>>>>>>>>>>>>>>>> with how Pop is interpreted. For local scope, the range > >>>>>> ordinals > >>>>>>>>>>> are > >>>>>>>>>>>>>>>>> congruent with the list index ordinals. Thus, "limit(1)" > >>>> means > >>>>>>>>>>>>>>>>> "range(0,1)" which means List.get(0). Since "tail(1)" is > >>>> the > >>>>>>>>>>>>>>> complement of > >>>>>>>>>>>>>>>>> "limit(1)", it means "the highest numbered element" or > >>>>>>>>>>>>>>>>> List.get(List.size()-1). > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> I understand your description of a stream, but I was > trying > >>>> to > >>>>>>>>>>>>> reconcile > >>>>>>>>>>>>>>>>> the terms with Gremlin and not with streams. > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> If you compare a stream with a Unix command line, and how > >>>> the > >>>>>>>>>>> "head" > >>>>>>>>>>>>> and > >>>>>>>>>>>>>>>>> "tail" utilities act, then "head" means "the first lines > you > >>>>>> see" > >>>>>>>>>>> and > >>>>>>>>>>>>>>>>> "tail" means "the last lines you see". > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> For global scope, it seems that "limit(1)" means "the > first > >>>>>>>>>>> traverser" > >>>>>>>>>>>>>>> and > >>>>>>>>>>>>>>>>> "tail(1)" means "the last traverser". For any > Traversal, t, > >>>>>>>>>>>>> t.limit(1) > >>>>>>>>>>>>>>>>> produces the same thing as t.toList().get(0). > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> Good news on select(pop)! > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> On Thu, Jun 11, 2015 at 11:43 AM, Marko Rodriguez < > >>>>>>>>>>>>> [email protected] > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> wrote: > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> Hey, > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> Yes -- "first = tail" and "last = head". > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> A path grows with its "head growing" .. its tail is > static. > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> a-->b-->c-->d-->e > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> the tail is always "a"…the head is "a", then "b", then > "c", > >>>>>> then > >>>>>>>>>>>>> "d"…. > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> In a list or stream, the tail is the first element. > >>>>>>>>>>>>>>>>>> - get(0) for list > >>>>>>>>>>>>>>>>>> - stream().toList().get(0) > >>>>>>>>>>>>>>>>>> In a list or stream, the head is always the most current > >>>>>>>> element. > >>>>>>>>>>>>>>>>>> - get(list.size() - 1) for list > >>>>>>>>>>>>>>>>>> - stream().next() > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> …..? > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> I will hide your interface inside ImmutablePath just > for my > >>>>>>>> sanity > >>>>>>>>>>>>> :). > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> BTW: select(pop) is on its way. > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> Marko. > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> http://markorodriguez.com > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> On Jun 11, 2015, at 12:30 PM, Matt Frantz < > >>>>>>>>>>>>> [email protected]> > >>>>>>>>>>>>>>>>>> wrote: > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> limit(1) means "first" and tail(1) means "last" (in > both > >>>>>> global > >>>>>>>>>>> and > >>>>>>>>>>>>>>>>>> local > >>>>>>>>>>>>>>>>>>> manifestations). > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> In the Path.get results, you get a list whose first > >>>> element > >>>>>> is > >>>>>>>>>>> the > >>>>>>>>>>>>>>>>>>> first/oldest object matching the step label, so that > felt > >>>>>> like > >>>>>>>>>>>>> "head" > >>>>>>>>>>>>>>> to > >>>>>>>>>>>>>>>>>>> me, while the last element is the most recent and thus > >>>>>> "tail". > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> get => [a,b,c,d] > >>>>>>>>>>>>>>>>>>> getSingle(head) => a > >>>>>>>>>>>>>>>>>>> getSingle(tail) => d > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> In other words the following should be equal: > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> ...map{it->it.path().get('foo')}.tail(local, 1) > >>>>>>>>>>>>>>>>>>> ...map{it->it.path().getSingle(tail, 'foo')} > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> I used ImmutablePathImpl because I needed HeadPath to > have > >>>>>> the > >>>>>>>>>>>>>>>>>>> getSingleTail/getSingleHead methods, too. Thus, a > common > >>>>>>>>>>> interface > >>>>>>>>>>>>>>>>>> between > >>>>>>>>>>>>>>>>>>> ImmutablePath and HeadPath was required. The interface > >>>> has > >>>>>>>>>>> package > >>>>>>>>>>>>>>>>>> scope, > >>>>>>>>>>>>>>>>>>> so it is not part of the public API. > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> On Thu, Jun 11, 2015 at 11:12 AM, Marko Rodriguez < > >>>>>>>>>>>>>>> [email protected] > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> wrote: > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> Hi Matt, > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> limit(1) means the most recent value. > >>>>>>>>>>>>>>>>>>>> tail(1) means the oldest value. ? > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> path: [a,b,c,d] > >>>>>>>>>>>>>>>>>>>> a = tail > >>>>>>>>>>>>>>>>>>>> d = head > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> No? > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> Also, why did you do ImmutablePathImpl? Seems that can > >>>> just > >>>>>> be > >>>>>>>>>>>>>>> private > >>>>>>>>>>>>>>>>>>>> methods inside of ImmutablePath? > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> Thanks, > >>>>>>>>>>>>>>>>>>>> Marko. > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> http://markorodriguez.com > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> On Jun 11, 2015, at 11:56 AM, mhfrantz < > >>>> [email protected]> > >>>>>>>>>>> wrote: > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> GitHub user mhfrantz opened a pull request: > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> > https://github.com/apache/incubator-tinkerpop/pull/76 > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> TINKERPOP3-700 Path getSingle/getList improvements > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> As requested in the comments of TINKERPOP3-700. I > also > >>>>>>>>>>> reversed > >>>>>>>>>>>>>>> the > >>>>>>>>>>>>>>>>>>>> sense of `Pop` to align with `tail(local)`. Thus > >>>> `Pop.tail` > >>>>>>>> now > >>>>>>>>>>>>>>> means > >>>>>>>>>>>>>>>>>> the > >>>>>>>>>>>>>>>>>>>> most recent value. > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> You can merge this pull request into a Git > repository by > >>>>>>>>>>> running: > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> $ git pull > >>>>>> https://github.com/RedSeal-co/incubator-tinkerpop > >>>>>>>>>>>>>>>>>>>> TINKERPOP3-700-Path-getSingle > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> Alternatively you can review and apply these changes > as > >>>> the > >>>>>>>>>>> patch > >>>>>>>>>>>>>>> at: > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> > >>>>>> https://github.com/apache/incubator-tinkerpop/pull/76.patch > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> To close this pull request, make a commit to your > >>>>>>>> master/trunk > >>>>>>>>>>>>>>> branch > >>>>>>>>>>>>>>>>>>>>> with (at least) the following in the commit message: > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> This closes #76 > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> ---- > >>>>>>>>>>>>>>>>>>>>> commit e1e1a40b068ffe6da3d321256d6200dee0504074 > >>>>>>>>>>>>>>>>>>>>> Author: mhfrantz <[email protected]> > >>>>>>>>>>>>>>>>>>>>> Date: 2015-06-11T16:47:41Z > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> Add javadoc for Path getList/getSingle > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> commit 4939cf0a22c4fc44a4f86ed3e023fa30e4e872cc > >>>>>>>>>>>>>>>>>>>>> Author: mhfrantz <[email protected]> > >>>>>>>>>>>>>>>>>>>>> Date: 2015-06-11T17:10:27Z > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> Reverse sense of Path.getSingle Pop to align with > >>>>>> tail(local) > >>>>>>>>>>> step > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> commit 027d6319f9ff06ca26d785e83bf17b21364c3dca > >>>>>>>>>>>>>>>>>>>>> Author: mhfrantz <[email protected]> > >>>>>>>>>>>>>>>>>>>>> Date: 2015-06-11T17:51:23Z > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> Optimize MutablePath.getSingle > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> commit 5e9ad8d7dff6c63b9746147a1d255cbf7258cea3 > >>>>>>>>>>>>>>>>>>>>> Author: mhfrantz <[email protected]> > >>>>>>>>>>>>>>>>>>>>> Date: 2015-06-11T17:52:43Z > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> Optimize ImmutablePath getSingle and getList > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> ---- > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>>> --- > >>>>>>>>>>>>>>>>>>>>> If your project is set up for it, you can reply to > this > >>>>>> email > >>>>>>>>>>> and > >>>>>>>>>>>>>>> have > >>>>>>>>>>>>>>>>>>>> your > >>>>>>>>>>>>>>>>>>>>> reply appear on GitHub as well. If your project does > not > >>>>>> have > >>>>>>>>>>> this > >>>>>>>>>>>>>>>>>>>> feature > >>>>>>>>>>>>>>>>>>>>> enabled and wishes so, or if the feature is enabled > but > >>>> not > >>>>>>>>>>>>> working, > >>>>>>>>>>>>>>>>>>>> please > >>>>>>>>>>>>>>>>>>>>> contact infrastructure at [email protected] > or > >>>>>> file > >>>>>>>> a > >>>>>>>>>>>>> JIRA > >>>>>>>>>>>>>>>>>>>> ticket > >>>>>>>>>>>>>>>>>>>>> with INFRA. > >>>>>>>>>>>>>>>>>>>>> --- > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>> > >>>>>>>> > >>>>>>>> > >>>>>> > >>>>>> > >>>> > >>>> > >>> > > > >
