std.xml should just go

retard re at tard.com.invalid
Mon Feb 14 09:54:34 PST 2011


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
>> <SeeWebsiteForEmail at 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


More information about the Digitalmars-d mailing list