September 20, 2013
On 2013-09-20 12:02, Szymon Gatner wrote:

> Not sure what you mean but C++ has no concept of a range. Apparent there
> is now a study group but atm standard algos are crippled compared to
> "container for".

Oh, I was thinking about D. Sorry for the confusion.

-- 
/Jacob Carlborg
September 20, 2013
On Fri, Sep 20, 2013 at 09:14:28AM +0200, PauloPinto wrote:
> On Thursday, 19 September 2013 at 23:50:04 UTC, H. S. Teoh wrote:
[...]
> I dislike C, and will take C++ safety and abstraction capabilities over C, unless forced to do otherwise.
[...]

C++ does have some parts that improve over C, it's true. But it's also a minefield filled with pitfalls. Due to its insistence with C compatibility, it basically can only paper over C's flaws, but push hard enough and you're floundering in C problems once more. Well, actually, don't even push -- write straightforward code, and it's almost always wrong. And of the exponential number of ways to write *non*-straightforward code, only one is correct (if that even exists in C++ -- maybe I should rather say, only one is least problematic, 'cos they all are).

It's unfortunate that due to C++ basically giving you a gun that can shoot you in the foot backwards while you're aiming at something else (all convniently abstracted away behind wrappers so you won't even notice the bleeding), it's just sooo easy to abuse. As I said many times before, at my job they migrated from C++ back to C, because, for all of its flaws, C at least has a well-understood core and well-known ways of managing its risky parts. The C++ codebase we used to have was completely unmaintainable because it just combines so many C++ features in the worst possible ways -- something inevitable when it has passed through so many hands. Both C and C++ require a lot of coding by convention and extreme attention to detail, but at least in C, mistakes tend to be noticed rather quickly, whereas in C++ you could be coding for months, years, before you even notice anything wrong. And by then, it's too late to fix it because half the codebase is already written in the "wrong" way. (And there are just too many wrong ways to write C++ code.)

It's such a refreshing change whenever I get to work with D in my free time. D does have its own warts and problems, it's true, but it's a world of a difference from C/C++. It's like the difference between being pricked by a needle every now and then vs. drinking glass shards.


T

-- 
Be in denial for long enough, and one day you'll deny yourself of things you wish you hadn't.
September 20, 2013
20-Sep-2013 15:01, Szymon Gatner пишет:
> On Friday, 20 September 2013 at 10:47:52 UTC, Dmitry Olshansky wrote:
>> 20-Sep-2013 14:00, Jacob Carlborg пишет:
>>> On 2013-09-20 11:37, Szymon Gatner wrote:
>>>
>>>> If only std algorithms took containers (by that I mean things that
>>>> container for accepts too) as arguments (and not iterators)... even in
>>>> the form of new functions like foreach_all, transform_all etc.
>>>
>>> Can't a container be a range as well?
>>>
>>
>> For Christ sake no, no and no. For starters range skips/drops elements
>> when iterating, and thusly iteration has its own state that is useless
>> for a container otherwise.
>>
>
> Iteration is a stateful process, ranges are related to the process of
> iteration not to containers. As you say state is useless for containers
> but is necessary to iteration and its context.
>

A text-book example of self-destruction(?).
Ranges (in particular Input/Forward) are not much above encapsulation of iteration, hence must contain that state required to iterate said elements. Which leads to the point that indeed containers have no business being ranges by themselves.

The bottom line is:
sort(container[]);
vs
sort(container);

Where I hardly see how coupling containers with algorithms can bring even slightest benefit.

-- 
Dmitry Olshansky
September 20, 2013
20-Sep-2013 14:55, Szymon Gatner пишет:
> On Friday, 20 September 2013 at 10:47:52 UTC, Dmitry Olshansky wrote:
>> 20-Sep-2013 14:00, Jacob Carlborg пишет:
>>> On 2013-09-20 11:37, Szymon Gatner wrote:
>>>
>>>> If only std algorithms took containers (by that I mean things that
>>>> container for accepts too) as arguments (and not iterators)... even in
>>>> the form of new functions like foreach_all, transform_all etc.
>>>
>>> Can't a container be a range as well?
>>>
>>
>> For Christ sake no, no and no. For starters range skips/drops elements
>> when iterating, and thusly iteration has its own state that is useless
>> for a container otherwise.
>
> That would be a filtering range which adds additional logic that costs
> exactly the same as an if() statement inside a for loop when filtering
> on condition manually.
>
Filtering is just an adapter.
Better examples are traversing e.g. binary-tree depth-first in-order, or post-order and that would require state.
Again it's easy to miss by looking at built-in arrays.

>>
>> TL;DR: Suboptimal, unnatural and error prone are keywords.
>
> Why would it be suboptimal?

If said tree needs to be a range I would be horrified to see how it manges to be at the same time a range that (for the sake of example) traverses said tree depth-first in-order.

Not even talking about trees having no one "natural" range over them.

-- 
Dmitry Olshansky
September 20, 2013
20-Sep-2013 15:08, Nick Sabalausky пишет:
> On Fri, 20 Sep 2013 14:47:38 +0400
> Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
>> For Christ sake no, no and no. For starters range skips/drops
>> elements when iterating, and thusly iteration has its own state that
>> is useless for a container otherwise.
>>
>> The idea of "contange" spreads like virus, no matter how abominable
>> the end result is. The fact that slices sometimes look like
>> containers (BTW ill-suited for anything beyond primitives/PODish
>> stuff )  must be the corner stone of this belief. Strengthened on the
>> motto of trying to make user defined types to mimic behavior of
>> built-ins it leads to a school of thought that it's fine to blend
>> ownership and access.
>
> I can vouch that ease of conflating array/slice/range, while normally
> a wonderful convenience, has indeed led me into confusion when trying to
> make a custom type range-compatible.
>
> I felt naturally inclined to add the range primitives to the type
> itself, but when that led to issues like you described (especially the
> fact that a range *consumes* its elements while iterating, plus the
> inability to provide alternate views of the same data - which is a
> very powerful tool IMO),

Aye.

I finally started to grok that a container
> needs to *provide* a range, and not actually *be* one.
>

This ^^
I can't stress that last statement enough.

> Well, except maybe for output ranges. (I think?)

Output ranges in my mind may wrap a suitable container by ref.

I think that adding 'put' to container is not a bad idea.
It would essentially do insertAny(..) implying that order of insertion is not interesting.

However since there are many ways of inserting items (insertFront/insertBack?) it makes more sense in general
to have simple helper sink. backInserter ? Silly but simple to remember.

>
>>
>> TL;DR: Suboptimal, unnatural and error prone are keywords.
>>
>
> They are? Cool!
>

Yes :)

1. Suboptimal - extra state to worry about, with mutation backed-in. Harder path to immutability/shared.
2. Unnatural - the reason to have ranges in the first place? Now we pass containers to algorithms ... The decoupling is lost.
3. Error prone - unclean semantics. Does iterating a container mutate it? If not what about iterating it twice in a loop (inner-outer)? Is there a copy somewhere? Copy of what? I can go on for days here.

> auto foo(T)(real a, unnatural b, lazy Suboptimal!T opts) {...}
>
> Looks fun! :)
>



-- 
Dmitry Olshansky
September 20, 2013
On Friday, 20 September 2013 at 13:00:49 UTC, H. S. Teoh wrote:
> [...]
> It's unfortunate that due to C++ basically giving you a gun that can
> shoot you in the foot backwards while you're aiming at something else
> (all convniently abstracted away behind wrappers so you won't even
> notice the bleeding)

This seems apt:
"C lets you shoot yourself in the foot.
C++ lets you std::anatomy<limb>(std::dim::Directions.DOWN, std::anatomy::digits<5>).shoot(this)" --@eevee

-Wyatt
September 20, 2013
On Friday, 20 September 2013 at 13:00:49 UTC, H. S. Teoh wrote:
> On Fri, Sep 20, 2013 at 09:14:28AM +0200, PauloPinto wrote:
>> On Thursday, 19 September 2013 at 23:50:04 UTC, H. S. Teoh wrote:
> [...]
>> I dislike C, and will take C++ safety and abstraction capabilities
>> over C, unless forced to do otherwise.
> [...]
>
> C++ does have some parts that improve over C, it's true. But it's also a
> minefield filled with pitfalls. Due to its insistence with C
> compatibility, it basically can only paper over C's flaws, but push hard
> enough and you're floundering in C problems once more. Well, actually,
> don't even push -- write straightforward code, and it's almost always
> wrong. And of the exponential number of ways to write
> *non*-straightforward code, only one is correct (if that even exists in
> C++ -- maybe I should rather say, only one is least problematic, 'cos
> they all are).
>
> It's unfortunate that due to C++ basically giving you a gun that can
> shoot you in the foot backwards while you're aiming at something else
> (all convniently abstracted away behind wrappers so you won't even
> notice the bleeding), it's just sooo easy to abuse. As I said many times
> before, at my job they migrated from C++ back to C, because, for all of
> its flaws, C at least has a well-understood core and well-known ways of
> managing its risky parts. The C++ codebase we used to have was
> completely unmaintainable because it just combines so many C++ features
> in the worst possible ways -- something inevitable when it has passed
> through so many hands. Both C and C++ require a lot of coding by
> convention and extreme attention to detail, but at least in C, mistakes
> tend to be noticed rather quickly, whereas in C++ you could be coding
> for months, years, before you even notice anything wrong. And by then,
> it's too late to fix it because half the codebase is already written in
> the "wrong" way. (And there are just too many wrong ways to write C++
> code.)
>
> It's such a refreshing change whenever I get to work with D in my free
> time. D does have its own warts and problems, it's true, but it's a
> world of a difference from C/C++. It's like the difference between being
> pricked by a needle every now and then vs. drinking glass shards.
>
>
> T

I understand you situation.

In my case, when I met C, I already knew Turbo Pascal, so C seemed a bit of stone age due to string handling, no modules, unsafe by default, no reference types, no OO.

C++ gave me some of the Turbo Pascal comfort back, together with C compatibility and portability. Although writing portable C and C++ code in the 90's, meant lots of #ifdefs.

Anyway, as I mentioned on my previous post, both languages hardly play any role in the type of work my employer targets.

I guess it is always a matter of how we got to learn our tools, and personal experience.

--
Paulo
September 20, 2013
On Friday, 20 September 2013 at 13:32:47 UTC, Dmitry Olshansky wrote:
> 20-Sep-2013 15:01, Szymon Gatner пишет:
>> On Friday, 20 September 2013 at 10:47:52 UTC, Dmitry Olshansky wrote:
>>> 20-Sep-2013 14:00, Jacob Carlborg пишет:
>>>> On 2013-09-20 11:37, Szymon Gatner wrote:
>>>>
>>>>> If only std algorithms took containers (by that I mean things that
>>>>> container for accepts too) as arguments (and not iterators)... even in
>>>>> the form of new functions like foreach_all, transform_all etc.
>>>>
>>>> Can't a container be a range as well?
>>>>
>>>
>>> For Christ sake no, no and no. For starters range skips/drops elements
>>> when iterating, and thusly iteration has its own state that is useless
>>> for a container otherwise.
>>>
>>
>> Iteration is a stateful process, ranges are related to the process of
>> iteration not to containers. As you say state is useless for containers
>> but is necessary to iteration and its context.
>>
>
> A text-book example of self-destruction(?).
> Ranges (in particular Input/Forward) are not much above encapsulation of iteration, hence must contain that state required to iterate said elements. Which leads to the point that indeed containers have no business being ranges by themselves.
>
> The bottom line is:
> sort(container[]);
> vs
> sort(container);
>
> Where I hardly see how coupling containers with algorithms can bring even slightest benefit.

OK so it seems we agree. I never said that containers should be ranges. Ranges are abstraction on iterators and that is it. Single container can have multiple ranges existing at the same time. State is attached to ranges not containers. And most importantly ranges are mutable always, even if underlying container isn't. Ranges are meant to have state. No idea what you mean by self destruction.
September 20, 2013
20-Sep-2013 17:50, Szymon Gatner пишет:
> On Friday, 20 September 2013 at 13:32:47 UTC, Dmitry Olshansky wrote:
>> 20-Sep-2013 15:01, Szymon Gatner пишет:
>>> On Friday, 20 September 2013 at 10:47:52 UTC, Dmitry Olshansky wrote:
[snip]
>>
>> A text-book example of self-destruction(?).
>> Ranges (in particular Input/Forward) are not much above encapsulation
>> of iteration, hence must contain that state required to iterate said
>> elements. Which leads to the point that indeed containers have no
>> business being ranges by themselves.
>>
>> The bottom line is:
>> sort(container[]);
>> vs
>> sort(container);
>>
>> Where I hardly see how coupling containers with algorithms can bring
>> even slightest benefit.
>
> OK so it seems we agree. I never said that containers should be ranges.
> Ranges are abstraction on iterators and that is it. Single container can
> have multiple ranges existing at the same time. State is attached to
> ranges not containers. And most importantly ranges are mutable always,
> even if underlying container isn't. Ranges are meant to have state. No
> idea what you mean by self destruction.

Then it may be a misunderstanding on my part. I was referring to your previous reply. Where I basically said:

>> Can't a container be a range as well?
>>

>For Christ sake no, no and no.

[... Because that would be ...]

> TL;DR: Suboptimal, unnatural and error prone are keywords.

Then your question - Why would it be suboptimal?

Which your second reply seem to clearly explain: extra state placed where it doesn't belong. I can't easily correlate your two answers as they look as if the second one answers questions of the first.
Anyhow we are in agreement here.

-- 
Dmitry Olshansky
September 20, 2013
On Friday, 20 September 2013 at 14:04:06 UTC, Dmitry Olshansky wrote:
> 20-Sep-2013 17:50, Szymon Gatner пишет:
>> On Friday, 20 September 2013 at 13:32:47 UTC, Dmitry Olshansky wrote:
>>> 20-Sep-2013 15:01, Szymon Gatner пишет:
>>>> On Friday, 20 September 2013 at 10:47:52 UTC, Dmitry Olshansky wrote:
> [snip]
>>>
>>> A text-book example of self-destruction(?).
>>> Ranges (in particular Input/Forward) are not much above encapsulation
>>> of iteration, hence must contain that state required to iterate said
>>> elements. Which leads to the point that indeed containers have no
>>> business being ranges by themselves.
>>>
>>> The bottom line is:
>>> sort(container[]);
>>> vs
>>> sort(container);
>>>
>>> Where I hardly see how coupling containers with algorithms can bring
>>> even slightest benefit.
>>
>> OK so it seems we agree. I never said that containers should be ranges.
>> Ranges are abstraction on iterators and that is it. Single container can
>> have multiple ranges existing at the same time. State is attached to
>> ranges not containers. And most importantly ranges are mutable always,
>> even if underlying container isn't. Ranges are meant to have state. No
>> idea what you mean by self destruction.
>
> Then it may be a misunderstanding on my part. I was referring to your previous reply. Where I basically said:
>
> >> Can't a container be a range as well?
> >>
>
> >For Christ sake no, no and no.
>
> [... Because that would be ...]
>
> > TL;DR: Suboptimal, unnatural and error prone are keywords.
>
> Then your question - Why would it be suboptimal?
>
> Which your second reply seem to clearly explain: extra state placed where it doesn't belong. I can't easily correlate your two answers as they look as if the second one answers questions of the first.
> Anyhow we are in agreement here.

Mind that "Can't a container be a range as well?" was not from me. Still, moving computation over a range from for loop body into the range implementation (like filtering) incurs no performance penalty and has additional benefits of composability and maintainability. Do you mean that is suboptimal?