October 01, 2015
On 10/1/2015 11:18 AM, Ali Çehreli wrote:
>  From the days that I used to frequent comp.lang.c++.moderated (before around
> 2009 or so), I remember an individual who was trying to sell the idea of ranges
> to the C++ community. As I remember, nobody took him seriously at that time.
> Reading the page above, I think that individual must have been John Torjo or
> Matthew Wilson.

It was Andrei's talk "Iterators Must Go" that was the turning point for C++ to start paying attention to ranges.

C++ was inspirational to D in the foundational work with iterators. But iterators are not ranges, and I don't see evidence that C++ had ranges before D. Boost ranges are not what we think of as ranges.

It is true that Matthew first implemented ranges in C++, and then D. But the C++ version never got any interest from the C++ community, and went nowhere. I am credited with helping Matthew in the CUJ article talking about his range library. What I helped with was a D design, which he then implemented in C++ :-(

There's probably more in the thousands of emails I have, but I don't want to spend more time spelunking them.
October 01, 2015
On 09/30/2015 06:06 PM, Joakim wrote:
> It is amazing how noisy some of the implementation code with templates
> is in C++: I felt like I was looking at some Haskell variant compared to
> how clean D would look for the same code.

It's easy to write a clean Haskell version, in case you were trying to imply otherwise.
October 02, 2015
On Thursday, 1 October 2015 at 21:03:16 UTC, Walter Bright wrote:
> I don't see evidence that C++ had ranges before D. Boost ranges are not what we think of as ranges.

Why not?

October 02, 2015
On 10/2/2015 10:49 AM, Eric Niebler wrote:
> On Thursday, 1 October 2015 at 21:03:16 UTC, Walter Bright wrote:
>> I don't see evidence that C++ had ranges before D. Boost ranges are not what
>> we think of as ranges.
>
> Why not?

Because it returns iterators. It should expose functions (or operators) that do this:

   front
   popFront
   empty

not iterators. Instead, it has:

   begin
   end
   empty

The begin and end are iterators, and don't encapsulate (i.e. constrain) what can be done with those iterators. For example, begin can return an iterator that can be used to increment right on past the end. The iterator itself has no knowledge of where the end is.

This is the issue that D ranges (and Matthew's and your's) solve. I believe the difference is fundamental.

http://www.boost.org/doc/libs/1_34_0/libs/range/doc/range.html

It's possible I misunderstand it, please correct me if so.
October 03, 2015
On 1 October 2015 at 08:47, H. S. Teoh via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> [...]
> (D has seriously ruined my life; I simply can't bring myself to go back to C++ anymore. At least not voluntarily.)

OMG, this!
Seriously, this is more true than I can express in words ;)
My career is severely damaged by D, because I can't use D at work (no
matter how hard I try, for however many years), and I can't enjoy
coding C++ anymore! >_<


> Also, this seems to confirm that C++ is gradually falling to the position where it's playing catch-up with respect to innovations in newer languages like D and Rust. The fact that ranges are being proposed for the C++ standard library is a big endorsement of D, IMO.

My strategy has been to backport D ideas into C++ over the past year
since my last failed attempt to get D into my office, and this has
been an AGONISING and extremely time consuming process.
I have slices, ranges (as best I can), delegates, and my code is
generally D-ish. Most people in the office like working with it, and
they're starting to realise the connection to D ;)
None of it would be possible without C++11 variadic templates. It's
been the biggest improvement to C++ for a long time, even though some
of the constructs they lead to are far more obtuse than anything I've
ever seen emerge in C++ before.
October 05, 2015
On 10/2/15 6:57 PM, Walter Bright wrote:
> On 10/2/2015 10:49 AM, Eric Niebler wrote:
>> On Thursday, 1 October 2015 at 21:03:16 UTC, Walter Bright wrote:
>>> I don't see evidence that C++ had ranges before D. Boost ranges are
>>> not what
>>> we think of as ranges.
>>
>> Why not?
>
> Because it returns iterators. It should expose functions (or operators)
> that do this:
>
>     front
>     popFront
>     empty
>
> not iterators. Instead, it has:
>
>     begin
>     end
>     empty
>
> The begin and end are iterators, and don't encapsulate (i.e. constrain)
> what can be done with those iterators. For example, begin can return an
> iterator that can be used to increment right on past the end. The
> iterator itself has no knowledge of where the end is.

The solution to this is cursors. i.e. ranges that point at exactly one element.

All dcollection ranges have begin and end accessors for cursors to the first and one beyond the last element, but unlike iterators you cannot do anything dangerous with them.

What you CAN do, is construct ranges from them safely (there is a slight cost for this). The interface is much superior IMO to how containers do ranges in std.container.

There is a deficiency in ranges in that they are very fragile when it comes to pointing at one element. Iterators are much better in this regard.

-Steve
October 05, 2015
On Friday, 2 October 2015 at 22:57:52 UTC, Walter Bright wrote:
> On 10/2/2015 10:49 AM, Eric Niebler wrote:
>> On Thursday, 1 October 2015 at 21:03:16 UTC, Walter Bright wrote:
>>> I don't see evidence that C++ had ranges before D. Boost ranges are not what
>>> we think of as ranges.
>>
>> Why not?
>
> Because it returns iterators. It should expose functions (or operators) that do this:
>
>    front
>    popFront
>    empty
>
> not iterators. Instead, it has:
>
>    begin
>    end
>    empty
>
> The begin and end are iterators, and don't encapsulate (i.e. constrain) what can be done with those iterators. For example, begin can return an iterator that can be used to increment right on past the end. The iterator itself has no knowledge of where the end is.


For a D range, what happens if you popFront from an empty range? An assertion, I'm guessing. It is not hard for a C++ iterator to do the same, and many debug standard libraries have iterators that do that.


> This is the issue that D ranges (and Matthew's and your's) solve. I believe the difference is fundamental.


A C++ iterator can store a pointer back to its range and implement all its core functionality in terms of simple operations like current, next, and done. The Boost.Iterators and Boost.Range libraries made that possible and have been around a long time.

Some iterators can be implemented more efficiently without an indirection to the range. Those iterators are unsafe in the way you describe. The win is that iterators are a more powerful basis for building algorithms (i.e., you can express more with them).


> http://www.boost.org/doc/libs/1_34_0/libs/range/doc/range.html
>
> It's possible I misunderstand it, please correct me if so.


October 05, 2015
On Thursday, 1 October 2015 at 07:37:28 UTC, deadalnix wrote:
> Well, yes and no. Sure I'm sure there are precedent for ranges, be it in C++ or even I'm sure one can find them in other languages. I'm sure someone in the 70s had something like ranges already.

Yes, certainly in the 70s, but I would be surprised if something like it was not done for Lisp in the 60s? What D/C++ call ranges is iterators/generators. C++ mislabeled "table-pointers" as "iterators", which is a source for endless confusion. Co-routines, like the ones in Simula which was "stackless", can be viewed as a heavy async version of iterators/generators too. Adapters can be hooked up at runtime also (if speed is not a priority).

So, "ranges" are very common, with varying syntax/performance.

October 05, 2015
On Saturday, 3 October 2015 at 08:58:26 UTC, Manu wrote:
> My strategy has been to backport D ideas into C++ over the past year
> since my last failed attempt to get D into my office, and this has
> been an AGONISING and extremely time consuming process.
> I have slices, ranges (as best I can), delegates, and my code is
> generally D-ish.

What do you need delegates for when you have flexible function-object lambdas?

Microsoft GSL have array_view for slicing and transferring views of arrays/memory to functions. It supports fixed sized slices (so you don't transfer length) and multi dimensional slices). A bit rough, but usable:

https://github.com/Microsoft/GSL/blob/master/tests/array_view_tests.cpp

October 05, 2015
On 10/5/2015 9:39 AM, Eric Niebler wrote:
> On Friday, 2 October 2015 at 22:57:52 UTC, Walter Bright wrote:
>> The begin and end are iterators, and don't encapsulate (i.e. constrain) what
>> can be done with those iterators. For example, begin can return an iterator
>> that can be used to increment right on past the end. The iterator itself has
>> no knowledge of where the end is.
>
>
> For a D range, what happens if you popFront from an empty range? An assertion,
> I'm guessing.

You'd be right, and this is easy to do because a range encapsulates this knowledge.


> It is not hard for a C++ iterator to do the same, and many debug
> standard libraries have iterators that do that.
>
>
>> This is the issue that D ranges (and Matthew's and your's) solve. I believe
>> the difference is fundamental.
>
>
> A C++ iterator can store a pointer back to its range and implement all its core
> functionality in terms of simple operations like current, next, and done. The
> Boost.Iterators and Boost.Range libraries made that possible and have been
> around a long time.
>
> Some iterators can be implemented more efficiently without an indirection to the
> range. Those iterators are unsafe in the way you describe.

Yes, you can build debug iterators that know their limits, or iterators with back pointers to the range. This is not an inherent property of Boost ranges, does not appear in the Boost description of ranges (unless I missed it), and is a kludge. I do not agree that D ranges owe anything to that design.

In fact, it looks like an attempt to make iterators themselves ranges, rendering the Boost:range rather pointless?