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.
>> >>>>>>>>>> ---
>> >>>>>>>>>
>> >>>>>>>>>
>> >>>>>>>
>> >>>>>>>
>> >>>>>>
>> >>>>
>> >>>>
>> >>
>> >>
>>
>>
>

Reply via email to