Mon, 14 Feb 2011 18:48:53 +0100, spir wrote: > On 02/14/2011 04:11 PM, Steven Schveighoffer wrote: >> On Fri, 11 Feb 2011 19:06:48 -0500, Andrei Alexandrescu >> <seewebsiteforem...@erdani.org> wrote: >> >>> On 2/11/11 8:31 AM, Bruno Medeiros wrote: >>>> On 04/02/2011 16:14, Eric Poggel wrote: >>>>> On 2/3/2011 10:20 PM, Andrei Alexandrescu wrote: >>>>>> At this point there is no turning back from ranges, unless we come >>>>>> about with an even better idea (I discussed one with Walter but >>>>>> we're not pursuing it yet). >>>>> >>>>> Care to elaborate on the new idea? Or at least a quick summary so >>>>> we're not all left wondering? >>>> >>>> That comment left me curious as well... >>> >>> The discussed idea went as follows. >>> >>> Currently we have r.front and r.back for accessing the first and last >>> element, and r[n] for an arbitrary element. >>> >>> Plus, r[n] is extremely flexible (opIndex, opIndexAssign, >>> opIndexOpAssign... awesome level of control... just perfect). So then >>> I thought, how about unifying everything? >>> >>> Imagine we gave up on r.front and r.back. Poof. They disappeared. Now >>> we define two entities "first" and last" such that r[first] and >>> r[last] refer the first and last elements in the range. Now we have >>> the situ: >>> >>> - Input and forward ranges statically allow only r[first] >>> >>> - Bidirectional ranges allow r[first] and r[last] >>> >>> - Random-access ranges allow r[first], r[last], and r[n] for integrals >>> n >>> >>> Now we have a unified way of referring to elements in ranges. Walter's >>> excellent follow-up is that the compiler could use lowering such that >>> you don't even need to use first and last. You'd just use r[0] and r[$ >>> - 1] and the compiler would take care of handling these special cases. >> >> er... I don't like this. 0 does not necessarily mean first element. A >> map has arbitrary keys. >> >> That is, even though it potentially could be unambiguous (the compiler >> could ensure that it is indeed a range type before allowing the >> conversion of 0 to first), there would be confusion where [0] *didn't* >> mean first element. >> >> >>> Advantages: unified syntax, increased flexibility with opIndexAssign >>> and opIndexOpAssign. Disadvantages: breaks all range-oriented code out >>> there. >> >> opIndexOpAssign is really the only improvement. I think code-wise, >> things would get uglier. For example, in a bidirectional range, front() >> and back() do not simply translate to some index that can be applied to >> another function. However, in random-access ranges, front() can simply >> be defined as opIndex. So for, random-access ranges, code gets shorter, >> but not necessarily simpler (slightly less boilerplate) but >> bidirectional ranges get much uglier (static ifs and the like). >> >> But I agree the opIndexOpAssign is a missing piece for front and back. >> >> But let's think about something else -- you want first and last, but >> front and back also work. What if we continued to use front and back, >> kept the current functions, but treated r[front] and r[back] as you >> say? Then, you'd have some rule for r[front] like: >> >> 1. if front() is defined, translates to r.front() 2. if opIndex is >> defined, translates to r.opIndex[0], although I would prefer some >> symbol other than 0, because I'd like to use it on a custom map type to >> mean "front element". >> >> And then all existing ranges still work, with the new syntax, and you >> can keep the clear separation of functions for when it makes sense. > > I'd also like r.rest or r[rest] (meaning lisp's cdr = all but first). > Rather frequent needs in functions à la reduce (take first element as > seed, then iterate/recurse on rest), and recursive functional algorithms > in general. What do you think? > > functional 'in': > > bool contains (E) (E[] elements, E element) { > if (elements.length == 0) > return false; > if (elements[0] == element) > return true; > return contains(elements.rest(), element); > } > > [By the way, I'm looking for a clear explanation of how tail recursion > elimination is typically implemented: pointer welcome off list if you > have that.]
http://en.wikipedia.org/wiki/Tail_recursion#Implementation_methods